mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-01-14 09:17:55 -05:00
Compare commits
195 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
817c39a130 | ||
|
|
0f02c50834 | ||
|
|
6a64bff370 | ||
|
|
8984dd3eaf | ||
|
|
98a23315d7 | ||
|
|
5748210ea8 | ||
|
|
1dfa23b049 | ||
|
|
ae946308d7 | ||
|
|
d3f06e3b43 | ||
|
|
feaea21c47 | ||
|
|
b51361abe7 | ||
|
|
519248fc7d | ||
|
|
6b4f166eb9 | ||
|
|
4f365524d7 | ||
|
|
8d32c713c5 | ||
|
|
76cf769abf | ||
|
|
44bf59923e | ||
|
|
d535a78e32 | ||
|
|
3ad26de8f0 | ||
|
|
3d39d205d8 | ||
|
|
6fd58ef11c | ||
|
|
f557c0579b | ||
|
|
20b8362887 | ||
|
|
726c0858e4 | ||
|
|
887a6174e9 | ||
|
|
ed6733d177 | ||
|
|
d572d744eb | ||
|
|
e82de9c0f6 | ||
|
|
f5073fa132 | ||
|
|
f9c3316aa5 | ||
|
|
ff13d85625 | ||
|
|
c4f1fe7132 | ||
|
|
b0946c3c60 | ||
|
|
b90bc2459a | ||
|
|
07f644c392 | ||
|
|
2fd9ee403c | ||
|
|
389ce89555 | ||
|
|
75d376f2ef | ||
|
|
3136bde928 | ||
|
|
26a7ba1659 | ||
|
|
9cef39d21a | ||
|
|
92ad04b9b1 | ||
|
|
6fe980e569 | ||
|
|
bb8df1e052 | ||
|
|
61d408f093 | ||
|
|
ba41b4417d | ||
|
|
33bbef963c | ||
|
|
c4f0c9ed06 | ||
|
|
8677a0dbc4 | ||
|
|
ee2a107f3c | ||
|
|
8fb5c1ba4f | ||
|
|
b2b2f97873 | ||
|
|
0045cb21ba | ||
|
|
a8273bf980 | ||
|
|
3e7c570679 | ||
|
|
a34c0c9502 | ||
|
|
2ab714b4fe | ||
|
|
56eec0bc4e | ||
|
|
f528e5e754 | ||
|
|
bdcb2c73af | ||
|
|
9b37f16f11 | ||
|
|
26351096a6 | ||
|
|
a091bb82f9 | ||
|
|
a6d4bf1982 | ||
|
|
0e51cdaccd | ||
|
|
d4b7bd3a1f | ||
|
|
559e735994 | ||
|
|
09caa217c2 | ||
|
|
a35df430db | ||
|
|
05d45e9b27 | ||
|
|
69521b97ce | ||
|
|
c7e538a624 | ||
|
|
44be72a4d9 | ||
|
|
9cfcf8623c | ||
|
|
25c23786af | ||
|
|
47bf5d962b | ||
|
|
a30e6807b1 | ||
|
|
d735c81da0 | ||
|
|
f56515b100 | ||
|
|
74d6635f95 | ||
|
|
e8d0deae78 | ||
|
|
95d6ec7492 | ||
|
|
09c95394e1 | ||
|
|
ddb5dac49d | ||
|
|
265b251a7d | ||
|
|
7539f7af2e | ||
|
|
2f27225e8c | ||
|
|
99ad0cc16c | ||
|
|
70c2c4706f | ||
|
|
9d1af43c91 | ||
|
|
c6fdde8834 | ||
|
|
0174ee082c | ||
|
|
82b7bd3a92 | ||
|
|
1f22c16bee | ||
|
|
f33d4dd4f1 | ||
|
|
9c913f86fa | ||
|
|
f0bb59790a | ||
|
|
391fcc4afa | ||
|
|
7b2fb18a0b | ||
|
|
5596a5c209 | ||
|
|
71750554c3 | ||
|
|
0574b664e8 | ||
|
|
ca0ac814b3 | ||
|
|
c0b3217766 | ||
|
|
12a5271489 | ||
|
|
f4fcf65750 | ||
|
|
92f69b2bca | ||
|
|
742224471f | ||
|
|
086430840e | ||
|
|
82f92fea97 | ||
|
|
d23919c430 | ||
|
|
ada35d8951 | ||
|
|
7e0eb6a92d | ||
|
|
28a1a1d304 | ||
|
|
0c2d3673d3 | ||
|
|
e6f6aa8c85 | ||
|
|
c09d8fbedb | ||
|
|
730a4bcdad | ||
|
|
7466c81414 | ||
|
|
b79ea321a3 | ||
|
|
ae2f72e15d | ||
|
|
f6d63776c3 | ||
|
|
b982b7cd0e | ||
|
|
0b5bac666f | ||
|
|
41b31c7293 | ||
|
|
eaeb77a527 | ||
|
|
ec034e2673 | ||
|
|
ff24e5ce52 | ||
|
|
4549f9a4c5 | ||
|
|
d0be6391c6 | ||
|
|
f70f4f09b7 | ||
|
|
3f5abb3c60 | ||
|
|
ca275c2a1c | ||
|
|
99b7826f1b | ||
|
|
806a442894 | ||
|
|
63ffe0aead | ||
|
|
74e0798f89 | ||
|
|
247b511c6a | ||
|
|
6a8e6a4078 | ||
|
|
42402da526 | ||
|
|
42622b15a9 | ||
|
|
1879af6585 | ||
|
|
a7b1fa51e7 | ||
|
|
38c8b2f35f | ||
|
|
4392d26985 | ||
|
|
2f82b75862 | ||
|
|
459814f58d | ||
|
|
088659f893 | ||
|
|
0e37130f2e | ||
|
|
fb539579c3 | ||
|
|
7c54532010 | ||
|
|
5d57ea785c | ||
|
|
94e29c9a95 | ||
|
|
fe7377aed5 | ||
|
|
e934a42e75 | ||
|
|
294bb4754e | ||
|
|
5eab5f1d22 | ||
|
|
8b775c95ad | ||
|
|
251700549a | ||
|
|
3fbf76e135 | ||
|
|
ca04dd6e47 | ||
|
|
a82f869453 | ||
|
|
f932206213 | ||
|
|
849dd53287 | ||
|
|
e03a87da04 | ||
|
|
29aa9b36fe | ||
|
|
c6472fa617 | ||
|
|
1bbbca6496 | ||
|
|
6b1e9bb82b | ||
|
|
eb22196850 | ||
|
|
3b1c49240b | ||
|
|
ea33c28f1b | ||
|
|
7b251f493d | ||
|
|
0be8c5d161 | ||
|
|
617a2d5b65 | ||
|
|
e1625a0d31 | ||
|
|
4c6cc8d060 | ||
|
|
e6153d9841 | ||
|
|
d83b95bd39 | ||
|
|
4ba1be131c | ||
|
|
8dabec0f9b | ||
|
|
e679cbccf7 | ||
|
|
b18e91f936 | ||
|
|
c31a30d3fa | ||
|
|
99b2578aa7 | ||
|
|
ddfde6810c | ||
|
|
71350d67c4 | ||
|
|
13857a5d71 | ||
|
|
6ce1d36acd | ||
|
|
b2669abecc | ||
|
|
db86dc4d8b | ||
|
|
16b4448fe8 | ||
|
|
af82c1f41f | ||
|
|
3e089ca59d | ||
|
|
8a25195442 |
44
.github/workflows/continuous-integration.yml
vendored
Normal file
44
.github/workflows/continuous-integration.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Based on https://github.com/actions/starter-workflows/blob/master/ci/node.js.yml
|
||||||
|
|
||||||
|
name: Build and Test
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
node-version: [12.x, 14.x, 16.x, 18.x, 20.x]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- run: npm ci
|
||||||
|
|
||||||
|
# Ensure that we can still build in the current version of Node
|
||||||
|
- run: node ./bin/cake build:except-parser
|
||||||
|
- run: node ./bin/cake build:parser
|
||||||
|
# Build twice to ensure that the latest build of the compiler can still build itself
|
||||||
|
- run: node ./bin/cake build:except-parser
|
||||||
|
- run: node ./bin/cake build:parser
|
||||||
|
# Build the browser compiler for the headless browser test
|
||||||
|
- run: node ./bin/cake build:browser
|
||||||
|
# Build test.html, so that test:browser uses the latest tests
|
||||||
|
- run: node ./bin/cake doc:test
|
||||||
|
|
||||||
|
# Check that the git diff is clean, to ensure that the updated build output was committed
|
||||||
|
- run: git diff --exit-code
|
||||||
|
|
||||||
|
# Test
|
||||||
|
- run: node ./bin/cake test
|
||||||
|
- run: node ./bin/cake test:browser || node ./bin/cake test:browser || node ./bin/cake test:browser
|
||||||
|
- run: node ./bin/cake test:browser:node
|
||||||
|
- run: node ./bin/cake test:integrations
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,3 +9,4 @@ parser.output
|
|||||||
/node_modules
|
/node_modules
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
.DS_Store
|
||||||
|
|||||||
20
.travis.yml
20
.travis.yml
@@ -1,20 +0,0 @@
|
|||||||
language: node_js
|
|
||||||
|
|
||||||
node_js:
|
|
||||||
- 6
|
|
||||||
- 8
|
|
||||||
- 10
|
|
||||||
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- node_modules
|
|
||||||
|
|
||||||
script:
|
|
||||||
- node ./bin/cake build:except-parser
|
|
||||||
- node ./bin/cake build:parser
|
|
||||||
- node ./bin/cake build:full
|
|
||||||
- node ./bin/cake build:browser
|
|
||||||
- node ./bin/cake test
|
|
||||||
- node --harmony ./bin/cake test
|
|
||||||
- node ./bin/cake test:browser
|
|
||||||
- node ./bin/cake test:integrations
|
|
||||||
148
Cakefile
148
Cakefile
@@ -21,7 +21,7 @@ header = """
|
|||||||
* CoffeeScript Compiler v#{CoffeeScript.VERSION}
|
* CoffeeScript Compiler v#{CoffeeScript.VERSION}
|
||||||
* https://coffeescript.org
|
* https://coffeescript.org
|
||||||
*
|
*
|
||||||
* Copyright 2011, Jeremy Ashkenas
|
* Copyright 2011-#{new Date().getFullYear()}, Jeremy Ashkenas
|
||||||
* Released under the MIT License
|
* Released under the MIT License
|
||||||
*/
|
*/
|
||||||
"""
|
"""
|
||||||
@@ -66,18 +66,23 @@ build = (callback) ->
|
|||||||
buildParser()
|
buildParser()
|
||||||
buildExceptParser callback
|
buildExceptParser callback
|
||||||
|
|
||||||
transpile = (code) ->
|
transpile = (code, options = {}) ->
|
||||||
|
options.minify = process.env.MINIFY isnt 'false'
|
||||||
|
options.transform = process.env.TRANSFORM isnt 'false'
|
||||||
|
options.sourceType ?= 'script'
|
||||||
babel = require '@babel/core'
|
babel = require '@babel/core'
|
||||||
presets = []
|
presets = []
|
||||||
# Exclude the `modules` plugin in order to not break the `}(this));`
|
# Exclude the `modules` plugin in order to not break the `}(this));`
|
||||||
# at the end of the `build:browser` code block.
|
# at the end of the `build:browser` code block.
|
||||||
presets.push ['@babel/env', {modules: no}] unless process.env.TRANSFORM is 'false'
|
presets.push ['@babel/env', {modules: no}] if options.transform
|
||||||
presets.push ['minify', {mangle: no, evaluate: no, removeUndefined: no}] unless process.env.MINIFY is 'false'
|
presets.push ['minify', {mangle: no, evaluate: no, removeUndefined: no}] if options.minify
|
||||||
babelOptions =
|
babelOptions =
|
||||||
compact: process.env.MINIFY isnt 'false'
|
|
||||||
presets: presets
|
presets: presets
|
||||||
sourceType: 'script'
|
compact: options.minify
|
||||||
{ code } = babel.transform code, babelOptions unless presets.length is 0
|
minified: options.minify
|
||||||
|
comments: not options.minify
|
||||||
|
sourceType: options.sourceType
|
||||||
|
{ code } = babel.transformSync code, babelOptions unless presets.length is 0
|
||||||
code
|
code
|
||||||
|
|
||||||
testBuiltCode = (watch = no) ->
|
testBuiltCode = (watch = no) ->
|
||||||
@@ -140,13 +145,18 @@ task 'build:browser', 'merge the built scripts into a single file for use in a b
|
|||||||
return module.exports;
|
return module.exports;
|
||||||
})();
|
})();
|
||||||
"""
|
"""
|
||||||
|
# From here, we generate two outputs: a legacy script output for all browsers
|
||||||
|
# and a module output for browsers that support `<script type="module">`.
|
||||||
code = """
|
code = """
|
||||||
|
var CoffeeScript = function() {
|
||||||
|
function require(path){ return require[path]; }
|
||||||
|
#{code}
|
||||||
|
return require['./browser'];
|
||||||
|
}();
|
||||||
|
"""
|
||||||
|
scriptCode = transpile """
|
||||||
(function(root) {
|
(function(root) {
|
||||||
var CoffeeScript = function() {
|
#{code}
|
||||||
function require(path){ return require[path]; }
|
|
||||||
#{code}
|
|
||||||
return require['./browser'];
|
|
||||||
}();
|
|
||||||
|
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
define(function() { return CoffeeScript; });
|
define(function() { return CoffeeScript; });
|
||||||
@@ -155,10 +165,25 @@ task 'build:browser', 'merge the built scripts into a single file for use in a b
|
|||||||
}
|
}
|
||||||
}(this));
|
}(this));
|
||||||
"""
|
"""
|
||||||
code = transpile code
|
moduleCode = transpile """
|
||||||
outputFolder = "docs/v#{majorVersion}/browser-compiler"
|
#{code}
|
||||||
fs.mkdirSync outputFolder unless fs.existsSync outputFolder
|
|
||||||
fs.writeFileSync "#{outputFolder}/coffeescript.js", header + '\n' + code
|
export default CoffeeScript;
|
||||||
|
const { VERSION, compile, eval: evaluate, load, run, runScripts } = CoffeeScript;
|
||||||
|
export { VERSION, compile, evaluate as eval, load, run, runScripts };
|
||||||
|
""", {sourceType: 'module'}
|
||||||
|
outputFolders = [
|
||||||
|
"docs/v#{majorVersion}/browser-compiler-legacy"
|
||||||
|
"docs/v#{majorVersion}/browser-compiler-modern"
|
||||||
|
"lib/coffeescript-browser-compiler-legacy"
|
||||||
|
"lib/coffeescript-browser-compiler-modern"
|
||||||
|
]
|
||||||
|
for outputFolder in outputFolders
|
||||||
|
fs.mkdirSync outputFolder unless fs.existsSync outputFolder
|
||||||
|
fs.writeFileSync "#{outputFolder}/coffeescript.js", """
|
||||||
|
#{header}
|
||||||
|
#{if outputFolder.includes('legacy') then scriptCode else moduleCode}
|
||||||
|
"""
|
||||||
|
|
||||||
task 'build:browser:full', 'merge the built scripts into a single file for use in a browser, and test it', ->
|
task 'build:browser:full', 'merge the built scripts into a single file for use in a browser, and test it', ->
|
||||||
invoke 'build:browser'
|
invoke 'build:browser'
|
||||||
@@ -174,11 +199,12 @@ task 'build:watch:harmony', 'watch and continually rebuild the CoffeeScript comp
|
|||||||
|
|
||||||
buildDocs = (watch = no) ->
|
buildDocs = (watch = no) ->
|
||||||
# Constants
|
# Constants
|
||||||
indexFile = 'documentation/site/index.html'
|
indexFile = 'documentation/site/index.html'
|
||||||
siteSourceFolder = "documentation/site"
|
siteSourceFolder = "documentation/site"
|
||||||
sectionsSourceFolder = 'documentation/sections'
|
sectionsSourceFolder = 'documentation/sections'
|
||||||
examplesSourceFolder = 'documentation/examples'
|
changelogSourceFolder = 'documentation/sections/changelog'
|
||||||
outputFolder = "docs/v#{majorVersion}"
|
examplesSourceFolder = 'documentation/examples'
|
||||||
|
outputFolder = "docs/v#{majorVersion}"
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
releaseHeader = (date, version, prevVersion) ->
|
releaseHeader = (date, version, prevVersion) ->
|
||||||
@@ -196,11 +222,11 @@ buildDocs = (watch = no) ->
|
|||||||
markdownRenderer = require('markdown-it')
|
markdownRenderer = require('markdown-it')
|
||||||
html: yes
|
html: yes
|
||||||
typographer: yes
|
typographer: yes
|
||||||
highlight: (str, lang) ->
|
highlight: (str, language) ->
|
||||||
# From https://github.com/markdown-it/markdown-it#syntax-highlighting
|
# From https://github.com/markdown-it/markdown-it#syntax-highlighting
|
||||||
if lang and hljs.getLanguage(lang)
|
if language and hljs.getLanguage(language)
|
||||||
try
|
try
|
||||||
return hljs.highlight(lang, str).value
|
return hljs.highlight(str, { language }).value
|
||||||
catch ex
|
catch ex
|
||||||
return '' # No syntax highlighting
|
return '' # No syntax highlighting
|
||||||
|
|
||||||
@@ -261,7 +287,7 @@ buildDocs = (watch = no) ->
|
|||||||
catch exception
|
catch exception
|
||||||
|
|
||||||
if watch
|
if watch
|
||||||
for target in [indexFile, siteSourceFolder, examplesSourceFolder, sectionsSourceFolder]
|
for target in [indexFile, siteSourceFolder, examplesSourceFolder, sectionsSourceFolder, changelogSourceFolder]
|
||||||
fs.watch target, interval: 200, renderIndex
|
fs.watch target, interval: 200, renderIndex
|
||||||
log 'watching...', green
|
log 'watching...', green
|
||||||
|
|
||||||
@@ -284,7 +310,7 @@ buildDocTests = (watch = no) ->
|
|||||||
# Helpers
|
# Helpers
|
||||||
testsInScriptBlocks = ->
|
testsInScriptBlocks = ->
|
||||||
output = ''
|
output = ''
|
||||||
for filename in fs.readdirSync testsSourceFolder
|
for filename in fs.readdirSync(testsSourceFolder).sort()
|
||||||
if filename.indexOf('.coffee') isnt -1
|
if filename.indexOf('.coffee') isnt -1
|
||||||
type = 'coffeescript'
|
type = 'coffeescript'
|
||||||
else if filename.indexOf('.litcoffee') isnt -1
|
else if filename.indexOf('.litcoffee') isnt -1
|
||||||
@@ -338,15 +364,18 @@ task 'doc:source:watch', 'watch and continually rebuild the annotated source doc
|
|||||||
buildAnnotatedSource yes
|
buildAnnotatedSource yes
|
||||||
|
|
||||||
|
|
||||||
task 'release', 'build and test the CoffeeScript source, and build the documentation', ->
|
task 'release', 'update dependencies, build and test the CoffeeScript source, and build the documentation', ->
|
||||||
execSync '''
|
execSync '''
|
||||||
|
npm install --silent
|
||||||
cake build:full
|
cake build:full
|
||||||
cake build:browser
|
cake build:browser
|
||||||
|
cake doc:test
|
||||||
|
cake test:browser:node
|
||||||
cake test:browser
|
cake test:browser
|
||||||
cake test:integrations
|
cake test:integrations
|
||||||
cake doc:site
|
cake doc:site
|
||||||
cake doc:test
|
cake doc:source
|
||||||
cake doc:source''', stdio: 'inherit'
|
''', stdio: 'inherit'
|
||||||
|
|
||||||
|
|
||||||
task 'bench', 'quick benchmark of compilation time', ->
|
task 'bench', 'quick benchmark of compilation time', ->
|
||||||
@@ -446,6 +475,9 @@ runTests = (CoffeeScript) ->
|
|||||||
skipUnless 'var a = 2 ** 2; a **= 3', ['exponentiation.coffee']
|
skipUnless 'var a = 2 ** 2; a **= 3', ['exponentiation.coffee']
|
||||||
skipUnless 'var {...a} = {}', ['object_rest_spread.coffee']
|
skipUnless 'var {...a} = {}', ['object_rest_spread.coffee']
|
||||||
skipUnless '/foo.bar/s.test("foo\tbar")', ['regex_dotall.coffee']
|
skipUnless '/foo.bar/s.test("foo\tbar")', ['regex_dotall.coffee']
|
||||||
|
skipUnless '1_2_3', ['numeric_literal_separators.coffee']
|
||||||
|
skipUnless '1n', ['numbers_bigint.coffee']
|
||||||
|
skipUnless 'async () => { await import(\'data:application/json,{"foo":"bar"}\', { assert: { type: "json" } }) }', ['import_assertions.coffee']
|
||||||
files = fs.readdirSync('test').filter (filename) ->
|
files = fs.readdirSync('test').filter (filename) ->
|
||||||
filename not in testFilesToSkip
|
filename not in testFilesToSkip
|
||||||
|
|
||||||
@@ -467,8 +499,54 @@ task 'test', 'run the CoffeeScript language test suite', ->
|
|||||||
runTests(CoffeeScript).catch -> process.exit 1
|
runTests(CoffeeScript).catch -> process.exit 1
|
||||||
|
|
||||||
|
|
||||||
task 'test:browser', 'run the test suite against the merged browser script', ->
|
task 'test:browser', 'run the test suite against the modern browser compiler in a headless browser', ->
|
||||||
source = fs.readFileSync "docs/v#{majorVersion}/browser-compiler/coffeescript.js", 'utf-8'
|
# Create very simple web server to serve the two files we need.
|
||||||
|
http = require 'http'
|
||||||
|
serveFile = (res, fileToServe, mimeType) ->
|
||||||
|
res.statusCode = 200
|
||||||
|
res.setHeader 'Content-Type', mimeType
|
||||||
|
fs.createReadStream(fileToServe).pipe res
|
||||||
|
server = http.createServer (req, res) ->
|
||||||
|
if req.url is '/'
|
||||||
|
serveFile res, path.join(__dirname, 'docs', "v#{majorVersion}", 'test.html'), 'text/html'
|
||||||
|
else if req.url is '/browser-compiler-modern/coffeescript.js'
|
||||||
|
# The `text/javascript` MIME type is required for an ES module file to be
|
||||||
|
# loaded in a browser.
|
||||||
|
serveFile res, path.join(__dirname, 'docs', "v#{majorVersion}", 'browser-compiler-modern', 'coffeescript.js'), 'text/javascript'
|
||||||
|
else
|
||||||
|
res.statusCode = 404
|
||||||
|
res.end()
|
||||||
|
|
||||||
|
server.listen 8080, ->
|
||||||
|
puppeteer = require 'puppeteer'
|
||||||
|
browser = await puppeteer.launch()
|
||||||
|
page = await browser.newPage()
|
||||||
|
result = ""
|
||||||
|
|
||||||
|
try
|
||||||
|
await page.goto 'http://localhost:8080/'
|
||||||
|
|
||||||
|
element = await page.waitForSelector '#result',
|
||||||
|
visible: yes
|
||||||
|
polling: 'mutation'
|
||||||
|
timeout: 60000
|
||||||
|
|
||||||
|
result = await page.evaluate ((el) => el.textContent), element
|
||||||
|
catch e
|
||||||
|
log e, red
|
||||||
|
finally
|
||||||
|
try browser.close()
|
||||||
|
server.close()
|
||||||
|
|
||||||
|
if result and not result.includes('failed')
|
||||||
|
log result, green
|
||||||
|
else
|
||||||
|
log result, red
|
||||||
|
process.exit 1
|
||||||
|
|
||||||
|
|
||||||
|
task 'test:browser:node', 'run the test suite against the legacy browser compiler in Node', ->
|
||||||
|
source = fs.readFileSync "lib/coffeescript-browser-compiler-legacy/coffeescript.js", 'utf-8'
|
||||||
result = {}
|
result = {}
|
||||||
global.testingBrowser = yes
|
global.testingBrowser = yes
|
||||||
(-> eval source).call result
|
(-> eval source).call result
|
||||||
@@ -482,10 +560,16 @@ task 'test:integrations', 'test the module integrated with other libraries and e
|
|||||||
# can be built by such tools; if such a build succeeds, it verifies that no
|
# can be built by such tools; if such a build succeeds, it verifies that no
|
||||||
# Node modules are required as part of the compiler (as opposed to the tests)
|
# Node modules are required as part of the compiler (as opposed to the tests)
|
||||||
# and that therefore the compiler will run in a browser environment.
|
# and that therefore the compiler will run in a browser environment.
|
||||||
|
# Webpack 5 requires Node >= 10.13.0.
|
||||||
|
[major, minor] = process.versions.node.split('.').map (n) -> parseInt(n, 10)
|
||||||
|
return if major < 10 or (major is 10 and minor < 13)
|
||||||
tmpdir = os.tmpdir()
|
tmpdir = os.tmpdir()
|
||||||
webpack = require 'webpack'
|
webpack = require 'webpack'
|
||||||
webpack {
|
webpack {
|
||||||
entry: './'
|
entry: './'
|
||||||
|
optimization:
|
||||||
|
# Webpack’s minification causes the CoffeeScript module to fail some tests.
|
||||||
|
minimize: off
|
||||||
output:
|
output:
|
||||||
path: tmpdir
|
path: tmpdir
|
||||||
filename: 'coffeescript.js'
|
filename: 'coffeescript.js'
|
||||||
@@ -503,7 +587,7 @@ task 'test:integrations', 'test the module integrated with other libraries and e
|
|||||||
process.exit 1
|
process.exit 1
|
||||||
|
|
||||||
builtCompiler = path.join tmpdir, 'coffeescript.js'
|
builtCompiler = path.join tmpdir, 'coffeescript.js'
|
||||||
CoffeeScript = require builtCompiler
|
{ CoffeeScript } = require builtCompiler
|
||||||
global.testingBrowser = yes
|
global.testingBrowser = yes
|
||||||
testResults = runTests CoffeeScript
|
testResults = runTests CoffeeScript
|
||||||
fs.unlinkSync builtCompiler
|
fs.unlinkSync builtCompiler
|
||||||
|
|||||||
29
appveyor.yml
29
appveyor.yml
@@ -1,29 +0,0 @@
|
|||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- nodejs_version: '6'
|
|
||||||
- nodejs_version: '8'
|
|
||||||
- nodejs_version: '10'
|
|
||||||
- nodejs_version: '' # Installs latest.
|
|
||||||
|
|
||||||
install:
|
|
||||||
- ps: Install-Product node $env:nodejs_version
|
|
||||||
- node --version
|
|
||||||
- npm --version
|
|
||||||
- npm install
|
|
||||||
|
|
||||||
cache:
|
|
||||||
- node_modules
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- node ./bin/cake build:except-parser
|
|
||||||
- node ./bin/cake build:parser
|
|
||||||
- node ./bin/cake build:full
|
|
||||||
- node ./bin/cake build:browser
|
|
||||||
- node ./bin/cake test
|
|
||||||
- node --harmony ./bin/cake test
|
|
||||||
- node ./bin/cake test:browser
|
|
||||||
- node ./bin/cake test:integrations
|
|
||||||
|
|
||||||
build: off
|
|
||||||
|
|
||||||
version: "{build}"
|
|
||||||
@@ -1 +1 @@
|
|||||||
v2/browser-compiler
|
v2/browser-compiler-legacy
|
||||||
1
docs/browser-compiler-legacy
Symbolic link
1
docs/browser-compiler-legacy
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
v2/browser-compiler-legacy
|
||||||
1
docs/browser-compiler-modern
Symbolic link
1
docs/browser-compiler-modern
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
v2/browser-compiler-modern
|
||||||
@@ -555,7 +555,8 @@ pre .xml .cdata {
|
|||||||
<a href="#destructuring">Destructuring Assignment</a>
|
<a href="#destructuring">Destructuring Assignment</a>
|
||||||
<a href="#fat-arrow">Bound and Generator Functions</a>
|
<a href="#fat-arrow">Bound and Generator Functions</a>
|
||||||
<a href="#embedded">Embedded JavaScript</a>
|
<a href="#embedded">Embedded JavaScript</a>
|
||||||
<a href="#switch">Switch and Try/Catch</a>
|
<a href="#switch">Switch/When/Else</a>
|
||||||
|
<a href="#try-catch">Try/Catch/Finally</a>
|
||||||
<a href="#comparisons">Chained Comparisons</a>
|
<a href="#comparisons">Chained Comparisons</a>
|
||||||
<a href="#strings">String Interpolation, Block Strings, and Block Comments</a>
|
<a href="#strings">String Interpolation, Block Strings, and Block Comments</a>
|
||||||
<a href="#tagged-template-literals">Tagged Template Literals</a>
|
<a href="#tagged-template-literals">Tagged Template Literals</a>
|
||||||
@@ -853,7 +854,7 @@ cubes = (function() {
|
|||||||
<h2>Language Reference</h2>
|
<h2>Language Reference</h2>
|
||||||
<p><em>This reference is structured so that it can be read from top to bottom, if you like. Later sections use ideas and syntax previously introduced. Familiarity with JavaScript is assumed. In all of the following examples, the source CoffeeScript is provided on the left, and the direct compilation into JavaScript is on the right.</em></p>
|
<p><em>This reference is structured so that it can be read from top to bottom, if you like. Later sections use ideas and syntax previously introduced. Familiarity with JavaScript is assumed. In all of the following examples, the source CoffeeScript is provided on the left, and the direct compilation into JavaScript is on the right.</em></p>
|
||||||
<p><em>Many of the examples can be run (where it makes sense) by pressing the <strong>run</strong> button on the right, and can be loaded into the “Try CoffeeScript” console by pressing the <strong>load</strong> button on the left.</em></p>
|
<p><em>Many of the examples can be run (where it makes sense) by pressing the <strong>run</strong> button on the right, and can be loaded into the “Try CoffeeScript” console by pressing the <strong>load</strong> button on the left.</em></p>
|
||||||
<p>First, the basics: CoffeeScript uses significant whitespace to delimit blocks of code. You don’t need to use semicolons <code>;</code> to terminate expressions, ending the line will do just as well (although semicolons can still be used to fit multiple expressions onto a single line). Instead of using curly braces <code>{ }</code> to surround blocks of code in <a href="#literals">functions</a>, <a href="#conditionals">if-statements</a>, <a href="#switch">switch</a>, and <a href="#try">try/catch</a>, use indentation.</p>
|
<p>First, the basics: CoffeeScript uses significant whitespace to delimit blocks of code. You don’t need to use semicolons <code>;</code> to terminate expressions, ending the line will do just as well (although semicolons can still be used to fit multiple expressions onto a single line). Instead of using curly braces <code>{ }</code> to surround blocks of code in <a href="#literals">functions</a>, <a href="#conditionals">if-statements</a>, <a href="#switch">switch</a>, and <a href="#try-catch">try/catch</a>, use indentation.</p>
|
||||||
<p>You don’t need to use parentheses to invoke a function if you’re passing arguments. The implicit call wraps forward to the end of the line or block expression.<br>
|
<p>You don’t need to use parentheses to invoke a function if you’re passing arguments. The implicit call wraps forward to the end of the line or block expression.<br>
|
||||||
<code>console.log sys.inspect object</code> → <code>console.log(sys.inspect(object));</code></p>
|
<code>console.log sys.inspect object</code> → <code>console.log(sys.inspect(object));</code></p>
|
||||||
|
|
||||||
|
|||||||
@@ -112,8 +112,8 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>This <strong>Browser</strong> compatibility layer extends core CoffeeScript functions
|
<p>This <strong>Browser</strong> compatibility layer extends core CoffeeScript functions
|
||||||
to make things work smoothly when compiling code directly in the browser.
|
to make things work smoothly when compiling code directly in the browser.
|
||||||
@@ -123,7 +123,7 @@ We add support for loading remote Coffee scripts via <strong>XHR</strong>, and
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>
|
<div class="content"><div class='highlight'><pre>
|
||||||
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffeescript'</span>
|
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffeescript'</span>
|
||||||
{ compile } = CoffeeScript</pre></div></div>
|
{ compile } = CoffeeScript</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -132,8 +132,8 @@ CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-stri
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Use <code>window.eval</code> to evaluate code, rather than just <code>eval</code>, to run the
|
<p>Use <code>window.eval</code> to evaluate code, rather than just <code>eval</code>, to run the
|
||||||
script in a clean global scope rather than inheriting the scope of the
|
script in a clean global scope rather than inheriting the scope of the
|
||||||
@@ -142,10 +142,10 @@ use either <code>window.eval</code> or <code>global.eval</code> as appropriate).
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>CoffeeScript.eval = <span class="hljs-function"><span class="hljs-params">(code, options = {})</span> -></span>
|
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="hljs-built_in">eval</span> = <span class="hljs-function"><span class="hljs-params">(code, options = {})</span> -></span>
|
||||||
options.bare ?= <span class="hljs-literal">on</span>
|
options.bare ?= <span class="hljs-literal">on</span>
|
||||||
globalRoot = <span class="hljs-keyword">if</span> <span class="hljs-built_in">window</span>? <span class="hljs-keyword">then</span> <span class="hljs-built_in">window</span> <span class="hljs-keyword">else</span> <span class="hljs-built_in">global</span>
|
globalRoot = <span class="hljs-keyword">if</span> window? <span class="hljs-keyword">then</span> window <span class="hljs-keyword">else</span> global
|
||||||
globalRoot[<span class="hljs-string">'eval'</span>] compile code, options</pre></div></div>
|
globalRoot[<span class="hljs-string">'eval'</span>] compile code, options</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -153,8 +153,8 @@ use either <code>window.eval</code> or <code>global.eval</code> as appropriate).
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Running code does not provide access to this scope.</p>
|
<p>Running code does not provide access to this scope.</p>
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ use either <code>window.eval</code> or <code>global.eval</code> as appropriate).
|
|||||||
<div class="content"><div class='highlight'><pre>CoffeeScript.run = <span class="hljs-function"><span class="hljs-params">(code, options = {})</span> -></span>
|
<div class="content"><div class='highlight'><pre>CoffeeScript.run = <span class="hljs-function"><span class="hljs-params">(code, options = {})</span> -></span>
|
||||||
options.bare = <span class="hljs-literal">on</span>
|
options.bare = <span class="hljs-literal">on</span>
|
||||||
options.shiftLine = <span class="hljs-literal">on</span>
|
options.shiftLine = <span class="hljs-literal">on</span>
|
||||||
Function(compile code, options)()</pre></div></div>
|
<span class="hljs-built_in">Function</span>(compile code, options)()</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -171,15 +171,15 @@ use either <code>window.eval</code> or <code>global.eval</code> as appropriate).
|
|||||||
<li id="section-4">
|
<li id="section-4">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-4">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Export this more limited <code>CoffeeScript</code> than what is exported by
|
<p>Export this more limited <code>CoffeeScript</code> than what is exported by
|
||||||
<code>index.coffee</code>, which is intended for a Node environment.</p>
|
<code>index.coffee</code>, which is intended for a Node environment.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">module</span>.exports = CoffeeScript</pre></div></div>
|
<div class="content"><div class='highlight'><pre>module.<span class="hljs-built_in">exports</span> = CoffeeScript</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -187,14 +187,14 @@ use either <code>window.eval</code> or <code>global.eval</code> as appropriate).
|
|||||||
<li id="section-5">
|
<li id="section-5">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>If we’re not in a browser environment, we’re finished with the public API.</p>
|
<p>If we’re not in a browser environment, we’re finished with the public API.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> <span class="hljs-built_in">window</span>?</pre></div></div>
|
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> window?</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -202,8 +202,8 @@ use either <code>window.eval</code> or <code>global.eval</code> as appropriate).
|
|||||||
<li id="section-6">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Include source maps where possible. If we’ve got a base64 encoder, a
|
<p>Include source maps where possible. If we’ve got a base64 encoder, a
|
||||||
JSON serializer, and tools for escaping unicode characters, we’re good to go.
|
JSON serializer, and tools for escaping unicode characters, we’re good to go.
|
||||||
@@ -211,7 +211,7 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> btoa? <span class="hljs-keyword">and</span> JSON?
|
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> btoa? <span class="hljs-keyword">and</span> <span class="hljs-built_in">JSON</span>?
|
||||||
<span class="hljs-function"> <span class="hljs-title">compile</span> = <span class="hljs-params">(code, options = {})</span> -></span>
|
<span class="hljs-function"> <span class="hljs-title">compile</span> = <span class="hljs-params">(code, options = {})</span> -></span>
|
||||||
options.inlineMap = <span class="hljs-literal">true</span>
|
options.inlineMap = <span class="hljs-literal">true</span>
|
||||||
CoffeeScript.compile code, options</pre></div></div>
|
CoffeeScript.compile code, options</pre></div></div>
|
||||||
@@ -222,8 +222,8 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Load a remote script from the current domain via XHR.</p>
|
<p>Load a remote script from the current domain via XHR.</p>
|
||||||
|
|
||||||
@@ -231,19 +231,19 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>CoffeeScript.load = <span class="hljs-function"><span class="hljs-params">(url, callback, options = {}, hold = <span class="hljs-literal">false</span>)</span> -></span>
|
<div class="content"><div class='highlight'><pre>CoffeeScript.load = <span class="hljs-function"><span class="hljs-params">(url, callback, options = {}, hold = <span class="hljs-literal">false</span>)</span> -></span>
|
||||||
options.sourceFiles = [url]
|
options.sourceFiles = [url]
|
||||||
xhr = <span class="hljs-keyword">if</span> <span class="hljs-built_in">window</span>.ActiveXObject
|
xhr = <span class="hljs-keyword">if</span> window.ActiveXObject
|
||||||
<span class="hljs-keyword">new</span> <span class="hljs-built_in">window</span>.ActiveXObject(<span class="hljs-string">'Microsoft.XMLHTTP'</span>)
|
<span class="hljs-keyword">new</span> window.ActiveXObject(<span class="hljs-string">'Microsoft.XMLHTTP'</span>)
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
<span class="hljs-keyword">new</span> <span class="hljs-built_in">window</span>.XMLHttpRequest()
|
<span class="hljs-keyword">new</span> window.XMLHttpRequest()
|
||||||
xhr.open <span class="hljs-string">'GET'</span>, url, <span class="hljs-literal">true</span>
|
xhr.open <span class="hljs-string">'GET'</span>, url, <span class="hljs-literal">true</span>
|
||||||
xhr.overrideMimeType <span class="hljs-string">'text/plain'</span> <span class="hljs-keyword">if</span> <span class="hljs-string">'overrideMimeType'</span> <span class="hljs-keyword">of</span> xhr
|
xhr.overrideMimeType <span class="hljs-string">'text/plain'</span> <span class="hljs-keyword">if</span> <span class="hljs-string">'overrideMimeType'</span> <span class="hljs-keyword">of</span> xhr
|
||||||
xhr.onreadystatechange = <span class="hljs-function">-></span>
|
xhr.onreadystatechange = <span class="hljs-function">-></span>
|
||||||
<span class="hljs-keyword">if</span> xhr.readyState <span class="hljs-keyword">is</span> <span class="hljs-number">4</span>
|
<span class="hljs-keyword">if</span> xhr.readyState <span class="hljs-keyword">is</span> <span class="hljs-number">4</span>
|
||||||
<span class="hljs-keyword">if</span> xhr.status <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, <span class="hljs-number">200</span>]
|
<span class="hljs-keyword">if</span> xhr.status <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, <span class="hljs-number">200</span>]
|
||||||
param = [xhr.responseText, options]
|
param = [xhr.responseText, options]
|
||||||
CoffeeScript.run param... <span class="hljs-keyword">unless</span> hold
|
CoffeeScript.run param... <span class="hljs-keyword">unless</span> hold
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"Could not load <span class="hljs-subst">#{url}</span>"</span>
|
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">"Could not load <span class="hljs-subst">#{url}</span>"</span>
|
||||||
callback param <span class="hljs-keyword">if</span> callback
|
callback param <span class="hljs-keyword">if</span> callback
|
||||||
xhr.send <span class="hljs-literal">null</span></pre></div></div>
|
xhr.send <span class="hljs-literal">null</span></pre></div></div>
|
||||||
|
|
||||||
@@ -253,8 +253,8 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
|
|||||||
<li id="section-8">
|
<li id="section-8">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-8">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Activate CoffeeScript in the browser by having it compile and evaluate
|
<p>Activate CoffeeScript in the browser by having it compile and evaluate
|
||||||
all script tags with a content-type of <code>text/coffeescript</code>.
|
all script tags with a content-type of <code>text/coffeescript</code>.
|
||||||
@@ -262,15 +262,15 @@ This happens on page load.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">runScripts</span> = -></span>
|
<div class="content"><div class='highlight'><pre>CoffeeScript.runScripts = <span class="hljs-function">-></span>
|
||||||
scripts = <span class="hljs-built_in">window</span>.<span class="hljs-built_in">document</span>.getElementsByTagName <span class="hljs-string">'script'</span>
|
scripts = window.document.getElementsByTagName <span class="hljs-string">'script'</span>
|
||||||
coffeetypes = [<span class="hljs-string">'text/coffeescript'</span>, <span class="hljs-string">'text/literate-coffeescript'</span>]
|
coffeetypes = [<span class="hljs-string">'text/coffeescript'</span>, <span class="hljs-string">'text/literate-coffeescript'</span>]
|
||||||
coffees = (s <span class="hljs-keyword">for</span> s <span class="hljs-keyword">in</span> scripts <span class="hljs-keyword">when</span> s.type <span class="hljs-keyword">in</span> coffeetypes)
|
coffees = (s <span class="hljs-keyword">for</span> s <span class="hljs-keyword">in</span> scripts <span class="hljs-keyword">when</span> s.type <span class="hljs-keyword">in</span> coffeetypes)
|
||||||
index = <span class="hljs-number">0</span>
|
index = <span class="hljs-number">0</span>
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">execute</span> = -></span>
|
<span class="hljs-title">execute</span> = -></span>
|
||||||
param = coffees[index]
|
param = coffees[index]
|
||||||
<span class="hljs-keyword">if</span> param <span class="hljs-keyword">instanceof</span> Array
|
<span class="hljs-keyword">if</span> param <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>
|
||||||
CoffeeScript.run param...
|
CoffeeScript.run param...
|
||||||
index++
|
index++
|
||||||
execute()
|
execute()
|
||||||
@@ -278,7 +278,7 @@ This happens on page load.</p>
|
|||||||
<span class="hljs-keyword">for</span> script, i <span class="hljs-keyword">in</span> coffees
|
<span class="hljs-keyword">for</span> script, i <span class="hljs-keyword">in</span> coffees
|
||||||
<span class="hljs-keyword">do</span> (script, i) ->
|
<span class="hljs-keyword">do</span> (script, i) ->
|
||||||
options = literate: script.type <span class="hljs-keyword">is</span> coffeetypes[<span class="hljs-number">1</span>]
|
options = literate: script.type <span class="hljs-keyword">is</span> coffeetypes[<span class="hljs-number">1</span>]
|
||||||
source = script.src <span class="hljs-keyword">or</span> script.getAttribute(<span class="hljs-string">'data-src'</span>)
|
source = script.src <span class="hljs-keyword">or</span> script.getAttribute(<span class="hljs-string">'data-src'</span>)
|
||||||
<span class="hljs-keyword">if</span> source
|
<span class="hljs-keyword">if</span> source
|
||||||
options.filename = source
|
options.filename = source
|
||||||
CoffeeScript.load source,
|
CoffeeScript.load source,
|
||||||
@@ -295,8 +295,8 @@ This happens on page load.</p>
|
|||||||
<li id="section-9">
|
<li id="section-9">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="ss" href="#section-9">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p><code>options.filename</code> defines the filename the source map appears as
|
<p><code>options.filename</code> defines the filename the source map appears as
|
||||||
in Developer Tools. If a script tag has an <code>id</code>, use that as the
|
in Developer Tools. If a script tag has an <code>id</code>, use that as the
|
||||||
@@ -306,8 +306,8 @@ only one CoffeeScript script block to parse.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> options.filename = <span class="hljs-keyword">if</span> script.id <span class="hljs-keyword">and</span> script.id <span class="hljs-keyword">isnt</span> <span class="hljs-string">''</span> <span class="hljs-keyword">then</span> script.id <span class="hljs-keyword">else</span> <span class="hljs-string">"coffeescript<span class="hljs-subst">#{<span class="hljs-keyword">if</span> i <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> i <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>}</span>"</span>
|
<div class="content"><div class='highlight'><pre> options.filename = <span class="hljs-keyword">if</span> script.id <span class="hljs-keyword">and</span> script.id <span class="hljs-keyword">isnt</span> <span class="hljs-string">''</span> <span class="hljs-keyword">then</span> script.id <span class="hljs-keyword">else</span> <span class="hljs-string">"coffeescript<span class="hljs-subst">#{<span class="hljs-keyword">if</span> i <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> i <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>}</span>"</span>
|
||||||
options.sourceFiles = [<span class="hljs-string">'embedded'</span>]
|
options.sourceFiles = [<span class="hljs-string">'embedded'</span>]
|
||||||
coffees[i] = [script.innerHTML, options]
|
coffees[i] = [script.innerHTML, options]
|
||||||
|
|
||||||
execute()</pre></div></div>
|
execute()</pre></div></div>
|
||||||
@@ -318,17 +318,22 @@ only one CoffeeScript script block to parse.</p>
|
|||||||
<li id="section-10">
|
<li id="section-10">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Listen for window load, both in decent browsers and in IE.</p>
|
<p>Listen for window load, both in decent browsers and in IE.
|
||||||
|
Only attach this event handler on startup for the
|
||||||
|
non-ES module version of the browser compiler, to preserve
|
||||||
|
backward compatibility while letting the ES module version
|
||||||
|
be importable without side effects.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> <span class="hljs-built_in">window</span>.addEventListener
|
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> this <span class="hljs-keyword">is</span> window
|
||||||
<span class="hljs-built_in">window</span>.addEventListener <span class="hljs-string">'DOMContentLoaded'</span>, runScripts, <span class="hljs-literal">no</span>
|
<span class="hljs-keyword">if</span> window.addEventListener
|
||||||
<span class="hljs-keyword">else</span>
|
window.addEventListener <span class="hljs-string">'DOMContentLoaded'</span>, CoffeeScript.runScripts, <span class="hljs-literal">no</span>
|
||||||
<span class="hljs-built_in">window</span>.attachEvent <span class="hljs-string">'onload'</span>, runScripts</pre></div></div>
|
<span class="hljs-keyword">else</span>
|
||||||
|
window.attachEvent <span class="hljs-string">'onload'</span>, CoffeeScript.runScripts</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
@@ -112,8 +112,8 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p><code>cake</code> is a simplified version of <a href="http://www.gnu.org/software/make/">Make</a>
|
<p><code>cake</code> is a simplified version of <a href="http://www.gnu.org/software/make/">Make</a>
|
||||||
(<a href="http://rake.rubyforge.org/">Rake</a>, <a href="https://github.com/280north/jake">Jake</a>)
|
(<a href="http://rake.rubyforge.org/">Rake</a>, <a href="https://github.com/280north/jake">Jake</a>)
|
||||||
@@ -130,18 +130,18 @@ current directory’s Cakefile.</p>
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>External dependencies.</p>
|
<p>External dependencies.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
||||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
||||||
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||||
optparse = <span class="hljs-built_in">require</span> <span class="hljs-string">'./optparse'</span>
|
optparse = <span class="hljs-built_in">require</span> <span class="hljs-string">'./optparse'</span>
|
||||||
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./'</span></pre></div></div>
|
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -149,8 +149,8 @@ CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-stri
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Register .coffee extension</p>
|
<p>Register .coffee extension</p>
|
||||||
|
|
||||||
@@ -164,8 +164,8 @@ CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-stri
|
|||||||
<li id="section-4">
|
<li id="section-4">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-4">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Keep track of the list of defined tasks, the accepted options, and so on.</p>
|
<p>Keep track of the list of defined tasks, the accepted options, and so on.</p>
|
||||||
|
|
||||||
@@ -182,14 +182,14 @@ oparse = <span class="hljs-literal">null</span></pre></div></div>
|
|||||||
<li id="section-5">
|
<li id="section-5">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Mixin the top-level Cake functions for Cakefiles to use directly.</p>
|
<p>Mixin the top-level Cake functions for Cakefiles to use directly.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>helpers.extend <span class="hljs-built_in">global</span>,</pre></div></div>
|
<div class="content"><div class='highlight'><pre>helpers.extend global,</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -197,8 +197,8 @@ oparse = <span class="hljs-literal">null</span></pre></div></div>
|
|||||||
<li id="section-6">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Define a Cake task with a short name, an optional sentence description,
|
<p>Define a Cake task with a short name, an optional sentence description,
|
||||||
and the function to run as the action itself.</p>
|
and the function to run as the action itself.</p>
|
||||||
@@ -215,8 +215,8 @@ and the function to run as the action itself.</p>
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Define an option that the Cakefile accepts. The parsed options hash,
|
<p>Define an option that the Cakefile accepts. The parsed options hash,
|
||||||
containing all of the command-line options passed, will be made available
|
containing all of the command-line options passed, will be made available
|
||||||
@@ -233,8 +233,8 @@ as the first argument to the action.</p>
|
|||||||
<li id="section-8">
|
<li id="section-8">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-8">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Invoke another task in the current Cakefile.</p>
|
<p>Invoke another task in the current Cakefile.</p>
|
||||||
|
|
||||||
@@ -250,8 +250,8 @@ as the first argument to the action.</p>
|
|||||||
<li id="section-9">
|
<li id="section-9">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="ss" href="#section-9">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Run <code>cake</code>. Executes all of the tasks you pass, in order. Note that Node’s
|
<p>Run <code>cake</code>. Executes all of the tasks you pass, in order. Note that Node’s
|
||||||
asynchrony may cause tasks to execute in a different order than you’d expect.
|
asynchrony may cause tasks to execute in a different order than you’d expect.
|
||||||
@@ -260,17 +260,17 @@ original directory name, when running Cake tasks from subdirectories.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.run = <span class="hljs-function">-></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.run = <span class="hljs-function">-></span>
|
||||||
<span class="hljs-built_in">global</span>.__originalDirname = fs.realpathSync <span class="hljs-string">'.'</span>
|
global.__originalDirname = fs.realpathSync <span class="hljs-string">'.'</span>
|
||||||
process.chdir cakefileDirectory __originalDirname
|
process.chdir cakefileDirectory __originalDirname
|
||||||
args = process.argv[<span class="hljs-number">2.</span>.]
|
args = process.argv[<span class="hljs-number">2.</span>.]
|
||||||
CoffeeScript.run fs.readFileSync(<span class="hljs-string">'Cakefile'</span>).toString(), filename: <span class="hljs-string">'Cakefile'</span>
|
CoffeeScript.run fs.readFileSync(<span class="hljs-string">'Cakefile'</span>).toString(), filename: <span class="hljs-string">'Cakefile'</span>
|
||||||
oparse = <span class="hljs-keyword">new</span> optparse.OptionParser switches
|
oparse = <span class="hljs-keyword">new</span> optparse.OptionParser switches
|
||||||
<span class="hljs-keyword">return</span> printTasks() <span class="hljs-keyword">unless</span> args.length
|
<span class="hljs-keyword">return</span> printTasks() <span class="hljs-keyword">unless</span> args.length
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
options = oparse.parse(args)
|
options = oparse.parse(args)
|
||||||
<span class="hljs-keyword">catch</span> e
|
<span class="hljs-keyword">catch</span> e
|
||||||
<span class="hljs-keyword">return</span> fatalError <span class="hljs-string">"<span class="hljs-subst">#{e}</span>"</span>
|
<span class="hljs-keyword">return</span> fatalError <span class="hljs-string">"<span class="hljs-subst">#{e}</span>"</span>
|
||||||
invoke arg <span class="hljs-keyword">for</span> arg <span class="hljs-keyword">in</span> options.arguments</pre></div></div>
|
invoke arg <span class="hljs-keyword">for</span> arg <span class="hljs-keyword">in</span> options.arguments</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -279,8 +279,8 @@ original directory name, when running Cake tasks from subdirectories.</p>
|
|||||||
<li id="section-10">
|
<li id="section-10">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Display the list of Cake tasks in a format similar to <code>rake -T</code></p>
|
<p>Display the list of Cake tasks in a format similar to <code>rake -T</code></p>
|
||||||
|
|
||||||
@@ -288,14 +288,14 @@ original directory name, when running Cake tasks from subdirectories.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">printTasks</span> = -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">printTasks</span> = -></span>
|
||||||
relative = path.relative <span class="hljs-keyword">or</span> path.resolve
|
relative = path.relative <span class="hljs-keyword">or</span> path.resolve
|
||||||
cakefilePath = path.join relative(__originalDirname, process.cwd()), <span class="hljs-string">'Cakefile'</span>
|
cakefilePath = path.join relative(__originalDirname, process.cwd()), <span class="hljs-string">'Cakefile'</span>
|
||||||
<span class="hljs-built_in">console</span>.log <span class="hljs-string">"<span class="hljs-subst">#{cakefilePath}</span> defines the following tasks:\n"</span>
|
console.log <span class="hljs-string">"<span class="hljs-subst">#{cakefilePath}</span> defines the following tasks:\n"</span>
|
||||||
<span class="hljs-keyword">for</span> name, task <span class="hljs-keyword">of</span> tasks
|
<span class="hljs-keyword">for</span> name, task <span class="hljs-keyword">of</span> tasks
|
||||||
spaces = <span class="hljs-number">20</span> - name.length
|
spaces = <span class="hljs-number">20</span> - name.length
|
||||||
spaces = <span class="hljs-keyword">if</span> spaces > <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> Array(spaces + <span class="hljs-number">1</span>).join(<span class="hljs-string">' '</span>) <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
spaces = <span class="hljs-keyword">if</span> spaces > <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> <span class="hljs-built_in">Array</span>(spaces + <span class="hljs-number">1</span>).join(<span class="hljs-string">' '</span>) <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
||||||
desc = <span class="hljs-keyword">if</span> task.description <span class="hljs-keyword">then</span> <span class="hljs-string">"# <span class="hljs-subst">#{task.description}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
desc = <span class="hljs-keyword">if</span> task.description <span class="hljs-keyword">then</span> <span class="hljs-string">"# <span class="hljs-subst">#{task.description}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
||||||
<span class="hljs-built_in">console</span>.log <span class="hljs-string">"cake <span class="hljs-subst">#{name}</span><span class="hljs-subst">#{spaces}</span> <span class="hljs-subst">#{desc}</span>"</span>
|
console.log <span class="hljs-string">"cake <span class="hljs-subst">#{name}</span><span class="hljs-subst">#{spaces}</span> <span class="hljs-subst">#{desc}</span>"</span>
|
||||||
<span class="hljs-built_in">console</span>.log oparse.help() <span class="hljs-keyword">if</span> switches.length</pre></div></div>
|
console.log oparse.help() <span class="hljs-keyword">if</span> switches.length</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -303,19 +303,19 @@ original directory name, when running Cake tasks from subdirectories.</p>
|
|||||||
<li id="section-11">
|
<li id="section-11">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="ss" href="#section-11">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Print an error and exit when attempting to use an invalid task/option.</p>
|
<p>Print an error and exit when attempting to use an invalid task/option.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">fatalError</span> = <span class="hljs-params">(message)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">fatalError</span> = <span class="hljs-params">(message)</span> -></span>
|
||||||
<span class="hljs-built_in">console</span>.error message + <span class="hljs-string">'\n'</span>
|
console.error message + <span class="hljs-string">'\n'</span>
|
||||||
<span class="hljs-built_in">console</span>.log <span class="hljs-string">'To see a list of all tasks/options, run "cake"'</span>
|
console.log <span class="hljs-string">'To see a list of all tasks/options, run "cake"'</span>
|
||||||
process.exit <span class="hljs-number">1</span>
|
process.exit <span class="hljs-number">1</span>
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">missingTask</span> = <span class="hljs-params">(task)</span> -></span> fatalError <span class="hljs-string">"No such task: <span class="hljs-subst">#{task}</span>"</span></pre></div></div>
|
<span class="hljs-title">missingTask</span> = <span class="hljs-params">(task)</span> -></span> fatalError <span class="hljs-string">"No such task: <span class="hljs-subst">#{task}</span>"</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -323,8 +323,8 @@ original directory name, when running Cake tasks from subdirectories.</p>
|
|||||||
<li id="section-12">
|
<li id="section-12">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="ss" href="#section-12">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>When <code>cake</code> is invoked, search in the current and all parent directories
|
<p>When <code>cake</code> is invoked, search in the current and all parent directories
|
||||||
to find the relevant Cakefile.</p>
|
to find the relevant Cakefile.</p>
|
||||||
@@ -332,10 +332,10 @@ to find the relevant Cakefile.</p>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">cakefileDirectory</span> = <span class="hljs-params">(dir)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">cakefileDirectory</span> = <span class="hljs-params">(dir)</span> -></span>
|
||||||
<span class="hljs-keyword">return</span> dir <span class="hljs-keyword">if</span> fs.existsSync path.join dir, <span class="hljs-string">'Cakefile'</span>
|
<span class="hljs-keyword">return</span> dir <span class="hljs-keyword">if</span> fs.existsSync path.join dir, <span class="hljs-string">'Cakefile'</span>
|
||||||
parent = path.normalize path.join dir, <span class="hljs-string">'..'</span>
|
parent = path.normalize path.join dir, <span class="hljs-string">'..'</span>
|
||||||
<span class="hljs-keyword">return</span> cakefileDirectory parent <span class="hljs-keyword">unless</span> parent <span class="hljs-keyword">is</span> dir
|
<span class="hljs-keyword">return</span> cakefileDirectory parent <span class="hljs-keyword">unless</span> parent <span class="hljs-keyword">is</span> dir
|
||||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"Cakefile not found in <span class="hljs-subst">#{process.cwd()}</span>"</span></pre></div></div>
|
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">"Cakefile not found in <span class="hljs-subst">#{process.cwd()}</span>"</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -112,8 +112,8 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The <code>coffee</code> utility. Handles command-line compilation of CoffeeScript
|
<p>The <code>coffee</code> utility. Handles command-line compilation of CoffeeScript
|
||||||
into various forms: saved into <code>.js</code> files or printed to stdout
|
into various forms: saved into <code>.js</code> files or printed to stdout
|
||||||
@@ -129,22 +129,22 @@ interactive REPL.</p>
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>External dependencies.</p>
|
<p>External dependencies.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
||||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
||||||
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||||
optparse = <span class="hljs-built_in">require</span> <span class="hljs-string">'./optparse'</span>
|
optparse = <span class="hljs-built_in">require</span> <span class="hljs-string">'./optparse'</span>
|
||||||
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./'</span>
|
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./'</span>
|
||||||
{spawn, exec} = <span class="hljs-built_in">require</span> <span class="hljs-string">'child_process'</span>
|
{spawn, exec} = <span class="hljs-built_in">require</span> <span class="hljs-string">'child_process'</span>
|
||||||
{EventEmitter} = <span class="hljs-built_in">require</span> <span class="hljs-string">'events'</span>
|
{EventEmitter} = <span class="hljs-built_in">require</span> <span class="hljs-string">'events'</span>
|
||||||
|
|
||||||
useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs-string">'\\'</span></pre></div></div>
|
useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs-string">'\\'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -152,8 +152,8 @@ useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Allow CoffeeScript to emit Node.js events.</p>
|
<p>Allow CoffeeScript to emit Node.js events.</p>
|
||||||
|
|
||||||
@@ -161,8 +161,8 @@ useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>helpers.extend CoffeeScript, <span class="hljs-keyword">new</span> EventEmitter
|
<div class="content"><div class='highlight'><pre>helpers.extend CoffeeScript, <span class="hljs-keyword">new</span> EventEmitter
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">printLine</span> = <span class="hljs-params">(line)</span> -></span> process.stdout.write line + <span class="hljs-string">'\n'</span>
|
<span class="hljs-title">printLine</span> = <span class="hljs-params">(line)</span> -></span> process.stdout.write line + <span class="hljs-string">'\n'</span>
|
||||||
<span class="hljs-function"><span class="hljs-title">printWarn</span> = <span class="hljs-params">(line)</span> -></span> process.stderr.write line + <span class="hljs-string">'\n'</span>
|
<span class="hljs-function"><span class="hljs-title">printWarn</span> = <span class="hljs-params">(line)</span> -></span> process.stderr.write line + <span class="hljs-string">'\n'</span>
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">hidden</span> = <span class="hljs-params">(file)</span> -></span> <span class="hljs-regexp">/^\.|~$/</span>.test file</pre></div></div>
|
<span class="hljs-title">hidden</span> = <span class="hljs-params">(file)</span> -></span> <span class="hljs-regexp">/^\.|~$/</span>.test file</pre></div></div>
|
||||||
|
|
||||||
@@ -172,18 +172,18 @@ useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs
|
|||||||
<li id="section-4">
|
<li id="section-4">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-4">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The help banner that is printed in conjunction with <code>-h</code>/<code>--help</code>.</p>
|
<p>The help banner that is printed in conjunction with <code>-h</code>/<code>--help</code>.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>BANNER = <span class="hljs-string">'''
|
<div class="content"><div class='highlight'><pre>BANNER = <span class="hljs-string">'''
|
||||||
Usage: coffee [options] path/to/script.coffee [args]
|
Usage: coffee [options] path/to/script.coffee [args]
|
||||||
|
|
||||||
If called without options, `coffee` will run your script.
|
If called without options, `coffee` will run your script.
|
||||||
'''</span></pre></div></div>
|
'''</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -191,34 +191,35 @@ useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs
|
|||||||
<li id="section-5">
|
<li id="section-5">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The list of all the valid option flags that <code>coffee</code> knows how to handle.</p>
|
<p>The list of all the valid option flags that <code>coffee</code> knows how to handle.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>SWITCHES = [
|
<div class="content"><div class='highlight'><pre>SWITCHES = [
|
||||||
[<span class="hljs-string">'-b'</span>, <span class="hljs-string">'--bare'</span>, <span class="hljs-string">'compile without a top-level function wrapper'</span>]
|
[ <span class="hljs-string">'--ast'</span>, <span class="hljs-string">'generate an abstract syntax tree of nodes'</span>]
|
||||||
[<span class="hljs-string">'-c'</span>, <span class="hljs-string">'--compile'</span>, <span class="hljs-string">'compile to JavaScript and save as .js files'</span>]
|
[<span class="hljs-string">'-b'</span>, <span class="hljs-string">'--bare'</span>, <span class="hljs-string">'compile without a top-level function wrapper'</span>]
|
||||||
[<span class="hljs-string">'-e'</span>, <span class="hljs-string">'--eval'</span>, <span class="hljs-string">'pass a string from the command line as input'</span>]
|
[<span class="hljs-string">'-c'</span>, <span class="hljs-string">'--compile'</span>, <span class="hljs-string">'compile to JavaScript and save as .js files'</span>]
|
||||||
[<span class="hljs-string">'-h'</span>, <span class="hljs-string">'--help'</span>, <span class="hljs-string">'display this help message'</span>]
|
[<span class="hljs-string">'-e'</span>, <span class="hljs-string">'--eval'</span>, <span class="hljs-string">'pass a string from the command line as input'</span>]
|
||||||
[<span class="hljs-string">'-i'</span>, <span class="hljs-string">'--interactive'</span>, <span class="hljs-string">'run an interactive CoffeeScript REPL'</span>]
|
[<span class="hljs-string">'-h'</span>, <span class="hljs-string">'--help'</span>, <span class="hljs-string">'display this help message'</span>]
|
||||||
[<span class="hljs-string">'-j'</span>, <span class="hljs-string">'--join [FILE]'</span>, <span class="hljs-string">'concatenate the source CoffeeScript before compiling'</span>]
|
[<span class="hljs-string">'-i'</span>, <span class="hljs-string">'--interactive'</span>, <span class="hljs-string">'run an interactive CoffeeScript REPL'</span>]
|
||||||
[<span class="hljs-string">'-m'</span>, <span class="hljs-string">'--map'</span>, <span class="hljs-string">'generate source map and save as .js.map files'</span>]
|
[<span class="hljs-string">'-j'</span>, <span class="hljs-string">'--join [FILE]'</span>, <span class="hljs-string">'concatenate the source CoffeeScript before compiling'</span>]
|
||||||
[<span class="hljs-string">'-M'</span>, <span class="hljs-string">'--inline-map'</span>, <span class="hljs-string">'generate source map and include it directly in output'</span>]
|
[<span class="hljs-string">'-l'</span>, <span class="hljs-string">'--literate'</span>, <span class="hljs-string">'treat stdio as literate style coffeescript'</span>]
|
||||||
[<span class="hljs-string">'-n'</span>, <span class="hljs-string">'--nodes'</span>, <span class="hljs-string">'print out the parse tree that the parser produces'</span>]
|
[<span class="hljs-string">'-m'</span>, <span class="hljs-string">'--map'</span>, <span class="hljs-string">'generate source map and save as .js.map files'</span>]
|
||||||
[ <span class="hljs-string">'--nodejs [ARGS]'</span>, <span class="hljs-string">'pass options directly to the "node" binary'</span>]
|
[<span class="hljs-string">'-M'</span>, <span class="hljs-string">'--inline-map'</span>, <span class="hljs-string">'generate source map and include it directly in output'</span>]
|
||||||
[ <span class="hljs-string">'--no-header'</span>, <span class="hljs-string">'suppress the "Generated by" header'</span>]
|
[<span class="hljs-string">'-n'</span>, <span class="hljs-string">'--nodes'</span>, <span class="hljs-string">'print out the parse tree that the parser produces'</span>]
|
||||||
[<span class="hljs-string">'-o'</span>, <span class="hljs-string">'--output [PATH]'</span>, <span class="hljs-string">'set the output path or path/filename for compiled JavaScript'</span>]
|
[ <span class="hljs-string">'--nodejs [ARGS]'</span>, <span class="hljs-string">'pass options directly to the "node" binary'</span>]
|
||||||
[<span class="hljs-string">'-p'</span>, <span class="hljs-string">'--print'</span>, <span class="hljs-string">'print out the compiled JavaScript'</span>]
|
[ <span class="hljs-string">'--no-header'</span>, <span class="hljs-string">'suppress the "Generated by" header'</span>]
|
||||||
[<span class="hljs-string">'-r'</span>, <span class="hljs-string">'--require [MODULE*]'</span>, <span class="hljs-string">'require the given module before eval or REPL'</span>]
|
[<span class="hljs-string">'-o'</span>, <span class="hljs-string">'--output [PATH]'</span>, <span class="hljs-string">'set the output path or path/filename for compiled JavaScript'</span>]
|
||||||
[<span class="hljs-string">'-s'</span>, <span class="hljs-string">'--stdio'</span>, <span class="hljs-string">'listen for and compile scripts over stdio'</span>]
|
[<span class="hljs-string">'-p'</span>, <span class="hljs-string">'--print'</span>, <span class="hljs-string">'print out the compiled JavaScript'</span>]
|
||||||
[<span class="hljs-string">'-l'</span>, <span class="hljs-string">'--literate'</span>, <span class="hljs-string">'treat stdio as literate style coffeescript'</span>]
|
[<span class="hljs-string">'-r'</span>, <span class="hljs-string">'--require [MODULE*]'</span>, <span class="hljs-string">'require the given module before eval or REPL'</span>]
|
||||||
[<span class="hljs-string">'-t'</span>, <span class="hljs-string">'--transpile'</span>, <span class="hljs-string">'pipe generated JavaScript through Babel'</span>]
|
[<span class="hljs-string">'-s'</span>, <span class="hljs-string">'--stdio'</span>, <span class="hljs-string">'listen for and compile scripts over stdio'</span>]
|
||||||
[ <span class="hljs-string">'--tokens'</span>, <span class="hljs-string">'print out the tokens that the lexer/rewriter produce'</span>]
|
[<span class="hljs-string">'-t'</span>, <span class="hljs-string">'--transpile'</span>, <span class="hljs-string">'pipe generated JavaScript through Babel'</span>]
|
||||||
[<span class="hljs-string">'-v'</span>, <span class="hljs-string">'--version'</span>, <span class="hljs-string">'display the version number'</span>]
|
[ <span class="hljs-string">'--tokens'</span>, <span class="hljs-string">'print out the tokens that the lexer/rewriter produce'</span>]
|
||||||
[<span class="hljs-string">'-w'</span>, <span class="hljs-string">'--watch'</span>, <span class="hljs-string">'watch scripts for changes and rerun commands'</span>]
|
[<span class="hljs-string">'-v'</span>, <span class="hljs-string">'--version'</span>, <span class="hljs-string">'display the version number'</span>]
|
||||||
|
[<span class="hljs-string">'-w'</span>, <span class="hljs-string">'--watch'</span>, <span class="hljs-string">'watch scripts for changes and rerun commands'</span>]
|
||||||
]</pre></div></div>
|
]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -227,8 +228,8 @@ useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs
|
|||||||
<li id="section-6">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Top-level objects shared by all the functions.</p>
|
<p>Top-level objects shared by all the functions.</p>
|
||||||
|
|
||||||
@@ -241,7 +242,7 @@ notSources = {}
|
|||||||
watchedDirs = {}
|
watchedDirs = {}
|
||||||
optionParser = <span class="hljs-literal">null</span>
|
optionParser = <span class="hljs-literal">null</span>
|
||||||
|
|
||||||
exports.buildCSOptionParser = buildCSOptionParser = <span class="hljs-function">-></span>
|
<span class="hljs-built_in">exports</span>.buildCSOptionParser = buildCSOptionParser = <span class="hljs-function">-></span>
|
||||||
<span class="hljs-keyword">new</span> optparse.OptionParser SWITCHES, BANNER</pre></div></div>
|
<span class="hljs-keyword">new</span> optparse.OptionParser SWITCHES, BANNER</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -250,8 +251,8 @@ exports.buildCSOptionParser = buildCSOptionParser = <span class="hljs-function">
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Run <code>coffee</code> by parsing passed options and determining what action to take.
|
<p>Run <code>coffee</code> by parsing passed options and determining what action to take.
|
||||||
Many flags cause us to divert before compiling anything. Flags passed after
|
Many flags cause us to divert before compiling anything. Flags passed after
|
||||||
@@ -259,22 +260,22 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.run = <span class="hljs-function">-></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.run = <span class="hljs-function">-></span>
|
||||||
optionParser = buildCSOptionParser()
|
optionParser = buildCSOptionParser()
|
||||||
<span class="hljs-keyword">try</span> parseOptions()
|
<span class="hljs-keyword">try</span> parseOptions()
|
||||||
<span class="hljs-keyword">catch</span> err
|
<span class="hljs-keyword">catch</span> err
|
||||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"option parsing error: <span class="hljs-subst">#{err.message}</span>"</span>
|
console.error <span class="hljs-string">"option parsing error: <span class="hljs-subst">#{err.message}</span>"</span>
|
||||||
process.exit <span class="hljs-number">1</span>
|
process.exit <span class="hljs-number">1</span>
|
||||||
|
|
||||||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">not</span> opts.doubleDashed) <span class="hljs-keyword">and</span> (opts.arguments[<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'--'</span>)
|
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">not</span> opts.doubleDashed) <span class="hljs-keyword">and</span> (opts.arguments[<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'--'</span>)
|
||||||
printWarn <span class="hljs-string">'''
|
printWarn <span class="hljs-string">'''
|
||||||
coffee was invoked with '--' as the second positional argument, which is
|
coffee was invoked with '--' as the second positional argument, which is
|
||||||
now deprecated. To pass '--' as an argument to a script to run, put an
|
now deprecated. To pass '--' as an argument to a script to run, put an
|
||||||
additional '--' before the path to your script.
|
additional '--' before the path to your script.
|
||||||
|
|
||||||
'--' will be removed from the argument list.
|
'--' will be removed from the argument list.
|
||||||
'''</span>
|
'''</span>
|
||||||
printWarn <span class="hljs-string">"The positional arguments were: <span class="hljs-subst">#{JSON.stringify opts.arguments}</span>"</span>
|
printWarn <span class="hljs-string">"The positional arguments were: <span class="hljs-subst">#{<span class="hljs-built_in">JSON</span>.stringify opts.arguments}</span>"</span>
|
||||||
opts.arguments = [opts.arguments[<span class="hljs-number">0</span>]].concat opts.arguments[<span class="hljs-number">2.</span>.]</pre></div></div>
|
opts.arguments = [opts.arguments[<span class="hljs-number">0</span>]].concat opts.arguments[<span class="hljs-number">2.</span>.]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -283,8 +284,8 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
|||||||
<li id="section-8">
|
<li id="section-8">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-8">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Make the REPL <em>CLI</em> use the global context so as to (a) be consistent with the
|
<p>Make the REPL <em>CLI</em> use the global context so as to (a) be consistent with the
|
||||||
<code>node</code> REPL CLI and, therefore, (b) make packages that modify native prototypes
|
<code>node</code> REPL CLI and, therefore, (b) make packages that modify native prototypes
|
||||||
@@ -299,18 +300,18 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
|||||||
<span class="hljs-keyword">return</span> forkNode() <span class="hljs-keyword">if</span> opts.nodejs
|
<span class="hljs-keyword">return</span> forkNode() <span class="hljs-keyword">if</span> opts.nodejs
|
||||||
<span class="hljs-keyword">return</span> usage() <span class="hljs-keyword">if</span> opts.help
|
<span class="hljs-keyword">return</span> usage() <span class="hljs-keyword">if</span> opts.help
|
||||||
<span class="hljs-keyword">return</span> version() <span class="hljs-keyword">if</span> opts.version
|
<span class="hljs-keyword">return</span> version() <span class="hljs-keyword">if</span> opts.version
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./repl'</span>).start(replCliOpts) <span class="hljs-keyword">if</span> opts.interactive
|
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./repl'</span>).start(replCliOpts) <span class="hljs-keyword">if</span> opts.interactive
|
||||||
<span class="hljs-keyword">return</span> compileStdio() <span class="hljs-keyword">if</span> opts.stdio
|
<span class="hljs-keyword">return</span> compileStdio() <span class="hljs-keyword">if</span> opts.stdio
|
||||||
<span class="hljs-keyword">return</span> compileScript <span class="hljs-literal">null</span>, opts.arguments[<span class="hljs-number">0</span>] <span class="hljs-keyword">if</span> opts.eval
|
<span class="hljs-keyword">return</span> compileScript <span class="hljs-literal">null</span>, opts.arguments[<span class="hljs-number">0</span>] <span class="hljs-keyword">if</span> opts.<span class="hljs-built_in">eval</span>
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./repl'</span>).start(replCliOpts) <span class="hljs-keyword">unless</span> opts.arguments.length
|
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./repl'</span>).start(replCliOpts) <span class="hljs-keyword">unless</span> opts.arguments.length
|
||||||
literals = <span class="hljs-keyword">if</span> opts.run <span class="hljs-keyword">then</span> opts.arguments.splice <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> []
|
literals = <span class="hljs-keyword">if</span> opts.run <span class="hljs-keyword">then</span> opts.arguments.splice <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> []
|
||||||
process.argv = process.argv[<span class="hljs-number">0.</span><span class="hljs-number">.1</span>].concat literals
|
process.argv = process.argv[<span class="hljs-number">0.</span><span class="hljs-number">.1</span>].concat literals
|
||||||
process.argv[<span class="hljs-number">0</span>] = <span class="hljs-string">'coffee'</span>
|
process.argv[<span class="hljs-number">0</span>] = <span class="hljs-string">'coffee'</span>
|
||||||
|
|
||||||
<span class="hljs-keyword">if</span> opts.output
|
<span class="hljs-keyword">if</span> opts.output
|
||||||
outputBasename = path.basename opts.output
|
outputBasename = path.basename opts.output
|
||||||
<span class="hljs-keyword">if</span> <span class="hljs-string">'.'</span> <span class="hljs-keyword">in</span> outputBasename <span class="hljs-keyword">and</span>
|
<span class="hljs-keyword">if</span> <span class="hljs-string">'.'</span> <span class="hljs-keyword">in</span> outputBasename <span class="hljs-keyword">and</span>
|
||||||
outputBasename <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'.'</span>, <span class="hljs-string">'..'</span>] <span class="hljs-keyword">and</span>
|
outputBasename <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'.'</span>, <span class="hljs-string">'..'</span>] <span class="hljs-keyword">and</span>
|
||||||
<span class="hljs-keyword">not</span> helpers.ends(opts.output, path.sep)</pre></div></div>
|
<span class="hljs-keyword">not</span> helpers.ends(opts.output, path.sep)</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -319,8 +320,8 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
|||||||
<li id="section-9">
|
<li id="section-9">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="ss" href="#section-9">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>An output filename was specified, e.g. <code>/dist/scripts.js</code>.</p>
|
<p>An output filename was specified, e.g. <code>/dist/scripts.js</code>.</p>
|
||||||
|
|
||||||
@@ -336,8 +337,8 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
|||||||
<li id="section-10">
|
<li id="section-10">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>An output path was specified, e.g. <code>/dist</code>.</p>
|
<p>An output path was specified, e.g. <code>/dist</code>.</p>
|
||||||
|
|
||||||
@@ -348,11 +349,11 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
|||||||
|
|
||||||
<span class="hljs-keyword">if</span> opts.join
|
<span class="hljs-keyword">if</span> opts.join
|
||||||
opts.join = path.resolve opts.join
|
opts.join = path.resolve opts.join
|
||||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
|
console.error <span class="hljs-string">'''
|
||||||
|
|
||||||
The --join option is deprecated and will be removed in a future version.
|
The --join option is deprecated and will be removed in a future version.
|
||||||
|
|
||||||
If for some reason it's necessary to share local variables between files,
|
If for some reason it's necessary to share local variables between files,
|
||||||
replace...
|
replace...
|
||||||
|
|
||||||
$ coffee --compile --join bundle.js -- a.coffee b.coffee c.coffee
|
$ coffee --compile --join bundle.js -- a.coffee b.coffee c.coffee
|
||||||
@@ -361,17 +362,17 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
|||||||
|
|
||||||
$ cat a.coffee b.coffee c.coffee | coffee --compile --stdio > bundle.js
|
$ cat a.coffee b.coffee c.coffee | coffee --compile --stdio > bundle.js
|
||||||
|
|
||||||
'''</span>
|
'''</span>
|
||||||
<span class="hljs-keyword">for</span> source <span class="hljs-keyword">in</span> opts.arguments
|
<span class="hljs-keyword">for</span> source <span class="hljs-keyword">in</span> opts.arguments
|
||||||
source = path.resolve source
|
source = path.resolve source
|
||||||
compilePath source, <span class="hljs-literal">yes</span>, source
|
compilePath source, <span class="hljs-literal">yes</span>, source
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">makePrelude</span> = <span class="hljs-params">(requires)</span> -></span>
|
<span class="hljs-title">makePrelude</span> = <span class="hljs-params">(requires)</span> -></span>
|
||||||
requires.map (<span class="hljs-built_in">module</span>) ->
|
requires.map (module) ->
|
||||||
[full, name, <span class="hljs-built_in">module</span>] = match <span class="hljs-keyword">if</span> match = <span class="hljs-built_in">module</span>.match(<span class="hljs-regexp">/^(.*)=(.*)$/</span>)
|
[full, name, module] = match <span class="hljs-keyword">if</span> match = module.match(<span class="hljs-regexp">/^(.*)=(.*)$/</span>)
|
||||||
name <span class="hljs-keyword">or</span>= helpers.baseFileName <span class="hljs-built_in">module</span>, <span class="hljs-literal">yes</span>, useWinPathSep
|
name <span class="hljs-keyword">or</span>= helpers.baseFileName module, <span class="hljs-literal">yes</span>, useWinPathSep
|
||||||
<span class="hljs-string">"global['<span class="hljs-subst">#{name}</span>'] = require('<span class="hljs-subst">#{<span class="hljs-built_in">module</span>}</span>')"</span>
|
<span class="hljs-string">"global['<span class="hljs-subst">#{name}</span>'] = require('<span class="hljs-subst">#{module}</span>')"</span>
|
||||||
.join <span class="hljs-string">';'</span></pre></div></div>
|
.join <span class="hljs-string">';'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -379,8 +380,8 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
|||||||
<li id="section-11">
|
<li id="section-11">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="ss" href="#section-11">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Compile a path, which could be a script or a directory. If a directory
|
<p>Compile a path, which could be a script or a directory. If a directory
|
||||||
is passed, recursively compile all ‘.coffee’, ‘.litcoffee’, and ‘.coffee.md’
|
is passed, recursively compile all ‘.coffee’, ‘.litcoffee’, and ‘.coffee.md’
|
||||||
@@ -395,12 +396,12 @@ extension source files in it and all subdirectories.</p>
|
|||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
stats = fs.statSync source
|
stats = fs.statSync source
|
||||||
<span class="hljs-keyword">catch</span> err
|
<span class="hljs-keyword">catch</span> err
|
||||||
<span class="hljs-keyword">if</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
<span class="hljs-keyword">if</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"File not found: <span class="hljs-subst">#{source}</span>"</span>
|
console.error <span class="hljs-string">"File not found: <span class="hljs-subst">#{source}</span>"</span>
|
||||||
process.exit <span class="hljs-number">1</span>
|
process.exit <span class="hljs-number">1</span>
|
||||||
<span class="hljs-keyword">throw</span> err
|
<span class="hljs-keyword">throw</span> err
|
||||||
<span class="hljs-keyword">if</span> stats.isDirectory()
|
<span class="hljs-keyword">if</span> stats.isDirectory()
|
||||||
<span class="hljs-keyword">if</span> path.basename(source) <span class="hljs-keyword">is</span> <span class="hljs-string">'node_modules'</span>
|
<span class="hljs-keyword">if</span> path.basename(source) <span class="hljs-keyword">is</span> <span class="hljs-string">'node_modules'</span>
|
||||||
notSources[source] = <span class="hljs-literal">yes</span>
|
notSources[source] = <span class="hljs-literal">yes</span>
|
||||||
<span class="hljs-keyword">return</span>
|
<span class="hljs-keyword">return</span>
|
||||||
<span class="hljs-keyword">if</span> opts.run
|
<span class="hljs-keyword">if</span> opts.run
|
||||||
@@ -410,7 +411,7 @@ extension source files in it and all subdirectories.</p>
|
|||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
files = fs.readdirSync source
|
files = fs.readdirSync source
|
||||||
<span class="hljs-keyword">catch</span> err
|
<span class="hljs-keyword">catch</span> err
|
||||||
<span class="hljs-keyword">if</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span> <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">throw</span> err
|
<span class="hljs-keyword">if</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span> <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">throw</span> err
|
||||||
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> files
|
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> files
|
||||||
compilePath (path.join source, file), <span class="hljs-literal">no</span>, base
|
compilePath (path.join source, file), <span class="hljs-literal">no</span>, base
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> topLevel <span class="hljs-keyword">or</span> helpers.isCoffee source
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> topLevel <span class="hljs-keyword">or</span> helpers.isCoffee source
|
||||||
@@ -421,19 +422,19 @@ extension source files in it and all subdirectories.</p>
|
|||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
code = fs.readFileSync source
|
code = fs.readFileSync source
|
||||||
<span class="hljs-keyword">catch</span> err
|
<span class="hljs-keyword">catch</span> err
|
||||||
<span class="hljs-keyword">if</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span> <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">throw</span> err
|
<span class="hljs-keyword">if</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span> <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">throw</span> err
|
||||||
compileScript source, code.toString(), base
|
compileScript source, code.toString(), base
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
notSources[source] = <span class="hljs-literal">yes</span>
|
notSources[source] = <span class="hljs-literal">yes</span>
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">findDirectoryIndex</span> = <span class="hljs-params">(source)</span> -></span>
|
<span class="hljs-title">findDirectoryIndex</span> = <span class="hljs-params">(source)</span> -></span>
|
||||||
<span class="hljs-keyword">for</span> ext <span class="hljs-keyword">in</span> CoffeeScript.FILE_EXTENSIONS
|
<span class="hljs-keyword">for</span> ext <span class="hljs-keyword">in</span> CoffeeScript.FILE_EXTENSIONS
|
||||||
index = path.join source, <span class="hljs-string">"index<span class="hljs-subst">#{ext}</span>"</span>
|
index = path.join source, <span class="hljs-string">"index<span class="hljs-subst">#{ext}</span>"</span>
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
<span class="hljs-keyword">return</span> index <span class="hljs-keyword">if</span> (fs.statSync index).isFile()
|
<span class="hljs-keyword">return</span> index <span class="hljs-keyword">if</span> (fs.statSync index).isFile()
|
||||||
<span class="hljs-keyword">catch</span> err
|
<span class="hljs-keyword">catch</span> err
|
||||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"Missing index.coffee or index.litcoffee in <span class="hljs-subst">#{source}</span>"</span>
|
console.error <span class="hljs-string">"Missing index.coffee or index.litcoffee in <span class="hljs-subst">#{source}</span>"</span>
|
||||||
process.exit <span class="hljs-number">1</span></pre></div></div>
|
process.exit <span class="hljs-number">1</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -442,8 +443,8 @@ extension source files in it and all subdirectories.</p>
|
|||||||
<li id="section-12">
|
<li id="section-12">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="ss" href="#section-12">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Compile a single source script, containing the given code, according to the
|
<p>Compile a single source script, containing the given code, according to the
|
||||||
requested options. If evaluating the script directly, set <code>__filename</code>,
|
requested options. If evaluating the script directly, set <code>__filename</code>,
|
||||||
@@ -455,14 +456,17 @@ requested options. If evaluating the script directly, set <code>__filename</code
|
|||||||
options = compileOptions file, base
|
options = compileOptions file, base
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
task = {file, input, options}
|
task = {file, input, options}
|
||||||
CoffeeScript.emit <span class="hljs-string">'compile'</span>, task
|
CoffeeScript.emit <span class="hljs-string">'compile'</span>, task
|
||||||
<span class="hljs-keyword">if</span> opts.tokens
|
<span class="hljs-keyword">if</span> opts.tokens
|
||||||
printTokens CoffeeScript.tokens task.input, task.options
|
printTokens CoffeeScript.tokens task.input, task.options
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.nodes
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.nodes
|
||||||
printLine CoffeeScript.nodes(task.input, task.options).toString().trim()
|
printLine CoffeeScript.nodes(task.input, task.options).toString().trim()
|
||||||
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.ast
|
||||||
|
compiled = CoffeeScript.compile task.input, task.options
|
||||||
|
printLine <span class="hljs-built_in">JSON</span>.stringify(compiled, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>)
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.run
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.run
|
||||||
CoffeeScript.register()
|
CoffeeScript.register()
|
||||||
CoffeeScript.eval opts.prelude, task.options <span class="hljs-keyword">if</span> opts.prelude
|
CoffeeScript.<span class="hljs-built_in">eval</span> opts.prelude, task.options <span class="hljs-keyword">if</span> opts.prelude
|
||||||
CoffeeScript.run task.input, task.options
|
CoffeeScript.run task.input, task.options
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.join <span class="hljs-keyword">and</span> task.file <span class="hljs-keyword">isnt</span> opts.join
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.join <span class="hljs-keyword">and</span> task.file <span class="hljs-keyword">isnt</span> opts.join
|
||||||
task.input = helpers.invertLiterate task.input <span class="hljs-keyword">if</span> helpers.isLiterate file
|
task.input = helpers.invertLiterate task.input <span class="hljs-keyword">if</span> helpers.isLiterate file
|
||||||
@@ -475,7 +479,7 @@ requested options. If evaluating the script directly, set <code>__filename</code
|
|||||||
task.output = compiled.js
|
task.output = compiled.js
|
||||||
task.sourceMap = compiled.v3SourceMap
|
task.sourceMap = compiled.v3SourceMap
|
||||||
|
|
||||||
CoffeeScript.emit <span class="hljs-string">'success'</span>, task
|
CoffeeScript.emit <span class="hljs-string">'success'</span>, task
|
||||||
<span class="hljs-keyword">if</span> opts.<span class="hljs-built_in">print</span>
|
<span class="hljs-keyword">if</span> opts.<span class="hljs-built_in">print</span>
|
||||||
printLine task.output.trim()
|
printLine task.output.trim()
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.compile <span class="hljs-keyword">or</span> opts.map
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.compile <span class="hljs-keyword">or</span> opts.map
|
||||||
@@ -485,11 +489,11 @@ requested options. If evaluating the script directly, set <code>__filename</code
|
|||||||
options.jsPath
|
options.jsPath
|
||||||
writeJs base, task.file, task.output, saveTo, task.sourceMap
|
writeJs base, task.file, task.output, saveTo, task.sourceMap
|
||||||
<span class="hljs-keyword">catch</span> err
|
<span class="hljs-keyword">catch</span> err
|
||||||
CoffeeScript.emit <span class="hljs-string">'failure'</span>, err, task
|
CoffeeScript.emit <span class="hljs-string">'failure'</span>, err, task
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> CoffeeScript.listeners(<span class="hljs-string">'failure'</span>).length
|
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> CoffeeScript.listeners(<span class="hljs-string">'failure'</span>).length
|
||||||
message = err?.stack <span class="hljs-keyword">or</span> <span class="hljs-string">"<span class="hljs-subst">#{err}</span>"</span>
|
message = err?.stack <span class="hljs-keyword">or</span> <span class="hljs-string">"<span class="hljs-subst">#{err}</span>"</span>
|
||||||
<span class="hljs-keyword">if</span> opts.watch
|
<span class="hljs-keyword">if</span> opts.watch
|
||||||
printLine message + <span class="hljs-string">'\x07'</span>
|
printLine message + <span class="hljs-string">'\x07'</span>
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
printWarn message
|
printWarn message
|
||||||
process.exit <span class="hljs-number">1</span></pre></div></div>
|
process.exit <span class="hljs-number">1</span></pre></div></div>
|
||||||
@@ -500,8 +504,8 @@ requested options. If evaluating the script directly, set <code>__filename</code
|
|||||||
<li id="section-13">
|
<li id="section-13">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-13">¶</a>
|
<a class="ss" href="#section-13">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Attach the appropriate listeners to compile scripts incoming over <strong>stdin</strong>,
|
<p>Attach the appropriate listeners to compile scripts incoming over <strong>stdin</strong>,
|
||||||
and write them back to <strong>stdout</strong>.</p>
|
and write them back to <strong>stdout</strong>.</p>
|
||||||
@@ -510,13 +514,13 @@ and write them back to <strong>stdout</strong>.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">compileStdio</span> = -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">compileStdio</span> = -></span>
|
||||||
<span class="hljs-keyword">if</span> opts.map
|
<span class="hljs-keyword">if</span> opts.map
|
||||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'--stdio and --map cannot be used together'</span>
|
console.error <span class="hljs-string">'--stdio and --map cannot be used together'</span>
|
||||||
process.exit <span class="hljs-number">1</span>
|
process.exit <span class="hljs-number">1</span>
|
||||||
buffers = []
|
buffers = []
|
||||||
stdin = process.openStdin()
|
stdin = process.openStdin()
|
||||||
stdin.<span class="hljs-literal">on</span> <span class="hljs-string">'data'</span>, <span class="hljs-function"><span class="hljs-params">(buffer)</span> -></span>
|
stdin.<span class="hljs-literal">on</span> <span class="hljs-string">'data'</span>, <span class="hljs-function"><span class="hljs-params">(buffer)</span> -></span>
|
||||||
buffers.push buffer <span class="hljs-keyword">if</span> buffer
|
buffers.push buffer <span class="hljs-keyword">if</span> buffer
|
||||||
stdin.<span class="hljs-literal">on</span> <span class="hljs-string">'end'</span>, <span class="hljs-function">-></span>
|
stdin.<span class="hljs-literal">on</span> <span class="hljs-string">'end'</span>, <span class="hljs-function">-></span>
|
||||||
compileScript <span class="hljs-literal">null</span>, Buffer.concat(buffers).toString()</pre></div></div>
|
compileScript <span class="hljs-literal">null</span>, Buffer.concat(buffers).toString()</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -525,8 +529,8 @@ and write them back to <strong>stdout</strong>.</p>
|
|||||||
<li id="section-14">
|
<li id="section-14">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-14">¶</a>
|
<a class="ss" href="#section-14">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>If all of the source files are done being read, concatenate and compile
|
<p>If all of the source files are done being read, concatenate and compile
|
||||||
them together.</p>
|
them together.</p>
|
||||||
@@ -537,9 +541,9 @@ them together.</p>
|
|||||||
<span class="hljs-function"><span class="hljs-title">compileJoin</span> = -></span>
|
<span class="hljs-function"><span class="hljs-title">compileJoin</span> = -></span>
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> opts.join
|
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> opts.join
|
||||||
<span class="hljs-keyword">unless</span> sourceCode.some(<span class="hljs-function"><span class="hljs-params">(code)</span> -></span> code <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>)
|
<span class="hljs-keyword">unless</span> sourceCode.some(<span class="hljs-function"><span class="hljs-params">(code)</span> -></span> code <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>)
|
||||||
clearTimeout joinTimeout
|
<span class="hljs-built_in">clearTimeout</span> joinTimeout
|
||||||
joinTimeout = wait <span class="hljs-number">100</span>, <span class="hljs-function">-></span>
|
joinTimeout = wait <span class="hljs-number">100</span>, <span class="hljs-function">-></span>
|
||||||
compileScript opts.join, sourceCode.join(<span class="hljs-string">'\n'</span>), opts.join</pre></div></div>
|
compileScript opts.join, sourceCode.join(<span class="hljs-string">'\n'</span>), opts.join</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -547,8 +551,8 @@ them together.</p>
|
|||||||
<li id="section-15">
|
<li id="section-15">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-15">¶</a>
|
<a class="ss" href="#section-15">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Watch a source CoffeeScript file using <code>fs.watch</code>, recompiling it every
|
<p>Watch a source CoffeeScript file using <code>fs.watch</code>, recompiling it every
|
||||||
time the file is updated. May be used in combination with other options,
|
time the file is updated. May be used in combination with other options,
|
||||||
@@ -562,7 +566,7 @@ such as <code>--print</code>.</p>
|
|||||||
compileTimeout = <span class="hljs-literal">null</span>
|
compileTimeout = <span class="hljs-literal">null</span>
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">watchErr</span> = <span class="hljs-params">(err)</span> -></span>
|
<span class="hljs-title">watchErr</span> = <span class="hljs-params">(err)</span> -></span>
|
||||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> source <span class="hljs-keyword">in</span> sources
|
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> source <span class="hljs-keyword">in</span> sources
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
rewatch()
|
rewatch()
|
||||||
@@ -572,7 +576,7 @@ such as <code>--print</code>.</p>
|
|||||||
compileJoin()
|
compileJoin()
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">compile</span> = -></span>
|
<span class="hljs-title">compile</span> = -></span>
|
||||||
clearTimeout compileTimeout
|
<span class="hljs-built_in">clearTimeout</span> compileTimeout
|
||||||
compileTimeout = wait <span class="hljs-number">25</span>, <span class="hljs-function">-></span>
|
compileTimeout = wait <span class="hljs-number">25</span>, <span class="hljs-function">-></span>
|
||||||
fs.stat source, <span class="hljs-function"><span class="hljs-params">(err, stats)</span> -></span>
|
fs.stat source, <span class="hljs-function"><span class="hljs-params">(err, stats)</span> -></span>
|
||||||
<span class="hljs-keyword">return</span> watchErr err <span class="hljs-keyword">if</span> err
|
<span class="hljs-keyword">return</span> watchErr err <span class="hljs-keyword">if</span> err
|
||||||
@@ -587,9 +591,9 @@ such as <code>--print</code>.</p>
|
|||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">startWatcher</span> = -></span>
|
<span class="hljs-title">startWatcher</span> = -></span>
|
||||||
watcher = fs.watch source
|
watcher = fs.watch source
|
||||||
.<span class="hljs-literal">on</span> <span class="hljs-string">'change'</span>, compile
|
.<span class="hljs-literal">on</span> <span class="hljs-string">'change'</span>, compile
|
||||||
.<span class="hljs-literal">on</span> <span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
.<span class="hljs-literal">on</span> <span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
||||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'EPERM'</span>
|
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'EPERM'</span>
|
||||||
removeSource source, base
|
removeSource source, base
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">rewatch</span> = -></span>
|
<span class="hljs-title">rewatch</span> = -></span>
|
||||||
@@ -607,8 +611,8 @@ such as <code>--print</code>.</p>
|
|||||||
<li id="section-16">
|
<li id="section-16">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-16">¶</a>
|
<a class="ss" href="#section-16">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Watch a directory of files for new additions.</p>
|
<p>Watch a directory of files for new additions.</p>
|
||||||
|
|
||||||
@@ -620,16 +624,16 @@ such as <code>--print</code>.</p>
|
|||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">startWatcher</span> = -></span>
|
<span class="hljs-title">startWatcher</span> = -></span>
|
||||||
watcher = fs.watch source
|
watcher = fs.watch source
|
||||||
.<span class="hljs-literal">on</span> <span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
.<span class="hljs-literal">on</span> <span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
||||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'EPERM'</span>
|
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'EPERM'</span>
|
||||||
stopWatcher()
|
stopWatcher()
|
||||||
.<span class="hljs-literal">on</span> <span class="hljs-string">'change'</span>, <span class="hljs-function">-></span>
|
.<span class="hljs-literal">on</span> <span class="hljs-string">'change'</span>, <span class="hljs-function">-></span>
|
||||||
clearTimeout readdirTimeout
|
<span class="hljs-built_in">clearTimeout</span> readdirTimeout
|
||||||
readdirTimeout = wait <span class="hljs-number">25</span>, <span class="hljs-function">-></span>
|
readdirTimeout = wait <span class="hljs-number">25</span>, <span class="hljs-function">-></span>
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
files = fs.readdirSync source
|
files = fs.readdirSync source
|
||||||
<span class="hljs-keyword">catch</span> err
|
<span class="hljs-keyword">catch</span> err
|
||||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||||
<span class="hljs-keyword">return</span> stopWatcher()
|
<span class="hljs-keyword">return</span> stopWatcher()
|
||||||
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> files
|
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> files
|
||||||
compilePath (path.join source, file), <span class="hljs-literal">no</span>, base
|
compilePath (path.join source, file), <span class="hljs-literal">no</span>, base
|
||||||
@@ -642,7 +646,7 @@ such as <code>--print</code>.</p>
|
|||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
startWatcher()
|
startWatcher()
|
||||||
<span class="hljs-keyword">catch</span> err
|
<span class="hljs-keyword">catch</span> err
|
||||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">removeSourceDir</span> = <span class="hljs-params">(source, base)</span> -></span>
|
<span class="hljs-title">removeSourceDir</span> = <span class="hljs-params">(source, base)</span> -></span>
|
||||||
<span class="hljs-keyword">delete</span> watchedDirs[source]
|
<span class="hljs-keyword">delete</span> watchedDirs[source]
|
||||||
@@ -658,8 +662,8 @@ such as <code>--print</code>.</p>
|
|||||||
<li id="section-17">
|
<li id="section-17">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-17">¶</a>
|
<a class="ss" href="#section-17">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Remove a file from our source list, and source code cache. Optionally remove
|
<p>Remove a file from our source list, and source code cache. Optionally remove
|
||||||
the compiled JS version as well.</p>
|
the compiled JS version as well.</p>
|
||||||
@@ -672,14 +676,14 @@ the compiled JS version as well.</p>
|
|||||||
sourceCode.splice index, <span class="hljs-number">1</span>
|
sourceCode.splice index, <span class="hljs-number">1</span>
|
||||||
<span class="hljs-keyword">unless</span> opts.join
|
<span class="hljs-keyword">unless</span> opts.join
|
||||||
silentUnlink outputPath source, base
|
silentUnlink outputPath source, base
|
||||||
silentUnlink outputPath source, base, <span class="hljs-string">'.js.map'</span>
|
silentUnlink outputPath source, base, <span class="hljs-string">'.js.map'</span>
|
||||||
timeLog <span class="hljs-string">"removed <span class="hljs-subst">#{source}</span>"</span>
|
timeLog <span class="hljs-string">"removed <span class="hljs-subst">#{source}</span>"</span>
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">silentUnlink</span> = <span class="hljs-params">(path)</span> -></span>
|
<span class="hljs-title">silentUnlink</span> = <span class="hljs-params">(path)</span> -></span>
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
fs.unlinkSync path
|
fs.unlinkSync path
|
||||||
<span class="hljs-keyword">catch</span> err
|
<span class="hljs-keyword">catch</span> err
|
||||||
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">in</span> [<span class="hljs-string">'ENOENT'</span>, <span class="hljs-string">'EPERM'</span>]</pre></div></div>
|
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">in</span> [<span class="hljs-string">'ENOENT'</span>, <span class="hljs-string">'EPERM'</span>]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -687,14 +691,14 @@ the compiled JS version as well.</p>
|
|||||||
<li id="section-18">
|
<li id="section-18">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-18">¶</a>
|
<a class="ss" href="#section-18">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Get the corresponding output JavaScript path for a source file.</p>
|
<p>Get the corresponding output JavaScript path for a source file.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">outputPath</span> = <span class="hljs-params">(source, base, extension=<span class="hljs-string">".js"</span>)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">outputPath</span> = <span class="hljs-params">(source, base, extension=<span class="hljs-string">".js"</span>)</span> -></span>
|
||||||
basename = helpers.baseFileName source, <span class="hljs-literal">yes</span>, useWinPathSep
|
basename = helpers.baseFileName source, <span class="hljs-literal">yes</span>, useWinPathSep
|
||||||
srcDir = path.dirname source
|
srcDir = path.dirname source
|
||||||
dir = <span class="hljs-keyword">unless</span> opts.outputPath
|
dir = <span class="hljs-keyword">unless</span> opts.outputPath
|
||||||
@@ -711,8 +715,8 @@ the compiled JS version as well.</p>
|
|||||||
<li id="section-19">
|
<li id="section-19">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-19">¶</a>
|
<a class="ss" href="#section-19">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Recursively mkdir, like <code>mkdir -p</code>.</p>
|
<p>Recursively mkdir, like <code>mkdir -p</code>.</p>
|
||||||
|
|
||||||
@@ -737,8 +741,8 @@ the compiled JS version as well.</p>
|
|||||||
<li id="section-20">
|
<li id="section-20">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-20">¶</a>
|
<a class="ss" href="#section-20">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Write out a JavaScript source file with the compiled code. By default, files
|
<p>Write out a JavaScript source file with the compiled code. By default, files
|
||||||
are written out in <code>cwd</code> as <code>.js</code> files with the same name, but the output
|
are written out in <code>cwd</code> as <code>.js</code> files with the same name, but the output
|
||||||
@@ -749,22 +753,22 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">writeJs</span> = <span class="hljs-params">(base, sourcePath, js, jsPath, generatedSourceMap = <span class="hljs-literal">null</span>)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">writeJs</span> = <span class="hljs-params">(base, sourcePath, js, jsPath, generatedSourceMap = <span class="hljs-literal">null</span>)</span> -></span>
|
||||||
sourceMapPath = <span class="hljs-string">"<span class="hljs-subst">#{jsPath}</span>.map"</span>
|
sourceMapPath = <span class="hljs-string">"<span class="hljs-subst">#{jsPath}</span>.map"</span>
|
||||||
jsDir = path.dirname jsPath
|
jsDir = path.dirname jsPath
|
||||||
<span class="hljs-function"> <span class="hljs-title">compile</span> = -></span>
|
<span class="hljs-function"> <span class="hljs-title">compile</span> = -></span>
|
||||||
<span class="hljs-keyword">if</span> opts.compile
|
<span class="hljs-keyword">if</span> opts.compile
|
||||||
js = <span class="hljs-string">' '</span> <span class="hljs-keyword">if</span> js.length <= <span class="hljs-number">0</span>
|
js = <span class="hljs-string">' '</span> <span class="hljs-keyword">if</span> js.length <= <span class="hljs-number">0</span>
|
||||||
<span class="hljs-keyword">if</span> generatedSourceMap <span class="hljs-keyword">then</span> js = <span class="hljs-string">"<span class="hljs-subst">#{js}</span>\n//# sourceMappingURL=<span class="hljs-subst">#{helpers.baseFileName sourceMapPath, <span class="hljs-literal">no</span>, useWinPathSep}</span>\n"</span>
|
<span class="hljs-keyword">if</span> generatedSourceMap <span class="hljs-keyword">then</span> js = <span class="hljs-string">"<span class="hljs-subst">#{js}</span>\n//# sourceMappingURL=<span class="hljs-subst">#{helpers.baseFileName sourceMapPath, <span class="hljs-literal">no</span>, useWinPathSep}</span>\n"</span>
|
||||||
fs.writeFile jsPath, js, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
fs.writeFile jsPath, js, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
||||||
<span class="hljs-keyword">if</span> err
|
<span class="hljs-keyword">if</span> err
|
||||||
printLine err.message
|
printLine err.message
|
||||||
process.exit <span class="hljs-number">1</span>
|
process.exit <span class="hljs-number">1</span>
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.compile <span class="hljs-keyword">and</span> opts.watch
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.compile <span class="hljs-keyword">and</span> opts.watch
|
||||||
timeLog <span class="hljs-string">"compiled <span class="hljs-subst">#{sourcePath}</span>"</span>
|
timeLog <span class="hljs-string">"compiled <span class="hljs-subst">#{sourcePath}</span>"</span>
|
||||||
<span class="hljs-keyword">if</span> generatedSourceMap
|
<span class="hljs-keyword">if</span> generatedSourceMap
|
||||||
fs.writeFile sourceMapPath, generatedSourceMap, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
fs.writeFile sourceMapPath, generatedSourceMap, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
|
||||||
<span class="hljs-keyword">if</span> err
|
<span class="hljs-keyword">if</span> err
|
||||||
printLine <span class="hljs-string">"Could not write source map: <span class="hljs-subst">#{err.message}</span>"</span>
|
printLine <span class="hljs-string">"Could not write source map: <span class="hljs-subst">#{err.message}</span>"</span>
|
||||||
process.exit <span class="hljs-number">1</span>
|
process.exit <span class="hljs-number">1</span>
|
||||||
fs.exists jsDir, <span class="hljs-function"><span class="hljs-params">(itExists)</span> -></span>
|
fs.exists jsDir, <span class="hljs-function"><span class="hljs-params">(itExists)</span> -></span>
|
||||||
<span class="hljs-keyword">if</span> itExists <span class="hljs-keyword">then</span> compile() <span class="hljs-keyword">else</span> mkdirp jsDir, compile</pre></div></div>
|
<span class="hljs-keyword">if</span> itExists <span class="hljs-keyword">then</span> compile() <span class="hljs-keyword">else</span> mkdirp jsDir, compile</pre></div></div>
|
||||||
@@ -775,14 +779,14 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
<li id="section-21">
|
<li id="section-21">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-21">¶</a>
|
<a class="ss" href="#section-21">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Convenience for cleaner setTimeouts.</p>
|
<p>Convenience for cleaner setTimeouts.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">wait</span> = <span class="hljs-params">(milliseconds, func)</span> -></span> setTimeout func, milliseconds</pre></div></div>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">wait</span> = <span class="hljs-params">(milliseconds, func)</span> -></span> <span class="hljs-built_in">setTimeout</span> func, milliseconds</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -790,15 +794,15 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
<li id="section-22">
|
<li id="section-22">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-22">¶</a>
|
<a class="ss" href="#section-22">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>When watching scripts, it’s useful to log changes with the timestamp.</p>
|
<p>When watching scripts, it’s useful to log changes with the timestamp.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">timeLog</span> = <span class="hljs-params">(message)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">timeLog</span> = <span class="hljs-params">(message)</span> -></span>
|
||||||
<span class="hljs-built_in">console</span>.log <span class="hljs-string">"<span class="hljs-subst">#{(<span class="hljs-keyword">new</span> Date).toLocaleTimeString()}</span> - <span class="hljs-subst">#{message}</span>"</span></pre></div></div>
|
console.log <span class="hljs-string">"<span class="hljs-subst">#{(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>).toLocaleTimeString()}</span> - <span class="hljs-subst">#{message}</span>"</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -806,8 +810,8 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
<li id="section-23">
|
<li id="section-23">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-23">¶</a>
|
<a class="ss" href="#section-23">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Pretty-print a stream of tokens, sans location data.</p>
|
<p>Pretty-print a stream of tokens, sans location data.</p>
|
||||||
|
|
||||||
@@ -816,9 +820,9 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">printTokens</span> = <span class="hljs-params">(tokens)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">printTokens</span> = <span class="hljs-params">(tokens)</span> -></span>
|
||||||
strings = <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens
|
strings = <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens
|
||||||
tag = token[<span class="hljs-number">0</span>]
|
tag = token[<span class="hljs-number">0</span>]
|
||||||
value = token[<span class="hljs-number">1</span>].toString().replace(<span class="hljs-regexp">/\n/</span>, <span class="hljs-string">'\\n'</span>)
|
value = token[<span class="hljs-number">1</span>].toString().replace(<span class="hljs-regexp">/\n/</span>, <span class="hljs-string">'\\n'</span>)
|
||||||
<span class="hljs-string">"[<span class="hljs-subst">#{tag}</span> <span class="hljs-subst">#{value}</span>]"</span>
|
<span class="hljs-string">"[<span class="hljs-subst">#{tag}</span> <span class="hljs-subst">#{value}</span>]"</span>
|
||||||
printLine strings.join(<span class="hljs-string">' '</span>)</pre></div></div>
|
printLine strings.join(<span class="hljs-string">' '</span>)</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -826,8 +830,8 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
<li id="section-24">
|
<li id="section-24">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-24">¶</a>
|
<a class="ss" href="#section-24">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Use the <a href="optparse.html">OptionParser module</a> to extract all options from
|
<p>Use the <a href="optparse.html">OptionParser module</a> to extract all options from
|
||||||
<code>process.argv</code> that are specified in <code>SWITCHES</code>.</p>
|
<code>process.argv</code> that are specified in <code>SWITCHES</code>.</p>
|
||||||
@@ -838,7 +842,7 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
o = opts = optionParser.parse process.argv[<span class="hljs-number">2.</span>.]
|
o = opts = optionParser.parse process.argv[<span class="hljs-number">2.</span>.]
|
||||||
o.compile <span class="hljs-keyword">or</span>= !!o.output
|
o.compile <span class="hljs-keyword">or</span>= !!o.output
|
||||||
o.run = <span class="hljs-keyword">not</span> (o.compile <span class="hljs-keyword">or</span> o.<span class="hljs-built_in">print</span> <span class="hljs-keyword">or</span> o.map)
|
o.run = <span class="hljs-keyword">not</span> (o.compile <span class="hljs-keyword">or</span> o.<span class="hljs-built_in">print</span> <span class="hljs-keyword">or</span> o.map)
|
||||||
o.<span class="hljs-built_in">print</span> = !! (o.<span class="hljs-built_in">print</span> <span class="hljs-keyword">or</span> (o.eval <span class="hljs-keyword">or</span> o.stdio <span class="hljs-keyword">and</span> o.compile))</pre></div></div>
|
o.<span class="hljs-built_in">print</span> = !! (o.<span class="hljs-built_in">print</span> <span class="hljs-keyword">or</span> (o.<span class="hljs-built_in">eval</span> <span class="hljs-keyword">or</span> o.stdio <span class="hljs-keyword">and</span> o.compile))</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -846,8 +850,8 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
<li id="section-25">
|
<li id="section-25">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-25">¶</a>
|
<a class="ss" href="#section-25">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The compile-time options to pass to the CoffeeScript compiler.</p>
|
<p>The compile-time options to pass to the CoffeeScript compiler.</p>
|
||||||
|
|
||||||
@@ -862,8 +866,8 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
<li id="section-26">
|
<li id="section-26">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-26">¶</a>
|
<a class="ss" href="#section-26">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The user has requested that the CoffeeScript compiler also transpile
|
<p>The user has requested that the CoffeeScript compiler also transpile
|
||||||
via Babel. We don’t include Babel as a dependency because we want to
|
via Babel. We don’t include Babel as a dependency because we want to
|
||||||
@@ -875,10 +879,10 @@ browsers) or use a proper build chain like Gulp or Webpack.</p>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">try</span>
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">try</span>
|
||||||
<span class="hljs-built_in">require</span> <span class="hljs-string">'@babel/core'</span>
|
<span class="hljs-built_in">require</span> <span class="hljs-string">'@babel/core'</span>
|
||||||
<span class="hljs-keyword">catch</span>
|
<span class="hljs-keyword">catch</span>
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
<span class="hljs-built_in">require</span> <span class="hljs-string">'babel-core'</span>
|
<span class="hljs-built_in">require</span> <span class="hljs-string">'babel-core'</span>
|
||||||
<span class="hljs-keyword">catch</span></pre></div></div>
|
<span class="hljs-keyword">catch</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -887,31 +891,31 @@ browsers) or use a proper build chain like Gulp or Webpack.</p>
|
|||||||
<li id="section-27">
|
<li id="section-27">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-27">¶</a>
|
<a class="ss" href="#section-27">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Give appropriate instructions depending on whether <code>coffee</code> was run
|
<p>Give appropriate instructions depending on whether <code>coffee</code> was run
|
||||||
locally or globally.</p>
|
locally or globally.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> <span class="hljs-built_in">require</span>.resolve(<span class="hljs-string">'.'</span>).indexOf(process.cwd()) <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> <span class="hljs-built_in">require</span>.resolve(<span class="hljs-string">'.'</span>).indexOf(process.cwd()) <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
|
||||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
|
console.error <span class="hljs-string">'''
|
||||||
To use --transpile, you must have @babel/core installed:
|
To use --transpile, you must have @babel/core installed:
|
||||||
npm install --save-dev @babel/core
|
npm install --save-dev @babel/core
|
||||||
And you must save options to configure Babel in one of the places it looks to find its options.
|
And you must save options to configure Babel in one of the places it looks to find its options.
|
||||||
See https://coffeescript.org/#transpilation
|
See https://coffeescript.org/#transpilation
|
||||||
'''</span>
|
'''</span>
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
|
console.error <span class="hljs-string">'''
|
||||||
To use --transpile with globally-installed CoffeeScript, you must have @babel/core installed globally:
|
To use --transpile with globally-installed CoffeeScript, you must have @babel/core installed globally:
|
||||||
npm install --global @babel/core
|
npm install --global @babel/core
|
||||||
And you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.
|
And you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.
|
||||||
See https://coffeescript.org/#transpilation
|
See https://coffeescript.org/#transpilation
|
||||||
'''</span>
|
'''</span>
|
||||||
process.exit <span class="hljs-number">1</span>
|
process.exit <span class="hljs-number">1</span>
|
||||||
|
|
||||||
opts.transpile = {} <span class="hljs-keyword">unless</span> <span class="hljs-keyword">typeof</span> opts.transpile <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span></pre></div></div>
|
opts.transpile = {} <span class="hljs-keyword">unless</span> <span class="hljs-keyword">typeof</span> opts.transpile <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -919,8 +923,8 @@ locally or globally.</p>
|
|||||||
<li id="section-28">
|
<li id="section-28">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-28">¶</a>
|
<a class="ss" href="#section-28">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Pass a reference to Babel into the compiler, so that the transpile option
|
<p>Pass a reference to Babel into the compiler, so that the transpile option
|
||||||
is available for the CLI. We need to do this so that tools like Webpack
|
is available for the CLI. We need to do this so that tools like Webpack
|
||||||
@@ -937,8 +941,8 @@ require Babel.</p>
|
|||||||
<li id="section-29">
|
<li id="section-29">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-29">¶</a>
|
<a class="ss" href="#section-29">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Babel searches for its options (a <code>.babelrc</code> file, a <code>.babelrc.js</code> file,
|
<p>Babel searches for its options (a <code>.babelrc</code> file, a <code>.babelrc.js</code> file,
|
||||||
a <code>package.json</code> file with a <code>babel</code> key, etc.) relative to the path
|
a <code>package.json</code> file with a <code>babel</code> key, etc.) relative to the path
|
||||||
@@ -948,7 +952,7 @@ along.</p>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> opts.transpile.filename
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> opts.transpile.filename
|
||||||
opts.transpile.filename = filename <span class="hljs-keyword">or</span> path.resolve(base <span class="hljs-keyword">or</span> process.cwd(), <span class="hljs-string">'<anonymous>'</span>)
|
opts.transpile.filename = filename <span class="hljs-keyword">or</span> path.resolve(base <span class="hljs-keyword">or</span> process.cwd(), <span class="hljs-string">'<anonymous>'</span>)
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
opts.transpile = <span class="hljs-literal">no</span>
|
opts.transpile = <span class="hljs-literal">no</span>
|
||||||
|
|
||||||
@@ -956,10 +960,11 @@ along.</p>
|
|||||||
filename: filename
|
filename: filename
|
||||||
literate: opts.literate <span class="hljs-keyword">or</span> helpers.isLiterate(filename)
|
literate: opts.literate <span class="hljs-keyword">or</span> helpers.isLiterate(filename)
|
||||||
bare: opts.bare
|
bare: opts.bare
|
||||||
header: opts.compile <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> opts[<span class="hljs-string">'no-header'</span>]
|
header: opts.compile <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> opts[<span class="hljs-string">'no-header'</span>]
|
||||||
transpile: opts.transpile
|
transpile: opts.transpile
|
||||||
sourceMap: opts.map
|
sourceMap: opts.map
|
||||||
inlineMap: opts[<span class="hljs-string">'inline-map'</span>]
|
inlineMap: opts[<span class="hljs-string">'inline-map'</span>]
|
||||||
|
ast: opts.ast
|
||||||
|
|
||||||
<span class="hljs-keyword">if</span> filename
|
<span class="hljs-keyword">if</span> filename
|
||||||
<span class="hljs-keyword">if</span> base
|
<span class="hljs-keyword">if</span> base
|
||||||
@@ -968,15 +973,15 @@ along.</p>
|
|||||||
jsDir = path.dirname jsPath
|
jsDir = path.dirname jsPath
|
||||||
answer = helpers.merge answer, {
|
answer = helpers.merge answer, {
|
||||||
jsPath
|
jsPath
|
||||||
sourceRoot: path.relative jsDir, cwd
|
sourceRoot: path.relative(jsDir, cwd) + path.sep
|
||||||
sourceFiles: [path.relative cwd, filename]
|
sourceFiles: [path.relative cwd, filename]
|
||||||
generatedFile: helpers.baseFileName(jsPath, <span class="hljs-literal">no</span>, useWinPathSep)
|
generatedFile: helpers.baseFileName(jsPath, <span class="hljs-literal">no</span>, useWinPathSep)
|
||||||
}
|
}
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
answer = helpers.merge answer,
|
answer = helpers.merge answer,
|
||||||
sourceRoot: <span class="hljs-string">""</span>
|
sourceRoot: <span class="hljs-string">""</span>
|
||||||
sourceFiles: [helpers.baseFileName filename, <span class="hljs-literal">no</span>, useWinPathSep]
|
sourceFiles: [helpers.baseFileName filename, <span class="hljs-literal">no</span>, useWinPathSep]
|
||||||
generatedFile: helpers.baseFileName(filename, <span class="hljs-literal">yes</span>, useWinPathSep) + <span class="hljs-string">".js"</span>
|
generatedFile: helpers.baseFileName(filename, <span class="hljs-literal">yes</span>, useWinPathSep) + <span class="hljs-string">".js"</span>
|
||||||
answer</pre></div></div>
|
answer</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -985,8 +990,8 @@ along.</p>
|
|||||||
<li id="section-30">
|
<li id="section-30">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-30">¶</a>
|
<a class="ss" href="#section-30">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Start up a new Node.js instance with the arguments in <code>--nodejs</code> passed to
|
<p>Start up a new Node.js instance with the arguments in <code>--nodejs</code> passed to
|
||||||
the <code>node</code> binary, preserving the other options.</p>
|
the <code>node</code> binary, preserving the other options.</p>
|
||||||
@@ -996,15 +1001,15 @@ the <code>node</code> binary, preserving the other options.</p>
|
|||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">forkNode</span> = -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">forkNode</span> = -></span>
|
||||||
nodeArgs = opts.nodejs.split <span class="hljs-regexp">/\s+/</span>
|
nodeArgs = opts.nodejs.split <span class="hljs-regexp">/\s+/</span>
|
||||||
args = process.argv[<span class="hljs-number">1.</span>.]
|
args = process.argv[<span class="hljs-number">1.</span>.]
|
||||||
args.splice args.indexOf(<span class="hljs-string">'--nodejs'</span>), <span class="hljs-number">2</span>
|
args.splice args.indexOf(<span class="hljs-string">'--nodejs'</span>), <span class="hljs-number">2</span>
|
||||||
p = spawn process.execPath, nodeArgs.concat(args),
|
p = spawn process.execPath, nodeArgs.concat(args),
|
||||||
cwd: process.cwd()
|
cwd: process.cwd()
|
||||||
env: process.env
|
env: process.env
|
||||||
stdio: [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]
|
stdio: [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]
|
||||||
<span class="hljs-keyword">for</span> signal <span class="hljs-keyword">in</span> [<span class="hljs-string">'SIGINT'</span>, <span class="hljs-string">'SIGTERM'</span>]
|
<span class="hljs-keyword">for</span> signal <span class="hljs-keyword">in</span> [<span class="hljs-string">'SIGINT'</span>, <span class="hljs-string">'SIGTERM'</span>]
|
||||||
process.<span class="hljs-literal">on</span> signal, <span class="hljs-keyword">do</span> (signal) ->
|
process.<span class="hljs-literal">on</span> signal, <span class="hljs-keyword">do</span> (signal) ->
|
||||||
-> p.kill signal
|
-> p.kill signal
|
||||||
p.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>, <span class="hljs-function"><span class="hljs-params">(code)</span> -></span> process.exit code</pre></div></div>
|
p.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>, <span class="hljs-function"><span class="hljs-params">(code)</span> -></span> process.exit code</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -1012,8 +1017,8 @@ the <code>node</code> binary, preserving the other options.</p>
|
|||||||
<li id="section-31">
|
<li id="section-31">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-31">¶</a>
|
<a class="ss" href="#section-31">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Print the <code>--help</code> usage message and exit. Deprecated switches are not
|
<p>Print the <code>--help</code> usage message and exit. Deprecated switches are not
|
||||||
shown.</p>
|
shown.</p>
|
||||||
@@ -1029,15 +1034,15 @@ shown.</p>
|
|||||||
<li id="section-32">
|
<li id="section-32">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-32">¶</a>
|
<a class="ss" href="#section-32">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Print the <code>--version</code> message and exit.</p>
|
<p>Print the <code>--version</code> message and exit.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">version</span> = -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">version</span> = -></span>
|
||||||
printLine <span class="hljs-string">"CoffeeScript version <span class="hljs-subst">#{CoffeeScript.VERSION}</span>"</span></pre></div></div>
|
printLine <span class="hljs-string">"CoffeeScript version <span class="hljs-subst">#{CoffeeScript.VERSION}</span>"</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ ul.sections > li > div {
|
|||||||
|
|
||||||
/*---------------------- Low resolutions (> 320px) ---------------------*/
|
/*---------------------- Low resolutions (> 320px) ---------------------*/
|
||||||
@media only screen and (min-width: 320px) {
|
@media only screen and (min-width: 320px) {
|
||||||
.pilwrap { display: none; }
|
.sswrap { display: none; }
|
||||||
|
|
||||||
ul.sections > li > div {
|
ul.sections > li > div {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -330,12 +330,12 @@ ul.sections > li > div {
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pilwrap {
|
.sswrap {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pilcrow {
|
.ss {
|
||||||
font: 12px Arial;
|
font: 12px Arial;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #454545;
|
color: #454545;
|
||||||
@@ -345,14 +345,14 @@ ul.sections > li > div {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
-webkit-transition: opacity 0.2s linear;
|
-webkit-transition: opacity 0.2s linear;
|
||||||
}
|
}
|
||||||
.for-h1 .pilcrow {
|
.for-h1 .ss {
|
||||||
top: 47px;
|
top: 47px;
|
||||||
}
|
}
|
||||||
.for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow {
|
.for-h2 .ss, .for-h3 .ss, .for-h4 .ss {
|
||||||
top: 35px;
|
top: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.sections > li > div.annotation:hover .pilcrow {
|
ul.sections > li > div.annotation:hover .ss {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -112,8 +112,8 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>This file contains the common helper functions that we’d like to share among
|
<p>This file contains the common helper functions that we’d like to share among
|
||||||
the <strong>Lexer</strong>, <strong>Rewriter</strong>, and the <strong>Nodes</strong>. Merge objects, flatten
|
the <strong>Lexer</strong>, <strong>Rewriter</strong>, and the <strong>Nodes</strong>. Merge objects, flatten
|
||||||
@@ -127,14 +127,14 @@ arrays, count characters, that sort of thing.</p>
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Peek at the beginning of a given string to see if it matches a sequence.</p>
|
<p>Peek at the beginning of a given string to see if it matches a sequence.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.starts = <span class="hljs-function"><span class="hljs-params">(string, literal, start)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.starts = <span class="hljs-function"><span class="hljs-params">(string, literal, start)</span> -></span>
|
||||||
literal <span class="hljs-keyword">is</span> string.substr start, literal.length</pre></div></div>
|
literal <span class="hljs-keyword">is</span> string.substr start, literal.length</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -143,14 +143,14 @@ arrays, count characters, that sort of thing.</p>
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Peek at the end of a given string to see if it matches a sequence.</p>
|
<p>Peek at the end of a given string to see if it matches a sequence.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.ends = <span class="hljs-function"><span class="hljs-params">(string, literal, back)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.ends = <span class="hljs-function"><span class="hljs-params">(string, literal, back)</span> -></span>
|
||||||
len = literal.length
|
len = literal.length
|
||||||
literal <span class="hljs-keyword">is</span> string.substr string.length - len - (back <span class="hljs-keyword">or</span> <span class="hljs-number">0</span>), len</pre></div></div>
|
literal <span class="hljs-keyword">is</span> string.substr string.length - len - (back <span class="hljs-keyword">or</span> <span class="hljs-number">0</span>), len</pre></div></div>
|
||||||
|
|
||||||
@@ -160,14 +160,14 @@ arrays, count characters, that sort of thing.</p>
|
|||||||
<li id="section-4">
|
<li id="section-4">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-4">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Repeat a string <code>n</code> times.</p>
|
<p>Repeat a string <code>n</code> times.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.repeat = repeat = <span class="hljs-function"><span class="hljs-params">(str, n)</span> -></span></pre></div></div>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.repeat = repeat = <span class="hljs-function"><span class="hljs-params">(str, n)</span> -></span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -175,14 +175,14 @@ arrays, count characters, that sort of thing.</p>
|
|||||||
<li id="section-5">
|
<li id="section-5">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Use clever algorithm to have O(log(n)) string concatenation operations.</p>
|
<p>Use clever algorithm to have O(log(n)) string concatenation operations.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> res = <span class="hljs-string">''</span>
|
<div class="content"><div class='highlight'><pre> res = <span class="hljs-string">''</span>
|
||||||
<span class="hljs-keyword">while</span> n > <span class="hljs-number">0</span>
|
<span class="hljs-keyword">while</span> n > <span class="hljs-number">0</span>
|
||||||
res += str <span class="hljs-keyword">if</span> n & <span class="hljs-number">1</span>
|
res += str <span class="hljs-keyword">if</span> n & <span class="hljs-number">1</span>
|
||||||
n >>>= <span class="hljs-number">1</span>
|
n >>>= <span class="hljs-number">1</span>
|
||||||
@@ -195,14 +195,14 @@ arrays, count characters, that sort of thing.</p>
|
|||||||
<li id="section-6">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Trim out all falsy values from an array.</p>
|
<p>Trim out all falsy values from an array.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.compact = <span class="hljs-function"><span class="hljs-params">(array)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.compact = <span class="hljs-function"><span class="hljs-params">(array)</span> -></span>
|
||||||
item <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> array <span class="hljs-keyword">when</span> item</pre></div></div>
|
item <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> array <span class="hljs-keyword">when</span> item</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -211,14 +211,14 @@ arrays, count characters, that sort of thing.</p>
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Count the number of occurrences of a string in a string.</p>
|
<p>Count the number of occurrences of a string in a string.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.count = <span class="hljs-function"><span class="hljs-params">(string, substr)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.count = <span class="hljs-function"><span class="hljs-params">(string, substr)</span> -></span>
|
||||||
num = pos = <span class="hljs-number">0</span>
|
num = pos = <span class="hljs-number">0</span>
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>/<span class="hljs-number">0</span> <span class="hljs-keyword">unless</span> substr.length
|
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>/<span class="hljs-number">0</span> <span class="hljs-keyword">unless</span> substr.length
|
||||||
num++ <span class="hljs-keyword">while</span> pos = <span class="hljs-number">1</span> + string.indexOf substr, pos
|
num++ <span class="hljs-keyword">while</span> pos = <span class="hljs-number">1</span> + string.indexOf substr, pos
|
||||||
@@ -230,8 +230,8 @@ arrays, count characters, that sort of thing.</p>
|
|||||||
<li id="section-8">
|
<li id="section-8">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-8">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Merge objects, returning a fresh copy with attributes from both sides.
|
<p>Merge objects, returning a fresh copy with attributes from both sides.
|
||||||
Used every time <code>Base#compile</code> is called, to allow properties in the
|
Used every time <code>Base#compile</code> is called, to allow properties in the
|
||||||
@@ -239,7 +239,7 @@ options hash to propagate down the tree without polluting other branches.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.merge = <span class="hljs-function"><span class="hljs-params">(options, overrides)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.merge = <span class="hljs-function"><span class="hljs-params">(options, overrides)</span> -></span>
|
||||||
extend (extend {}, options), overrides</pre></div></div>
|
extend (extend {}, options), overrides</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -248,14 +248,14 @@ options hash to propagate down the tree without polluting other branches.</p>
|
|||||||
<li id="section-9">
|
<li id="section-9">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="ss" href="#section-9">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Extend a source object with the properties of another object (shallow copy).</p>
|
<p>Extend a source object with the properties of another object (shallow copy).</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>extend = exports.extend = <span class="hljs-function"><span class="hljs-params">(object, properties)</span> -></span>
|
<div class="content"><div class='highlight'><pre>extend = <span class="hljs-built_in">exports</span>.extend = <span class="hljs-function"><span class="hljs-params">(object, properties)</span> -></span>
|
||||||
<span class="hljs-keyword">for</span> key, val <span class="hljs-keyword">of</span> properties
|
<span class="hljs-keyword">for</span> key, val <span class="hljs-keyword">of</span> properties
|
||||||
object[key] = val
|
object[key] = val
|
||||||
object</pre></div></div>
|
object</pre></div></div>
|
||||||
@@ -266,22 +266,16 @@ options hash to propagate down the tree without polluting other branches.</p>
|
|||||||
<li id="section-10">
|
<li id="section-10">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Return a flattened version of an array.
|
<p>Return a flattened version of an array.
|
||||||
Handy for getting a list of <code>children</code> from the nodes.</p>
|
Handy for getting a list of <code>children</code> from the nodes.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.flatten = flatten = <span class="hljs-function"><span class="hljs-params">(array)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.flatten = flatten = <span class="hljs-function"><span class="hljs-params">(array)</span> -></span>
|
||||||
flattened = []
|
array.flat(<span class="hljs-literal">Infinity</span>)</pre></div></div>
|
||||||
<span class="hljs-keyword">for</span> element <span class="hljs-keyword">in</span> array
|
|
||||||
<span class="hljs-keyword">if</span> <span class="hljs-string">'[object Array]'</span> <span class="hljs-keyword">is</span> Object::toString.call element
|
|
||||||
flattened = flattened.concat flatten element
|
|
||||||
<span class="hljs-keyword">else</span>
|
|
||||||
flattened.push element
|
|
||||||
flattened</pre></div></div>
|
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -289,15 +283,15 @@ Handy for getting a list of <code>children</code> from the nodes.</p>
|
|||||||
<li id="section-11">
|
<li id="section-11">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="ss" href="#section-11">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Delete a key from an object, returning the value. Useful when a node is
|
<p>Delete a key from an object, returning the value. Useful when a node is
|
||||||
looking for a particular method in an options hash.</p>
|
looking for a particular method in an options hash.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.del = <span class="hljs-function"><span class="hljs-params">(obj, key)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.del = <span class="hljs-function"><span class="hljs-params">(obj, key)</span> -></span>
|
||||||
val = obj[key]
|
val = obj[key]
|
||||||
<span class="hljs-keyword">delete</span> obj[key]
|
<span class="hljs-keyword">delete</span> obj[key]
|
||||||
val</pre></div></div>
|
val</pre></div></div>
|
||||||
@@ -308,15 +302,15 @@ looking for a particular method in an options hash.</p>
|
|||||||
<li id="section-12">
|
<li id="section-12">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="ss" href="#section-12">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Typical Array::some</p>
|
<p>Typical Array::some</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.some = Array::some ? (fn) ->
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.some = Array::some ? (fn) ->
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">when</span> fn e
|
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> this <span class="hljs-keyword">when</span> fn e
|
||||||
<span class="hljs-literal">false</span></pre></div></div>
|
<span class="hljs-literal">false</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -325,8 +319,8 @@ looking for a particular method in an options hash.</p>
|
|||||||
<li id="section-13">
|
<li id="section-13">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-13">¶</a>
|
<a class="ss" href="#section-13">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Helper function for extracting code from Literate CoffeeScript by stripping
|
<p>Helper function for extracting code from Literate CoffeeScript by stripping
|
||||||
out all non-code blocks, producing a string of CoffeeScript code that can
|
out all non-code blocks, producing a string of CoffeeScript code that can
|
||||||
@@ -334,7 +328,7 @@ be compiled “normally.”</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.invertLiterate = <span class="hljs-function"><span class="hljs-params">(code)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.invertLiterate = <span class="hljs-function"><span class="hljs-params">(code)</span> -></span>
|
||||||
out = []
|
out = []
|
||||||
blankLine = <span class="hljs-regexp">/^\s*$/</span>
|
blankLine = <span class="hljs-regexp">/^\s*$/</span>
|
||||||
indented = <span class="hljs-regexp">/^[\t ]/</span>
|
indented = <span class="hljs-regexp">/^[\t ]/</span>
|
||||||
@@ -347,19 +341,19 @@ be compiled “normally.”</p>
|
|||||||
[\ \t] <span class="hljs-comment"># followed by a space or a tab.</span>
|
[\ \t] <span class="hljs-comment"># followed by a space or a tab.</span>
|
||||||
///</span>
|
///</span>
|
||||||
insideComment = <span class="hljs-literal">no</span>
|
insideComment = <span class="hljs-literal">no</span>
|
||||||
<span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> code.split(<span class="hljs-string">'\n'</span>)
|
<span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> code.split(<span class="hljs-string">'\n'</span>)
|
||||||
<span class="hljs-keyword">if</span> blankLine.test(line)
|
<span class="hljs-keyword">if</span> blankLine.test(line)
|
||||||
insideComment = <span class="hljs-literal">no</span>
|
insideComment = <span class="hljs-literal">no</span>
|
||||||
out.push line
|
out.push line
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> insideComment <span class="hljs-keyword">or</span> listItemStart.test(line)
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> insideComment <span class="hljs-keyword">or</span> listItemStart.test(line)
|
||||||
insideComment = <span class="hljs-literal">yes</span>
|
insideComment = <span class="hljs-literal">yes</span>
|
||||||
out.push <span class="hljs-string">"# <span class="hljs-subst">#{line}</span>"</span>
|
out.push <span class="hljs-string">"# <span class="hljs-subst">#{line}</span>"</span>
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> insideComment <span class="hljs-keyword">and</span> indented.test(line)
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> insideComment <span class="hljs-keyword">and</span> indented.test(line)
|
||||||
out.push line
|
out.push line
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
insideComment = <span class="hljs-literal">yes</span>
|
insideComment = <span class="hljs-literal">yes</span>
|
||||||
out.push <span class="hljs-string">"# <span class="hljs-subst">#{line}</span>"</span>
|
out.push <span class="hljs-string">"# <span class="hljs-subst">#{line}</span>"</span>
|
||||||
out.join <span class="hljs-string">'\n'</span></pre></div></div>
|
out.join <span class="hljs-string">'\n'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -367,8 +361,8 @@ be compiled “normally.”</p>
|
|||||||
<li id="section-14">
|
<li id="section-14">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-14">¶</a>
|
<a class="ss" href="#section-14">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Merge two jison-style location data objects together.
|
<p>Merge two jison-style location data objects together.
|
||||||
If <code>last</code> is not provided, this will simply return <code>first</code>.</p>
|
If <code>last</code> is not provided, this will simply return <code>first</code>.</p>
|
||||||
@@ -383,9 +377,12 @@ If <code>last</code> is not provided, this will simply return <code>first</code>
|
|||||||
first_column: first.first_column
|
first_column: first.first_column
|
||||||
last_line: last.last_line
|
last_line: last.last_line
|
||||||
last_column: last.last_column
|
last_column: last.last_column
|
||||||
<span class="hljs-function">
|
last_line_exclusive: last.last_line_exclusive
|
||||||
<span class="hljs-title">buildLocationHash</span> = <span class="hljs-params">(loc)</span> -></span>
|
last_column_exclusive: last.last_column_exclusive
|
||||||
<span class="hljs-string">"<span class="hljs-subst">#{loc.first_line}</span>x<span class="hljs-subst">#{loc.first_column}</span>-<span class="hljs-subst">#{loc.last_line}</span>x<span class="hljs-subst">#{loc.last_column}</span>"</span></pre></div></div>
|
range: [
|
||||||
|
first.range[<span class="hljs-number">0</span>]
|
||||||
|
last.range[<span class="hljs-number">1</span>]
|
||||||
|
]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -393,18 +390,22 @@ If <code>last</code> is not provided, this will simply return <code>first</code>
|
|||||||
<li id="section-15">
|
<li id="section-15">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-15">¶</a>
|
<a class="ss" href="#section-15">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Build a dictionary of extra token properties organized by tokens’ locations
|
<p>Build a list of all comments attached to tokens.</p>
|
||||||
used as lookup hashes.</p>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildTokenDataDictionary</span> = <span class="hljs-params">(parserState)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.extractAllCommentTokens = <span class="hljs-function"><span class="hljs-params">(tokens)</span> -></span>
|
||||||
tokenData = {}
|
allCommentsObj = {}
|
||||||
<span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> parserState.parser.tokens <span class="hljs-keyword">when</span> token.comments
|
<span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token.comments
|
||||||
tokenHash = buildLocationHash token[<span class="hljs-number">2</span>]</pre></div></div>
|
<span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> token.comments
|
||||||
|
commentKey = comment.locationData.range[<span class="hljs-number">0</span>]
|
||||||
|
allCommentsObj[commentKey] = comment
|
||||||
|
sortedKeys = <span class="hljs-built_in">Object</span>.keys(allCommentsObj).sort (a, b) -> a - b
|
||||||
|
<span class="hljs-keyword">for</span> key <span class="hljs-keyword">in</span> sortedKeys
|
||||||
|
allCommentsObj[key]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -412,8 +413,46 @@ used as lookup hashes.</p>
|
|||||||
<li id="section-16">
|
<li id="section-16">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-16">¶</a>
|
<a class="ss" href="#section-16">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Get a lookup hash for a token based on its location data.
|
||||||
|
Multiple tokens might have the same location hash, but using exclusive
|
||||||
|
location data distinguishes e.g. zero-length generated tokens from
|
||||||
|
actual source tokens.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildLocationHash</span> = <span class="hljs-params">(loc)</span> -></span>
|
||||||
|
<span class="hljs-string">"<span class="hljs-subst">#{loc.range[<span class="hljs-number">0</span>]}</span>-<span class="hljs-subst">#{loc.range[<span class="hljs-number">1</span>]}</span>"</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-17">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-17">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Build a dictionary of extra token properties organized by tokens’ locations
|
||||||
|
used as lookup hashes.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.buildTokenDataDictionary = buildTokenDataDictionary = <span class="hljs-function"><span class="hljs-params">(tokens)</span> -></span>
|
||||||
|
tokenData = {}
|
||||||
|
<span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token.comments
|
||||||
|
tokenHash = buildLocationHash token[<span class="hljs-number">2</span>]</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-18">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-18">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Multiple tokens might have the same location hash, such as the generated
|
<p>Multiple tokens might have the same location hash, such as the generated
|
||||||
<code>JS</code> tokens added at the start or end of the token stream to hold
|
<code>JS</code> tokens added at the start or end of the token stream to hold
|
||||||
@@ -427,11 +466,11 @@ comments that start or end a file.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-17">
|
<li id="section-19">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-17">¶</a>
|
<a class="ss" href="#section-19">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>For “overlapping” tokens, that is tokens with the same location data
|
<p>For “overlapping” tokens, that is tokens with the same location data
|
||||||
and therefore matching <code>tokenHash</code>es, merge the comments from both/all
|
and therefore matching <code>tokenHash</code>es, merge the comments from both/all
|
||||||
@@ -446,11 +485,11 @@ they will get sorted out later.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-18">
|
<li id="section-20">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-18">¶</a>
|
<a class="ss" href="#section-20">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>This returns a function which takes an object as a parameter, and if that
|
<p>This returns a function which takes an object as a parameter, and if that
|
||||||
object is an AST node, updates that object’s locationData.
|
object is an AST node, updates that object’s locationData.
|
||||||
@@ -458,74 +497,27 @@ The object is returned either way.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.addDataToNode = <span class="hljs-function"><span class="hljs-params">(parserState, first, last)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.addDataToNode = <span class="hljs-function"><span class="hljs-params">(parserState, firstLocationData, firstValue, lastLocationData, lastValue, forceUpdateLocation = <span class="hljs-literal">yes</span>)</span> -></span>
|
||||||
(obj) -></pre></div></div>
|
(obj) -></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-19">
|
|
||||||
<div class="annotation">
|
|
||||||
|
|
||||||
<div class="pilwrap ">
|
|
||||||
<a class="pilcrow" href="#section-19">¶</a>
|
|
||||||
</div>
|
|
||||||
<p>Add location data.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> obj?.updateLocationDataIfMissing? <span class="hljs-keyword">and</span> first?
|
|
||||||
obj.updateLocationDataIfMissing buildLocationData(first, last)</pre></div></div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li id="section-20">
|
|
||||||
<div class="annotation">
|
|
||||||
|
|
||||||
<div class="pilwrap ">
|
|
||||||
<a class="pilcrow" href="#section-20">¶</a>
|
|
||||||
</div>
|
|
||||||
<p>Add comments, building the dictionary of token data if it hasn’t been
|
|
||||||
built yet.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> parserState.tokenData ?= buildTokenDataDictionary parserState
|
|
||||||
<span class="hljs-keyword">if</span> obj.locationData?
|
|
||||||
objHash = buildLocationHash obj.locationData
|
|
||||||
<span class="hljs-keyword">if</span> parserState.tokenData[objHash]?.comments?
|
|
||||||
attachCommentsToNode parserState.tokenData[objHash].comments, obj
|
|
||||||
obj
|
|
||||||
|
|
||||||
exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function"><span class="hljs-params">(comments, node)</span> -></span>
|
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> comments? <span class="hljs-keyword">or</span> comments.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
|
|
||||||
node.comments ?= []
|
|
||||||
node.comments.push comments...</pre></div></div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li id="section-21">
|
<li id="section-21">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-21">¶</a>
|
<a class="ss" href="#section-21">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Convert jison location data to a string.
|
<p>Add location data.</p>
|
||||||
<code>obj</code> can be a token, or a locationData.</p>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.locationDataToString = <span class="hljs-function"><span class="hljs-params">(obj)</span> -></span>
|
<div class="content"><div class='highlight'><pre> locationData = buildLocationData(firstValue?.locationData ? firstLocationData, lastValue?.locationData ? lastLocationData)
|
||||||
<span class="hljs-keyword">if</span> (<span class="hljs-string">"2"</span> <span class="hljs-keyword">of</span> obj) <span class="hljs-keyword">and</span> (<span class="hljs-string">"first_line"</span> <span class="hljs-keyword">of</span> obj[<span class="hljs-number">2</span>]) <span class="hljs-keyword">then</span> locationData = obj[<span class="hljs-number">2</span>]
|
<span class="hljs-keyword">if</span> obj?.updateLocationDataIfMissing? <span class="hljs-keyword">and</span> firstLocationData?
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-string">"first_line"</span> <span class="hljs-keyword">of</span> obj <span class="hljs-keyword">then</span> locationData = obj
|
obj.updateLocationDataIfMissing locationData, forceUpdateLocation
|
||||||
|
<span class="hljs-keyword">else</span>
|
||||||
<span class="hljs-keyword">if</span> locationData
|
obj.locationData = locationData</pre></div></div>
|
||||||
<span class="hljs-string">"<span class="hljs-subst">#{locationData.first_line + <span class="hljs-number">1</span>}</span>:<span class="hljs-subst">#{locationData.first_column + <span class="hljs-number">1</span>}</span>-"</span> +
|
|
||||||
<span class="hljs-string">"<span class="hljs-subst">#{locationData.last_line + <span class="hljs-number">1</span>}</span>:<span class="hljs-subst">#{locationData.last_column + <span class="hljs-number">1</span>}</span>"</span>
|
|
||||||
<span class="hljs-keyword">else</span>
|
|
||||||
<span class="hljs-string">"No location data"</span></pre></div></div>
|
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -533,22 +525,25 @@ exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function
|
|||||||
<li id="section-22">
|
<li id="section-22">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-22">¶</a>
|
<a class="ss" href="#section-22">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>A <code>.coffee.md</code> compatible version of <code>basename</code>, that returns the file sans-extension.</p>
|
<p>Add comments, building the dictionary of token data if it hasn’t been
|
||||||
|
built yet.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.baseFileName = <span class="hljs-function"><span class="hljs-params">(file, stripExt = <span class="hljs-literal">no</span>, useWinPathSep = <span class="hljs-literal">no</span>)</span> -></span>
|
<div class="content"><div class='highlight'><pre> parserState.tokenData ?= buildTokenDataDictionary parserState.parser.tokens
|
||||||
pathSep = <span class="hljs-keyword">if</span> useWinPathSep <span class="hljs-keyword">then</span> <span class="hljs-regexp">/\\|\//</span> <span class="hljs-keyword">else</span> <span class="hljs-regexp">/\//</span>
|
<span class="hljs-keyword">if</span> obj.locationData?
|
||||||
parts = file.split(pathSep)
|
objHash = buildLocationHash obj.locationData
|
||||||
file = parts[parts.length - <span class="hljs-number">1</span>]
|
<span class="hljs-keyword">if</span> parserState.tokenData[objHash]?.comments?
|
||||||
<span class="hljs-keyword">return</span> file <span class="hljs-keyword">unless</span> stripExt <span class="hljs-keyword">and</span> file.indexOf(<span class="hljs-string">'.'</span>) >= <span class="hljs-number">0</span>
|
attachCommentsToNode parserState.tokenData[objHash].comments, obj
|
||||||
parts = file.split(<span class="hljs-string">'.'</span>)
|
obj
|
||||||
parts.pop()
|
|
||||||
parts.pop() <span class="hljs-keyword">if</span> parts[parts.length - <span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'coffee'</span> <span class="hljs-keyword">and</span> parts.length > <span class="hljs-number">1</span>
|
<span class="hljs-built_in">exports</span>.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function"><span class="hljs-params">(comments, node)</span> -></span>
|
||||||
parts.join(<span class="hljs-string">'.'</span>)</pre></div></div>
|
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> comments? <span class="hljs-keyword">or</span> comments.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
|
||||||
|
node.comments ?= []
|
||||||
|
node.comments.push comments...</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -556,14 +551,23 @@ exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function
|
|||||||
<li id="section-23">
|
<li id="section-23">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-23">¶</a>
|
<a class="ss" href="#section-23">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Determine if a filename represents a CoffeeScript file.</p>
|
<p>Convert jison location data to a string.
|
||||||
|
<code>obj</code> can be a token, or a locationData.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.isCoffee = <span class="hljs-function"><span class="hljs-params">(file)</span> -></span> <span class="hljs-regexp">/\.((lit)?coffee|coffee\.md)$/</span>.test file</pre></div></div>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.locationDataToString = <span class="hljs-function"><span class="hljs-params">(obj)</span> -></span>
|
||||||
|
<span class="hljs-keyword">if</span> (<span class="hljs-string">"2"</span> <span class="hljs-keyword">of</span> obj) <span class="hljs-keyword">and</span> (<span class="hljs-string">"first_line"</span> <span class="hljs-keyword">of</span> obj[<span class="hljs-number">2</span>]) <span class="hljs-keyword">then</span> locationData = obj[<span class="hljs-number">2</span>]
|
||||||
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-string">"first_line"</span> <span class="hljs-keyword">of</span> obj <span class="hljs-keyword">then</span> locationData = obj
|
||||||
|
|
||||||
|
<span class="hljs-keyword">if</span> locationData
|
||||||
|
<span class="hljs-string">"<span class="hljs-subst">#{locationData.first_line + <span class="hljs-number">1</span>}</span>:<span class="hljs-subst">#{locationData.first_column + <span class="hljs-number">1</span>}</span>-"</span> +
|
||||||
|
<span class="hljs-string">"<span class="hljs-subst">#{locationData.last_line + <span class="hljs-number">1</span>}</span>:<span class="hljs-subst">#{locationData.last_column + <span class="hljs-number">1</span>}</span>"</span>
|
||||||
|
<span class="hljs-keyword">else</span>
|
||||||
|
<span class="hljs-string">"No location data"</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -571,14 +575,18 @@ exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function
|
|||||||
<li id="section-24">
|
<li id="section-24">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-24">¶</a>
|
<a class="ss" href="#section-24">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Determine if a filename represents a Literate CoffeeScript file.</p>
|
<p>Generate a unique anonymous file name so we can distinguish source map cache
|
||||||
|
entries for any number of anonymous scripts.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.isLiterate = <span class="hljs-function"><span class="hljs-params">(file)</span> -></span> <span class="hljs-regexp">/\.(litcoffee|coffee\.md)$/</span>.test file</pre></div></div>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.anonymousFileName = <span class="hljs-keyword">do</span> ->
|
||||||
|
n = <span class="hljs-number">0</span>
|
||||||
|
->
|
||||||
|
<span class="hljs-string">"<anonymous-<span class="hljs-subst">#{n++}</span>>"</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -586,8 +594,61 @@ exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function
|
|||||||
<li id="section-25">
|
<li id="section-25">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-25">¶</a>
|
<a class="ss" href="#section-25">§</a>
|
||||||
|
</div>
|
||||||
|
<p>A <code>.coffee.md</code> compatible version of <code>basename</code>, that returns the file sans-extension.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.baseFileName = <span class="hljs-function"><span class="hljs-params">(file, stripExt = <span class="hljs-literal">no</span>, useWinPathSep = <span class="hljs-literal">no</span>)</span> -></span>
|
||||||
|
pathSep = <span class="hljs-keyword">if</span> useWinPathSep <span class="hljs-keyword">then</span> <span class="hljs-regexp">/\\|\//</span> <span class="hljs-keyword">else</span> <span class="hljs-regexp">/\//</span>
|
||||||
|
parts = file.split(pathSep)
|
||||||
|
file = parts[parts.length - <span class="hljs-number">1</span>]
|
||||||
|
<span class="hljs-keyword">return</span> file <span class="hljs-keyword">unless</span> stripExt <span class="hljs-keyword">and</span> file.indexOf(<span class="hljs-string">'.'</span>) >= <span class="hljs-number">0</span>
|
||||||
|
parts = file.split(<span class="hljs-string">'.'</span>)
|
||||||
|
parts.pop()
|
||||||
|
parts.pop() <span class="hljs-keyword">if</span> parts[parts.length - <span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'coffee'</span> <span class="hljs-keyword">and</span> parts.length > <span class="hljs-number">1</span>
|
||||||
|
parts.join(<span class="hljs-string">'.'</span>)</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-26">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-26">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Determine if a filename represents a CoffeeScript file.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.isCoffee = <span class="hljs-function"><span class="hljs-params">(file)</span> -></span> <span class="hljs-regexp">/\.((lit)?coffee|coffee\.md)$/</span>.test file</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-27">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-27">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Determine if a filename represents a Literate CoffeeScript file.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.isLiterate = <span class="hljs-function"><span class="hljs-params">(file)</span> -></span> <span class="hljs-regexp">/\.(litcoffee|coffee\.md)$/</span>.test file</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-28">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-28">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Throws a SyntaxError from a given location.
|
<p>Throws a SyntaxError from a given location.
|
||||||
The error’s <code>toString</code> will return an error message following the “standard”
|
The error’s <code>toString</code> will return an error message following the “standard”
|
||||||
@@ -596,19 +657,19 @@ marker showing where the error is.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.throwSyntaxError = <span class="hljs-function"><span class="hljs-params">(message, location)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.throwSyntaxError = <span class="hljs-function"><span class="hljs-params">(message, location)</span> -></span>
|
||||||
error = <span class="hljs-keyword">new</span> SyntaxError message
|
error = <span class="hljs-keyword">new</span> <span class="hljs-built_in">SyntaxError</span> message
|
||||||
error.location = location
|
error.location = location
|
||||||
error.toString = syntaxErrorToString</pre></div></div>
|
error.toString = syntaxErrorToString</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-26">
|
<li id="section-29">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-26">¶</a>
|
<a class="ss" href="#section-29">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Instead of showing the compiler’s stacktrace, show our custom error message
|
<p>Instead of showing the compiler’s stacktrace, show our custom error message
|
||||||
(this is useful when the error bubbles up in Node.js applications that
|
(this is useful when the error bubbles up in Node.js applications that
|
||||||
@@ -623,27 +684,27 @@ compile CoffeeScript for example).</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-27">
|
<li id="section-30">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-27">¶</a>
|
<a class="ss" href="#section-30">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Update a compiler SyntaxError with source code information if it didn’t have
|
<p>Update a compiler SyntaxError with source code information if it didn’t have
|
||||||
it already.</p>
|
it already.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.updateSyntaxError = <span class="hljs-function"><span class="hljs-params">(error, code, filename)</span> -></span></pre></div></div>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.updateSyntaxError = <span class="hljs-function"><span class="hljs-params">(error, code, filename)</span> -></span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-28">
|
<li id="section-31">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-28">¶</a>
|
<a class="ss" href="#section-31">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Avoid screwing up the <code>stack</code> property of other errors (i.e. possible bugs).</p>
|
<p>Avoid screwing up the <code>stack</code> property of other errors (i.e. possible bugs).</p>
|
||||||
|
|
||||||
@@ -662,34 +723,38 @@ it already.</p>
|
|||||||
last_line ?= first_line
|
last_line ?= first_line
|
||||||
last_column ?= first_column
|
last_column ?= first_column
|
||||||
|
|
||||||
filename = @filename <span class="hljs-keyword">or</span> <span class="hljs-string">'[stdin]'</span>
|
<span class="hljs-keyword">if</span> @filename?.startsWith <span class="hljs-string">'<anonymous'</span>
|
||||||
codeLine = @code.split(<span class="hljs-string">'\n'</span>)[first_line]
|
filename = <span class="hljs-string">'[stdin]'</span>
|
||||||
|
<span class="hljs-keyword">else</span>
|
||||||
|
filename = @filename <span class="hljs-keyword">or</span> <span class="hljs-string">'[stdin]'</span>
|
||||||
|
|
||||||
|
codeLine = @code.split(<span class="hljs-string">'\n'</span>)[first_line]
|
||||||
start = first_column</pre></div></div>
|
start = first_column</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-29">
|
<li id="section-32">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-29">¶</a>
|
<a class="ss" href="#section-32">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Show only the first line on multi-line errors.</p>
|
<p>Show only the first line on multi-line errors.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> end = <span class="hljs-keyword">if</span> first_line <span class="hljs-keyword">is</span> last_line <span class="hljs-keyword">then</span> last_column + <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> codeLine.length
|
<div class="content"><div class='highlight'><pre> end = <span class="hljs-keyword">if</span> first_line <span class="hljs-keyword">is</span> last_line <span class="hljs-keyword">then</span> last_column + <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> codeLine.length
|
||||||
marker = codeLine[...start].replace(<span class="hljs-regexp">/[^\s]/g</span>, <span class="hljs-string">' '</span>) + repeat(<span class="hljs-string">'^'</span>, end - start)</pre></div></div>
|
marker = codeLine[...start].replace(<span class="hljs-regexp">/[^\s]/g</span>, <span class="hljs-string">' '</span>) + repeat(<span class="hljs-string">'^'</span>, end - start)</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-30">
|
<li id="section-33">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-30">¶</a>
|
<a class="ss" href="#section-33">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Check to see if we’re running on a color-enabled TTY.</p>
|
<p>Check to see if we’re running on a color-enabled TTY.</p>
|
||||||
|
|
||||||
@@ -699,23 +764,99 @@ it already.</p>
|
|||||||
colorsEnabled = process.stdout?.isTTY <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> process.env?.NODE_DISABLE_COLORS
|
colorsEnabled = process.stdout?.isTTY <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> process.env?.NODE_DISABLE_COLORS
|
||||||
|
|
||||||
<span class="hljs-keyword">if</span> @colorful ? colorsEnabled
|
<span class="hljs-keyword">if</span> @colorful ? colorsEnabled
|
||||||
<span class="hljs-function"> <span class="hljs-title">colorize</span> = <span class="hljs-params">(str)</span> -></span> <span class="hljs-string">"\x1B[1;31m<span class="hljs-subst">#{str}</span>\x1B[0m"</span>
|
<span class="hljs-function"> <span class="hljs-title">colorize</span> = <span class="hljs-params">(str)</span> -></span> <span class="hljs-string">"\x1B[1;31m<span class="hljs-subst">#{str}</span>\x1B[0m"</span>
|
||||||
codeLine = codeLine[...start] + colorize(codeLine[start...end]) + codeLine[end..]
|
codeLine = codeLine[...start] + colorize(codeLine[start...end]) + codeLine[end..]
|
||||||
marker = colorize marker
|
marker = colorize marker
|
||||||
|
|
||||||
<span class="hljs-string">"""
|
<span class="hljs-string">"""
|
||||||
<span class="hljs-subst">#{filename}</span>:<span class="hljs-subst">#{first_line + <span class="hljs-number">1</span>}</span>:<span class="hljs-subst">#{first_column + <span class="hljs-number">1</span>}</span>: error: <span class="hljs-subst">#{@message}</span>
|
<span class="hljs-subst">#{filename}</span>:<span class="hljs-subst">#{first_line + <span class="hljs-number">1</span>}</span>:<span class="hljs-subst">#{first_column + <span class="hljs-number">1</span>}</span>: error: <span class="hljs-subst">#{@message}</span>
|
||||||
<span class="hljs-subst">#{codeLine}</span>
|
<span class="hljs-subst">#{codeLine}</span>
|
||||||
<span class="hljs-subst">#{marker}</span>
|
<span class="hljs-subst">#{marker}</span>
|
||||||
"""</span>
|
"""</span>
|
||||||
|
|
||||||
exports.nameWhitespaceCharacter = <span class="hljs-function"><span class="hljs-params">(string)</span> -></span>
|
<span class="hljs-built_in">exports</span>.nameWhitespaceCharacter = <span class="hljs-function"><span class="hljs-params">(string)</span> -></span>
|
||||||
<span class="hljs-keyword">switch</span> string
|
<span class="hljs-keyword">switch</span> string
|
||||||
<span class="hljs-keyword">when</span> <span class="hljs-string">' '</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'space'</span>
|
<span class="hljs-keyword">when</span> <span class="hljs-string">' '</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'space'</span>
|
||||||
<span class="hljs-keyword">when</span> <span class="hljs-string">'\n'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'newline'</span>
|
<span class="hljs-keyword">when</span> <span class="hljs-string">'\n'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'newline'</span>
|
||||||
<span class="hljs-keyword">when</span> <span class="hljs-string">'\r'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'carriage return'</span>
|
<span class="hljs-keyword">when</span> <span class="hljs-string">'\r'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'carriage return'</span>
|
||||||
<span class="hljs-keyword">when</span> <span class="hljs-string">'\t'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'tab'</span>
|
<span class="hljs-keyword">when</span> <span class="hljs-string">'\t'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'tab'</span>
|
||||||
<span class="hljs-keyword">else</span> string</pre></div></div>
|
<span class="hljs-keyword">else</span> string
|
||||||
|
|
||||||
|
<span class="hljs-built_in">exports</span>.parseNumber = <span class="hljs-function"><span class="hljs-params">(string)</span> -></span>
|
||||||
|
<span class="hljs-keyword">return</span> <span class="hljs-literal">NaN</span> <span class="hljs-keyword">unless</span> string?
|
||||||
|
|
||||||
|
base = <span class="hljs-keyword">switch</span> string.charAt <span class="hljs-number">1</span>
|
||||||
|
<span class="hljs-keyword">when</span> <span class="hljs-string">'b'</span> <span class="hljs-keyword">then</span> <span class="hljs-number">2</span>
|
||||||
|
<span class="hljs-keyword">when</span> <span class="hljs-string">'o'</span> <span class="hljs-keyword">then</span> <span class="hljs-number">8</span>
|
||||||
|
<span class="hljs-keyword">when</span> <span class="hljs-string">'x'</span> <span class="hljs-keyword">then</span> <span class="hljs-number">16</span>
|
||||||
|
<span class="hljs-keyword">else</span> <span class="hljs-literal">null</span>
|
||||||
|
|
||||||
|
<span class="hljs-keyword">if</span> base?
|
||||||
|
<span class="hljs-built_in">parseInt</span> string[<span class="hljs-number">2.</span>.].replace(<span class="hljs-regexp">/_/g</span>, <span class="hljs-string">''</span>), base
|
||||||
|
<span class="hljs-keyword">else</span>
|
||||||
|
<span class="hljs-built_in">parseFloat</span> string.replace(<span class="hljs-regexp">/_/g</span>, <span class="hljs-string">''</span>)
|
||||||
|
|
||||||
|
<span class="hljs-built_in">exports</span>.isFunction = <span class="hljs-function"><span class="hljs-params">(obj)</span> -></span> Object::toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object Function]'</span>
|
||||||
|
<span class="hljs-built_in">exports</span>.isNumber = isNumber = <span class="hljs-function"><span class="hljs-params">(obj)</span> -></span> Object::toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object Number]'</span>
|
||||||
|
<span class="hljs-built_in">exports</span>.isString = isString = <span class="hljs-function"><span class="hljs-params">(obj)</span> -></span> Object::toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object String]'</span>
|
||||||
|
<span class="hljs-built_in">exports</span>.isBoolean = isBoolean = <span class="hljs-function"><span class="hljs-params">(obj)</span> -></span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">or</span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">or</span> Object::toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object Boolean]'</span>
|
||||||
|
<span class="hljs-built_in">exports</span>.isPlainObject = <span class="hljs-function"><span class="hljs-params">(obj)</span> -></span> <span class="hljs-keyword">typeof</span> obj <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span> <span class="hljs-keyword">and</span> !!obj <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> <span class="hljs-built_in">Array</span>.isArray(obj) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> isNumber(obj) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> isString(obj) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> isBoolean(obj)
|
||||||
|
<span class="hljs-function">
|
||||||
|
<span class="hljs-title">unicodeCodePointToUnicodeEscapes</span> = <span class="hljs-params">(codePoint)</span> -></span>
|
||||||
|
<span class="hljs-function"> <span class="hljs-title">toUnicodeEscape</span> = <span class="hljs-params">(val)</span> -></span>
|
||||||
|
str = val.toString <span class="hljs-number">16</span>
|
||||||
|
<span class="hljs-string">"\\u<span class="hljs-subst">#{repeat <span class="hljs-string">'0'</span>, <span class="hljs-number">4</span> - str.length}</span><span class="hljs-subst">#{str}</span>"</span>
|
||||||
|
<span class="hljs-keyword">return</span> toUnicodeEscape(codePoint) <span class="hljs-keyword">if</span> codePoint < <span class="hljs-number">0x10000</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-34">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-34">§</a>
|
||||||
|
</div>
|
||||||
|
<p>surrogate pair</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> high = <span class="hljs-built_in">Math</span>.floor((codePoint - <span class="hljs-number">0x10000</span>) / <span class="hljs-number">0x400</span>) + <span class="hljs-number">0xD800</span>
|
||||||
|
low = (codePoint - <span class="hljs-number">0x10000</span>) % <span class="hljs-number">0x400</span> + <span class="hljs-number">0xDC00</span>
|
||||||
|
<span class="hljs-string">"<span class="hljs-subst">#{toUnicodeEscape(high)}</span><span class="hljs-subst">#{toUnicodeEscape(low)}</span>"</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-35">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-35">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Replace <code>\u{...}</code> with <code>\uxxxx[\uxxxx]</code> in regexes without <code>u</code> flag</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.replaceUnicodeCodePointEscapes = <span class="hljs-function"><span class="hljs-params">(str, {flags, error, delimiter = <span class="hljs-string">''</span>} = {})</span> -></span>
|
||||||
|
shouldReplace = flags? <span class="hljs-keyword">and</span> <span class="hljs-string">'u'</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> flags
|
||||||
|
str.replace UNICODE_CODE_POINT_ESCAPE, <span class="hljs-function"><span class="hljs-params">(match, escapedBackslash, codePointHex, offset)</span> -></span>
|
||||||
|
<span class="hljs-keyword">return</span> escapedBackslash <span class="hljs-keyword">if</span> escapedBackslash
|
||||||
|
|
||||||
|
codePointDecimal = <span class="hljs-built_in">parseInt</span> codePointHex, <span class="hljs-number">16</span>
|
||||||
|
<span class="hljs-keyword">if</span> codePointDecimal > <span class="hljs-number">0x10ffff</span>
|
||||||
|
error <span class="hljs-string">"unicode code point escapes greater than \\u{10ffff} are not allowed"</span>,
|
||||||
|
offset: offset + delimiter.length
|
||||||
|
length: codePointHex.length + <span class="hljs-number">4</span>
|
||||||
|
<span class="hljs-keyword">return</span> match <span class="hljs-keyword">unless</span> shouldReplace
|
||||||
|
|
||||||
|
unicodeCodePointToUnicodeEscapes codePointDecimal
|
||||||
|
|
||||||
|
UNICODE_CODE_POINT_ESCAPE = <span class="hljs-regexp">///
|
||||||
|
( \\\\ ) <span class="hljs-comment"># Make sure the escape isn’t escaped.</span>
|
||||||
|
|
|
||||||
|
\\u\{ ( [\da-fA-F]+ ) \}
|
||||||
|
///</span>g</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
@@ -112,26 +112,26 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Node.js Implementation</p>
|
<p>Node.js Implementation</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffeescript'</span>
|
<div class="content"><div class='highlight'><pre>CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffeescript'</span>
|
||||||
fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
||||||
vm = <span class="hljs-built_in">require</span> <span class="hljs-string">'vm'</span>
|
vm = <span class="hljs-built_in">require</span> <span class="hljs-string">'vm'</span>
|
||||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
||||||
|
|
||||||
helpers = CoffeeScript.helpers
|
helpers = CoffeeScript.helpers
|
||||||
|
|
||||||
CoffeeScript.transpile = <span class="hljs-function"><span class="hljs-params">(js, options)</span> -></span>
|
CoffeeScript.transpile = <span class="hljs-function"><span class="hljs-params">(js, options)</span> -></span>
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
babel = <span class="hljs-built_in">require</span> <span class="hljs-string">'@babel/core'</span>
|
babel = <span class="hljs-built_in">require</span> <span class="hljs-string">'@babel/core'</span>
|
||||||
<span class="hljs-keyword">catch</span>
|
<span class="hljs-keyword">catch</span>
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
babel = <span class="hljs-built_in">require</span> <span class="hljs-string">'babel-core'</span>
|
babel = <span class="hljs-built_in">require</span> <span class="hljs-string">'babel-core'</span>
|
||||||
<span class="hljs-keyword">catch</span></pre></div></div>
|
<span class="hljs-keyword">catch</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -140,15 +140,15 @@ CoffeeScript.transpile = <span class="hljs-function"><span class="hljs-params">(
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>This error is only for Node, as CLI users will see a different error
|
<p>This error is only for Node, as CLI users will see a different error
|
||||||
earlier if they don’t have Babel installed.</p>
|
earlier if they don’t have Babel installed.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">'To use the transpile option, you must have the \'@babel/core\' module installed'</span>
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">'To use the transpile option, you must have the \'@babel/core\' module installed'</span>
|
||||||
babel.transform js, options</pre></div></div>
|
babel.transform js, options</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -157,8 +157,8 @@ earlier if they don’t have Babel installed.</p>
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The <code>compile</code> method shared by the CLI, Node and browser APIs.</p>
|
<p>The <code>compile</code> method shared by the CLI, Node and browser APIs.</p>
|
||||||
|
|
||||||
@@ -172,8 +172,8 @@ earlier if they don’t have Babel installed.</p>
|
|||||||
<li id="section-4">
|
<li id="section-4">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-4">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The <code>compile</code> method particular to the Node API.</p>
|
<p>The <code>compile</code> method particular to the Node API.</p>
|
||||||
|
|
||||||
@@ -187,8 +187,8 @@ earlier if they don’t have Babel installed.</p>
|
|||||||
<li id="section-5">
|
<li id="section-5">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Pass a reference to Babel into the compiler, so that the transpile option
|
<p>Pass a reference to Babel into the compiler, so that the transpile option
|
||||||
is available in the Node API. We need to do this so that tools like Webpack
|
is available in the Node API. We need to do this so that tools like Webpack
|
||||||
@@ -207,8 +207,8 @@ require Babel.</p>
|
|||||||
<li id="section-6">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Compile and execute a string of CoffeeScript (on the server), correctly
|
<p>Compile and execute a string of CoffeeScript (on the server), correctly
|
||||||
setting <code>__filename</code>, <code>__dirname</code>, and relative <code>require()</code>.</p>
|
setting <code>__filename</code>, <code>__dirname</code>, and relative <code>require()</code>.</p>
|
||||||
@@ -224,15 +224,15 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Set the filename.</p>
|
<p>Set the filename.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> mainModule.filename = process.argv[<span class="hljs-number">1</span>] =
|
<div class="content"><div class='highlight'><pre> mainModule.filename = process.argv[<span class="hljs-number">1</span>] =
|
||||||
<span class="hljs-keyword">if</span> options.filename <span class="hljs-keyword">then</span> fs.realpathSync(options.filename) <span class="hljs-keyword">else</span> <span class="hljs-string">'<anonymous>'</span></pre></div></div>
|
<span class="hljs-keyword">if</span> options.filename <span class="hljs-keyword">then</span> fs.realpathSync(options.filename) <span class="hljs-keyword">else</span> helpers.anonymousFileName()</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -240,8 +240,8 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||||||
<li id="section-8">
|
<li id="section-8">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-8">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Clear the module cache.</p>
|
<p>Clear the module cache.</p>
|
||||||
|
|
||||||
@@ -255,8 +255,8 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||||||
<li id="section-9">
|
<li id="section-9">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="ss" href="#section-9">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Assign paths for node_modules loading</p>
|
<p>Assign paths for node_modules loading</p>
|
||||||
|
|
||||||
@@ -265,8 +265,8 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||||||
<div class="content"><div class='highlight'><pre> dir = <span class="hljs-keyword">if</span> options.filename?
|
<div class="content"><div class='highlight'><pre> dir = <span class="hljs-keyword">if</span> options.filename?
|
||||||
path.dirname fs.realpathSync options.filename
|
path.dirname fs.realpathSync options.filename
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
fs.realpathSync <span class="hljs-string">'.'</span>
|
fs.realpathSync <span class="hljs-string">'.'</span>
|
||||||
mainModule.paths = <span class="hljs-built_in">require</span>(<span class="hljs-string">'module'</span>)._nodeModulePaths dir</pre></div></div>
|
mainModule.paths = <span class="hljs-built_in">require</span>(<span class="hljs-string">'module'</span>)._nodeModulePaths dir</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -274,14 +274,17 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||||||
<li id="section-10">
|
<li id="section-10">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Save the options for compiling child imports.</p>
|
<p>Save the options for compiling child imports.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> mainModule.options = options</pre></div></div>
|
<div class="content"><div class='highlight'><pre> mainModule.options = options
|
||||||
|
|
||||||
|
options.filename = mainModule.filename
|
||||||
|
options.inlineMap = <span class="hljs-literal">true</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -289,16 +292,15 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||||||
<li id="section-11">
|
<li id="section-11">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="ss" href="#section-11">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Compile.</p>
|
<p>Compile.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> helpers.isCoffee(mainModule.filename) <span class="hljs-keyword">or</span> <span class="hljs-built_in">require</span>.extensions
|
<div class="content"><div class='highlight'><pre> answer = CoffeeScript.compile code, options
|
||||||
answer = CoffeeScript.compile code, options
|
code = answer.js ? answer
|
||||||
code = answer.js ? answer
|
|
||||||
|
|
||||||
mainModule._compile code, mainModule.filename</pre></div></div>
|
mainModule._compile code, mainModule.filename</pre></div></div>
|
||||||
|
|
||||||
@@ -308,15 +310,15 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
|||||||
<li id="section-12">
|
<li id="section-12">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="ss" href="#section-12">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
|
<p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
|
||||||
The CoffeeScript REPL uses this to run the input.</p>
|
The CoffeeScript REPL uses this to run the input.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>CoffeeScript.eval = <span class="hljs-function"><span class="hljs-params">(code, options = {})</span> -></span>
|
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="hljs-built_in">eval</span> = <span class="hljs-function"><span class="hljs-params">(code, options = {})</span> -></span>
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> code = code.trim()
|
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> code = code.trim()
|
||||||
createContext = vm.Script.createContext ? vm.createContext
|
createContext = vm.Script.createContext ? vm.createContext
|
||||||
|
|
||||||
@@ -330,10 +332,10 @@ The CoffeeScript REPL uses this to run the input.</p>
|
|||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
sandbox = createContext()
|
sandbox = createContext()
|
||||||
sandbox[k] = v <span class="hljs-keyword">for</span> own k, v <span class="hljs-keyword">of</span> options.sandbox
|
sandbox[k] = v <span class="hljs-keyword">for</span> own k, v <span class="hljs-keyword">of</span> options.sandbox
|
||||||
sandbox.<span class="hljs-built_in">global</span> = sandbox.root = sandbox.GLOBAL = sandbox
|
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
sandbox = <span class="hljs-built_in">global</span>
|
sandbox = global
|
||||||
sandbox.__filename = options.filename || <span class="hljs-string">'eval'</span>
|
sandbox.__filename = options.filename || <span class="hljs-string">'eval'</span>
|
||||||
sandbox.__dirname = path.dirname sandbox.__filename</pre></div></div>
|
sandbox.__dirname = path.dirname sandbox.__filename</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -342,19 +344,19 @@ The CoffeeScript REPL uses this to run the input.</p>
|
|||||||
<li id="section-13">
|
<li id="section-13">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-13">¶</a>
|
<a class="ss" href="#section-13">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>define module/require only if they chose not to specify their own</p>
|
<p>define module/require only if they chose not to specify their own</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> sandbox <span class="hljs-keyword">isnt</span> <span class="hljs-built_in">global</span> <span class="hljs-keyword">or</span> sandbox.<span class="hljs-built_in">module</span> <span class="hljs-keyword">or</span> sandbox.<span class="hljs-built_in">require</span>
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> sandbox <span class="hljs-keyword">isnt</span> global <span class="hljs-keyword">or</span> sandbox.module <span class="hljs-keyword">or</span> sandbox.<span class="hljs-built_in">require</span>
|
||||||
Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
|
Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
|
||||||
sandbox.<span class="hljs-built_in">module</span> = _module = <span class="hljs-keyword">new</span> Module(options.modulename || <span class="hljs-string">'eval'</span>)
|
sandbox.module = _module = <span class="hljs-keyword">new</span> Module(options.modulename || <span class="hljs-string">'eval'</span>)
|
||||||
sandbox.<span class="hljs-built_in">require</span> = _require = <span class="hljs-function"><span class="hljs-params">(path)</span> -></span> Module._load path, _module, <span class="hljs-literal">true</span>
|
sandbox.<span class="hljs-built_in">require</span> = _require = <span class="hljs-function"><span class="hljs-params">(path)</span> -></span> Module._load path, _module, <span class="hljs-literal">true</span>
|
||||||
_module.filename = sandbox.__filename
|
_module.filename = sandbox.__filename
|
||||||
<span class="hljs-keyword">for</span> r <span class="hljs-keyword">in</span> Object.getOwnPropertyNames <span class="hljs-built_in">require</span> <span class="hljs-keyword">when</span> r <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'paths'</span>, <span class="hljs-string">'arguments'</span>, <span class="hljs-string">'caller'</span>]
|
<span class="hljs-keyword">for</span> r <span class="hljs-keyword">in</span> <span class="hljs-built_in">Object</span>.getOwnPropertyNames <span class="hljs-built_in">require</span> <span class="hljs-keyword">when</span> r <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'paths'</span>, <span class="hljs-string">'arguments'</span>, <span class="hljs-string">'caller'</span>]
|
||||||
_require[r] = <span class="hljs-built_in">require</span>[r]</pre></div></div>
|
_require[r] = <span class="hljs-built_in">require</span>[r]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -363,8 +365,8 @@ The CoffeeScript REPL uses this to run the input.</p>
|
|||||||
<li id="section-14">
|
<li id="section-14">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-14">¶</a>
|
<a class="ss" href="#section-14">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>use the same hack node currently uses for their own REPL</p>
|
<p>use the same hack node currently uses for their own REPL</p>
|
||||||
|
|
||||||
@@ -376,12 +378,12 @@ The CoffeeScript REPL uses this to run the input.</p>
|
|||||||
o[k] = v <span class="hljs-keyword">for</span> own k, v <span class="hljs-keyword">of</span> options
|
o[k] = v <span class="hljs-keyword">for</span> own k, v <span class="hljs-keyword">of</span> options
|
||||||
o.bare = <span class="hljs-literal">on</span> <span class="hljs-comment"># ensure return value</span>
|
o.bare = <span class="hljs-literal">on</span> <span class="hljs-comment"># ensure return value</span>
|
||||||
js = CoffeeScript.compile code, o
|
js = CoffeeScript.compile code, o
|
||||||
<span class="hljs-keyword">if</span> sandbox <span class="hljs-keyword">is</span> <span class="hljs-built_in">global</span>
|
<span class="hljs-keyword">if</span> sandbox <span class="hljs-keyword">is</span> global
|
||||||
vm.runInThisContext js
|
vm.runInThisContext js
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
vm.runInContext js, sandbox
|
vm.runInContext js, sandbox
|
||||||
|
|
||||||
CoffeeScript.register = <span class="hljs-function">-></span> <span class="hljs-built_in">require</span> <span class="hljs-string">'./register'</span></pre></div></div>
|
CoffeeScript.register = <span class="hljs-function">-></span> <span class="hljs-built_in">require</span> <span class="hljs-string">'./register'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -389,8 +391,8 @@ CoffeeScript.register = <span class="hljs-function">-></span> <span class="hl
|
|||||||
<li id="section-15">
|
<li id="section-15">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-15">¶</a>
|
<a class="ss" href="#section-15">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Throw error with deprecation warning when depending upon implicit <code>require.extensions</code> registration</p>
|
<p>Throw error with deprecation warning when depending upon implicit <code>require.extensions</code> registration</p>
|
||||||
|
|
||||||
@@ -399,12 +401,11 @@ CoffeeScript.register = <span class="hljs-function">-></span> <span class="hl
|
|||||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> <span class="hljs-built_in">require</span>.extensions
|
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> <span class="hljs-built_in">require</span>.extensions
|
||||||
<span class="hljs-keyword">for</span> ext <span class="hljs-keyword">in</span> CoffeeScript.FILE_EXTENSIONS <span class="hljs-keyword">then</span> <span class="hljs-keyword">do</span> (ext) ->
|
<span class="hljs-keyword">for</span> ext <span class="hljs-keyword">in</span> CoffeeScript.FILE_EXTENSIONS <span class="hljs-keyword">then</span> <span class="hljs-keyword">do</span> (ext) ->
|
||||||
<span class="hljs-built_in">require</span>.extensions[ext] ?= <span class="hljs-function">-></span>
|
<span class="hljs-built_in">require</span>.extensions[ext] ?= <span class="hljs-function">-></span>
|
||||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"""
|
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">"""
|
||||||
Use CoffeeScript.register() or require the coffeescript/register module to require <span class="hljs-subst">#{ext}</span> files.
|
Use CoffeeScript.register() or require the coffeescript/register module to require <span class="hljs-subst">#{ext}</span> files.
|
||||||
"""</span>
|
"""</span>
|
||||||
|
|
||||||
CoffeeScript._compileFile = <span class="hljs-function"><span class="hljs-params">(filename, options = {})</span> -></span>
|
CoffeeScript._compileRawFileContent = <span class="hljs-function"><span class="hljs-params">(raw, filename, options = {})</span> -></span></pre></div></div>
|
||||||
raw = fs.readFileSync filename, <span class="hljs-string">'utf8'</span></pre></div></div>
|
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -412,8 +413,8 @@ CoffeeScript._compileFile = <span class="hljs-function"><span class="hljs-params
|
|||||||
<li id="section-16">
|
<li id="section-16">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-16">¶</a>
|
<a class="ss" href="#section-16">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Strip the Unicode byte order mark, if this file begins with one.</p>
|
<p>Strip the Unicode byte order mark, if this file begins with one.</p>
|
||||||
|
|
||||||
@@ -421,11 +422,10 @@ CoffeeScript._compileFile = <span class="hljs-function"><span class="hljs-params
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> stripped = <span class="hljs-keyword">if</span> raw.charCodeAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-number">0xFEFF</span> <span class="hljs-keyword">then</span> raw.substring <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> raw
|
<div class="content"><div class='highlight'><pre> stripped = <span class="hljs-keyword">if</span> raw.charCodeAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-number">0xFEFF</span> <span class="hljs-keyword">then</span> raw.substring <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> raw
|
||||||
|
|
||||||
options = Object.assign {}, options,
|
options = <span class="hljs-built_in">Object</span>.assign {}, options,
|
||||||
filename: filename
|
filename: filename
|
||||||
literate: helpers.isLiterate filename
|
literate: helpers.isLiterate filename
|
||||||
sourceFiles: [filename]
|
sourceFiles: [filename]
|
||||||
inlineMap: <span class="hljs-literal">yes</span> <span class="hljs-comment"># Always generate a source map, so that stack traces line up.</span>
|
|
||||||
|
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
answer = CoffeeScript.compile stripped, options
|
answer = CoffeeScript.compile stripped, options
|
||||||
@@ -437,8 +437,8 @@ CoffeeScript._compileFile = <span class="hljs-function"><span class="hljs-params
|
|||||||
<li id="section-17">
|
<li id="section-17">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-17">¶</a>
|
<a class="ss" href="#section-17">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>As the filename and code of a dynamically loaded file will be different
|
<p>As the filename and code of a dynamically loaded file will be different
|
||||||
from the original file compiled with CoffeeScript.run, add that
|
from the original file compiled with CoffeeScript.run, add that
|
||||||
@@ -450,7 +450,44 @@ information to error so it can be pretty-printed later.</p>
|
|||||||
|
|
||||||
answer
|
answer
|
||||||
|
|
||||||
<span class="hljs-built_in">module</span>.exports = CoffeeScript</pre></div></div>
|
CoffeeScript._compileFile = <span class="hljs-function"><span class="hljs-params">(filename, options = {})</span> -></span>
|
||||||
|
raw = fs.readFileSync filename, <span class="hljs-string">'utf8'</span>
|
||||||
|
|
||||||
|
CoffeeScript._compileRawFileContent raw, filename, options
|
||||||
|
|
||||||
|
module.<span class="hljs-built_in">exports</span> = CoffeeScript</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-18">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-18">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Explicitly define all named exports so that Node’s automatic detection of
|
||||||
|
named exports from CommonJS packages finds all of them. This enables consuming
|
||||||
|
packages to write code like <code>import { compile } from 'coffeescript'</code>.
|
||||||
|
Don’t simplify this into a loop or similar; the <code>module.exports.name</code> part is
|
||||||
|
essential for Node’s algorithm to successfully detect the name.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre>module.<span class="hljs-built_in">exports</span>.VERSION = CoffeeScript.VERSION
|
||||||
|
module.<span class="hljs-built_in">exports</span>.FILE_EXTENSIONS = CoffeeScript.FILE_EXTENSIONS
|
||||||
|
module.<span class="hljs-built_in">exports</span>.helpers = CoffeeScript.helpers
|
||||||
|
module.<span class="hljs-built_in">exports</span>.registerCompiled = CoffeeScript.registerCompiled
|
||||||
|
module.<span class="hljs-built_in">exports</span>.compile = CoffeeScript.compile
|
||||||
|
module.<span class="hljs-built_in">exports</span>.tokens = CoffeeScript.tokens
|
||||||
|
module.<span class="hljs-built_in">exports</span>.nodes = CoffeeScript.nodes
|
||||||
|
module.<span class="hljs-built_in">exports</span>.register = CoffeeScript.register
|
||||||
|
module.<span class="hljs-built_in">exports</span>.<span class="hljs-built_in">eval</span> = CoffeeScript.<span class="hljs-built_in">eval</span>
|
||||||
|
module.<span class="hljs-built_in">exports</span>.run = CoffeeScript.run
|
||||||
|
module.<span class="hljs-built_in">exports</span>.transpile = CoffeeScript.transpile
|
||||||
|
module.<span class="hljs-built_in">exports</span>.patchStackTrace = CoffeeScript.patchStackTrace
|
||||||
|
module.<span class="hljs-built_in">exports</span>._compileRawFileContent = CoffeeScript._compileRawFileContent
|
||||||
|
module.<span class="hljs-built_in">exports</span>._compileFile = CoffeeScript._compileFile</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -112,13 +112,13 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>{repeat} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span></pre></div></div>
|
<div class="content"><div class='highlight'><pre>{repeat} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -126,21 +126,22 @@
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
|
<p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
|
||||||
Use it like so:</p>
|
Use it like so:</p>
|
||||||
<pre><code>parser = <span class="hljs-keyword">new</span> OptionParser switches, helpBanner
|
<pre><code>parser = <span class="hljs-keyword">new</span> OptionParser switches, helpBanner
|
||||||
options = parser.parse process.argv
|
options = parser.parse process.argv
|
||||||
</code></pre><p>The first non-option is considered to be the start of the file (and file
|
</code></pre>
|
||||||
|
<p>The first non-option is considered to be the start of the file (and file
|
||||||
option) list, and all subsequent arguments are left unparsed.</p>
|
option) list, and all subsequent arguments are left unparsed.</p>
|
||||||
<p>The <code>coffee</code> command uses an instance of <strong>OptionParser</strong> to parse its
|
<p>The <code>coffee</code> command uses an instance of <strong>OptionParser</strong> to parse its
|
||||||
command-line arguments in <code>src/command.coffee</code>.</p>
|
command-line arguments in <code>src/command.coffee</code>.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.OptionParser = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OptionParser</span></span></pre></div></div>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.OptionParser = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OptionParser</span></span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -148,12 +149,13 @@ command-line arguments in <code>src/command.coffee</code>.</p>
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Initialize with a list of valid options, in the form:</p>
|
<p>Initialize with a list of valid options, in the form:</p>
|
||||||
<pre><code>[short-flag, long-flag, description]
|
<pre><code>[short-flag, long-flag, description]
|
||||||
</code></pre><p>Along with an optional banner for the usage help.</p>
|
</code></pre>
|
||||||
|
<p>Along with an optional banner for the usage help.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -166,8 +168,8 @@ command-line arguments in <code>src/command.coffee</code>.</p>
|
|||||||
<li id="section-4">
|
<li id="section-4">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-4">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Parse the list of arguments, populating an <code>options</code> object with all of the
|
<p>Parse the list of arguments, populating an <code>options</code> object with all of the
|
||||||
specified options, and return it. Options after the first non-option
|
specified options, and return it. Options after the first non-option
|
||||||
@@ -186,8 +188,8 @@ you’re responsible for interpreting the options object.</p>
|
|||||||
<li id="section-5">
|
<li id="section-5">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The CoffeeScript option parser is a little odd; options after the first
|
<p>The CoffeeScript option parser is a little odd; options after the first
|
||||||
non-option argument are treated as non-option arguments themselves.
|
non-option argument are treated as non-option arguments themselves.
|
||||||
@@ -208,8 +210,8 @@ line <code>#!/usr/bin/env coffee</code>, or <code>#!/absolute/path/to/coffee</co
|
|||||||
<li id="section-6">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The <code>argument</code> field is added to the rule instance non-destructively by
|
<p>The <code>argument</code> field is added to the rule instance non-destructively by
|
||||||
<code>normalizeArguments</code>.</p>
|
<code>normalizeArguments</code>.</p>
|
||||||
@@ -226,7 +228,7 @@ line <code>#!/usr/bin/env coffee</code>, or <code>#!/absolute/path/to/coffee</co
|
|||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
options[name] = <span class="hljs-literal">true</span>
|
options[name] = <span class="hljs-literal">true</span>
|
||||||
|
|
||||||
<span class="hljs-keyword">if</span> positional[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'--'</span>
|
<span class="hljs-keyword">if</span> positional[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'--'</span>
|
||||||
options.doubleDashed = <span class="hljs-literal">yes</span>
|
options.doubleDashed = <span class="hljs-literal">yes</span>
|
||||||
positional = positional[<span class="hljs-number">1.</span>.]
|
positional = positional[<span class="hljs-number">1.</span>.]
|
||||||
|
|
||||||
@@ -239,8 +241,8 @@ line <code>#!/usr/bin/env coffee</code>, or <code>#!/absolute/path/to/coffee</co
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
|
<p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
|
||||||
of the valid options, for <code>--help</code> and such.</p>
|
of the valid options, for <code>--help</code> and such.</p>
|
||||||
@@ -249,13 +251,13 @@ of the valid options, for <code>--help</code> and such.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> help: <span class="hljs-function">-></span>
|
<div class="content"><div class='highlight'><pre> help: <span class="hljs-function">-></span>
|
||||||
lines = []
|
lines = []
|
||||||
lines.unshift <span class="hljs-string">"<span class="hljs-subst">#{@banner}</span>\n"</span> <span class="hljs-keyword">if</span> @banner
|
lines.unshift <span class="hljs-string">"<span class="hljs-subst">#{@banner}</span>\n"</span> <span class="hljs-keyword">if</span> @banner
|
||||||
<span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> @rules.ruleList
|
<span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> @rules.ruleList
|
||||||
spaces = <span class="hljs-number">15</span> - rule.longFlag.length
|
spaces = <span class="hljs-number">15</span> - rule.longFlag.length
|
||||||
spaces = <span class="hljs-keyword">if</span> spaces > <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> repeat <span class="hljs-string">' '</span>, spaces <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
spaces = <span class="hljs-keyword">if</span> spaces > <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> repeat <span class="hljs-string">' '</span>, spaces <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
||||||
letPart = <span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">then</span> rule.shortFlag + <span class="hljs-string">', '</span> <span class="hljs-keyword">else</span> <span class="hljs-string">' '</span>
|
letPart = <span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">then</span> rule.shortFlag + <span class="hljs-string">', '</span> <span class="hljs-keyword">else</span> <span class="hljs-string">' '</span>
|
||||||
lines.push <span class="hljs-string">' '</span> + letPart + rule.longFlag + spaces + rule.description
|
lines.push <span class="hljs-string">' '</span> + letPart + rule.longFlag + spaces + rule.description
|
||||||
<span class="hljs-string">"\n<span class="hljs-subst">#{ lines.join(<span class="hljs-string">'\n'</span>) }</span>\n"</span></pre></div></div>
|
<span class="hljs-string">"\n<span class="hljs-subst">#{ lines.join(<span class="hljs-string">'\n'</span>) }</span>\n"</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -263,8 +265,8 @@ of the valid options, for <code>--help</code> and such.</p>
|
|||||||
<li id="section-8">
|
<li id="section-8">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-8">§</a>
|
||||||
</div>
|
</div>
|
||||||
<h2 id="helpers">Helpers</h2>
|
<h2 id="helpers">Helpers</h2>
|
||||||
|
|
||||||
@@ -276,8 +278,8 @@ of the valid options, for <code>--help</code> and such.</p>
|
|||||||
<li id="section-9">
|
<li id="section-9">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="ss" href="#section-9">§</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -288,8 +290,8 @@ of the valid options, for <code>--help</code> and such.</p>
|
|||||||
<li id="section-10">
|
<li id="section-10">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Regex matchers for option flags on the command line and their rules.</p>
|
<p>Regex matchers for option flags on the command line and their rules.</p>
|
||||||
|
|
||||||
@@ -305,8 +307,8 @@ MULTI_FLAG = <span class="hljs-regexp">/^-(\w{2,})/</span></pre></div></div>
|
|||||||
<li id="section-11">
|
<li id="section-11">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="ss" href="#section-11">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Matches the long flag part of a rule for an option with an argument. Not
|
<p>Matches the long flag part of a rule for an option with an argument. Not
|
||||||
applied to anything in process.argv.</p>
|
applied to anything in process.argv.</p>
|
||||||
@@ -321,8 +323,8 @@ applied to anything in process.argv.</p>
|
|||||||
<li id="section-12">
|
<li id="section-12">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="ss" href="#section-12">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Build and return the list of option rules. If the optional <em>short-flag</em> is
|
<p>Build and return the list of option rules. If the optional <em>short-flag</em> is
|
||||||
unspecified, leave it out by padding with <code>null</code>.</p>
|
unspecified, leave it out by padding with <code>null</code>.</p>
|
||||||
@@ -342,8 +344,8 @@ unspecified, leave it out by padding with <code>null</code>.</p>
|
|||||||
<li id="section-13">
|
<li id="section-13">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-13">¶</a>
|
<a class="ss" href="#section-13">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p><code>shortFlag</code> is null if not provided in the rule.</p>
|
<p><code>shortFlag</code> is null if not provided in the rule.</p>
|
||||||
|
|
||||||
@@ -351,8 +353,8 @@ unspecified, leave it out by padding with <code>null</code>.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> flag <span class="hljs-keyword">in</span> [rule.shortFlag, rule.longFlag] <span class="hljs-keyword">when</span> flag?
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> flag <span class="hljs-keyword">in</span> [rule.shortFlag, rule.longFlag] <span class="hljs-keyword">when</span> flag?
|
||||||
<span class="hljs-keyword">if</span> flagDict[flag]?
|
<span class="hljs-keyword">if</span> flagDict[flag]?
|
||||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"flag <span class="hljs-subst">#{flag}</span> for switch <span class="hljs-subst">#{rule.name}</span>
|
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">"flag <span class="hljs-subst">#{flag}</span> for switch <span class="hljs-subst">#{rule.name}</span>
|
||||||
was already declared for switch <span class="hljs-subst">#{flagDict[flag].name}</span>"</span>
|
was already declared for switch <span class="hljs-subst">#{flagDict[flag].name}</span>"</span>
|
||||||
flagDict[flag] = rule
|
flagDict[flag] = rule
|
||||||
|
|
||||||
{ruleList, flagDict}</pre></div></div>
|
{ruleList, flagDict}</pre></div></div>
|
||||||
@@ -363,8 +365,8 @@ unspecified, leave it out by padding with <code>null</code>.</p>
|
|||||||
<li id="section-14">
|
<li id="section-14">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-14">¶</a>
|
<a class="ss" href="#section-14">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
|
<p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
|
||||||
description of what the option does.</p>
|
description of what the option does.</p>
|
||||||
@@ -376,7 +378,7 @@ description of what the option does.</p>
|
|||||||
shortFlag = shortFlag?.match(SHORT_FLAG)[<span class="hljs-number">1</span>]
|
shortFlag = shortFlag?.match(SHORT_FLAG)[<span class="hljs-number">1</span>]
|
||||||
longFlag = longFlag.match(LONG_FLAG)[<span class="hljs-number">1</span>]
|
longFlag = longFlag.match(LONG_FLAG)[<span class="hljs-number">1</span>]
|
||||||
{
|
{
|
||||||
name: longFlag.replace <span class="hljs-regexp">/^--/</span>, <span class="hljs-string">''</span>
|
name: longFlag.replace <span class="hljs-regexp">/^--/</span>, <span class="hljs-string">''</span>
|
||||||
shortFlag: shortFlag
|
shortFlag: shortFlag
|
||||||
longFlag: longFlag
|
longFlag: longFlag
|
||||||
description: description
|
description: description
|
||||||
@@ -396,8 +398,8 @@ description of what the option does.</p>
|
|||||||
<li id="section-15">
|
<li id="section-15">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-15">¶</a>
|
<a class="ss" href="#section-15">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>If the previous argument given to the script was an option that uses the
|
<p>If the previous argument given to the script was an option that uses the
|
||||||
next command-line argument as its argument, create copy of the option’s
|
next command-line argument as its argument, create copy of the option’s
|
||||||
@@ -406,19 +408,19 @@ rule with an <code>argument</code> field.</p>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> needsArgOpt?
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> needsArgOpt?
|
||||||
withArg = Object.assign {}, needsArgOpt.rule, {argument: arg}
|
withArg = <span class="hljs-built_in">Object</span>.assign {}, needsArgOpt.rule, {argument: arg}
|
||||||
rules.push withArg
|
rules.push withArg
|
||||||
needsArgOpt = <span class="hljs-literal">null</span>
|
needsArgOpt = <span class="hljs-literal">null</span>
|
||||||
<span class="hljs-keyword">continue</span>
|
<span class="hljs-keyword">continue</span>
|
||||||
|
|
||||||
multiFlags = arg.match(MULTI_FLAG)?[<span class="hljs-number">1</span>]
|
multiFlags = arg.match(MULTI_FLAG)?[<span class="hljs-number">1</span>]
|
||||||
.split(<span class="hljs-string">''</span>)
|
.split(<span class="hljs-string">''</span>)
|
||||||
.map (flagName) -> <span class="hljs-string">"-<span class="hljs-subst">#{flagName}</span>"</span>
|
.map (flagName) -> <span class="hljs-string">"-<span class="hljs-subst">#{flagName}</span>"</span>
|
||||||
<span class="hljs-keyword">if</span> multiFlags?
|
<span class="hljs-keyword">if</span> multiFlags?
|
||||||
multiOpts = multiFlags.map (flag) ->
|
multiOpts = multiFlags.map (flag) ->
|
||||||
rule = flagDict[flag]
|
rule = flagDict[flag]
|
||||||
<span class="hljs-keyword">unless</span> rule?
|
<span class="hljs-keyword">unless</span> rule?
|
||||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"unrecognized option <span class="hljs-subst">#{flag}</span> in multi-flag <span class="hljs-subst">#{arg}</span>"</span>
|
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">"unrecognized option <span class="hljs-subst">#{flag}</span> in multi-flag <span class="hljs-subst">#{arg}</span>"</span>
|
||||||
{rule, flag}</pre></div></div>
|
{rule, flag}</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -427,8 +429,8 @@ rule with an <code>argument</code> field.</p>
|
|||||||
<li id="section-16">
|
<li id="section-16">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-16">¶</a>
|
<a class="ss" href="#section-16">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Only the last flag in a multi-flag may have an argument.</p>
|
<p>Only the last flag in a multi-flag may have an argument.</p>
|
||||||
|
|
||||||
@@ -437,8 +439,8 @@ rule with an <code>argument</code> field.</p>
|
|||||||
<div class="content"><div class='highlight'><pre> [innerOpts..., lastOpt] = multiOpts
|
<div class="content"><div class='highlight'><pre> [innerOpts..., lastOpt] = multiOpts
|
||||||
<span class="hljs-keyword">for</span> {rule, flag} <span class="hljs-keyword">in</span> innerOpts
|
<span class="hljs-keyword">for</span> {rule, flag} <span class="hljs-keyword">in</span> innerOpts
|
||||||
<span class="hljs-keyword">if</span> rule.hasArgument
|
<span class="hljs-keyword">if</span> rule.hasArgument
|
||||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"cannot use option <span class="hljs-subst">#{flag}</span> in multi-flag <span class="hljs-subst">#{arg}</span> except
|
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">"cannot use option <span class="hljs-subst">#{flag}</span> in multi-flag <span class="hljs-subst">#{arg}</span> except
|
||||||
as the last option, because it needs an argument"</span>
|
as the last option, because it needs an argument"</span>
|
||||||
rules.push rule
|
rules.push rule
|
||||||
<span class="hljs-keyword">if</span> lastOpt.rule.hasArgument
|
<span class="hljs-keyword">if</span> lastOpt.rule.hasArgument
|
||||||
needsArgOpt = lastOpt
|
needsArgOpt = lastOpt
|
||||||
@@ -447,7 +449,7 @@ rule with an <code>argument</code> field.</p>
|
|||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ([LONG_FLAG, SHORT_FLAG].some (pat) -> arg.match(pat)?)
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ([LONG_FLAG, SHORT_FLAG].some (pat) -> arg.match(pat)?)
|
||||||
singleRule = flagDict[arg]
|
singleRule = flagDict[arg]
|
||||||
<span class="hljs-keyword">unless</span> singleRule?
|
<span class="hljs-keyword">unless</span> singleRule?
|
||||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"unrecognized option <span class="hljs-subst">#{arg}</span>"</span>
|
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">"unrecognized option <span class="hljs-subst">#{arg}</span>"</span>
|
||||||
<span class="hljs-keyword">if</span> singleRule.hasArgument
|
<span class="hljs-keyword">if</span> singleRule.hasArgument
|
||||||
needsArgOpt = {rule: singleRule, flag: arg}
|
needsArgOpt = {rule: singleRule, flag: arg}
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
@@ -460,8 +462,8 @@ rule with an <code>argument</code> field.</p>
|
|||||||
<li id="section-17">
|
<li id="section-17">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-17">¶</a>
|
<a class="ss" href="#section-17">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>This is a positional argument.</p>
|
<p>This is a positional argument.</p>
|
||||||
|
|
||||||
@@ -471,8 +473,8 @@ rule with an <code>argument</code> field.</p>
|
|||||||
<span class="hljs-keyword">break</span>
|
<span class="hljs-keyword">break</span>
|
||||||
|
|
||||||
<span class="hljs-keyword">if</span> needsArgOpt?
|
<span class="hljs-keyword">if</span> needsArgOpt?
|
||||||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"value required for <span class="hljs-subst">#{needsArgOpt.flag}</span>, but it was the last
|
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">"value required for <span class="hljs-subst">#{needsArgOpt.flag}</span>, but it was the last
|
||||||
argument provided"</span>
|
argument provided"</span>
|
||||||
{rules, positional}</pre></div></div>
|
{rules, positional}</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
0
docs/v2/annotated-source/public/fonts/roboto-black.eot
Executable file → Normal file
0
docs/v2/annotated-source/public/fonts/roboto-black.eot
Executable file → Normal file
0
docs/v2/annotated-source/public/fonts/roboto-black.ttf
Executable file → Normal file
0
docs/v2/annotated-source/public/fonts/roboto-black.ttf
Executable file → Normal file
0
docs/v2/annotated-source/public/fonts/roboto-black.woff
Executable file → Normal file
0
docs/v2/annotated-source/public/fonts/roboto-black.woff
Executable file → Normal file
@@ -112,16 +112,18 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./'</span>
|
<div class="content"><div class='highlight'><pre>CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./'</span>
|
||||||
child_process = <span class="hljs-built_in">require</span> <span class="hljs-string">'child_process'</span>
|
child_process = <span class="hljs-built_in">require</span> <span class="hljs-string">'child_process'</span>
|
||||||
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span></pre></div></div>
|
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
||||||
|
|
||||||
|
{patchStackTrace} = CoffeeScript</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -129,17 +131,21 @@ path = <span class="hljs-built_in">require</span> <span class="hljs-str
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Load and run a CoffeeScript file for Node, stripping any <code>BOM</code>s.</p>
|
<p>Check if Node’s built-in source map stack trace transformations are enabled.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">loadFile</span> = <span class="hljs-params">(<span class="hljs-built_in">module</span>, filename)</span> -></span>
|
<div class="content"><div class='highlight'><pre>nodeSourceMapsSupportEnabled = process? <span class="hljs-keyword">and</span> (
|
||||||
options = <span class="hljs-built_in">module</span>.options <span class="hljs-keyword">or</span> getRootModule(<span class="hljs-built_in">module</span>).options
|
process.execArgv.includes(<span class="hljs-string">'--enable-source-maps'</span>) <span class="hljs-keyword">or</span>
|
||||||
answer = CoffeeScript._compileFile filename, options
|
process.env.NODE_OPTIONS?.includes(<span class="hljs-string">'--enable-source-maps'</span>)
|
||||||
<span class="hljs-built_in">module</span>._compile answer, filename</pre></div></div>
|
)
|
||||||
|
|
||||||
|
<span class="hljs-keyword">unless</span> <span class="hljs-built_in">Error</span>.prepareStackTrace <span class="hljs-keyword">or</span> nodeSourceMapsSupportEnabled
|
||||||
|
cacheSourceMaps = <span class="hljs-literal">true</span>
|
||||||
|
patchStackTrace()</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -147,8 +153,44 @@ path = <span class="hljs-built_in">require</span> <span class="hljs-str
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Load and run a CoffeeScript file for Node, stripping any <code>BOM</code>s.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">loadFile</span> = <span class="hljs-params">(module, filename)</span> -></span>
|
||||||
|
options = module.options <span class="hljs-keyword">or</span> getRootModule(module).options <span class="hljs-keyword">or</span> {}</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-4">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-4">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Currently <code>CoffeeScript.compile</code> caches all source maps if present. They
|
||||||
|
are available in <code>getSourceMap</code> retrieved by <code>filename</code>.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> cacheSourceMaps <span class="hljs-keyword">or</span> nodeSourceMapsSupportEnabled
|
||||||
|
options.inlineMap = <span class="hljs-literal">true</span>
|
||||||
|
js = CoffeeScript._compileFile filename, options
|
||||||
|
|
||||||
|
module._compile js, filename</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-5">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>If the installed version of Node supports <code>require.extensions</code>, register
|
<p>If the installed version of Node supports <code>require.extensions</code>, register
|
||||||
CoffeeScript as an extension.</p>
|
CoffeeScript as an extension.</p>
|
||||||
@@ -162,61 +204,21 @@ CoffeeScript as an extension.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-4">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Patch Node’s module loader to be able to handle multi-dot extensions.
|
<p>Patch Node’s module loader to be able to handle multi-dot extensions.
|
||||||
This is a horrible thing that should not be required.</p>
|
This is a horrible thing that should not be required.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
|
<div class="content"><div class='highlight'><pre> Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">findExtension</span> = <span class="hljs-params">(filename)</span> -></span>
|
<span class="hljs-title">findExtension</span> = <span class="hljs-params">(filename)</span> -></span>
|
||||||
extensions = path.basename(filename).split <span class="hljs-string">'.'</span></pre></div></div>
|
extensions = path.basename(filename).split <span class="hljs-string">'.'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li id="section-5">
|
|
||||||
<div class="annotation">
|
|
||||||
|
|
||||||
<div class="pilwrap ">
|
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
|
||||||
</div>
|
|
||||||
<p>Remove the initial dot from dotfiles.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> extensions.shift() <span class="hljs-keyword">if</span> extensions[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span></pre></div></div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li id="section-6">
|
|
||||||
<div class="annotation">
|
|
||||||
|
|
||||||
<div class="pilwrap ">
|
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
|
||||||
</div>
|
|
||||||
<p>Start with the longest possible extension and work our way shortwards.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> extensions.shift()
|
|
||||||
curExtension = <span class="hljs-string">'.'</span> + extensions.join <span class="hljs-string">'.'</span>
|
|
||||||
<span class="hljs-keyword">return</span> curExtension <span class="hljs-keyword">if</span> Module._extensions[curExtension]
|
|
||||||
<span class="hljs-string">'.js'</span>
|
|
||||||
|
|
||||||
Module::load = <span class="hljs-function"><span class="hljs-params">(filename)</span> -></span>
|
|
||||||
@filename = filename
|
|
||||||
@paths = Module._nodeModulePaths path.dirname filename
|
|
||||||
extension = findExtension filename
|
|
||||||
Module._extensions[extension](<span class="hljs-keyword">this</span>, filename)
|
|
||||||
@loaded = <span class="hljs-literal">true</span></pre></div></div>
|
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -224,8 +226,48 @@ This is a horrible thing that should not be required.</p>
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Remove the initial dot from dotfiles.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> extensions.shift() <span class="hljs-keyword">if</span> extensions[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-8">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-8">§</a>
|
||||||
|
</div>
|
||||||
|
<p>Start with the longest possible extension and work our way shortwards.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> extensions.shift()
|
||||||
|
curExtension = <span class="hljs-string">'.'</span> + extensions.join <span class="hljs-string">'.'</span>
|
||||||
|
<span class="hljs-keyword">return</span> curExtension <span class="hljs-keyword">if</span> Module._extensions[curExtension]
|
||||||
|
<span class="hljs-string">'.js'</span>
|
||||||
|
|
||||||
|
Module::load = <span class="hljs-function"><span class="hljs-params">(filename)</span> -></span>
|
||||||
|
@filename = filename
|
||||||
|
@paths = Module._nodeModulePaths path.dirname filename
|
||||||
|
extension = findExtension filename
|
||||||
|
Module._extensions[extension](this, filename)
|
||||||
|
@loaded = <span class="hljs-literal">true</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-9">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-9">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>If we’re on Node, patch <code>child_process.fork</code> so that Coffee scripts are able
|
<p>If we’re on Node, patch <code>child_process.fork</code> so that Coffee scripts are able
|
||||||
to fork both CoffeeScript files, and JavaScript files, directly.</p>
|
to fork both CoffeeScript files, and JavaScript files, directly.</p>
|
||||||
@@ -234,10 +276,10 @@ to fork both CoffeeScript files, and JavaScript files, directly.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> child_process
|
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> child_process
|
||||||
{fork} = child_process
|
{fork} = child_process
|
||||||
binary = <span class="hljs-built_in">require</span>.resolve <span class="hljs-string">'../../bin/coffee'</span>
|
binary = <span class="hljs-built_in">require</span>.resolve <span class="hljs-string">'../../bin/coffee'</span>
|
||||||
child_process.fork = <span class="hljs-function"><span class="hljs-params">(path, args, options)</span> -></span>
|
child_process.fork = <span class="hljs-function"><span class="hljs-params">(path, args, options)</span> -></span>
|
||||||
<span class="hljs-keyword">if</span> helpers.isCoffee path
|
<span class="hljs-keyword">if</span> helpers.isCoffee path
|
||||||
<span class="hljs-keyword">unless</span> Array.isArray args
|
<span class="hljs-keyword">unless</span> <span class="hljs-built_in">Array</span>.isArray args
|
||||||
options = args <span class="hljs-keyword">or</span> {}
|
options = args <span class="hljs-keyword">or</span> {}
|
||||||
args = []
|
args = []
|
||||||
args = [path].concat args
|
args = [path].concat args
|
||||||
@@ -247,18 +289,18 @@ to fork both CoffeeScript files, and JavaScript files, directly.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-8">
|
<li id="section-10">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Utility function to find the <code>options</code> object attached to the topmost module.</p>
|
<p>Utility function to find the <code>options</code> object attached to the topmost module.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">getRootModule</span> = <span class="hljs-params">(<span class="hljs-built_in">module</span>)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">getRootModule</span> = <span class="hljs-params">(module)</span> -></span>
|
||||||
<span class="hljs-keyword">if</span> <span class="hljs-built_in">module</span>.parent <span class="hljs-keyword">then</span> getRootModule <span class="hljs-built_in">module</span>.parent <span class="hljs-keyword">else</span> <span class="hljs-built_in">module</span></pre></div></div>
|
<span class="hljs-keyword">if</span> module.parent <span class="hljs-keyword">then</span> getRootModule module.parent <span class="hljs-keyword">else</span> module</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
@@ -112,27 +112,27 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
<div class="content"><div class='highlight'><pre>fs = <span class="hljs-built_in">require</span> <span class="hljs-string">'fs'</span>
|
||||||
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
path = <span class="hljs-built_in">require</span> <span class="hljs-string">'path'</span>
|
||||||
vm = <span class="hljs-built_in">require</span> <span class="hljs-string">'vm'</span>
|
vm = <span class="hljs-built_in">require</span> <span class="hljs-string">'vm'</span>
|
||||||
nodeREPL = <span class="hljs-built_in">require</span> <span class="hljs-string">'repl'</span>
|
nodeREPL = <span class="hljs-built_in">require</span> <span class="hljs-string">'repl'</span>
|
||||||
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./'</span>
|
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./'</span>
|
||||||
{merge, updateSyntaxError} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
{merge, updateSyntaxError} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||||
|
|
||||||
sawSIGINT = <span class="hljs-literal">no</span>
|
sawSIGINT = <span class="hljs-literal">no</span>
|
||||||
transpile = <span class="hljs-literal">no</span>
|
transpile = <span class="hljs-literal">no</span>
|
||||||
|
|
||||||
replDefaults =
|
replDefaults =
|
||||||
prompt: <span class="hljs-string">'coffee> '</span>,
|
prompt: <span class="hljs-string">'coffee> '</span>,
|
||||||
historyFile: <span class="hljs-keyword">do</span> ->
|
historyFile: <span class="hljs-keyword">do</span> ->
|
||||||
historyPath = process.env.XDG_CACHE_HOME <span class="hljs-keyword">or</span> process.env.HOME
|
historyPath = process.env.XDG_CACHE_HOME <span class="hljs-keyword">or</span> process.env.HOME
|
||||||
path.join historyPath, <span class="hljs-string">'.coffee_history'</span> <span class="hljs-keyword">if</span> historyPath
|
path.join historyPath, <span class="hljs-string">'.coffee_history'</span> <span class="hljs-keyword">if</span> historyPath
|
||||||
historyMaxInputSize: <span class="hljs-number">10240</span>
|
historyMaxInputSize: <span class="hljs-number">10240</span>
|
||||||
eval: <span class="hljs-function"><span class="hljs-params">(input, context, filename, cb)</span> -></span></pre></div></div>
|
eval: <span class="hljs-function"><span class="hljs-params">(input, context, filename, cb)</span> -></span></pre></div></div>
|
||||||
|
|
||||||
@@ -142,14 +142,14 @@ replDefaults =
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>XXX: multiline hack.</p>
|
<p>XXX: multiline hack.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> input = input.replace <span class="hljs-regexp">/\uFF00/g</span>, <span class="hljs-string">'\n'</span></pre></div></div>
|
<div class="content"><div class='highlight'><pre> input = input.replace <span class="hljs-regexp">/\uFF00/g</span>, <span class="hljs-string">'\n'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -157,15 +157,15 @@ replDefaults =
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Node’s REPL sends the input ending with a newline and then wrapped in
|
<p>Node’s REPL sends the input ending with a newline and then wrapped in
|
||||||
parens. Unwrap all that.</p>
|
parens. Unwrap all that.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> input = input.replace <span class="hljs-regexp">/^\(([\s\S]*)\n\)$/m</span>, <span class="hljs-string">'$1'</span></pre></div></div>
|
<div class="content"><div class='highlight'><pre> input = input.replace <span class="hljs-regexp">/^\(([\s\S]*)\n\)$/m</span>, <span class="hljs-string">'$1'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -173,15 +173,15 @@ parens. Unwrap all that.</p>
|
|||||||
<li id="section-4">
|
<li id="section-4">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-4">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Node’s REPL v6.9.1+ sends the input wrapped in a try/catch statement.
|
<p>Node’s REPL v6.9.1+ sends the input wrapped in a try/catch statement.
|
||||||
Unwrap that too.</p>
|
Unwrap that too.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> input = input.replace <span class="hljs-regexp">/^\s*try\s*{([\s\S]*)}\s*catch.*$/m</span>, <span class="hljs-string">'$1'</span></pre></div></div>
|
<div class="content"><div class='highlight'><pre> input = input.replace <span class="hljs-regexp">/^\s*try\s*{([\s\S]*)}\s*catch.*$/m</span>, <span class="hljs-string">'$1'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -189,14 +189,14 @@ Unwrap that too.</p>
|
|||||||
<li id="section-5">
|
<li id="section-5">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Require AST nodes to do some AST manipulation.</p>
|
<p>Require AST nodes to do some AST manipulation.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> {Block, Assign, Value, Literal, Call, Code} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span>
|
<div class="content"><div class='highlight'><pre> {Block, Assign, Value, Literal, Call, Code, Root} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span>
|
||||||
|
|
||||||
<span class="hljs-keyword">try</span></pre></div></div>
|
<span class="hljs-keyword">try</span></pre></div></div>
|
||||||
|
|
||||||
@@ -206,8 +206,8 @@ Unwrap that too.</p>
|
|||||||
<li id="section-6">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Tokenize the clean input.</p>
|
<p>Tokenize the clean input.</p>
|
||||||
|
|
||||||
@@ -221,19 +221,19 @@ Unwrap that too.</p>
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Filter out tokens generated just to hold comments.</p>
|
<p>Filter out tokens generated just to hold comments.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> tokens.length >= <span class="hljs-number">2</span> <span class="hljs-keyword">and</span> tokens[<span class="hljs-number">0</span>].generated <span class="hljs-keyword">and</span>
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> tokens.length >= <span class="hljs-number">2</span> <span class="hljs-keyword">and</span> tokens[<span class="hljs-number">0</span>].generated <span class="hljs-keyword">and</span>
|
||||||
tokens[<span class="hljs-number">0</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> tokens[<span class="hljs-number">0</span>][<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span> <span class="hljs-keyword">and</span>
|
tokens[<span class="hljs-number">0</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> <span class="hljs-string">"<span class="hljs-subst">#{tokens[<span class="hljs-number">0</span>][<span class="hljs-number">1</span>]}</span>"</span> <span class="hljs-keyword">is</span> <span class="hljs-string">''</span> <span class="hljs-keyword">and</span>
|
||||||
tokens[<span class="hljs-number">1</span>][<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'TERMINATOR'</span>
|
tokens[<span class="hljs-number">1</span>][<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'TERMINATOR'</span>
|
||||||
tokens = tokens[<span class="hljs-number">2.</span>..]
|
tokens = tokens[<span class="hljs-number">2.</span>..]
|
||||||
<span class="hljs-keyword">if</span> tokens.length >= <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> tokens[tokens.length - <span class="hljs-number">1</span>].generated <span class="hljs-keyword">and</span>
|
<span class="hljs-keyword">if</span> tokens.length >= <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> tokens[tokens.length - <span class="hljs-number">1</span>].generated <span class="hljs-keyword">and</span>
|
||||||
tokens[tokens.length - <span class="hljs-number">1</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> tokens[tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span>
|
tokens[tokens.length - <span class="hljs-number">1</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> <span class="hljs-string">"<span class="hljs-subst">#{tokens[tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">1</span>]}</span>"</span> <span class="hljs-keyword">is</span> <span class="hljs-string">''</span>
|
||||||
tokens.pop()</pre></div></div>
|
tokens.pop()</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -242,14 +242,14 @@ Unwrap that too.</p>
|
|||||||
<li id="section-8">
|
<li id="section-8">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-8">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Collect referenced variable names just like in <code>CoffeeScript.compile</code>.</p>
|
<p>Collect referenced variable names just like in <code>CoffeeScript.compile</code>.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> referencedVars = (token[<span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'IDENTIFIER'</span>)</pre></div></div>
|
<div class="content"><div class='highlight'><pre> referencedVars = (token[<span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'IDENTIFIER'</span>)</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -257,14 +257,14 @@ Unwrap that too.</p>
|
|||||||
<li id="section-9">
|
<li id="section-9">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="ss" href="#section-9">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Generate the AST of the tokens.</p>
|
<p>Generate the AST of the tokens.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> ast = CoffeeScript.nodes tokens</pre></div></div>
|
<div class="content"><div class='highlight'><pre> ast = CoffeeScript.nodes(tokens).body</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -272,14 +272,14 @@ Unwrap that too.</p>
|
|||||||
<li id="section-10">
|
<li id="section-10">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Add assignment to <code>__</code> variable to force the input to be an expression.</p>
|
<p>Add assignment to <code>__</code> variable to force the input to be an expression.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'__'</span>), ast, <span class="hljs-string">'='</span>]</pre></div></div>
|
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'__'</span>), ast, <span class="hljs-string">'='</span>]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -287,8 +287,8 @@ Unwrap that too.</p>
|
|||||||
<li id="section-11">
|
<li id="section-11">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="ss" href="#section-11">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Wrap the expression in a closure to support top-level <code>await</code>.</p>
|
<p>Wrap the expression in a closure to support top-level <code>await</code>.</p>
|
||||||
|
|
||||||
@@ -303,15 +303,15 @@ Unwrap that too.</p>
|
|||||||
<li id="section-12">
|
<li id="section-12">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="ss" href="#section-12">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Invoke the wrapping closure.</p>
|
<p>Invoke the wrapping closure.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Call ast]
|
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Root <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Call ast]
|
||||||
js = ast.compile {bare: <span class="hljs-literal">yes</span>, locals: Object.keys(context), referencedVars, sharedScope: <span class="hljs-literal">yes</span>}
|
js = ast.compile {bare: <span class="hljs-literal">yes</span>, locals: <span class="hljs-built_in">Object</span>.keys(context), referencedVars, sharedScope: <span class="hljs-literal">yes</span>}
|
||||||
<span class="hljs-keyword">if</span> transpile
|
<span class="hljs-keyword">if</span> transpile
|
||||||
js = transpile.transpile(js, transpile.options).code</pre></div></div>
|
js = transpile.transpile(js, transpile.options).code</pre></div></div>
|
||||||
|
|
||||||
@@ -321,15 +321,15 @@ Unwrap that too.</p>
|
|||||||
<li id="section-13">
|
<li id="section-13">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-13">¶</a>
|
<a class="ss" href="#section-13">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Strip <code>"use strict"</code>, to avoid an exception on assigning to
|
<p>Strip <code>"use strict"</code>, to avoid an exception on assigning to
|
||||||
undeclared variable <code>__</code>.</p>
|
undeclared variable <code>__</code>.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> js = js.replace <span class="hljs-regexp">/^"use strict"|^'use strict'/</span>, <span class="hljs-string">''</span>
|
<div class="content"><div class='highlight'><pre> js = js.replace <span class="hljs-regexp">/^"use strict"|^'use strict'/</span>, <span class="hljs-string">''</span>
|
||||||
result = runInContext js, context, filename</pre></div></div>
|
result = runInContext js, context, filename</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -338,8 +338,8 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-14">
|
<li id="section-14">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-14">¶</a>
|
<a class="ss" href="#section-14">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Await an async result, if necessary.</p>
|
<p>Await an async result, if necessary.</p>
|
||||||
|
|
||||||
@@ -359,8 +359,8 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-15">
|
<li id="section-15">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-15">¶</a>
|
<a class="ss" href="#section-15">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>AST’s <code>compile</code> does not add source code information to syntax errors.</p>
|
<p>AST’s <code>compile</code> does not add source code information to syntax errors.</p>
|
||||||
|
|
||||||
@@ -370,13 +370,13 @@ undeclared variable <code>__</code>.</p>
|
|||||||
cb err
|
cb err
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">runInContext</span> = <span class="hljs-params">(js, context, filename)</span> -></span>
|
<span class="hljs-title">runInContext</span> = <span class="hljs-params">(js, context, filename)</span> -></span>
|
||||||
<span class="hljs-keyword">if</span> context <span class="hljs-keyword">is</span> <span class="hljs-built_in">global</span>
|
<span class="hljs-keyword">if</span> context <span class="hljs-keyword">is</span> global
|
||||||
vm.runInThisContext js, filename
|
vm.runInThisContext js, filename
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
vm.runInContext js, context, filename
|
vm.runInContext js, context, filename
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">addMultilineHandler</span> = <span class="hljs-params">(repl)</span> -></span>
|
<span class="hljs-title">addMultilineHandler</span> = <span class="hljs-params">(repl)</span> -></span>
|
||||||
{rli, inputStream, outputStream} = repl</pre></div></div>
|
{inputStream, outputStream} = repl</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -384,8 +384,8 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-16">
|
<li id="section-16">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-16">¶</a>
|
<a class="ss" href="#section-16">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Node 0.11.12 changed API, prompt is now _prompt.</p>
|
<p>Node 0.11.12 changed API, prompt is now _prompt.</p>
|
||||||
|
|
||||||
@@ -395,9 +395,9 @@ undeclared variable <code>__</code>.</p>
|
|||||||
|
|
||||||
multiline =
|
multiline =
|
||||||
enabled: <span class="hljs-literal">off</span>
|
enabled: <span class="hljs-literal">off</span>
|
||||||
initialPrompt: origPrompt.replace <span class="hljs-regexp">/^[^> ]*/</span>, <span class="hljs-function"><span class="hljs-params">(x)</span> -></span> x.replace <span class="hljs-regexp">/./g</span>, <span class="hljs-string">'-'</span>
|
initialPrompt: origPrompt.replace <span class="hljs-regexp">/^[^> ]*/</span>, <span class="hljs-function"><span class="hljs-params">(x)</span> -></span> x.replace <span class="hljs-regexp">/./g</span>, <span class="hljs-string">'-'</span>
|
||||||
prompt: origPrompt.replace <span class="hljs-regexp">/^[^> ]*>?/</span>, <span class="hljs-function"><span class="hljs-params">(x)</span> -></span> x.replace <span class="hljs-regexp">/./g</span>, <span class="hljs-string">'.'</span>
|
prompt: origPrompt.replace <span class="hljs-regexp">/^[^> ]*>?/</span>, <span class="hljs-function"><span class="hljs-params">(x)</span> -></span> x.replace <span class="hljs-regexp">/./g</span>, <span class="hljs-string">'.'</span>
|
||||||
buffer: <span class="hljs-string">''</span></pre></div></div>
|
buffer: <span class="hljs-string">''</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -405,22 +405,22 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-17">
|
<li id="section-17">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-17">¶</a>
|
<a class="ss" href="#section-17">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Proxy node’s line listener</p>
|
<p>Proxy node’s line listener</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> nodeLineListener = rli.listeners(<span class="hljs-string">'line'</span>)[<span class="hljs-number">0</span>]
|
<div class="content"><div class='highlight'><pre> nodeLineListener = repl.listeners(<span class="hljs-string">'line'</span>)[<span class="hljs-number">0</span>]
|
||||||
rli.removeListener <span class="hljs-string">'line'</span>, nodeLineListener
|
repl.removeListener <span class="hljs-string">'line'</span>, nodeLineListener
|
||||||
rli.<span class="hljs-literal">on</span> <span class="hljs-string">'line'</span>, <span class="hljs-function"><span class="hljs-params">(cmd)</span> -></span>
|
repl.<span class="hljs-literal">on</span> <span class="hljs-string">'line'</span>, <span class="hljs-function"><span class="hljs-params">(cmd)</span> -></span>
|
||||||
<span class="hljs-keyword">if</span> multiline.enabled
|
<span class="hljs-keyword">if</span> multiline.enabled
|
||||||
multiline.buffer += <span class="hljs-string">"<span class="hljs-subst">#{cmd}</span>\n"</span>
|
multiline.buffer += <span class="hljs-string">"<span class="hljs-subst">#{cmd}</span>\n"</span>
|
||||||
rli.setPrompt multiline.prompt
|
repl.setPrompt multiline.prompt
|
||||||
rli.prompt <span class="hljs-literal">true</span>
|
repl.prompt <span class="hljs-literal">true</span>
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
rli.setPrompt origPrompt
|
repl.setPrompt origPrompt
|
||||||
nodeLineListener cmd
|
nodeLineListener cmd
|
||||||
<span class="hljs-keyword">return</span></pre></div></div>
|
<span class="hljs-keyword">return</span></pre></div></div>
|
||||||
|
|
||||||
@@ -430,15 +430,15 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-18">
|
<li id="section-18">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-18">¶</a>
|
<a class="ss" href="#section-18">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Handle Ctrl-v</p>
|
<p>Handle Ctrl-v</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> inputStream.<span class="hljs-literal">on</span> <span class="hljs-string">'keypress'</span>, <span class="hljs-function"><span class="hljs-params">(char, key)</span> -></span>
|
<div class="content"><div class='highlight'><pre> inputStream.<span class="hljs-literal">on</span> <span class="hljs-string">'keypress'</span>, <span class="hljs-function"><span class="hljs-params">(char, key)</span> -></span>
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> key <span class="hljs-keyword">and</span> key.ctrl <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> key.meta <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> key.shift <span class="hljs-keyword">and</span> key.name <span class="hljs-keyword">is</span> <span class="hljs-string">'v'</span>
|
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> key <span class="hljs-keyword">and</span> key.ctrl <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> key.meta <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> key.shift <span class="hljs-keyword">and</span> key.name <span class="hljs-keyword">is</span> <span class="hljs-string">'v'</span>
|
||||||
<span class="hljs-keyword">if</span> multiline.enabled</pre></div></div>
|
<span class="hljs-keyword">if</span> multiline.enabled</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -447,8 +447,8 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-19">
|
<li id="section-19">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-19">¶</a>
|
<a class="ss" href="#section-19">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>allow arbitrarily switching between modes any time before multiple lines are entered</p>
|
<p>allow arbitrarily switching between modes any time before multiple lines are entered</p>
|
||||||
|
|
||||||
@@ -456,8 +456,8 @@ undeclared variable <code>__</code>.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> multiline.buffer.match <span class="hljs-regexp">/\n/</span>
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> multiline.buffer.match <span class="hljs-regexp">/\n/</span>
|
||||||
multiline.enabled = <span class="hljs-keyword">not</span> multiline.enabled
|
multiline.enabled = <span class="hljs-keyword">not</span> multiline.enabled
|
||||||
rli.setPrompt origPrompt
|
repl.setPrompt origPrompt
|
||||||
rli.prompt <span class="hljs-literal">true</span>
|
repl.prompt <span class="hljs-literal">true</span>
|
||||||
<span class="hljs-keyword">return</span></pre></div></div>
|
<span class="hljs-keyword">return</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -466,14 +466,14 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-20">
|
<li id="section-20">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-20">¶</a>
|
<a class="ss" href="#section-20">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>no-op unless the current line is empty</p>
|
<p>no-op unless the current line is empty</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> rli.line? <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> rli.line.match <span class="hljs-regexp">/^\s*$/</span></pre></div></div>
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> repl.line? <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> repl.line.match <span class="hljs-regexp">/^\s*$/</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -481,18 +481,18 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-21">
|
<li id="section-21">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-21">¶</a>
|
<a class="ss" href="#section-21">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>eval, print, loop</p>
|
<p>eval, print, loop</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> multiline.enabled = <span class="hljs-keyword">not</span> multiline.enabled
|
<div class="content"><div class='highlight'><pre> multiline.enabled = <span class="hljs-keyword">not</span> multiline.enabled
|
||||||
rli.line = <span class="hljs-string">''</span>
|
repl.line = <span class="hljs-string">''</span>
|
||||||
rli.cursor = <span class="hljs-number">0</span>
|
repl.cursor = <span class="hljs-number">0</span>
|
||||||
rli.output.cursorTo <span class="hljs-number">0</span>
|
repl.output.cursorTo <span class="hljs-number">0</span>
|
||||||
rli.output.clearLine <span class="hljs-number">1</span></pre></div></div>
|
repl.output.clearLine <span class="hljs-number">1</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -500,20 +500,20 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-22">
|
<li id="section-22">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-22">¶</a>
|
<a class="ss" href="#section-22">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>XXX: multiline hack</p>
|
<p>XXX: multiline hack</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> multiline.buffer = multiline.buffer.replace <span class="hljs-regexp">/\n/g</span>, <span class="hljs-string">'\uFF00'</span>
|
<div class="content"><div class='highlight'><pre> multiline.buffer = multiline.buffer.replace <span class="hljs-regexp">/\n/g</span>, <span class="hljs-string">'\uFF00'</span>
|
||||||
rli.emit <span class="hljs-string">'line'</span>, multiline.buffer
|
repl.emit <span class="hljs-string">'line'</span>, multiline.buffer
|
||||||
multiline.buffer = <span class="hljs-string">''</span>
|
multiline.buffer = <span class="hljs-string">''</span>
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
multiline.enabled = <span class="hljs-keyword">not</span> multiline.enabled
|
multiline.enabled = <span class="hljs-keyword">not</span> multiline.enabled
|
||||||
rli.setPrompt multiline.initialPrompt
|
repl.setPrompt multiline.initialPrompt
|
||||||
rli.prompt <span class="hljs-literal">true</span>
|
repl.prompt <span class="hljs-literal">true</span>
|
||||||
<span class="hljs-keyword">return</span></pre></div></div>
|
<span class="hljs-keyword">return</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -522,8 +522,8 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-23">
|
<li id="section-23">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-23">¶</a>
|
<a class="ss" href="#section-23">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Store and load command history from a file</p>
|
<p>Store and load command history from a file</p>
|
||||||
|
|
||||||
@@ -539,15 +539,15 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-24">
|
<li id="section-24">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-24">¶</a>
|
<a class="ss" href="#section-24">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Get file info and at most maxSize of command history</p>
|
<p>Get file info and at most maxSize of command history</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> stat = fs.statSync filename
|
<div class="content"><div class='highlight'><pre> stat = fs.statSync filename
|
||||||
size = Math.min maxSize, stat.size</pre></div></div>
|
size = <span class="hljs-built_in">Math</span>.min maxSize, stat.size</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -555,14 +555,14 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-25">
|
<li id="section-25">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-25">¶</a>
|
<a class="ss" href="#section-25">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Read last <code>size</code> bytes from the file</p>
|
<p>Read last <code>size</code> bytes from the file</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> readFd = fs.openSync filename, <span class="hljs-string">'r'</span>
|
<div class="content"><div class='highlight'><pre> readFd = fs.openSync filename, <span class="hljs-string">'r'</span>
|
||||||
buffer = Buffer.alloc size
|
buffer = Buffer.alloc size
|
||||||
fs.readSync readFd, buffer, <span class="hljs-number">0</span>, size, stat.size - size
|
fs.readSync readFd, buffer, <span class="hljs-number">0</span>, size, stat.size - size
|
||||||
fs.closeSync readFd</pre></div></div>
|
fs.closeSync readFd</pre></div></div>
|
||||||
@@ -573,14 +573,14 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-26">
|
<li id="section-26">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-26">¶</a>
|
<a class="ss" href="#section-26">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Set the history on the interpreter</p>
|
<p>Set the history on the interpreter</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> repl.rli.history = buffer.toString().split(<span class="hljs-string">'\n'</span>).reverse()</pre></div></div>
|
<div class="content"><div class='highlight'><pre> repl.history = buffer.toString().split(<span class="hljs-string">'\n'</span>).reverse()</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -588,14 +588,14 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-27">
|
<li id="section-27">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-27">¶</a>
|
<a class="ss" href="#section-27">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>If the history file was truncated we should pop off a potential partial line</p>
|
<p>If the history file was truncated we should pop off a potential partial line</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> repl.rli.history.pop() <span class="hljs-keyword">if</span> stat.size > maxSize</pre></div></div>
|
<div class="content"><div class='highlight'><pre> repl.history.pop() <span class="hljs-keyword">if</span> stat.size > maxSize</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -603,21 +603,21 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-28">
|
<li id="section-28">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-28">¶</a>
|
<a class="ss" href="#section-28">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Shift off the final blank newline</p>
|
<p>Shift off the final blank newline</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> repl.rli.history.shift() <span class="hljs-keyword">if</span> repl.rli.history[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span>
|
<div class="content"><div class='highlight'><pre> repl.history.shift() <span class="hljs-keyword">if</span> repl.history[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span>
|
||||||
repl.rli.historyIndex = <span class="hljs-number">-1</span>
|
repl.historyIndex = <span class="hljs-number">-1</span>
|
||||||
lastLine = repl.rli.history[<span class="hljs-number">0</span>]
|
lastLine = repl.history[<span class="hljs-number">0</span>]
|
||||||
|
|
||||||
fd = fs.openSync filename, <span class="hljs-string">'a'</span>
|
fd = fs.openSync filename, <span class="hljs-string">'a'</span>
|
||||||
|
|
||||||
repl.rli.addListener <span class="hljs-string">'line'</span>, <span class="hljs-function"><span class="hljs-params">(code)</span> -></span>
|
repl.addListener <span class="hljs-string">'line'</span>, <span class="hljs-function"><span class="hljs-params">(code)</span> -></span>
|
||||||
<span class="hljs-keyword">if</span> code <span class="hljs-keyword">and</span> code.length <span class="hljs-keyword">and</span> code <span class="hljs-keyword">isnt</span> <span class="hljs-string">'.history'</span> <span class="hljs-keyword">and</span> code <span class="hljs-keyword">isnt</span> <span class="hljs-string">'.exit'</span> <span class="hljs-keyword">and</span> lastLine <span class="hljs-keyword">isnt</span> code</pre></div></div>
|
<span class="hljs-keyword">if</span> code <span class="hljs-keyword">and</span> code.length <span class="hljs-keyword">and</span> code <span class="hljs-keyword">isnt</span> <span class="hljs-string">'.history'</span> <span class="hljs-keyword">and</span> code <span class="hljs-keyword">isnt</span> <span class="hljs-string">'.exit'</span> <span class="hljs-keyword">and</span> lastLine <span class="hljs-keyword">isnt</span> code</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -625,14 +625,14 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-29">
|
<li id="section-29">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-29">¶</a>
|
<a class="ss" href="#section-29">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Save the latest command in the file</p>
|
<p>Save the latest command in the file</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> fs.writeSync fd, <span class="hljs-string">"<span class="hljs-subst">#{code}</span>\n"</span>
|
<div class="content"><div class='highlight'><pre> fs.writeSync fd, <span class="hljs-string">"<span class="hljs-subst">#{code}</span>\n"</span>
|
||||||
lastLine = code</pre></div></div>
|
lastLine = code</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -641,15 +641,15 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-30">
|
<li id="section-30">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-30">¶</a>
|
<a class="ss" href="#section-30">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>XXX: The SIGINT event from REPLServer is undocumented, so this is a bit fragile</p>
|
<p>XXX: The SIGINT event from REPLServer is undocumented, so this is a bit fragile</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> repl.<span class="hljs-literal">on</span> <span class="hljs-string">'SIGINT'</span>, <span class="hljs-function">-></span> sawSIGINT = <span class="hljs-literal">yes</span>
|
<div class="content"><div class='highlight'><pre> repl.<span class="hljs-literal">on</span> <span class="hljs-string">'SIGINT'</span>, <span class="hljs-function">-></span> sawSIGINT = <span class="hljs-literal">yes</span>
|
||||||
repl.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>, <span class="hljs-function">-></span> fs.closeSync fd</pre></div></div>
|
repl.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>, <span class="hljs-function">-></span> fs.closeSync fd</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -657,17 +657,17 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-31">
|
<li id="section-31">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-31">¶</a>
|
<a class="ss" href="#section-31">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Add a command to show the history stack</p>
|
<p>Add a command to show the history stack</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> repl.commands[getCommandId(repl, <span class="hljs-string">'history'</span>)] =
|
<div class="content"><div class='highlight'><pre> repl.commands[getCommandId(repl, <span class="hljs-string">'history'</span>)] =
|
||||||
help: <span class="hljs-string">'Show command history'</span>
|
help: <span class="hljs-string">'Show command history'</span>
|
||||||
action: <span class="hljs-function">-></span>
|
action: <span class="hljs-function">-></span>
|
||||||
repl.outputStream.write <span class="hljs-string">"<span class="hljs-subst">#{repl.rli.history[..].reverse().join <span class="hljs-string">'\n'</span>}</span>\n"</span>
|
repl.outputStream.write <span class="hljs-string">"<span class="hljs-subst">#{repl.history[..].reverse().join <span class="hljs-string">'\n'</span>}</span>\n"</span>
|
||||||
repl.displayPrompt()
|
repl.displayPrompt()
|
||||||
<span class="hljs-function">
|
<span class="hljs-function">
|
||||||
<span class="hljs-title">getCommandId</span> = <span class="hljs-params">(repl, commandName)</span> -></span></pre></div></div>
|
<span class="hljs-title">getCommandId</span> = <span class="hljs-params">(repl, commandName)</span> -></span></pre></div></div>
|
||||||
@@ -678,45 +678,45 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-32">
|
<li id="section-32">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-32">¶</a>
|
<a class="ss" href="#section-32">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Node 0.11 changed API, a command such as ‘.help’ is now stored as ‘help’</p>
|
<p>Node 0.11 changed API, a command such as ‘.help’ is now stored as ‘help’</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> commandsHaveLeadingDot = repl.commands[<span class="hljs-string">'.help'</span>]?
|
<div class="content"><div class='highlight'><pre> commandsHaveLeadingDot = repl.commands[<span class="hljs-string">'.help'</span>]?
|
||||||
<span class="hljs-keyword">if</span> commandsHaveLeadingDot <span class="hljs-keyword">then</span> <span class="hljs-string">".<span class="hljs-subst">#{commandName}</span>"</span> <span class="hljs-keyword">else</span> commandName
|
<span class="hljs-keyword">if</span> commandsHaveLeadingDot <span class="hljs-keyword">then</span> <span class="hljs-string">".<span class="hljs-subst">#{commandName}</span>"</span> <span class="hljs-keyword">else</span> commandName
|
||||||
|
|
||||||
<span class="hljs-built_in">module</span>.exports =
|
module.<span class="hljs-built_in">exports</span> =
|
||||||
start: <span class="hljs-function"><span class="hljs-params">(opts = {})</span> -></span>
|
start: <span class="hljs-function"><span class="hljs-params">(opts = {})</span> -></span>
|
||||||
[major, minor, build] = process.versions.node.split(<span class="hljs-string">'.'</span>).map (n) -> parseInt(n, <span class="hljs-number">10</span>)
|
[major, minor, build] = process.versions.node.split(<span class="hljs-string">'.'</span>).map (n) -> <span class="hljs-built_in">parseInt</span>(n, <span class="hljs-number">10</span>)
|
||||||
|
|
||||||
<span class="hljs-keyword">if</span> major < <span class="hljs-number">6</span>
|
<span class="hljs-keyword">if</span> major < <span class="hljs-number">6</span>
|
||||||
<span class="hljs-built_in">console</span>.warn <span class="hljs-string">"Node 6+ required for CoffeeScript REPL"</span>
|
console.warn <span class="hljs-string">"Node 6+ required for CoffeeScript REPL"</span>
|
||||||
process.exit <span class="hljs-number">1</span>
|
process.exit <span class="hljs-number">1</span>
|
||||||
|
|
||||||
CoffeeScript.register()
|
CoffeeScript.register()
|
||||||
process.argv = [<span class="hljs-string">'coffee'</span>].concat process.argv[<span class="hljs-number">2.</span>.]
|
process.argv = [<span class="hljs-string">'coffee'</span>].concat process.argv[<span class="hljs-number">2.</span>.]
|
||||||
<span class="hljs-keyword">if</span> opts.transpile
|
<span class="hljs-keyword">if</span> opts.transpile
|
||||||
transpile = {}
|
transpile = {}
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
transpile.transpile = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@babel/core'</span>).transform
|
transpile.transpile = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@babel/core'</span>).transform
|
||||||
<span class="hljs-keyword">catch</span>
|
<span class="hljs-keyword">catch</span>
|
||||||
<span class="hljs-keyword">try</span>
|
<span class="hljs-keyword">try</span>
|
||||||
transpile.transpile = <span class="hljs-built_in">require</span>(<span class="hljs-string">'babel-core'</span>).transform
|
transpile.transpile = <span class="hljs-built_in">require</span>(<span class="hljs-string">'babel-core'</span>).transform
|
||||||
<span class="hljs-keyword">catch</span>
|
<span class="hljs-keyword">catch</span>
|
||||||
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
|
console.error <span class="hljs-string">'''
|
||||||
To use --transpile with an interactive REPL, @babel/core must be installed either in the current folder or globally:
|
To use --transpile with an interactive REPL, @babel/core must be installed either in the current folder or globally:
|
||||||
npm install --save-dev @babel/core
|
npm install --save-dev @babel/core
|
||||||
or
|
or
|
||||||
npm install --global @babel/core
|
npm install --global @babel/core
|
||||||
And you must save options to configure Babel in one of the places it looks to find its options.
|
And you must save options to configure Babel in one of the places it looks to find its options.
|
||||||
See https://coffeescript.org/#transpilation
|
See https://coffeescript.org/#transpilation
|
||||||
'''</span>
|
'''</span>
|
||||||
process.exit <span class="hljs-number">1</span>
|
process.exit <span class="hljs-number">1</span>
|
||||||
transpile.options =
|
transpile.options =
|
||||||
filename: path.resolve process.cwd(), <span class="hljs-string">'<repl>'</span></pre></div></div>
|
filename: path.resolve process.cwd(), <span class="hljs-string">'<repl>'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -724,8 +724,8 @@ undeclared variable <code>__</code>.</p>
|
|||||||
<li id="section-33">
|
<li id="section-33">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-33">¶</a>
|
<a class="ss" href="#section-33">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Since the REPL compilation path is unique (in <code>eval</code> above), we need
|
<p>Since the REPL compilation path is unique (in <code>eval</code> above), we need
|
||||||
another way to get the <code>options</code> object attached to a module so that
|
another way to get the <code>options</code> object attached to a module so that
|
||||||
@@ -734,15 +734,15 @@ the REPL, the only applicable option is <code>transpile</code>.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
|
<div class="content"><div class='highlight'><pre> Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
|
||||||
originalModuleLoad = Module::load
|
originalModuleLoad = Module::load
|
||||||
Module::load = <span class="hljs-function"><span class="hljs-params">(filename)</span> -></span>
|
Module::load = <span class="hljs-function"><span class="hljs-params">(filename)</span> -></span>
|
||||||
@options = transpile: transpile.options
|
@options = transpile: transpile.options
|
||||||
originalModuleLoad.call @, filename
|
originalModuleLoad.call @, filename
|
||||||
opts = merge replDefaults, opts
|
opts = merge replDefaults, opts
|
||||||
repl = nodeREPL.start opts
|
repl = nodeREPL.start opts
|
||||||
runInContext opts.prelude, repl.context, <span class="hljs-string">'prelude'</span> <span class="hljs-keyword">if</span> opts.prelude
|
runInContext opts.prelude, repl.context, <span class="hljs-string">'prelude'</span> <span class="hljs-keyword">if</span> opts.prelude
|
||||||
repl.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>, <span class="hljs-function">-></span> repl.outputStream.write <span class="hljs-string">'\n'</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> repl.rli.closed
|
repl.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>, <span class="hljs-function">-></span> repl.outputStream.write <span class="hljs-string">'\n'</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> repl.closed
|
||||||
addMultilineHandler repl
|
addMultilineHandler repl
|
||||||
addHistory repl, opts.historyFile, opts.historyMaxInputSize <span class="hljs-keyword">if</span> opts.historyFile</pre></div></div>
|
addHistory repl, opts.historyFile, opts.historyMaxInputSize <span class="hljs-keyword">if</span> opts.historyFile</pre></div></div>
|
||||||
|
|
||||||
@@ -752,14 +752,14 @@ the REPL, the only applicable option is <code>transpile</code>.</p>
|
|||||||
<li id="section-34">
|
<li id="section-34">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-34">¶</a>
|
<a class="ss" href="#section-34">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Adapt help inherited from the node REPL</p>
|
<p>Adapt help inherited from the node REPL</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> repl.commands[getCommandId(repl, <span class="hljs-string">'load'</span>)].help = <span class="hljs-string">'Load code from a file into this REPL session'</span>
|
<div class="content"><div class='highlight'><pre> repl.commands[getCommandId(repl, <span class="hljs-string">'load'</span>)].help = <span class="hljs-string">'Load code from a file into this REPL session'</span>
|
||||||
repl</pre></div></div>
|
repl</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -112,8 +112,8 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The <strong>Scope</strong> class regulates lexical scoping within CoffeeScript. As you
|
<p>The <strong>Scope</strong> class regulates lexical scoping within CoffeeScript. As you
|
||||||
generate code, you create a tree of scopes in the same shape as the nested
|
generate code, you create a tree of scopes in the same shape as the nested
|
||||||
@@ -124,7 +124,7 @@ with external scopes.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>exports.Scope = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Scope</span></span></pre></div></div>
|
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Scope = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Scope</span></span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -132,8 +132,8 @@ with external scopes.</p>
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Initialize a scope with its parent, for lookups up the chain,
|
<p>Initialize a scope with its parent, for lookups up the chain,
|
||||||
as well as a reference to the <strong>Block</strong> node it belongs to, which is
|
as well as a reference to the <strong>Block</strong> node it belongs to, which is
|
||||||
@@ -145,7 +145,7 @@ that should be output as part of variable declarations.</p>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> constructor: <span class="hljs-function"><span class="hljs-params">(@parent, @expressions, @method, @referencedVars)</span> -></span>
|
<div class="content"><div class='highlight'><pre> constructor: <span class="hljs-function"><span class="hljs-params">(@parent, @expressions, @method, @referencedVars)</span> -></span>
|
||||||
@variables = [{name: <span class="hljs-string">'arguments'</span>, type: <span class="hljs-string">'arguments'</span>}]
|
@variables = [{name: <span class="hljs-string">'arguments'</span>, type: <span class="hljs-string">'arguments'</span>}]
|
||||||
@comments = {}
|
@comments = {}
|
||||||
@positions = {}
|
@positions = {}
|
||||||
@utilities = {} <span class="hljs-keyword">unless</span> @parent</pre></div></div>
|
@utilities = {} <span class="hljs-keyword">unless</span> @parent</pre></div></div>
|
||||||
@@ -156,14 +156,14 @@ that should be output as part of variable declarations.</p>
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The <code>@root</code> is the top-level <strong>Scope</strong> object for a given file.</p>
|
<p>The <code>@root</code> is the top-level <strong>Scope</strong> object for a given file.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> @root = @parent?.root ? <span class="hljs-keyword">this</span></pre></div></div>
|
<div class="content"><div class='highlight'><pre> @root = @parent?.root ? this</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -171,8 +171,8 @@ that should be output as part of variable declarations.</p>
|
|||||||
<li id="section-4">
|
<li id="section-4">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-4">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Adds a new variable or overrides an existing one.</p>
|
<p>Adds a new variable or overrides an existing one.</p>
|
||||||
|
|
||||||
@@ -191,8 +191,8 @@ that should be output as part of variable declarations.</p>
|
|||||||
<li id="section-5">
|
<li id="section-5">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>When <code>super</code> is called, we need to find the name of the current method we’re
|
<p>When <code>super</code> is called, we need to find the name of the current method we’re
|
||||||
in, so that we know how to invoke the same method of the parent class. This
|
in, so that we know how to invoke the same method of the parent class. This
|
||||||
@@ -212,15 +212,15 @@ function object that has a name filled in, or bottoms out.</p>
|
|||||||
<li id="section-6">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Look up a variable name in lexical scope, and declare it if it does not
|
<p>Look up a variable name in lexical scope, and declare it if it does not
|
||||||
already exist.</p>
|
already exist.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> find: <span class="hljs-function"><span class="hljs-params">(name, type = <span class="hljs-string">'var'</span>)</span> -></span>
|
<div class="content"><div class='highlight'><pre> find: <span class="hljs-function"><span class="hljs-params">(name, type = <span class="hljs-string">'var'</span>)</span> -></span>
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @check name
|
<span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> @check name
|
||||||
@add name, type
|
@add name, type
|
||||||
<span class="hljs-literal">no</span></pre></div></div>
|
<span class="hljs-literal">no</span></pre></div></div>
|
||||||
@@ -231,8 +231,8 @@ already exist.</p>
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Reserve a variable name as originating from a function parameter for this
|
<p>Reserve a variable name as originating from a function parameter for this
|
||||||
scope. No <code>var</code> required for internal references.</p>
|
scope. No <code>var</code> required for internal references.</p>
|
||||||
@@ -241,7 +241,7 @@ scope. No <code>var</code> required for internal references.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> parameter: <span class="hljs-function"><span class="hljs-params">(name)</span> -></span>
|
<div class="content"><div class='highlight'><pre> parameter: <span class="hljs-function"><span class="hljs-params">(name)</span> -></span>
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> @shared <span class="hljs-keyword">and</span> @parent.check name, <span class="hljs-literal">yes</span>
|
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> @shared <span class="hljs-keyword">and</span> @parent.check name, <span class="hljs-literal">yes</span>
|
||||||
@add name, <span class="hljs-string">'param'</span></pre></div></div>
|
@add name, <span class="hljs-string">'param'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -249,8 +249,8 @@ scope. No <code>var</code> required for internal references.</p>
|
|||||||
<li id="section-8">
|
<li id="section-8">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-8">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Just check to see if a variable has already been declared, without reserving,
|
<p>Just check to see if a variable has already been declared, without reserving,
|
||||||
walks up to the root scope.</p>
|
walks up to the root scope.</p>
|
||||||
@@ -266,8 +266,8 @@ walks up to the root scope.</p>
|
|||||||
<li id="section-9">
|
<li id="section-9">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="ss" href="#section-9">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Generate a temporary variable name at the given index.</p>
|
<p>Generate a temporary variable name at the given index.</p>
|
||||||
|
|
||||||
@@ -276,14 +276,14 @@ walks up to the root scope.</p>
|
|||||||
<div class="content"><div class='highlight'><pre> temporary: <span class="hljs-function"><span class="hljs-params">(name, index, single=<span class="hljs-literal">false</span>)</span> -></span>
|
<div class="content"><div class='highlight'><pre> temporary: <span class="hljs-function"><span class="hljs-params">(name, index, single=<span class="hljs-literal">false</span>)</span> -></span>
|
||||||
<span class="hljs-keyword">if</span> single
|
<span class="hljs-keyword">if</span> single
|
||||||
startCode = name.charCodeAt(<span class="hljs-number">0</span>)
|
startCode = name.charCodeAt(<span class="hljs-number">0</span>)
|
||||||
endCode = <span class="hljs-string">'z'</span>.charCodeAt(<span class="hljs-number">0</span>)
|
endCode = <span class="hljs-string">'z'</span>.charCodeAt(<span class="hljs-number">0</span>)
|
||||||
diff = endCode - startCode
|
diff = endCode - startCode
|
||||||
newCode = startCode + index % (diff + <span class="hljs-number">1</span>)
|
newCode = startCode + index % (diff + <span class="hljs-number">1</span>)
|
||||||
letter = String.fromCharCode(newCode)
|
letter = <span class="hljs-built_in">String</span>.fromCharCode(newCode)
|
||||||
num = index <span class="hljs-regexp">//</span> (diff + <span class="hljs-number">1</span>)
|
num = index <span class="hljs-regexp">//</span> (diff + <span class="hljs-number">1</span>)
|
||||||
<span class="hljs-string">"<span class="hljs-subst">#{letter}</span><span class="hljs-subst">#{num <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>}</span>"</span>
|
<span class="hljs-string">"<span class="hljs-subst">#{letter}</span><span class="hljs-subst">#{num <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>}</span>"</span>
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
<span class="hljs-string">"<span class="hljs-subst">#{name}</span><span class="hljs-subst">#{index <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>}</span>"</span></pre></div></div>
|
<span class="hljs-string">"<span class="hljs-subst">#{name}</span><span class="hljs-subst">#{index <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>}</span>"</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -291,8 +291,8 @@ walks up to the root scope.</p>
|
|||||||
<li id="section-10">
|
<li id="section-10">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Gets the type of a variable.</p>
|
<p>Gets the type of a variable.</p>
|
||||||
|
|
||||||
@@ -308,8 +308,8 @@ walks up to the root scope.</p>
|
|||||||
<li id="section-11">
|
<li id="section-11">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="ss" href="#section-11">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>If we need to store an intermediate result, find an available name for a
|
<p>If we need to store an intermediate result, find an available name for a
|
||||||
compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on…</p>
|
compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on…</p>
|
||||||
@@ -322,7 +322,7 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on…
|
|||||||
temp = @temporary name, index, options.single
|
temp = @temporary name, index, options.single
|
||||||
<span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> @check(temp) <span class="hljs-keyword">or</span> temp <span class="hljs-keyword">in</span> @root.referencedVars
|
<span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> @check(temp) <span class="hljs-keyword">or</span> temp <span class="hljs-keyword">in</span> @root.referencedVars
|
||||||
index++
|
index++
|
||||||
@add temp, <span class="hljs-string">'var'</span>, <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> options.reserve ? <span class="hljs-literal">true</span>
|
@add temp, <span class="hljs-string">'var'</span>, <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> options.reserve ? <span class="hljs-literal">true</span>
|
||||||
temp</pre></div></div>
|
temp</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -331,8 +331,8 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on…
|
|||||||
<li id="section-12">
|
<li id="section-12">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="ss" href="#section-12">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Ensure that an assignment is made at the top of this scope
|
<p>Ensure that an assignment is made at the top of this scope
|
||||||
(or at the top-level scope, if requested).</p>
|
(or at the top-level scope, if requested).</p>
|
||||||
@@ -349,8 +349,8 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on…
|
|||||||
<li id="section-13">
|
<li id="section-13">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-13">¶</a>
|
<a class="ss" href="#section-13">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Does this scope have any declared variables?</p>
|
<p>Does this scope have any declared variables?</p>
|
||||||
|
|
||||||
@@ -365,15 +365,15 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on…
|
|||||||
<li id="section-14">
|
<li id="section-14">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-14">¶</a>
|
<a class="ss" href="#section-14">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Return the list of variables first declared in this scope.</p>
|
<p>Return the list of variables first declared in this scope.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> declaredVariables: <span class="hljs-function">-></span>
|
<div class="content"><div class='highlight'><pre> declaredVariables: <span class="hljs-function">-></span>
|
||||||
(v.name <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> @variables <span class="hljs-keyword">when</span> v.type <span class="hljs-keyword">is</span> <span class="hljs-string">'var'</span>).sort()</pre></div></div>
|
(v.name <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> @variables <span class="hljs-keyword">when</span> v.type <span class="hljs-keyword">is</span> <span class="hljs-string">'var'</span>).sort()</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -381,8 +381,8 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on…
|
|||||||
<li id="section-15">
|
<li id="section-15">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-15">¶</a>
|
<a class="ss" href="#section-15">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Return the list of assignments that are supposed to be made at the top
|
<p>Return the list of assignments that are supposed to be made at the top
|
||||||
of this scope.</p>
|
of this scope.</p>
|
||||||
@@ -390,7 +390,7 @@ of this scope.</p>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> assignedVariables: <span class="hljs-function">-></span>
|
<div class="content"><div class='highlight'><pre> assignedVariables: <span class="hljs-function">-></span>
|
||||||
<span class="hljs-string">"<span class="hljs-subst">#{v.name}</span> = <span class="hljs-subst">#{v.type.value}</span>"</span> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> @variables <span class="hljs-keyword">when</span> v.type.assigned</pre></div></div>
|
<span class="hljs-string">"<span class="hljs-subst">#{v.name}</span> = <span class="hljs-subst">#{v.type.value}</span>"</span> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> @variables <span class="hljs-keyword">when</span> v.type.assigned</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
@@ -112,8 +112,8 @@
|
|||||||
<li id="section-1">
|
<li id="section-1">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-1">¶</a>
|
<a class="ss" href="#section-1">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Source maps allow JavaScript runtimes to match running JavaScript back to
|
<p>Source maps allow JavaScript runtimes to match running JavaScript back to
|
||||||
the original source code that corresponds to it. This can be minified
|
the original source code that corresponds to it. This can be minified
|
||||||
@@ -134,8 +134,8 @@ of this information — to write out alongside the generated JavaScript.</p>
|
|||||||
<li id="section-2">
|
<li id="section-2">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-2">¶</a>
|
<a class="ss" href="#section-2">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>A <strong>LineMap</strong> object keeps track of information about original line and column
|
<p>A <strong>LineMap</strong> object keeps track of information about original line and column
|
||||||
positions for a single line of output JavaScript code.
|
positions for a single line of output JavaScript code.
|
||||||
@@ -161,8 +161,8 @@ positions for a single line of output JavaScript code.
|
|||||||
<li id="section-3">
|
<li id="section-3">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-3">¶</a>
|
<a class="ss" href="#section-3">§</a>
|
||||||
</div>
|
</div>
|
||||||
<h2 id="sourcemap">SourceMap</h2>
|
<h2 id="sourcemap">SourceMap</h2>
|
||||||
|
|
||||||
@@ -174,8 +174,8 @@ positions for a single line of output JavaScript code.
|
|||||||
<li id="section-4">
|
<li id="section-4">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-4">¶</a>
|
<a class="ss" href="#section-4">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Maps locations in a single generated JavaScript file back to locations in
|
<p>Maps locations in a single generated JavaScript file back to locations in
|
||||||
the original CoffeeScript source file.</p>
|
the original CoffeeScript source file.</p>
|
||||||
@@ -195,8 +195,8 @@ through the arrays of line and column buffer to produce it.</p>
|
|||||||
<li id="section-5">
|
<li id="section-5">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-5">¶</a>
|
<a class="ss" href="#section-5">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Adds a mapping to this SourceMap. <code>sourceLocation</code> and <code>generatedLocation</code>
|
<p>Adds a mapping to this SourceMap. <code>sourceLocation</code> and <code>generatedLocation</code>
|
||||||
are both <code>[line, column]</code> arrays. If <code>options.noReplace</code> is true, then if there
|
are both <code>[line, column]</code> arrays. If <code>options.noReplace</code> is true, then if there
|
||||||
@@ -216,8 +216,8 @@ effect.</p>
|
|||||||
<li id="section-6">
|
<li id="section-6">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-6">¶</a>
|
<a class="ss" href="#section-6">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Look up the original position of a given <code>line</code> and <code>column</code> in the generated
|
<p>Look up the original position of a given <code>line</code> and <code>column</code> in the generated
|
||||||
code.</p>
|
code.</p>
|
||||||
@@ -234,10 +234,10 @@ code.</p>
|
|||||||
<li id="section-7">
|
<li id="section-7">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="ss" href="#section-7">§</a>
|
||||||
</div>
|
</div>
|
||||||
<h2 id="v3-sourcemap-generation">V3 SourceMap Generation</h2>
|
<h2 id="caching">Caching</h2>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -247,8 +247,45 @@ code.</p>
|
|||||||
<li id="section-8">
|
<li id="section-8">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="ss" href="#section-8">§</a>
|
||||||
|
</div>
|
||||||
|
<p>A static source maps cache <code>filename</code>: <code>map</code>. These are used for transforming
|
||||||
|
stack traces and are currently set in <code>CoffeeScript.compile</code> for all files
|
||||||
|
compiled with the source maps option.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> @sourceMaps: <span class="hljs-built_in">Object</span>.create <span class="hljs-literal">null</span>
|
||||||
|
|
||||||
|
@registerCompiled: <span class="hljs-function"><span class="hljs-params">(filename, source, sourcemap)</span> =></span>
|
||||||
|
<span class="hljs-keyword">if</span> sourcemap?
|
||||||
|
@sourceMaps[filename] = sourcemap
|
||||||
|
|
||||||
|
@getSourceMap: <span class="hljs-function"><span class="hljs-params">(filename)</span> =></span>
|
||||||
|
@sourceMaps[filename]</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-9">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-9">§</a>
|
||||||
|
</div>
|
||||||
|
<h2 id="v3-sourcemap-generation">V3 SourceMap Generation</h2>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-10">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="sswrap ">
|
||||||
|
<a class="ss" href="#section-10">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Builds up a V3 source map, returning the generated JSON as a string.
|
<p>Builds up a V3 source map, returning the generated JSON as a string.
|
||||||
<code>options.sourceRoot</code> may be used to specify the sourceRoot written to the source
|
<code>options.sourceRoot</code> may be used to specify the sourceRoot written to the source
|
||||||
@@ -263,41 +300,41 @@ set “sources” and “file”, respectively.</p>
|
|||||||
lastSourceLine = <span class="hljs-number">0</span>
|
lastSourceLine = <span class="hljs-number">0</span>
|
||||||
lastSourceColumn = <span class="hljs-number">0</span>
|
lastSourceColumn = <span class="hljs-number">0</span>
|
||||||
needComma = <span class="hljs-literal">no</span>
|
needComma = <span class="hljs-literal">no</span>
|
||||||
buffer = <span class="hljs-string">""</span>
|
buffer = <span class="hljs-string">""</span>
|
||||||
|
|
||||||
<span class="hljs-keyword">for</span> lineMap, lineNumber <span class="hljs-keyword">in</span> @lines <span class="hljs-keyword">when</span> lineMap
|
<span class="hljs-keyword">for</span> lineMap, lineNumber <span class="hljs-keyword">in</span> @lines <span class="hljs-keyword">when</span> lineMap
|
||||||
<span class="hljs-keyword">for</span> mapping <span class="hljs-keyword">in</span> lineMap.columns <span class="hljs-keyword">when</span> mapping
|
<span class="hljs-keyword">for</span> mapping <span class="hljs-keyword">in</span> lineMap.columns <span class="hljs-keyword">when</span> mapping
|
||||||
<span class="hljs-keyword">while</span> writingline < mapping.line
|
<span class="hljs-keyword">while</span> writingline < mapping.line
|
||||||
lastColumn = <span class="hljs-number">0</span>
|
lastColumn = <span class="hljs-number">0</span>
|
||||||
needComma = <span class="hljs-literal">no</span>
|
needComma = <span class="hljs-literal">no</span>
|
||||||
buffer += <span class="hljs-string">";"</span>
|
buffer += <span class="hljs-string">";"</span>
|
||||||
writingline++</pre></div></div>
|
writingline++</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-9">
|
<li id="section-11">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="ss" href="#section-11">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Write a comma if we’ve already written a segment on this line.</p>
|
<p>Write a comma if we’ve already written a segment on this line.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> needComma
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> needComma
|
||||||
buffer += <span class="hljs-string">","</span>
|
buffer += <span class="hljs-string">","</span>
|
||||||
needComma = <span class="hljs-literal">no</span></pre></div></div>
|
needComma = <span class="hljs-literal">no</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-10">
|
<li id="section-12">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="ss" href="#section-12">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Write the next segment. Segments can be 1, 4, or 5 values. If just one, then it
|
<p>Write the next segment. Segments can be 1, 4, or 5 values. If just one, then it
|
||||||
is a generated column which doesn’t match anything in the source code.</p>
|
is a generated column which doesn’t match anything in the source code.</p>
|
||||||
@@ -312,11 +349,11 @@ column for the current line:</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-11">
|
<li id="section-13">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="ss" href="#section-13">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The index into the list of sources:</p>
|
<p>The index into the list of sources:</p>
|
||||||
|
|
||||||
@@ -327,11 +364,11 @@ column for the current line:</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-12">
|
<li id="section-14">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="ss" href="#section-14">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The starting line in the original source, relative to the previous source line.</p>
|
<p>The starting line in the original source, relative to the previous source line.</p>
|
||||||
|
|
||||||
@@ -343,11 +380,11 @@ column for the current line:</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-13">
|
<li id="section-15">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-13">¶</a>
|
<a class="ss" href="#section-15">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The starting column in the original source, relative to the previous column.</p>
|
<p>The starting column in the original source, relative to the previous column.</p>
|
||||||
|
|
||||||
@@ -360,11 +397,11 @@ column for the current line:</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-14">
|
<li id="section-16">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-14">¶</a>
|
<a class="ss" href="#section-16">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Produce the canonical JSON object format for a “v3” source map.</p>
|
<p>Produce the canonical JSON object format for a “v3” source map.</p>
|
||||||
|
|
||||||
@@ -375,12 +412,12 @@ column for the current line:</p>
|
|||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> options.filename
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> options.filename
|
||||||
[options.filename]
|
[options.filename]
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
[<span class="hljs-string">'<anonymous>'</span>]
|
[<span class="hljs-string">'<anonymous>'</span>]
|
||||||
|
|
||||||
v3 =
|
v3 =
|
||||||
version: <span class="hljs-number">3</span>
|
version: <span class="hljs-number">3</span>
|
||||||
file: options.generatedFile <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>
|
file: options.generatedFile <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>
|
||||||
sourceRoot: options.sourceRoot <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>
|
sourceRoot: options.sourceRoot <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>
|
||||||
sources: sources
|
sources: sources
|
||||||
names: []
|
names: []
|
||||||
mappings: buffer
|
mappings: buffer
|
||||||
@@ -392,11 +429,11 @@ column for the current line:</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-15">
|
<li id="section-17">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-15">¶</a>
|
<a class="ss" href="#section-17">§</a>
|
||||||
</div>
|
</div>
|
||||||
<h2 id="base64-vlq-encoding">Base64 VLQ Encoding</h2>
|
<h2 id="base64-vlq-encoding">Base64 VLQ Encoding</h2>
|
||||||
|
|
||||||
@@ -405,11 +442,11 @@ column for the current line:</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-16">
|
<li id="section-18">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-16">¶</a>
|
<a class="ss" href="#section-18">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Note that SourceMap VLQ encoding is “backwards”. MIDI-style VLQ encoding puts
|
<p>Note that SourceMap VLQ encoding is “backwards”. MIDI-style VLQ encoding puts
|
||||||
the most-significant-bit (MSB) from the original value into the MSB of the VLQ
|
the most-significant-bit (MSB) from the original value into the MSB of the VLQ
|
||||||
@@ -424,16 +461,16 @@ bits of the original value encoded into the first byte of the VLQ encoded value.
|
|||||||
VLQ_VALUE_MASK = VLQ_CONTINUATION_BIT - <span class="hljs-number">1</span> <span class="hljs-comment"># 0001 1111</span>
|
VLQ_VALUE_MASK = VLQ_CONTINUATION_BIT - <span class="hljs-number">1</span> <span class="hljs-comment"># 0001 1111</span>
|
||||||
|
|
||||||
encodeVlq: <span class="hljs-function"><span class="hljs-params">(value)</span> -></span>
|
encodeVlq: <span class="hljs-function"><span class="hljs-params">(value)</span> -></span>
|
||||||
answer = <span class="hljs-string">''</span></pre></div></div>
|
answer = <span class="hljs-string">''</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-17">
|
<li id="section-19">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-17">¶</a>
|
<a class="ss" href="#section-19">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Least significant bit represents the sign.</p>
|
<p>Least significant bit represents the sign.</p>
|
||||||
|
|
||||||
@@ -444,26 +481,26 @@ bits of the original value encoded into the first byte of the VLQ encoded value.
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-18">
|
<li id="section-20">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-18">¶</a>
|
<a class="ss" href="#section-20">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The next bits are the actual value.</p>
|
<p>The next bits are the actual value.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> valueToEncode = (Math.abs(value) << <span class="hljs-number">1</span>) + signBit</pre></div></div>
|
<div class="content"><div class='highlight'><pre> valueToEncode = (<span class="hljs-built_in">Math</span>.abs(value) << <span class="hljs-number">1</span>) + signBit</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-19">
|
<li id="section-21">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-19">¶</a>
|
<a class="ss" href="#section-21">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Make sure we encode at least one character, even if valueToEncode is 0.</p>
|
<p>Make sure we encode at least one character, even if valueToEncode is 0.</p>
|
||||||
|
|
||||||
@@ -480,11 +517,11 @@ bits of the original value encoded into the first byte of the VLQ encoded value.
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-20">
|
<li id="section-22">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-20">¶</a>
|
<a class="ss" href="#section-22">§</a>
|
||||||
</div>
|
</div>
|
||||||
<h2 id="regular-base64-encoding">Regular Base64 Encoding</h2>
|
<h2 id="regular-base64-encoding">Regular Base64 Encoding</h2>
|
||||||
|
|
||||||
@@ -493,34 +530,34 @@ bits of the original value encoded into the first byte of the VLQ encoded value.
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-21">
|
<li id="section-23">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-21">¶</a>
|
<a class="ss" href="#section-23">§</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> BASE64_CHARS = <span class="hljs-string">'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'</span>
|
<div class="content"><div class='highlight'><pre> BASE64_CHARS = <span class="hljs-string">'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'</span>
|
||||||
|
|
||||||
encodeBase64: <span class="hljs-function"><span class="hljs-params">(value)</span> -></span>
|
encodeBase64: <span class="hljs-function"><span class="hljs-params">(value)</span> -></span>
|
||||||
BASE64_CHARS[value] <span class="hljs-keyword">or</span> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"Cannot Base64 encode value: <span class="hljs-subst">#{value}</span>"</span></pre></div></div>
|
BASE64_CHARS[value] <span class="hljs-keyword">or</span> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">"Cannot Base64 encode value: <span class="hljs-subst">#{value}</span>"</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-22">
|
<li id="section-24">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="sswrap ">
|
||||||
<a class="pilcrow" href="#section-22">¶</a>
|
<a class="ss" href="#section-24">§</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Our API for source maps is just the <code>SourceMap</code> class.</p>
|
<p>Our API for source maps is just the <code>SourceMap</code> class.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">module</span>.exports = SourceMap</pre></div></div>
|
<div class="content"><div class='highlight'><pre>module.<span class="hljs-built_in">exports</span> = SourceMap</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
8
docs/v2/browser-compiler-legacy/coffeescript.js
Normal file
8
docs/v2/browser-compiler-legacy/coffeescript.js
Normal file
File diff suppressed because one or more lines are too long
8
docs/v2/browser-compiler-modern/coffeescript.js
Normal file
8
docs/v2/browser-compiler-modern/coffeescript.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
17464
docs/v2/test.html
17464
docs/v2/test.html
File diff suppressed because it is too large
Load Diff
10
documentation/examples/dynamic_import.coffee
Normal file
10
documentation/examples/dynamic_import.coffee
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Your browser must support dynamic import to run this example.
|
||||||
|
|
||||||
|
do ->
|
||||||
|
{ run } = await import('./browser-compiler-modern/coffeescript.js')
|
||||||
|
run '''
|
||||||
|
if 5 < new Date().getHours() < 9
|
||||||
|
alert 'Time to make the coffee!'
|
||||||
|
else
|
||||||
|
alert 'Time to get some work done.'
|
||||||
|
'''
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'local-file.coffee'
|
import './local-file.js' # Must be the filename of the generated file
|
||||||
import 'coffeescript'
|
import 'package'
|
||||||
|
|
||||||
import _ from 'underscore'
|
import _ from 'underscore'
|
||||||
import * as underscore from 'underscore'
|
import * as underscore from 'underscore'
|
||||||
@@ -9,6 +9,8 @@ import { now as currentTimestamp } from 'underscore'
|
|||||||
import { first, last } from 'underscore'
|
import { first, last } from 'underscore'
|
||||||
import utilityBelt, { each } from 'underscore'
|
import utilityBelt, { each } from 'underscore'
|
||||||
|
|
||||||
|
import dates from './calendar.json' assert { type: 'json' }
|
||||||
|
|
||||||
export default Math
|
export default Math
|
||||||
export square = (x) -> x * x
|
export square = (x) -> x * x
|
||||||
export class Mathematics
|
export class Mathematics
|
||||||
@@ -20,3 +22,4 @@ export { Mathematics as default, sqrt as squareRoot }
|
|||||||
|
|
||||||
export * from 'underscore'
|
export * from 'underscore'
|
||||||
export { max, min } from 'underscore'
|
export { max, min } from 'underscore'
|
||||||
|
export { version } from './package.json' assert { type: 'json' }
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ releaseHeader('2010-02-25', '0.5.2', '0.5.1')
|
|||||||
```
|
```
|
||||||
|
|
||||||
Added a compressed version of the compiler for inclusion in web pages as
|
Added a compressed version of the compiler for inclusion in web pages as
|
||||||
`/v<%= majorVersion %>/browser-compiler/coffeescript.js`. It’ll automatically run any script tags with type `text/coffeescript` for you. Added a `--stdio` option to the `coffee` command, for piped-in compiles.
|
`/v<%= majorVersion %>/browser-compiler-legacy/coffeescript.js`. It’ll automatically run any script tags with type `text/coffeescript` for you. Added a `--stdio` option to the `coffee` command, for piped-in compiles.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
releaseHeader('2017-09-02', '2.0.0-beta5', '2.0.0-beta4')
|
releaseHeader('2017-09-02', '2.0.0-beta5', '2.0.0-beta4')
|
||||||
```
|
```
|
||||||
|
|
||||||
* Node 6 is now supported, and we will try to maintain that as the minimum required version for CoffeeScript 2 via the `coffee` command or Node API. Older versions of Node, or non-evergreen browsers, can compile via the [browser compiler](./browser-compiler/coffeescript.js).
|
* Node 6 is now supported, and we will try to maintain that as the minimum required version for CoffeeScript 2 via the `coffee` command or Node API. Older versions of Node, or non-evergreen browsers, can compile via the [legacy browser compiler](./browser-compiler-legacy/coffeescript.js).
|
||||||
* The command line `--output` flag now allows you to specify an output filename, not just an output folder.
|
* The command line `--output` flag now allows you to specify an output filename, not just an output folder.
|
||||||
* The command line `--require` flag now properly handles filenames or module names that are invalid identifiers (like an NPM module with a hyphen in the name).
|
* The command line `--require` flag now properly handles filenames or module names that are invalid identifiers (like an NPM module with a hyphen in the name).
|
||||||
* `Object.assign`, output when object destructuring is used, is polyfilled using the same polyfill that Babel outputs. This means that polyfills shouldn’t be required unless support for Internet Explorer 8 or below is desired (or your own code uses a feature that requires a polyfill). See [ES2015+ Output](#es2015plus-output).
|
* `Object.assign`, output when object destructuring is used, is polyfilled using the same polyfill that Babel outputs. This means that polyfills shouldn’t be required unless support for Internet Explorer 8 or below is desired (or your own code uses a feature that requires a polyfill). See [ES2015+ Output](#es2015plus-output).
|
||||||
|
|||||||
8
documentation/sections/changelog/2.4.0.md
Normal file
8
documentation/sections/changelog/2.4.0.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
```
|
||||||
|
releaseHeader('2019-03-29', '2.4.0', '2.3.2')
|
||||||
|
```
|
||||||
|
|
||||||
|
* Dynamic `import()` expressions are now supported. The parentheses are always required, to distinguish from `import` statements. See [Modules](#dynamic-import). Note that as of this writing, the JavaScript feature itself is still Stage 3; if it changes before being fully standardized, it may change in CoffeeScript too. Using `import()` before its upstream [ECMAScript proposal](https://github.com/tc39/proposal-dynamic-import) is finalized should be considered provisional, subject to breaking changes if the proposal changes or is rejected. We have also revised our [policy](#contributing) on Stage 3 ECMAScript features, to support them when the features are [shipped](https://caniuse.com/#feat=es6-module-dynamic-import) in significant runtimes such as major browsers or Node.js.
|
||||||
|
* There are now two browser versions of the CoffeeScript compiler: the traditional one that’s been published for years, and a new [ES module version](/browser-compiler-modern/coffeescript.js) that can be used via `import`. If your browser supports it, it is in effect on this page. A reference to the ES module browser compiler is in the `package.json` `"module"` field.
|
||||||
|
* The Node API now exposes the previously private `registerCompiled` method, to allow plugins that use the `coffeescript` package to take advantage of CoffeeScript’s internal caching.
|
||||||
|
* Bugfixes for commas in strings in block arrays, a reference to `@` not being maintained in a `do` block in a class, and function default parameters should no longer be wrapped by extraneous parentheses.
|
||||||
5
documentation/sections/changelog/2.4.1.md
Normal file
5
documentation/sections/changelog/2.4.1.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
```
|
||||||
|
releaseHeader('2019-04-08', '2.4.1', '2.4.0')
|
||||||
|
```
|
||||||
|
|
||||||
|
* Both the [traditional ES5](/browser-compiler-legacy/coffeescript.js) and [modern ES module](/browser-compiler-modern/coffeescript.js) versions of the CoffeeScript browser compiler are now published to NPM, enabling the browser compilers’ use via services that provide NPM modules’ code available via public CDN. The traditional version is referenced via the `package.json` `"browser"` field, and the ES module version via the `"module"` field.
|
||||||
11
documentation/sections/changelog/2.5.0.md
Normal file
11
documentation/sections/changelog/2.5.0.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
```
|
||||||
|
releaseHeader('2019-12-31', '2.5.0', '2.4.1')
|
||||||
|
```
|
||||||
|
|
||||||
|
* The compiler now supports a new `ast` option, available via `--ast` on the command line or `ast` via the Node API. This option outputs an “abstract syntax tree,” or a JSON-like representation of the input CoffeeScript source code. This AST follows [Babel’s spec](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md) as closely as possible, for compatibility with tools that work with JavaScript source code. Two tools that use this new AST output are [`eslint-plugin-coffee`](https://github.com/helixbass/eslint-plugin-coffee), a plugin to lint CoffeeScript via [ESLint](https://eslint.org/); and [`prettier-plugin-coffeescript`](https://github.com/helixbass/prettier-plugin-coffeescript), a plugin to reformat CoffeeScript source code via [Prettier](https://prettier.io/). _The structure and properties of CoffeeScript’s AST are not final and may undergo breaking changes between CoffeeScript versions; please [open an issue](https://github.com/jashkenas/coffeescript/issues) if you are interested in creating new integrations._
|
||||||
|
* [Numeric separators](https://github.com/tc39/proposal-numeric-separator) are now supported in CoffeeScript, following the same syntax as JavaScript: `1_234_567`.
|
||||||
|
* [`BigInt` numbers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) are now supported in CoffeeScript, following the same syntax as JavaScript: `42n`.
|
||||||
|
* `'''` and `"""` strings are now output as more readable JavaScript template literals, or backtick (`` ` ``) strings, with actual newlines rather than `\n` escape sequences.
|
||||||
|
* Classes can now contain computed properties, e.g. `[someVar]: ->` or `@[anotherVar]: ->`.
|
||||||
|
* JSX tags can now contain XML-style namespaces, e.g. `<image xlink:href="data:image/png" />` or `<Something:Tag></Something:Tag>`.
|
||||||
|
* Bugfixes for comments after colons not appearing the output; reserved words mistakenly being disallowed as JSX attributes; indented leading elisions in multiline arrays; and invalid location data in source maps.
|
||||||
7
documentation/sections/changelog/2.5.1.md
Normal file
7
documentation/sections/changelog/2.5.1.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
```
|
||||||
|
releaseHeader('2020-01-31', '2.5.1', '2.5.0')
|
||||||
|
```
|
||||||
|
|
||||||
|
* Object splats can now include prototype shorthands, such as `a = {b::c...}`; and soaks, such as `a = {b?.c..., d?()...}`.
|
||||||
|
* Bugfix for regression in 2.5.0 where compilation became much slower for files with Windows-style line endings.
|
||||||
|
* Bugfix for an implicit object after a line continuation keyword like `or` inside a larger implicit object.
|
||||||
7
documentation/sections/changelog/2.6.0.md
Normal file
7
documentation/sections/changelog/2.6.0.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
```
|
||||||
|
releaseHeader('2021-09-19', '2.6.0', '2.5.1')
|
||||||
|
```
|
||||||
|
|
||||||
|
* The syntax `import.meta`, including `import.meta.url`, is now supported.
|
||||||
|
* The `await` keyword is now supported outside of functions (in other words, at the top level). [Note that JavaScript runtimes only support this for ES modules.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#top_level_await)
|
||||||
|
* Bugfix for a `for` comprehension at the end of an `unless` or `until` line.
|
||||||
6
documentation/sections/changelog/2.6.1.md
Normal file
6
documentation/sections/changelog/2.6.1.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
```
|
||||||
|
releaseHeader('2021-10-03', '2.6.1', '2.6.0')
|
||||||
|
```
|
||||||
|
|
||||||
|
* The `coffeescript` package itself now supports named exports when used by ES modules in Node.js; or in other words, `import { compile } from 'coffeescript'` now works, rather than only `import CoffeeScript from 'coffeescript'`.
|
||||||
|
* Bugfix for a stack overflow error when compiling large files in non-bare mode.
|
||||||
8
documentation/sections/changelog/2.7.0.md
Normal file
8
documentation/sections/changelog/2.7.0.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
```
|
||||||
|
releaseHeader('2022-04-23', '2.7.0', '2.6.1')
|
||||||
|
```
|
||||||
|
|
||||||
|
* The [import assertions syntax](https://github.com/tc39/proposal-import-assertions) is now supported. This allows statements like `export { version } from './package.json' assert { type: 'json' }` or expressions like `import('./calendar.json', { assert { type: 'json' } })`.
|
||||||
|
* CoffeeScript no longer always patches Node’s error stack traces. This patching, where the line and column numbers are adjusted to match the source CoffeeScript rather than the generated JavaScript, caused conflicts with other libraries and is unnecessary when Node’s new [`--enable-source-maps` flag](https://nodejs.org/docs/latest/api/cli.html#--enable-source-maps) is passed. The patching will now occur only when `--enable-source-maps` is not set, no other library has already patched the stack traces, and `require('coffeescript/register')` is used. The patching can be enabled explicitly via `require('coffeescript').patchStackTrace()` or `import { patchStackTrace } from 'coffeescript'; patchStackTrace()`.
|
||||||
|
* Bugfix for an issue where block (triple-quoted) strings weren’t getting transpiled correctly into a JSX expression container wrapping the template literal (such as ``<div a={`...`} />``).
|
||||||
|
* Bugfixes for line continuations not behaving as expected for a nonempty first line of an explicit `[` array or `{` object literal.
|
||||||
@@ -12,13 +12,14 @@ Once installed, you should have access to the `coffee` command, which can execut
|
|||||||
| `-o, --output [DIR]` | Write out all compiled JavaScript files into the specified directory. Use in conjunction with `--compile` or `--watch`. |
|
| `-o, --output [DIR]` | Write out all compiled JavaScript files into the specified directory. Use in conjunction with `--compile` or `--watch`. |
|
||||||
| `-w, --watch` | Watch files for changes, rerunning the specified command when any file is updated. |
|
| `-w, --watch` | Watch files for changes, rerunning the specified command when any file is updated. |
|
||||||
| `-p, --print` | Instead of writing out the JavaScript as a file, print it directly to **stdout**. |
|
| `-p, --print` | Instead of writing out the JavaScript as a file, print it directly to **stdout**. |
|
||||||
| `-s, --stdio` | Pipe in CoffeeScript to STDIN and get back JavaScript over STDOUT. Good for use with processes written in other languages. An example:<br>`cat src/cake.coffee | coffee -sc` |
|
| `-s, --stdio` | Pipe in CoffeeScript to STDIN and get back JavaScript over STDOUT. Good for use with processes written in other languages. An example:<br><code>cat src/cake.coffee | coffee -sc</code> |
|
||||||
| `-l, --literate` | Parses the code as Literate CoffeeScript. You only need to specify this when passing in code directly over **stdio**, or using some sort of extension-less file name. |
|
| `-l, --literate` | Parses the code as Literate CoffeeScript. You only need to specify this when passing in code directly over **stdio**, or using some sort of extension-less file name. |
|
||||||
| `-e, --eval` | Compile and print a little snippet of CoffeeScript directly from the command line. For example:<br>`coffee -e "console.log num for num in [10..1]"` |
|
| `-e, --eval` | Compile and print a little snippet of CoffeeScript directly from the command line. For example:<br>`coffee -e "console.log num for num in [10..1]"` |
|
||||||
| `-r, --require [MODULE]`  | `require()` the given module before starting the REPL or evaluating the code given with the `--eval` flag. |
|
| `-r, --require [MODULE]`  | `require()` the given module before starting the REPL or evaluating the code given with the `--eval` flag. |
|
||||||
| `-b, --bare` | Compile the JavaScript without the [top-level function safety wrapper](#lexical-scope). |
|
| `-b, --bare` | Compile the JavaScript without the [top-level function safety wrapper](#lexical-scope). |
|
||||||
| `--no-header` | Suppress the “Generated by CoffeeScript” header. |
|
| `--no-header` | Suppress the “Generated by CoffeeScript” header. |
|
||||||
| `--nodejs` | The `node` executable has some useful options you can set, such as `--debug`, `--debug-brk`, `--max-stack-size`, and `--expose-gc`. Use this flag to forward options directly to Node.js. To pass multiple flags, use `--nodejs` multiple times. |
|
| `--nodejs` | The `node` executable has some useful options you can set, such as `--debug`, `--debug-brk`, `--max-stack-size`, and `--expose-gc`. Use this flag to forward options directly to Node.js. To pass multiple flags, use `--nodejs` multiple times. |
|
||||||
|
| `--ast` | Generate an abstract syntax tree of nodes of the CoffeeScript. Used for integrating with JavaScript build tools. |
|
||||||
| `--tokens` | Instead of parsing the CoffeeScript, just lex it, and print out the token stream. Used for debugging the compiler. |
|
| `--tokens` | Instead of parsing the CoffeeScript, just lex it, and print out the token stream. Used for debugging the compiler. |
|
||||||
| `-n, --nodes` | Instead of compiling the CoffeeScript, just lex and parse it, and print out the parse tree. Used for debugging the compiler. |
|
| `-n, --nodes` | Instead of compiling the CoffeeScript, just lex and parse it, and print out the parse tree. Used for debugging the compiler. |
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
Most modern JavaScript features that CoffeeScript supports can run natively in Node 7.6+, meaning that Node can run CoffeeScript’s output without any further processing required. Here are some notable exceptions:
|
Most modern JavaScript features that CoffeeScript supports can run natively in Node 7.6+, meaning that Node can run CoffeeScript’s output without any further processing required. Here are some notable exceptions:
|
||||||
|
|
||||||
* [Modules](#modules) and [JSX](#jsx) always require transpilation.
|
* [JSX](#jsx) always requires transpilation.
|
||||||
* [Splats, a.k.a. object rest/spread syntax, for objects](https://coffeescript.org/#splats) are supported by Node 8.6+.
|
* [Splats, a.k.a. object rest/spread syntax, for objects](https://coffeescript.org/#splats) are supported by Node 8.6+.
|
||||||
* The [regular expression `s` (dotall) flag](https://github.com/tc39/proposal-regexp-dotall-flag) is supported by Node 9+.
|
* The [regular expression `s` (dotall) flag](https://github.com/tc39/proposal-regexp-dotall-flag) is supported by Node 9+.
|
||||||
* [Async generator functions](https://github.com/tc39/proposal-async-iteration) are supported by Node 10+.
|
* [Async generator functions](https://github.com/tc39/proposal-async-iteration) are supported by Node 10+.
|
||||||
|
* [Modules](#modules) are supported by Node 12+ with `"type": "module"` in your project’s `package.json`.
|
||||||
|
|
||||||
This list may be incomplete, and excludes versions of Node that support newer features behind flags; please refer to [node.green](http://node.green/) for full details. You can [run the tests in your browser](test.html) to see what your browser supports. It is your responsibility to ensure that your runtime supports the modern features you use; or that you [transpile](#transpilation) your code. When in doubt, transpile.
|
This list may be incomplete, and excludes versions of Node that support newer features behind flags; please refer to [node.green](http://node.green/) for full details. You can [run the tests in your browser](test.html) to see what your browser supports. It is your responsibility to ensure that your runtime supports the modern features you use; or that you [transpile](#transpilation) your code. When in doubt, transpile.
|
||||||
|
|
||||||
|
For compatibility with other JavaScript frameworks and tools, see [Integrations](#integrations).
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Contributions are welcome! Feel free to fork [the repo](https://github.com/jashkenas/coffeescript) and submit a pull request.
|
Contributions are welcome! Feel free to fork [the repo](https://github.com/jashkenas/coffeescript) and submit a pull request.
|
||||||
|
|
||||||
[Some features of ECMAScript are intentionally unsupported](#unsupported). Please review both the open and closed [issues on GitHub](https://github.com/jashkenas/coffeescript/issues) to see if the feature you’re looking for has already been discussed. As a general rule, we don’t support ECMAScript syntax for features that aren’t yet finalized (at Stage 4 in the proposal approval process).
|
[Some features of ECMAScript are intentionally unsupported](#unsupported). Please review both the open and closed [issues on GitHub](https://github.com/jashkenas/coffeescript/issues) to see if the feature you’re looking for has already been discussed. As a general rule, we don’t support ECMAScript syntax for features that aren’t yet finalized (at Stage 4 in the [proposal approval process](https://github.com/tc39/proposals)) or implemented in major browsers and/or Node (which can sometimes happen for features in Stage 3). Any Stage 3 features that CoffeeScript chooses to support should be considered experimental, subject to breaking changes or removal until the feature reaches Stage 4.
|
||||||
|
|
||||||
For more resources on adding to CoffeeScript, please see [the Wiki](https://github.com/jashkenas/coffeescript/wiki/%5BHowto%5D-Hacking-on-the-CoffeeScript-Compiler), especially [How The Parser Works](https://github.com/jashkenas/coffeescript/wiki/%5BHowTo%5D-How-parsing-works).
|
For more resources on adding to CoffeeScript, please see [the Wiki](https://github.com/jashkenas/coffeescript/wiki/%5BHowto%5D-Hacking-on-the-CoffeeScript-Compiler), especially [How The Parser Works](https://github.com/jashkenas/coffeescript/wiki/%5BHowTo%5D-How-parsing-works).
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ There are several things you can do to increase your odds of having your pull re
|
|||||||
|
|
||||||
* Create tests! Any pull request should probably include basic tests to verify you didn’t break anything, or future changes won’t break your code.
|
* Create tests! Any pull request should probably include basic tests to verify you didn’t break anything, or future changes won’t break your code.
|
||||||
* Follow the style of the rest of the CoffeeScript codebase.
|
* Follow the style of the rest of the CoffeeScript codebase.
|
||||||
* Ensure any ECMAScript syntax is mature (at Stage 4), with no further potential changes.
|
* Ensure any ECMAScript syntax is mature (at Stage 4, or at Stage 3 with support in major browsers or runtimes).
|
||||||
* Add only features that have broad utility, rather than a feature aimed at a specific use case or framework.
|
* Add only features that have broad utility, rather than a feature aimed at a specific use case or framework.
|
||||||
|
|
||||||
Of course, it’s entirely possible that you have a great addition, but it doesn’t fit within these constraints. Feel free to roll your own solution; you will have [plenty of company](https://github.com/jashkenas/coffeescript/wiki/In-The-Wild).
|
Of course, it’s entirely possible that you have a great addition, but it doesn’t fit within these constraints. Feel free to roll your own solution; you will have [plenty of company](https://github.com/jashkenas/coffeescript/wiki/In-The-Wild).
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The command-line version of `coffee` is available as a [Node.js](https://nodejs.org/) utility, requiring Node 6 or later. The [core compiler](/v<%= majorVersion %>/browser-compiler/coffeescript.js) however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see [Try CoffeeScript](#try)).
|
The command-line version of `coffee` is available as a [Node.js](https://nodejs.org/) utility, requiring Node 6 or later. The [core compiler](/v<%= majorVersion %>/browser-compiler-modern/coffeescript.js) however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see [Try CoffeeScript](#try)).
|
||||||
|
|
||||||
To install, first make sure you have a working copy of the latest stable version of [Node.js](https://nodejs.org/). You can then install CoffeeScript globally with [npm](https://www.npmjs.com/):
|
To install, first make sure you have a working copy of the latest stable version of [Node.js](https://nodejs.org/). You can then install CoffeeScript globally with [npm](https://www.npmjs.com/):
|
||||||
|
|
||||||
|
|||||||
3
documentation/sections/integrations.md
Normal file
3
documentation/sections/integrations.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
## Integrations
|
||||||
|
|
||||||
|
CoffeeScript is part of the vast JavaScript ecosystem, and many libraries help integrate CoffeeScript with JavaScript. Major projects, especially projects updated to work with CoffeeScript 2, are listed here; more can be found in the [wiki pages](https://github.com/jashkenas/coffeescript/wiki). If there’s a project that you feel should be added to this section, please open an issue or [pull request](https://github.com/jashkenas/coffeescript/wiki/%5BHowTo%5D-Update-the-docs). Projects are listed in alphabetical order by category.
|
||||||
13
documentation/sections/integrations_build_tools.md
Normal file
13
documentation/sections/integrations_build_tools.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
### Build Tools
|
||||||
|
|
||||||
|
* [Browserify](http://browserify.org) with [coffeeify](https://github.com/jnordberg/coffeeify)
|
||||||
|
|
||||||
|
* [Grunt](https://gruntjs.com) with [grunt-contrib-coffee](https://github.com/gruntjs/grunt-contrib-coffee)
|
||||||
|
|
||||||
|
* [Gulp](https://gulpjs.com) with [gulp-coffee](https://github.com/gulp-community/gulp-coffee)
|
||||||
|
|
||||||
|
* [Parcel](https://parceljs.org) with [transformer-coffeescript](https://github.com/parcel-bundler/parcel/tree/v2/packages/transformers/coffeescript)
|
||||||
|
|
||||||
|
* [Rollup](https://rollupjs.org) with [rollup-plugin-coffee-script](https://github.com/lautis/rollup-plugin-coffee-script)
|
||||||
|
|
||||||
|
* [Webpack](https://webpack.js.org) with [coffee-loader](https://github.com/webpack-contrib/coffee-loader)
|
||||||
7
documentation/sections/integrations_code_editors.md
Normal file
7
documentation/sections/integrations_code_editors.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
### Code Editors
|
||||||
|
|
||||||
|
* [Atom](https://atom.io) [packages](https://atom.io/packages/search?q=coffeescript)
|
||||||
|
|
||||||
|
* [Sublime Text](https://sublimetext.com) [packages](https://packagecontrol.io/search/coffeescript)
|
||||||
|
|
||||||
|
* [Visual Studio Code](https://code.visualstudio.com) [extensions](https://marketplace.visualstudio.com/search?target=VSCode&term=coffeescript)
|
||||||
6
documentation/sections/integrations_frameworks.md
Normal file
6
documentation/sections/integrations_frameworks.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
### Frameworks
|
||||||
|
|
||||||
|
* [Ember](https://emberjs.com)
|
||||||
|
with [ember-cli-coffeescript](https://github.com/kimroen/ember-cli-coffeescript)
|
||||||
|
|
||||||
|
* [Meteor](https://meteor.com) with [coffeescript-compiler](https://atmospherejs.com/meteor/coffeescript-compiler)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
### Linters and Formatting
|
||||||
|
|
||||||
|
* [CoffeeLint](https://coffeelint.github.io/)
|
||||||
|
|
||||||
|
* [ESLint](https://eslint.org) with [eslint-plugin-coffee](https://github.com/helixbass/eslint-plugin-coffee)
|
||||||
|
|
||||||
|
* [Prettier](https://prettier.io) with [prettier-plugin-coffeescript](https://github.com/helixbass/prettier-plugin-coffeescript)
|
||||||
3
documentation/sections/integrations_testing.md
Normal file
3
documentation/sections/integrations_testing.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
### Testing
|
||||||
|
|
||||||
|
* [Jest](https://jestjs.io) with [jest-preset-coffeescript](https://github.com/danielbayley/jest-preset-coffeescript)
|
||||||
@@ -4,7 +4,7 @@ _This reference is structured so that it can be read from top to bottom, if you
|
|||||||
|
|
||||||
_Many of the examples can be run (where it makes sense) by pressing the_ <small>▶</small> _button on the right. The CoffeeScript on the left is editable, and the JavaScript will update as you edit._
|
_Many of the examples can be run (where it makes sense) by pressing the_ <small>▶</small> _button on the right. The CoffeeScript on the left is editable, and the JavaScript will update as you edit._
|
||||||
|
|
||||||
First, the basics: CoffeeScript uses significant whitespace to delimit blocks of code. You don’t need to use semicolons `;` to terminate expressions, ending the line will do just as well (although semicolons can still be used to fit multiple expressions onto a single line). Instead of using curly braces `{ }` to surround blocks of code in [functions](#literals), [if-statements](#conditionals), [switch](#switch), and [try/catch](#try), use indentation.
|
First, the basics: CoffeeScript uses significant whitespace to delimit blocks of code. You don’t need to use semicolons `;` to terminate expressions, ending the line will do just as well (although semicolons can still be used to fit multiple expressions onto a single line). Instead of using curly braces `{ }` to surround blocks of code in [functions](#literals), [if-statements](#conditionals), [switch](#switch), and [try/catch](#try-catch), use indentation.
|
||||||
|
|
||||||
You don’t need to use parentheses to invoke a function if you’re passing arguments. The implicit call wraps forward to the end of the line or block expression.<br>
|
You don’t need to use parentheses to invoke a function if you’re passing arguments. The implicit call wraps forward to the end of the line or block expression.<br>
|
||||||
`console.log sys.inspect object` → `console.log(sys.inspect(object));`
|
`console.log sys.inspect object` → `console.log(sys.inspect(object));`
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
## Modules
|
## Modules
|
||||||
|
|
||||||
ES2015 modules are supported in CoffeeScript, with very similar `import` and `export` syntax:
|
[ES2015 modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) are supported in CoffeeScript, with very similar `import` and `export` syntax:
|
||||||
|
|
||||||
```
|
```
|
||||||
codeFor('modules')
|
codeFor('modules')
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<div id="dynamic-import" class="bookmark"></div>
|
||||||
|
|
||||||
|
[Dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports) is also supported, with mandatory parentheses:
|
||||||
|
|
||||||
|
```
|
||||||
|
codeFor('dynamic_import', true)
|
||||||
|
```
|
||||||
|
|
||||||
<div id="modules-note" class="bookmark"></div>
|
<div id="modules-note" class="bookmark"></div>
|
||||||
|
|
||||||
Note that the CoffeeScript compiler **does not resolve modules**; writing an `import` or `export` statement in CoffeeScript will produce an `import` or `export` statement in the resulting output. It is your responsibility to [transpile](#transpilation) this ES2015 syntax into code that will work in your target runtimes.
|
Note that the CoffeeScript compiler **does not resolve modules**; writing an `import` or `export` statement in CoffeeScript will produce an `import` or `export` statement in the resulting output. Such statements can be run by all modern browsers (when the script is referenced via `<script type="module">`) and [by Node.js](https://nodejs.org/api/esm.html#esm_enabling) when the output `.js` files are in a folder where the nearest parent `package.json` file contains `"type": "module"`. Because the runtime is evaluating the generated output, the `import` statements must reference the output files; so if `file.coffee` is output as `file.js`, it needs to be referenced as `file.js` in the `import` statement, with the `.js` extension included.
|
||||||
|
|
||||||
Also note that any file with an `import` or `export` statement will be output without a [top-level function safety wrapper](#lexical-scope); in other words, importing or exporting modules will automatically trigger [bare](#usage) mode for that file. This is because per the ES2015 spec, `import` or `export` statements must occur at the topmost scope.
|
Also, any file with an `import` or `export` statement will be output without a [top-level function safety wrapper](#lexical-scope); in other words, importing or exporting modules will automatically trigger [bare](#usage) mode for that file. This is because per the ES2015 spec, `import` or `export` statements must occur at the topmost scope.
|
||||||
|
|||||||
@@ -24,3 +24,4 @@ The `compile` method has the signature `compile(code, options)` where `code` is
|
|||||||
* `options.bare`, boolean: if true, output without the [top-level function safety wrapper](#lexical-scope).
|
* `options.bare`, boolean: if true, output without the [top-level function safety wrapper](#lexical-scope).
|
||||||
* `options.header`, boolean: if true, output the `Generated by CoffeeScript` header.
|
* `options.header`, boolean: if true, output the `Generated by CoffeeScript` header.
|
||||||
* `options.transpile`, **object**: if set, this must be an object with the [options to pass to Babel](http://babeljs.io/docs/usage/api/#options). See [Transpilation](#transpilation).
|
* `options.transpile`, **object**: if set, this must be an object with the [options to pass to Babel](http://babeljs.io/docs/usage/api/#options). See [Transpilation](#transpilation).
|
||||||
|
* `options.ast`, boolean: if true, return an abstract syntax tree of the input CoffeeScript source code.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ The CoffeeScript literals for objects and arrays look very similar to their Java
|
|||||||
codeFor('objects_and_arrays', 'song.join(" … ")')
|
codeFor('objects_and_arrays', 'song.join(" … ")')
|
||||||
```
|
```
|
||||||
|
|
||||||
CoffeeScript has a shortcut for creating objects when you want the key to be set with a variable of the same name.
|
CoffeeScript has a shortcut for creating objects when you want the key to be set with a variable of the same name. Note that the `{` and `}` are required for this shorthand.
|
||||||
|
|
||||||
```
|
```
|
||||||
codeFor('objects_shorthand')
|
codeFor('objects_shorthand')
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ All together now:
|
|||||||
| `isnt` | `!==` |
|
| `isnt` | `!==` |
|
||||||
| `not` | `!` |
|
| `not` | `!` |
|
||||||
| `and` | `&&` |
|
| `and` | `&&` |
|
||||||
| `or` | `||` |
|
| `or` | <code>||</code> |
|
||||||
| `true`, `yes`, `on` | `true` |
|
| `true`, `yes`, `on` | `true` |
|
||||||
| `false`, `no`, `off`  | `false` |
|
| `false`, `no`, `off`  | `false` |
|
||||||
| `@`, `this` | `this` |
|
| `@`, `this` | `this` |
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* [CoffeeScript Google Group](https://groups.google.com/forum/#!forum/coffeescript)<br>
|
* [CoffeeScript Google Group](https://groups.google.com/forum/#!forum/coffeescript)<br>
|
||||||
If you’d like to ask a question, the mailing list is a good place to get help.
|
If you’d like to ask a question, the mailing list is a good place to get help.
|
||||||
* [The CoffeeScript Wiki](https://github.com/jashkenas/coffeescript/wiki)<br>
|
* [The CoffeeScript Wiki](https://github.com/jashkenas/coffeescript/wiki)<br>
|
||||||
If you’ve ever learned a neat CoffeeScript tip or trick, or ran into a gotcha — share it on the wiki. The wiki also serves as a directory of handy [text editor extensions](https://github.com/jashkenas/coffeescript/wiki/Text-editor-plugins), [web framework plugins](https://github.com/jashkenas/coffeescript/wiki/Web-framework-plugins), and general [CoffeeScript build tools](https://github.com/jashkenas/coffeescript/wiki/Build-tools).
|
If you’ve ever learned a neat CoffeeScript tip or trick, or ran into a gotcha — share it on the wiki.
|
||||||
* [The FAQ](https://github.com/jashkenas/coffeescript/wiki/FAQ)<br>
|
* [The FAQ](https://github.com/jashkenas/coffeescript/wiki/FAQ)<br>
|
||||||
Perhaps your CoffeeScript-related question has been asked before. Check the FAQ first.
|
Perhaps your CoffeeScript-related question has been asked before. Check the FAQ first.
|
||||||
* [JS2Coffee](http://js2.coffee/)<br>
|
* [JS2Coffee](http://js2.coffee/)<br>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
## `"text/coffeescript"` Script Tags
|
## `"text/coffeescript"` Script Tags
|
||||||
|
|
||||||
While it’s not recommended for serious use, CoffeeScripts may be included directly within the browser using `<script type="text/coffeescript">` tags. The source includes a compressed and minified version of the compiler ([Download current version here, 51k when gzipped](/v<%= majorVersion %>/browser-compiler/coffeescript.js)) as `docs/v<%= majorVersion %>/browser-compiler/coffeescript.js`. Include this file on a page with inline CoffeeScript tags, and it will compile and evaluate them in order.
|
While it’s not recommended for serious use, CoffeeScripts may be included directly within the browser using `<script type="text/coffeescript">` tags. The source includes a compressed and minified version of the compiler ([Download current version here, 77k when gzipped](/v<%= majorVersion %>/browser-compiler-legacy/coffeescript.js)) as `docs/v<%= majorVersion %>/browser-compiler-legacy/coffeescript.js`. Include this file on a page with inline CoffeeScript tags, and it will compile and evaluate them in order.
|
||||||
|
|
||||||
The usual caveats about CoffeeScript apply — your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the `window` object.
|
The usual caveats about CoffeeScript apply — your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the `window` object.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
### Transpilation
|
### Transpilation
|
||||||
|
|
||||||
CoffeeScript 2 generates JavaScript that uses the latest, modern syntax. The runtime or browsers where you want your code to run [might not support all of that syntax](#compatibility). In that case, we want to convert modern JavaScript into older JavaScript that will run in older versions of Node or older browsers; for example, `{ a } = obj` into `a = obj.a`. This is done via transpilers like [Babel](http://babeljs.io/), [Bublé](https://buble.surge.sh/) or [Traceur Compiler](https://github.com/google/traceur-compiler).
|
CoffeeScript 2 generates JavaScript that uses the latest, modern syntax. The runtime or browsers where you want your code to run [might not support all of that syntax](#compatibility). In that case, we want to convert modern JavaScript into older JavaScript that will run in older versions of Node or older browsers; for example, `{ a } = obj` into `a = obj.a`. This is done via transpilers like [Babel](http://babeljs.io/), [Bublé](https://buble.surge.sh/) or [Traceur Compiler](https://github.com/google/traceur-compiler). See [Build Tools](#build-tools).
|
||||||
|
|
||||||
#### Quickstart
|
#### Quickstart
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
<section id="switch">
|
<section id="switch">
|
||||||
<%= htmlFor('switch') %>
|
<%= htmlFor('switch') %>
|
||||||
</section>
|
</section>
|
||||||
<section id="try">
|
<section id="try-catch">
|
||||||
<%= htmlFor('try') %>
|
<%= htmlFor('try') %>
|
||||||
</section>
|
</section>
|
||||||
<section id="comparisons">
|
<section id="comparisons">
|
||||||
@@ -142,6 +142,24 @@
|
|||||||
<section id="scripts">
|
<section id="scripts">
|
||||||
<%= htmlFor('scripts') %>
|
<%= htmlFor('scripts') %>
|
||||||
</section>
|
</section>
|
||||||
|
<section id="integrations">
|
||||||
|
<%= htmlFor('integrations') %>
|
||||||
|
<section id="build-tools">
|
||||||
|
<%= htmlFor('integrations_build_tools') %>
|
||||||
|
</section>
|
||||||
|
<section id="code-editors">
|
||||||
|
<%= htmlFor('integrations_code_editors') %>
|
||||||
|
</section>
|
||||||
|
<section id="frameworks">
|
||||||
|
<%= htmlFor('integrations_frameworks') %>
|
||||||
|
</section>
|
||||||
|
<section id="linters-and-formatting">
|
||||||
|
<%= htmlFor('integrations_linters_and_formatting') %>
|
||||||
|
</section>
|
||||||
|
<section id="testing">
|
||||||
|
<%= htmlFor('integrations_testing') %>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
<section id="resources">
|
<section id="resources">
|
||||||
<%= htmlFor('resources') %>
|
<%= htmlFor('resources') %>
|
||||||
<section id="books">
|
<section id="books">
|
||||||
@@ -207,6 +225,27 @@
|
|||||||
</section>
|
</section>
|
||||||
<section id="changelog">
|
<section id="changelog">
|
||||||
<%= htmlFor('changelog') %>
|
<%= htmlFor('changelog') %>
|
||||||
|
<section id="2.7.0">
|
||||||
|
<%= htmlFor('changelog/2.7.0') %>
|
||||||
|
</section>
|
||||||
|
<section id="2.6.1">
|
||||||
|
<%= htmlFor('changelog/2.6.1') %>
|
||||||
|
</section>
|
||||||
|
<section id="2.6.0">
|
||||||
|
<%= htmlFor('changelog/2.6.0') %>
|
||||||
|
</section>
|
||||||
|
<section id="2.5.1">
|
||||||
|
<%= htmlFor('changelog/2.5.1') %>
|
||||||
|
</section>
|
||||||
|
<section id="2.5.0">
|
||||||
|
<%= htmlFor('changelog/2.5.0') %>
|
||||||
|
</section>
|
||||||
|
<section id="2.4.1">
|
||||||
|
<%= htmlFor('changelog/2.4.1') %>
|
||||||
|
</section>
|
||||||
|
<section id="2.4.0">
|
||||||
|
<%= htmlFor('changelog/2.4.0') %>
|
||||||
|
</section>
|
||||||
<section id="2.3.2">
|
<section id="2.3.2">
|
||||||
<%= htmlFor('changelog/2.3.2') %>
|
<%= htmlFor('changelog/2.3.2') %>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
.CodeMirror pre,
|
.CodeMirror pre,
|
||||||
|
.CodeMirror pre.CodeMirror-line,
|
||||||
pre.placeholder-code {
|
pre.placeholder-code {
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ window.gtag 'config', window.GA_TRACKING_ID
|
|||||||
|
|
||||||
# Initialize the CoffeeScript docs interactions
|
# Initialize the CoffeeScript docs interactions
|
||||||
$(document).ready ->
|
$(document).ready ->
|
||||||
|
CoffeeScript.patchStackTrace()
|
||||||
|
|
||||||
# Format dates for the user’s locale, e.g. 'December 24, 2009' or '24 décembre 2009'
|
# Format dates for the user’s locale, e.g. 'December 24, 2009' or '24 décembre 2009'
|
||||||
$('time').each (index, el) ->
|
$('time').each (index, el) ->
|
||||||
date = el.dateTime or $(el).text()
|
date = el.dateTime or $(el).text()
|
||||||
@@ -105,11 +107,17 @@ $(document).ready ->
|
|||||||
if window.localStorage?
|
if window.localStorage?
|
||||||
window.localStorage.setItem 'tryCoffeeScriptCode', coffee
|
window.localStorage.setItem 'tryCoffeeScriptCode', coffee
|
||||||
catch exception
|
catch exception
|
||||||
output = CoffeeScript.compile coffee, bare: yes
|
|
||||||
|
js = CoffeeScript.compile coffee, bare: yes, inlineMap: true
|
||||||
|
# Inline map is added to adjust stack trace line numbers but we strip it from the displayed JS for visual clarity.
|
||||||
|
output = js.replace /(\n\/\/# [^\n]*){2}$/, ""
|
||||||
lastCompilationElapsedTime = Math.max(200, Date.now() - lastCompilationStartTime)
|
lastCompilationElapsedTime = Math.max(200, Date.now() - lastCompilationStartTime)
|
||||||
catch exception
|
catch exception
|
||||||
output = "#{exception}"
|
output = "#{exception}"
|
||||||
|
|
||||||
|
editors[index + 1].js = js
|
||||||
editors[index + 1].setValue output
|
editors[index + 1].setValue output
|
||||||
|
|
||||||
gtag 'event', 'edit_code',
|
gtag 'event', 'edit_code',
|
||||||
event_category: 'engagement'
|
event_category: 'engagement'
|
||||||
event_label: $textarea.closest('[data-example]').data('example')
|
event_label: $textarea.closest('[data-example]').data('example')
|
||||||
@@ -148,8 +156,8 @@ $(document).ready ->
|
|||||||
$('[data-action="run-code-example"]').click ->
|
$('[data-action="run-code-example"]').click ->
|
||||||
run = $(@).data 'run'
|
run = $(@).data 'run'
|
||||||
index = $("##{$(@).data('example')}-js").data 'index'
|
index = $("##{$(@).data('example')}-js").data 'index'
|
||||||
js = if editors[index]?
|
js = if editors[index]?.js
|
||||||
editors[index].getValue()
|
editors[index].js
|
||||||
else
|
else
|
||||||
$(textareas[index]).val()
|
$(textareas[index]).val()
|
||||||
js = "#{js}\nalert(#{unescape run});" unless run is yes
|
js = "#{js}\nalert(#{unescape run});" unless run is yes
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<div class="navbar-nav mr-auto d-none d-lg-flex">
|
<div class="navbar-nav mr-auto d-none d-lg-flex">
|
||||||
<a href="#try" id="try-link" class="nav-item nav-link" data-toggle="try">Try CoffeeScript</a>
|
<a href="#try" id="try-link" class="nav-item nav-link" data-toggle="try">Try CoffeeScript</a>
|
||||||
<a href="#language" class="nav-item nav-link" data-close="try">Language Reference</a>
|
<a href="#language" class="nav-item nav-link" data-close="try">Language Reference</a>
|
||||||
|
<a href="#integrations" class="nav-item nav-link" data-close="try">Integrations</a>
|
||||||
<a href="#resources" class="nav-item nav-link" data-close="try">Resources</a>
|
<a href="#resources" class="nav-item nav-link" data-close="try">Resources</a>
|
||||||
<a href="https://github.com/jashkenas/coffeescript/" class="nav-item nav-link" data-close="try">GitHub
|
<a href="https://github.com/jashkenas/coffeescript/" class="nav-item nav-link" data-close="try">GitHub
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT" crossorigin="anonymous"></script>
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/combine/npm/codemirror@5.37.0/lib/codemirror.js,npm/codemirror@5.37.0/mode/coffeescript/coffeescript.js,npm/codemirror@5.37.0/addon/lint/coffeescript-lint.js,npm/codemirror@5.37.0/mode/javascript/javascript.js"></script>
|
<script src="https://cdn.jsdelivr.net/combine/npm/codemirror@5.37.0/lib/codemirror.js,npm/codemirror@5.37.0/mode/coffeescript/coffeescript.js,npm/codemirror@5.37.0/addon/lint/coffeescript-lint.js,npm/codemirror@5.37.0/mode/javascript/javascript.js"></script>
|
||||||
|
|
||||||
<script src="browser-compiler/coffeescript.js"></script>
|
<script nomodule src="./browser-compiler-legacy/coffeescript.js"></script>
|
||||||
<script>
|
<script nomodule>
|
||||||
<%= includeScript('docs.coffee') %>
|
<%= includeScript('docs.coffee') %>
|
||||||
</script>
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import CoffeeScript from './browser-compiler-modern/coffeescript.js';
|
||||||
|
<%= includeScript('docs.coffee') %>
|
||||||
|
</script>
|
||||||
|
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-106156830-1"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-106156830-1"></script>
|
||||||
|
|||||||
@@ -36,7 +36,8 @@
|
|||||||
<a href="#async-functions" class="nav-link" data-action="sidebar-nav">Async Functions</a>
|
<a href="#async-functions" class="nav-link" data-action="sidebar-nav">Async Functions</a>
|
||||||
<a href="#classes" class="nav-link" data-action="sidebar-nav">Classes</a>
|
<a href="#classes" class="nav-link" data-action="sidebar-nav">Classes</a>
|
||||||
<a href="#prototypal-inheritance" class="nav-link" data-action="sidebar-nav">Prototypal Inheritance</a>
|
<a href="#prototypal-inheritance" class="nav-link" data-action="sidebar-nav">Prototypal Inheritance</a>
|
||||||
<a href="#switch" class="nav-link" data-action="sidebar-nav">Switch and Try/Catch</a>
|
<a href="#switch" class="nav-link" data-action="sidebar-nav">Switch/When/Else</a>
|
||||||
|
<a href="#try-catch" class="nav-link" data-action="sidebar-nav">Try/Catch/Finally</a>
|
||||||
<a href="#comparisons" class="nav-link" data-action="sidebar-nav">Chained Comparisons</a>
|
<a href="#comparisons" class="nav-link" data-action="sidebar-nav">Chained Comparisons</a>
|
||||||
<a href="#regexes" class="nav-link" data-action="sidebar-nav">Block Regular Expressions</a>
|
<a href="#regexes" class="nav-link" data-action="sidebar-nav">Block Regular Expressions</a>
|
||||||
<a href="#tagged-template-literals" class="nav-link" data-action="sidebar-nav">Tagged Template Literals</a>
|
<a href="#tagged-template-literals" class="nav-link" data-action="sidebar-nav">Tagged Template Literals</a>
|
||||||
@@ -49,7 +50,14 @@
|
|||||||
<a href="#source-maps" class="nav-link" data-action="sidebar-nav">Source Maps</a>
|
<a href="#source-maps" class="nav-link" data-action="sidebar-nav">Source Maps</a>
|
||||||
<a href="#cake" class="nav-link" data-action="sidebar-nav">Cake, and Cakefiles</a>
|
<a href="#cake" class="nav-link" data-action="sidebar-nav">Cake, and Cakefiles</a>
|
||||||
<a href="#scripts" class="nav-link" data-action="sidebar-nav"><code>"text/coffeescript"</code> Script Tags</a>
|
<a href="#scripts" class="nav-link" data-action="sidebar-nav"><code>"text/coffeescript"</code> Script Tags</a>
|
||||||
<a href="test.html" class="nav-link" data-action="sidebar-nav">Browser-Based Tests</a>
|
<a href="#integrations" class="nav-link" data-action="sidebar-nav">Integrations</a>
|
||||||
|
<nav class="nav flex-column">
|
||||||
|
<a href="#build-tools" class="nav-link" data-action="sidebar-nav">Build Tools</a>
|
||||||
|
<a href="#code-editors" class="nav-link" data-action="sidebar-nav">Code Editors</a>
|
||||||
|
<a href="#frameworks" class="nav-link" data-action="sidebar-nav">Frameworks</a>
|
||||||
|
<a href="#linters-and-formatting" class="nav-link" data-action="sidebar-nav">Linters and Formatting</a>
|
||||||
|
<a href="#testing" class="nav-link" data-action="sidebar-nav">Testing</a>
|
||||||
|
</nav>
|
||||||
<a href="#resources" class="nav-link" data-action="sidebar-nav">Resources</a>
|
<a href="#resources" class="nav-link" data-action="sidebar-nav">Resources</a>
|
||||||
<nav class="nav flex-column">
|
<nav class="nav flex-column">
|
||||||
<a href="#books" class="nav-link" data-action="sidebar-nav">Books</a>
|
<a href="#books" class="nav-link" data-action="sidebar-nav">Books</a>
|
||||||
@@ -79,6 +87,7 @@
|
|||||||
<a href="#breaking-changes-argument-parsing-and-shebang-lines" class="nav-link" data-action="sidebar-nav">Argument Parsing and <code>#!</code> Lines</a>
|
<a href="#breaking-changes-argument-parsing-and-shebang-lines" class="nav-link" data-action="sidebar-nav">Argument Parsing and <code>#!</code> Lines</a>
|
||||||
</nav>
|
</nav>
|
||||||
<a href="#changelog" class="nav-link" data-action="sidebar-nav">Changelog</a>
|
<a href="#changelog" class="nav-link" data-action="sidebar-nav">Changelog</a>
|
||||||
|
<a href="test.html" class="nav-link" data-action="sidebar-nav">Browser-Based Tests</a>
|
||||||
<a href="/v1/" class="nav-link" data-action="sidebar-nav">Version 1.x Documentation</a>
|
<a href="/v1/" class="nav-link" data-action="sidebar-nav">Version 1.x Documentation</a>
|
||||||
</nav>
|
</nav>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
|
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
|
||||||
<!-- The CoffeeScript logo font is Google’s Galada -->
|
<!-- The CoffeeScript logo font is Google’s Galada -->
|
||||||
<link href="https://fonts.googleapis.com/css?family=Alegreya+Sans:400,800|Lato:300,300i,400,700|Roboto+Mono:400,400i" rel="stylesheet" crossorigin="anonymous">
|
<link href="https://fonts.googleapis.com/css?family=Alegreya+Sans:400,800|Lato:300,300i,400,700|Roboto+Mono:400,400i" rel="stylesheet" crossorigin="anonymous">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/codemirror@5.37.0/lib/codemirror.css" rel="stylesheet" crossorigin="anonymous">
|
<link href="https://cdn.jsdelivr.net/npm/codemirror@5.62.3/lib/codemirror.css" rel="stylesheet" crossorigin="anonymous">
|
||||||
<style>
|
<style>
|
||||||
<%= include('code.css') %>
|
<%= include('code.css') %>
|
||||||
<%= include('docs.css') %>
|
<%= include('docs.css') %>
|
||||||
|
|||||||
@@ -3,7 +3,12 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||||
<title>CoffeeScript Test Suite</title>
|
<title>CoffeeScript Test Suite</title>
|
||||||
<script src="browser-compiler/coffeescript.js"></script>
|
<script nomodule src="browser-compiler-legacy/coffeescript.js"></script>
|
||||||
|
<script type="module">
|
||||||
|
import CoffeeScript from './browser-compiler-modern/coffeescript.js';
|
||||||
|
window.CoffeeScript = CoffeeScript;
|
||||||
|
window.addEventListener('DOMContentLoaded', CoffeeScript.runScripts, false);
|
||||||
|
</script>
|
||||||
<script src="https://cdn.jsdelivr.net/underscorejs/1.8.3/underscore-min.js"></script>
|
<script src="https://cdn.jsdelivr.net/underscorejs/1.8.3/underscore-min.js"></script>
|
||||||
<style>
|
<style>
|
||||||
body, pre {
|
body, pre {
|
||||||
@@ -39,15 +44,16 @@
|
|||||||
<script type="text/coffeescript">
|
<script type="text/coffeescript">
|
||||||
@testingBrowser = yes
|
@testingBrowser = yes
|
||||||
@global = window
|
@global = window
|
||||||
bold = red = green = reset = ''
|
@bold = @red = @green = @reset = ''
|
||||||
stdout = document.getElementById 'stdout'
|
stdout = document.getElementById 'stdout'
|
||||||
start = new Date
|
start = new Date
|
||||||
@currentFile = ''
|
@currentFile = ''
|
||||||
@passedTests = failedTests = total = done = 0
|
@passedTests = failedTests = total = done = 0
|
||||||
|
|
||||||
say = (msg, className) ->
|
say = (msg, className, id) ->
|
||||||
div = document.createElement 'div'
|
div = document.createElement 'div'
|
||||||
div.className = className if className?
|
div.className = className if className?
|
||||||
|
div.id = id if id?
|
||||||
div.appendChild document.createTextNode msg
|
div.appendChild document.createTextNode msg
|
||||||
stdout.appendChild div
|
stdout.appendChild div
|
||||||
msg
|
msg
|
||||||
@@ -132,7 +138,7 @@ done = ->
|
|||||||
sec = (new Date - start) / 1000
|
sec = (new Date - start) / 1000
|
||||||
msg = "passed #{passedTests} tests in #{sec.toFixed 2} seconds"
|
msg = "passed #{passedTests} tests in #{sec.toFixed 2} seconds"
|
||||||
msg = "failed #{total - passedTests} tests and #{msg}" unless yay
|
msg = "failed #{total - passedTests} tests and #{msg}" unless yay
|
||||||
say msg, (if yay then 'good' else 'bad')
|
say msg, (if yay then 'good' else 'bad'), 'result'
|
||||||
|
|
||||||
gtag 'event', 'tests_complete',
|
gtag 'event', 'tests_complete',
|
||||||
event_category: 'tests'
|
event_category: 'tests'
|
||||||
|
|||||||
8
lib/coffeescript-browser-compiler-legacy/coffeescript.js
Normal file
8
lib/coffeescript-browser-compiler-legacy/coffeescript.js
Normal file
File diff suppressed because one or more lines are too long
8
lib/coffeescript-browser-compiler-modern/coffeescript.js
Normal file
8
lib/coffeescript-browser-compiler-modern/coffeescript.js
Normal file
File diff suppressed because one or more lines are too long
@@ -1,10 +1,10 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
// This **Browser** compatibility layer extends core CoffeeScript functions
|
// This **Browser** compatibility layer extends core CoffeeScript functions
|
||||||
// to make things work smoothly when compiling code directly in the browser.
|
// to make things work smoothly when compiling code directly in the browser.
|
||||||
// We add support for loading remote Coffee scripts via **XHR**, and
|
// We add support for loading remote Coffee scripts via **XHR**, and
|
||||||
// `text/coffeescript` script tags, source maps via data-URLs, and so on.
|
// `text/coffeescript` script tags, source maps via data-URLs, and so on.
|
||||||
var CoffeeScript, compile, runScripts,
|
var CoffeeScript, compile,
|
||||||
indexOf = [].indexOf;
|
indexOf = [].indexOf;
|
||||||
|
|
||||||
CoffeeScript = require('./coffeescript');
|
CoffeeScript = require('./coffeescript');
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
// Activate CoffeeScript in the browser by having it compile and evaluate
|
// Activate CoffeeScript in the browser by having it compile and evaluate
|
||||||
// all script tags with a content-type of `text/coffeescript`.
|
// all script tags with a content-type of `text/coffeescript`.
|
||||||
// This happens on page load.
|
// This happens on page load.
|
||||||
runScripts = function() {
|
CoffeeScript.runScripts = function() {
|
||||||
var coffees, coffeetypes, execute, i, index, j, len, s, script, scripts;
|
var coffees, coffeetypes, execute, i, index, j, len, s, script, scripts;
|
||||||
scripts = window.document.getElementsByTagName('script');
|
scripts = window.document.getElementsByTagName('script');
|
||||||
coffeetypes = ['text/coffeescript', 'text/literate-coffeescript'];
|
coffeetypes = ['text/coffeescript', 'text/literate-coffeescript'];
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
// filename; otherwise use `coffeescript`, or `coffeescript1` etc.,
|
// filename; otherwise use `coffeescript`, or `coffeescript1` etc.,
|
||||||
// leaving the first one unnumbered for the common case that there’s
|
// leaving the first one unnumbered for the common case that there’s
|
||||||
// only one CoffeeScript script block to parse.
|
// only one CoffeeScript script block to parse.
|
||||||
options.filename = script.id && script.id !== '' ? script.id : `coffeescript${(i !== 0 ? i : '')}`;
|
options.filename = script.id && script.id !== '' ? script.id : `coffeescript${i !== 0 ? i : ''}`;
|
||||||
options.sourceFiles = ['embedded'];
|
options.sourceFiles = ['embedded'];
|
||||||
return coffees[i] = [script.innerHTML, options];
|
return coffees[i] = [script.innerHTML, options];
|
||||||
}
|
}
|
||||||
@@ -136,10 +136,16 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Listen for window load, both in decent browsers and in IE.
|
// Listen for window load, both in decent browsers and in IE.
|
||||||
if (window.addEventListener) {
|
// Only attach this event handler on startup for the
|
||||||
window.addEventListener('DOMContentLoaded', runScripts, false);
|
// non-ES module version of the browser compiler, to preserve
|
||||||
} else {
|
// backward compatibility while letting the ES module version
|
||||||
window.attachEvent('onload', runScripts);
|
// be importable without side effects.
|
||||||
|
if (this === window) {
|
||||||
|
if (window.addEventListener) {
|
||||||
|
window.addEventListener('DOMContentLoaded', CoffeeScript.runScripts, false);
|
||||||
|
} else {
|
||||||
|
window.attachEvent('onload', CoffeeScript.runScripts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
// `cake` is a simplified version of [Make](http://www.gnu.org/software/make/)
|
// `cake` is a simplified version of [Make](http://www.gnu.org/software/make/)
|
||||||
// ([Rake](http://rake.rubyforge.org/), [Jake](https://github.com/280north/jake))
|
// ([Rake](http://rake.rubyforge.org/), [Jake](https://github.com/280north/jake))
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
// CoffeeScript can be used both on the server, as a command-line compiler based
|
// CoffeeScript can be used both on the server, as a command-line compiler based
|
||||||
// on Node.js/V8, or to run CoffeeScript directly in the browser. This module
|
// on Node.js/V8, or to run CoffeeScript directly in the browser. This module
|
||||||
// contains the main entry functions for tokenizing, parsing, and compiling
|
// contains the main entry functions for tokenizing, parsing, and compiling
|
||||||
// source CoffeeScript into JavaScript.
|
// source CoffeeScript into JavaScript.
|
||||||
var FILE_EXTENSIONS, Lexer, SourceMap, base64encode, checkShebangLine, compile, formatSourcePosition, getSourceMap, helpers, lexer, packageJson, parser, sourceMaps, sources, withPrettyErrors,
|
var FILE_EXTENSIONS, Lexer, SourceMap, base64encode, checkShebangLine, compile, getSourceMap, helpers, lexer, packageJson, parser, registerCompiled, withPrettyErrors;
|
||||||
indexOf = [].indexOf;
|
|
||||||
|
|
||||||
({Lexer} = require('./lexer'));
|
({Lexer} = require('./lexer'));
|
||||||
|
|
||||||
@@ -27,6 +26,13 @@
|
|||||||
// Expose helpers for testing.
|
// Expose helpers for testing.
|
||||||
exports.helpers = helpers;
|
exports.helpers = helpers;
|
||||||
|
|
||||||
|
({getSourceMap, registerCompiled} = SourceMap);
|
||||||
|
|
||||||
|
// This is exported to enable an external module to implement caching of
|
||||||
|
// sourcemaps. This is used only when `patchStackTrace` has been called to adjust
|
||||||
|
// stack traces for files with cached source maps.
|
||||||
|
exports.registerCompiled = registerCompiled;
|
||||||
|
|
||||||
// Function that allows for btoa in both nodejs and the browser.
|
// Function that allows for btoa in both nodejs and the browser.
|
||||||
base64encode = function(src) {
|
base64encode = function(src) {
|
||||||
switch (false) {
|
switch (false) {
|
||||||
@@ -62,18 +68,6 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// For each compiled file, save its source in memory in case we need to
|
|
||||||
// recompile it later. We might need to recompile if the first compilation
|
|
||||||
// didn’t create a source map (faster) but something went wrong and we need
|
|
||||||
// a stack trace. Assuming that most of the time, code isn’t throwing
|
|
||||||
// exceptions, it’s probably more efficient to compile twice only when we
|
|
||||||
// need a stack trace, rather than always generating a source map even when
|
|
||||||
// it’s not likely to be used. Save in form of `filename`: [`(source)`]
|
|
||||||
sources = {};
|
|
||||||
|
|
||||||
// Also save source maps if generated, in form of `(source)`: [`(source map)`].
|
|
||||||
sourceMaps = {};
|
|
||||||
|
|
||||||
// Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.
|
// Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.
|
||||||
|
|
||||||
// If `options.sourceMap` is specified, then `options.filename` must also be
|
// If `options.sourceMap` is specified, then `options.filename` must also be
|
||||||
@@ -85,21 +79,14 @@
|
|||||||
// object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for
|
// object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for
|
||||||
// doing programmatic lookups.
|
// doing programmatic lookups.
|
||||||
exports.compile = compile = withPrettyErrors(function(code, options = {}) {
|
exports.compile = compile = withPrettyErrors(function(code, options = {}) {
|
||||||
var currentColumn, currentLine, encoded, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, transpiler, transpilerOptions, transpilerOutput, v3SourceMap;
|
var ast, currentColumn, currentLine, encoded, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, newLines, nodes, range, ref, sourceCodeLastLine, sourceCodeNumberOfLines, sourceMapDataURI, sourceURL, token, tokens, transpiler, transpilerOptions, transpilerOutput, v3SourceMap;
|
||||||
// Clone `options`, to avoid mutating the `options` object passed in.
|
// Clone `options`, to avoid mutating the `options` object passed in.
|
||||||
options = Object.assign({}, options);
|
options = Object.assign({}, options);
|
||||||
// Always generate a source map if no filename is passed in, since without a
|
|
||||||
// a filename we have no way to retrieve this source later in the event that
|
|
||||||
// we need to recompile it to get a source map for `prepareStackTrace`.
|
|
||||||
generateSourceMap = options.sourceMap || options.inlineMap || (options.filename == null);
|
generateSourceMap = options.sourceMap || options.inlineMap || (options.filename == null);
|
||||||
filename = options.filename || '<anonymous>';
|
filename = options.filename || helpers.anonymousFileName();
|
||||||
checkShebangLine(filename, code);
|
checkShebangLine(filename, code);
|
||||||
if (sources[filename] == null) {
|
|
||||||
sources[filename] = [];
|
|
||||||
}
|
|
||||||
sources[filename].push(code);
|
|
||||||
if (generateSourceMap) {
|
if (generateSourceMap) {
|
||||||
map = new SourceMap;
|
map = new SourceMap();
|
||||||
}
|
}
|
||||||
tokens = lexer.tokenize(code, options);
|
tokens = lexer.tokenize(code, options);
|
||||||
// Pass a list of referenced variables, so that generated variables won’t get
|
// Pass a list of referenced variables, so that generated variables won’t get
|
||||||
@@ -125,7 +112,31 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fragments = parser.parse(tokens).compileToFragments(options);
|
nodes = parser.parse(tokens);
|
||||||
|
// If all that was requested was a POJO representation of the nodes, e.g.
|
||||||
|
// the abstract syntax tree (AST), we can stop now and just return that
|
||||||
|
// (after fixing the location data for the root/`File`»`Program` node,
|
||||||
|
// which might’ve gotten misaligned from the original source due to the
|
||||||
|
// `clean` function in the lexer).
|
||||||
|
if (options.ast) {
|
||||||
|
nodes.allCommentTokens = helpers.extractAllCommentTokens(tokens);
|
||||||
|
sourceCodeNumberOfLines = (code.match(/\r?\n/g) || '').length + 1;
|
||||||
|
sourceCodeLastLine = /.*$/.exec(code)[0];
|
||||||
|
ast = nodes.ast(options);
|
||||||
|
range = [0, code.length];
|
||||||
|
ast.start = ast.program.start = range[0];
|
||||||
|
ast.end = ast.program.end = range[1];
|
||||||
|
ast.range = ast.program.range = range;
|
||||||
|
ast.loc.start = ast.program.loc.start = {
|
||||||
|
line: 1,
|
||||||
|
column: 0
|
||||||
|
};
|
||||||
|
ast.loc.end.line = ast.program.loc.end.line = sourceCodeNumberOfLines;
|
||||||
|
ast.loc.end.column = ast.program.loc.end.column = sourceCodeLastLine.length;
|
||||||
|
ast.tokens = tokens;
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
|
fragments = nodes.compileToFragments(options);
|
||||||
currentLine = 0;
|
currentLine = 0;
|
||||||
if (options.header) {
|
if (options.header) {
|
||||||
currentLine += 1;
|
currentLine += 1;
|
||||||
@@ -162,10 +173,6 @@
|
|||||||
}
|
}
|
||||||
if (generateSourceMap) {
|
if (generateSourceMap) {
|
||||||
v3SourceMap = map.generate(options, code);
|
v3SourceMap = map.generate(options, code);
|
||||||
if (sourceMaps[filename] == null) {
|
|
||||||
sourceMaps[filename] = [];
|
|
||||||
}
|
|
||||||
sourceMaps[filename].push(map);
|
|
||||||
}
|
}
|
||||||
if (options.transpile) {
|
if (options.transpile) {
|
||||||
if (typeof options.transpile !== 'object') {
|
if (typeof options.transpile !== 'object') {
|
||||||
@@ -193,9 +200,10 @@
|
|||||||
if (options.inlineMap) {
|
if (options.inlineMap) {
|
||||||
encoded = base64encode(JSON.stringify(v3SourceMap));
|
encoded = base64encode(JSON.stringify(v3SourceMap));
|
||||||
sourceMapDataURI = `//# sourceMappingURL=data:application/json;base64,${encoded}`;
|
sourceMapDataURI = `//# sourceMappingURL=data:application/json;base64,${encoded}`;
|
||||||
sourceURL = `//# sourceURL=${(ref1 = options.filename) != null ? ref1 : 'coffeescript'}`;
|
sourceURL = `//# sourceURL=${filename}`;
|
||||||
js = `${js}\n${sourceMapDataURI}\n${sourceURL}`;
|
js = `${js}\n${sourceMapDataURI}\n${sourceURL}`;
|
||||||
}
|
}
|
||||||
|
registerCompiled(filename, code, map);
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
return {
|
return {
|
||||||
js,
|
js,
|
||||||
@@ -217,10 +225,9 @@
|
|||||||
// or traverse it by using `.traverseChildren()` with a callback.
|
// or traverse it by using `.traverseChildren()` with a callback.
|
||||||
exports.nodes = withPrettyErrors(function(source, options) {
|
exports.nodes = withPrettyErrors(function(source, options) {
|
||||||
if (typeof source === 'string') {
|
if (typeof source === 'string') {
|
||||||
return parser.parse(lexer.tokenize(source, options));
|
source = lexer.tokenize(source, options);
|
||||||
} else {
|
|
||||||
return parser.parse(source);
|
|
||||||
}
|
}
|
||||||
|
return parser.parse(source);
|
||||||
});
|
});
|
||||||
|
|
||||||
// This file used to export these methods; leave stubs that throw warnings
|
// This file used to export these methods; leave stubs that throw warnings
|
||||||
@@ -233,12 +240,18 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Instantiate a Lexer for our use here.
|
// Instantiate a Lexer for our use here.
|
||||||
lexer = new Lexer;
|
lexer = new Lexer();
|
||||||
|
|
||||||
// The real Lexer produces a generic stream of tokens. This object provides a
|
// The real Lexer produces a generic stream of tokens. This object provides a
|
||||||
// thin wrapper around it, compatible with the Jison API. We can then pass it
|
// thin wrapper around it, compatible with the Jison API. We can then pass it
|
||||||
// directly as a “Jison lexer.”
|
// directly as a “Jison lexer.”
|
||||||
parser.lexer = {
|
parser.lexer = {
|
||||||
|
yylloc: {
|
||||||
|
range: []
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
ranges: true
|
||||||
|
},
|
||||||
lex: function() {
|
lex: function() {
|
||||||
var tag, token;
|
var tag, token;
|
||||||
token = parser.tokens[this.pos++];
|
token = parser.tokens[this.pos++];
|
||||||
@@ -290,110 +303,58 @@
|
|||||||
return helpers.throwSyntaxError(`unexpected ${errorText}`, errorLoc);
|
return helpers.throwSyntaxError(`unexpected ${errorText}`, errorLoc);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Based on http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js
|
exports.patchStackTrace = function() {
|
||||||
// Modified to handle sourceMap
|
var formatSourcePosition, getSourceMapping;
|
||||||
formatSourcePosition = function(frame, getSourceMapping) {
|
// Based on http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js
|
||||||
var as, column, fileLocation, filename, functionName, isConstructor, isMethodCall, line, methodName, source, tp, typeName;
|
// Modified to handle sourceMap
|
||||||
filename = void 0;
|
formatSourcePosition = function(frame, getSourceMapping) {
|
||||||
fileLocation = '';
|
var as, column, fileLocation, filename, functionName, isConstructor, isMethodCall, line, methodName, source, tp, typeName;
|
||||||
if (frame.isNative()) {
|
filename = void 0;
|
||||||
fileLocation = "native";
|
fileLocation = '';
|
||||||
} else {
|
if (frame.isNative()) {
|
||||||
if (frame.isEval()) {
|
fileLocation = "native";
|
||||||
filename = frame.getScriptNameOrSourceURL();
|
|
||||||
if (!filename) {
|
|
||||||
fileLocation = `${frame.getEvalOrigin()}, `;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
filename = frame.getFileName();
|
if (frame.isEval()) {
|
||||||
|
filename = frame.getScriptNameOrSourceURL();
|
||||||
|
if (!filename) {
|
||||||
|
fileLocation = `${frame.getEvalOrigin()}, `;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filename = frame.getFileName();
|
||||||
|
}
|
||||||
|
filename || (filename = "<anonymous>");
|
||||||
|
line = frame.getLineNumber();
|
||||||
|
column = frame.getColumnNumber();
|
||||||
|
// Check for a sourceMap position
|
||||||
|
source = getSourceMapping(filename, line, column);
|
||||||
|
fileLocation = source ? `${filename}:${source[0]}:${source[1]}` : `${filename}:${line}:${column}`;
|
||||||
}
|
}
|
||||||
filename || (filename = "<anonymous>");
|
functionName = frame.getFunctionName();
|
||||||
line = frame.getLineNumber();
|
isConstructor = frame.isConstructor();
|
||||||
column = frame.getColumnNumber();
|
isMethodCall = !(frame.isToplevel() || isConstructor);
|
||||||
// Check for a sourceMap position
|
if (isMethodCall) {
|
||||||
source = getSourceMapping(filename, line, column);
|
methodName = frame.getMethodName();
|
||||||
fileLocation = source ? `${filename}:${source[0]}:${source[1]}` : `${filename}:${line}:${column}`;
|
typeName = frame.getTypeName();
|
||||||
}
|
if (functionName) {
|
||||||
functionName = frame.getFunctionName();
|
tp = as = '';
|
||||||
isConstructor = frame.isConstructor();
|
if (typeName && functionName.indexOf(typeName)) {
|
||||||
isMethodCall = !(frame.isToplevel() || isConstructor);
|
tp = `${typeName}.`;
|
||||||
if (isMethodCall) {
|
}
|
||||||
methodName = frame.getMethodName();
|
if (methodName && functionName.indexOf(`.${methodName}`) !== functionName.length - methodName.length - 1) {
|
||||||
typeName = frame.getTypeName();
|
as = ` [as ${methodName}]`;
|
||||||
if (functionName) {
|
}
|
||||||
tp = as = '';
|
return `${tp}${functionName}${as} (${fileLocation})`;
|
||||||
if (typeName && functionName.indexOf(typeName)) {
|
} else {
|
||||||
tp = `${typeName}.`;
|
return `${typeName}.${methodName || '<anonymous>'} (${fileLocation})`;
|
||||||
}
|
}
|
||||||
if (methodName && functionName.indexOf(`.${methodName}`) !== functionName.length - methodName.length - 1) {
|
} else if (isConstructor) {
|
||||||
as = ` [as ${methodName}]`;
|
return `new ${functionName || '<anonymous>'} (${fileLocation})`;
|
||||||
}
|
} else if (functionName) {
|
||||||
return `${tp}${functionName}${as} (${fileLocation})`;
|
return `${functionName} (${fileLocation})`;
|
||||||
} else {
|
} else {
|
||||||
return `${typeName}.${methodName || '<anonymous>'} (${fileLocation})`;
|
return fileLocation;
|
||||||
}
|
}
|
||||||
} else if (isConstructor) {
|
};
|
||||||
return `new ${functionName || '<anonymous>'} (${fileLocation})`;
|
|
||||||
} else if (functionName) {
|
|
||||||
return `${functionName} (${fileLocation})`;
|
|
||||||
} else {
|
|
||||||
return fileLocation;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
getSourceMap = function(filename, line, column) {
|
|
||||||
var answer, i, map, ref, ref1, sourceLocation;
|
|
||||||
if (!(filename === '<anonymous>' || (ref = filename.slice(filename.lastIndexOf('.')), indexOf.call(FILE_EXTENSIONS, ref) >= 0))) {
|
|
||||||
// Skip files that we didn’t compile, like Node system files that appear in
|
|
||||||
// the stack trace, as they never have source maps.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (filename !== '<anonymous>' && (sourceMaps[filename] != null)) {
|
|
||||||
return sourceMaps[filename][sourceMaps[filename].length - 1];
|
|
||||||
// CoffeeScript compiled in a browser or via `CoffeeScript.compile` or `.run`
|
|
||||||
// may get compiled with `options.filename` that’s missing, which becomes
|
|
||||||
// `<anonymous>`; but the runtime might request the stack trace with the
|
|
||||||
// filename of the script file. See if we have a source map cached under
|
|
||||||
// `<anonymous>` that matches the error.
|
|
||||||
} else if (sourceMaps['<anonymous>'] != null) {
|
|
||||||
ref1 = sourceMaps['<anonymous>'];
|
|
||||||
// Work backwards from the most recent anonymous source maps, until we find
|
|
||||||
// one that works. This isn’t foolproof; there is a chance that multiple
|
|
||||||
// source maps will have line/column pairs that match. But we have no other
|
|
||||||
// way to match them. `frame.getFunction().toString()` doesn’t always work,
|
|
||||||
// and it’s not foolproof either.
|
|
||||||
for (i = ref1.length - 1; i >= 0; i += -1) {
|
|
||||||
map = ref1[i];
|
|
||||||
sourceLocation = map.sourceLocation([line - 1, column - 1]);
|
|
||||||
if (((sourceLocation != null ? sourceLocation[0] : void 0) != null) && (sourceLocation[1] != null)) {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If all else fails, recompile this source to get a source map. We need the
|
|
||||||
// previous section (for `<anonymous>`) despite this option, because after it
|
|
||||||
// gets compiled we will still need to look it up from
|
|
||||||
// `sourceMaps['<anonymous>']` in order to find and return it. That’s why we
|
|
||||||
// start searching from the end in the previous block, because most of the
|
|
||||||
// time the source map we want is the last one.
|
|
||||||
if (sources[filename] != null) {
|
|
||||||
answer = compile(sources[filename][sources[filename].length - 1], {
|
|
||||||
filename: filename,
|
|
||||||
sourceMap: true,
|
|
||||||
literate: helpers.isLiterate(filename)
|
|
||||||
});
|
|
||||||
return answer.sourceMap;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Based on [michaelficarra/CoffeeScriptRedux](http://goo.gl/ZTx1p)
|
|
||||||
// NodeJS / V8 have no support for transforming positions in stack traces using
|
|
||||||
// sourceMap, so we must monkey-patch Error to display CoffeeScript source
|
|
||||||
// positions.
|
|
||||||
Error.prepareStackTrace = function(err, stack) {
|
|
||||||
var frame, frames, getSourceMapping;
|
|
||||||
getSourceMapping = function(filename, line, column) {
|
getSourceMapping = function(filename, line, column) {
|
||||||
var answer, sourceMap;
|
var answer, sourceMap;
|
||||||
sourceMap = getSourceMap(filename, line, column);
|
sourceMap = getSourceMap(filename, line, column);
|
||||||
@@ -406,30 +367,40 @@
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
frames = (function() {
|
// Based on [michaelficarra/CoffeeScriptRedux](http://goo.gl/ZTx1p)
|
||||||
var i, len, results;
|
// NodeJS / V8 have no support for transforming positions in stack traces using
|
||||||
results = [];
|
// sourceMap, so we must monkey-patch Error to display CoffeeScript source
|
||||||
for (i = 0, len = stack.length; i < len; i++) {
|
// positions.
|
||||||
frame = stack[i];
|
return Error.prepareStackTrace = function(err, stack) {
|
||||||
if (frame.getFunction() === exports.run) {
|
var frame, frames;
|
||||||
break;
|
frames = (function() {
|
||||||
|
var i, len, results;
|
||||||
|
results = [];
|
||||||
|
for (i = 0, len = stack.length; i < len; i++) {
|
||||||
|
frame = stack[i];
|
||||||
|
if (frame.getFunction() === exports.run) {
|
||||||
|
// Don’t display stack frames deeper than `CoffeeScript.run`.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
results.push(` at ${formatSourcePosition(frame, getSourceMapping)}`);
|
||||||
}
|
}
|
||||||
results.push(` at ${formatSourcePosition(frame, getSourceMapping)}`);
|
return results;
|
||||||
}
|
})();
|
||||||
return results;
|
return `${err.toString()}\n${frames.join('\n')}\n`;
|
||||||
})();
|
};
|
||||||
return `${err.toString()}\n${frames.join('\n')}\n`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
checkShebangLine = function(file, input) {
|
checkShebangLine = function(file, input) {
|
||||||
var args, firstLine, ref, rest;
|
var args, firstLine, ref, rest;
|
||||||
firstLine = input.split(/$/m)[0];
|
firstLine = input.split(/$/m, 1)[0];
|
||||||
rest = firstLine != null ? firstLine.match(/^#!\s*([^\s]+\s*)(.*)/) : void 0;
|
rest = firstLine != null ? firstLine.match(/^#!\s*([^\s]+\s*)(.*)/) : void 0;
|
||||||
args = rest != null ? (ref = rest[2]) != null ? ref.split(/\s/).filter(function(s) {
|
args = rest != null ? (ref = rest[2]) != null ? ref.split(/\s/).filter(function(s) {
|
||||||
return s !== '';
|
return s !== '';
|
||||||
}) : void 0 : void 0;
|
}) : void 0 : void 0;
|
||||||
if ((args != null ? args.length : void 0) > 1) {
|
if ((args != null ? args.length : void 0) > 1) {
|
||||||
console.error('The script to be run begins with a shebang line with more than one\nargument. This script will fail on platforms such as Linux which only\nallow a single argument.');
|
console.error(`The script to be run begins with a shebang line with more than one
|
||||||
|
argument. This script will fail on platforms such as Linux which only
|
||||||
|
allow a single argument.`);
|
||||||
console.error(`The shebang line was: '${firstLine}' in file '${file}'`);
|
console.error(`The shebang line was: '${firstLine}' in file '${file}'`);
|
||||||
return console.error(`The arguments were: ${JSON.stringify(args)}`);
|
return console.error(`The arguments were: ${JSON.stringify(args)}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
// The `coffee` utility. Handles command-line compilation of CoffeeScript
|
// The `coffee` utility. Handles command-line compilation of CoffeeScript
|
||||||
// into various forms: saved into `.js` files or printed to stdout
|
// into various forms: saved into `.js` files or printed to stdout
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
useWinPathSep = path.sep === '\\';
|
useWinPathSep = path.sep === '\\';
|
||||||
|
|
||||||
// Allow CoffeeScript to emit Node.js events.
|
// Allow CoffeeScript to emit Node.js events.
|
||||||
helpers.extend(CoffeeScript, new EventEmitter);
|
helpers.extend(CoffeeScript, new EventEmitter());
|
||||||
|
|
||||||
printLine = function(line) {
|
printLine = function(line) {
|
||||||
return process.stdout.write(line + '\n');
|
return process.stdout.write(line + '\n');
|
||||||
@@ -42,10 +42,12 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// The help banner that is printed in conjunction with `-h`/`--help`.
|
// The help banner that is printed in conjunction with `-h`/`--help`.
|
||||||
BANNER = 'Usage: coffee [options] path/to/script.coffee [args]\n\nIf called without options, `coffee` will run your script.';
|
BANNER = `Usage: coffee [options] path/to/script.coffee [args]
|
||||||
|
|
||||||
|
If called without options, \`coffee\` will run your script.`;
|
||||||
|
|
||||||
// The list of all the valid option flags that `coffee` knows how to handle.
|
// The list of all the valid option flags that `coffee` knows how to handle.
|
||||||
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-m', '--map', 'generate source map and save as .js.map files'], ['-M', '--inline-map', 'generate source map and include it directly in output'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [PATH]', 'set the output path or path/filename for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [MODULE*]', 'require the given module before eval or REPL'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffeescript'], ['-t', '--transpile', 'pipe generated JavaScript through Babel'], ['--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
|
SWITCHES = [['--ast', 'generate an abstract syntax tree of nodes'], ['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--literate', 'treat stdio as literate style coffeescript'], ['-m', '--map', 'generate source map and save as .js.map files'], ['-M', '--inline-map', 'generate source map and include it directly in output'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [PATH]', 'set the output path or path/filename for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [MODULE*]', 'require the given module before eval or REPL'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--transpile', 'pipe generated JavaScript through Babel'], ['--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
|
||||||
|
|
||||||
// Top-level objects shared by all the functions.
|
// Top-level objects shared by all the functions.
|
||||||
opts = {};
|
opts = {};
|
||||||
@@ -78,7 +80,11 @@
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
if ((!opts.doubleDashed) && (opts.arguments[1] === '--')) {
|
if ((!opts.doubleDashed) && (opts.arguments[1] === '--')) {
|
||||||
printWarn('coffee was invoked with \'--\' as the second positional argument, which is\nnow deprecated. To pass \'--\' as an argument to a script to run, put an\nadditional \'--\' before the path to your script.\n\n\'--\' will be removed from the argument list.');
|
printWarn(`coffee was invoked with '--' as the second positional argument, which is
|
||||||
|
now deprecated. To pass '--' as an argument to a script to run, put an
|
||||||
|
additional '--' before the path to your script.
|
||||||
|
|
||||||
|
'--' will be removed from the argument list.`);
|
||||||
printWarn(`The positional arguments were: ${JSON.stringify(opts.arguments)}`);
|
printWarn(`The positional arguments were: ${JSON.stringify(opts.arguments)}`);
|
||||||
opts.arguments = [opts.arguments[0]].concat(opts.arguments.slice(2));
|
opts.arguments = [opts.arguments[0]].concat(opts.arguments.slice(2));
|
||||||
}
|
}
|
||||||
@@ -131,7 +137,18 @@
|
|||||||
}
|
}
|
||||||
if (opts.join) {
|
if (opts.join) {
|
||||||
opts.join = path.resolve(opts.join);
|
opts.join = path.resolve(opts.join);
|
||||||
console.error('\nThe --join option is deprecated and will be removed in a future version.\n\nIf for some reason it\'s necessary to share local variables between files,\nreplace...\n\n $ coffee --compile --join bundle.js -- a.coffee b.coffee c.coffee\n\nwith...\n\n $ cat a.coffee b.coffee c.coffee | coffee --compile --stdio > bundle.js\n');
|
console.error(`
|
||||||
|
The --join option is deprecated and will be removed in a future version.
|
||||||
|
|
||||||
|
If for some reason it's necessary to share local variables between files,
|
||||||
|
replace...
|
||||||
|
|
||||||
|
$ coffee --compile --join bundle.js -- a.coffee b.coffee c.coffee
|
||||||
|
|
||||||
|
with...
|
||||||
|
|
||||||
|
$ cat a.coffee b.coffee c.coffee | coffee --compile --stdio > bundle.js
|
||||||
|
`);
|
||||||
}
|
}
|
||||||
ref = opts.arguments;
|
ref = opts.arguments;
|
||||||
results = [];
|
results = [];
|
||||||
@@ -257,6 +274,9 @@
|
|||||||
return printTokens(CoffeeScript.tokens(task.input, task.options));
|
return printTokens(CoffeeScript.tokens(task.input, task.options));
|
||||||
} else if (opts.nodes) {
|
} else if (opts.nodes) {
|
||||||
return printLine(CoffeeScript.nodes(task.input, task.options).toString().trim());
|
return printLine(CoffeeScript.nodes(task.input, task.options).toString().trim());
|
||||||
|
} else if (opts.ast) {
|
||||||
|
compiled = CoffeeScript.compile(task.input, task.options);
|
||||||
|
return printLine(JSON.stringify(compiled, null, 2));
|
||||||
} else if (opts.run) {
|
} else if (opts.run) {
|
||||||
CoffeeScript.register();
|
CoffeeScript.register();
|
||||||
if (opts.prelude) {
|
if (opts.prelude) {
|
||||||
@@ -578,7 +598,7 @@
|
|||||||
|
|
||||||
// When watching scripts, it's useful to log changes with the timestamp.
|
// When watching scripts, it's useful to log changes with the timestamp.
|
||||||
timeLog = function(message) {
|
timeLog = function(message) {
|
||||||
return console.log(`${(new Date).toLocaleTimeString()} - ${message}`);
|
return console.log(`${(new Date()).toLocaleTimeString()} - ${message}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pretty-print a stream of tokens, sans location data.
|
// Pretty-print a stream of tokens, sans location data.
|
||||||
@@ -627,9 +647,15 @@
|
|||||||
// Give appropriate instructions depending on whether `coffee` was run
|
// Give appropriate instructions depending on whether `coffee` was run
|
||||||
// locally or globally.
|
// locally or globally.
|
||||||
if (require.resolve('.').indexOf(process.cwd()) === 0) {
|
if (require.resolve('.').indexOf(process.cwd()) === 0) {
|
||||||
console.error('To use --transpile, you must have @babel/core installed:\n npm install --save-dev @babel/core\nAnd you must save options to configure Babel in one of the places it looks to find its options.\nSee https://coffeescript.org/#transpilation');
|
console.error(`To use --transpile, you must have @babel/core installed:
|
||||||
|
npm install --save-dev @babel/core
|
||||||
|
And you must save options to configure Babel in one of the places it looks to find its options.
|
||||||
|
See https://coffeescript.org/#transpilation`);
|
||||||
} else {
|
} else {
|
||||||
console.error('To use --transpile with globally-installed CoffeeScript, you must have @babel/core installed globally:\n npm install --global @babel/core\nAnd you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.\nSee https://coffeescript.org/#transpilation');
|
console.error(`To use --transpile with globally-installed CoffeeScript, you must have @babel/core installed globally:
|
||||||
|
npm install --global @babel/core
|
||||||
|
And you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.
|
||||||
|
See https://coffeescript.org/#transpilation`);
|
||||||
}
|
}
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
@@ -659,7 +685,8 @@
|
|||||||
header: opts.compile && !opts['no-header'],
|
header: opts.compile && !opts['no-header'],
|
||||||
transpile: opts.transpile,
|
transpile: opts.transpile,
|
||||||
sourceMap: opts.map,
|
sourceMap: opts.map,
|
||||||
inlineMap: opts['inline-map']
|
inlineMap: opts['inline-map'],
|
||||||
|
ast: opts.ast
|
||||||
};
|
};
|
||||||
if (filename) {
|
if (filename) {
|
||||||
if (base) {
|
if (base) {
|
||||||
@@ -668,7 +695,7 @@
|
|||||||
jsDir = path.dirname(jsPath);
|
jsDir = path.dirname(jsPath);
|
||||||
answer = helpers.merge(answer, {
|
answer = helpers.merge(answer, {
|
||||||
jsPath,
|
jsPath,
|
||||||
sourceRoot: path.relative(jsDir, cwd),
|
sourceRoot: path.relative(jsDir, cwd) + path.sep,
|
||||||
sourceFiles: [path.relative(cwd, filename)],
|
sourceFiles: [path.relative(cwd, filename)],
|
||||||
generatedFile: helpers.baseFileName(jsPath, false, useWinPathSep)
|
generatedFile: helpers.baseFileName(jsPath, false, useWinPathSep)
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,12 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
// This file contains the common helper functions that we'd like to share among
|
// This file contains the common helper functions that we'd like to share among
|
||||||
// the **Lexer**, **Rewriter**, and the **Nodes**. Merge objects, flatten
|
// the **Lexer**, **Rewriter**, and the **Nodes**. Merge objects, flatten
|
||||||
// arrays, count characters, that sort of thing.
|
// arrays, count characters, that sort of thing.
|
||||||
|
|
||||||
// Peek at the beginning of a given string to see if it matches a sequence.
|
// Peek at the beginning of a given string to see if it matches a sequence.
|
||||||
var attachCommentsToNode, buildLocationData, buildLocationHash, buildTokenDataDictionary, extend, flatten, ref, repeat, syntaxErrorToString;
|
var UNICODE_CODE_POINT_ESCAPE, attachCommentsToNode, buildLocationData, buildLocationHash, buildTokenDataDictionary, extend, flatten, isBoolean, isNumber, isString, ref, repeat, syntaxErrorToString, unicodeCodePointToUnicodeEscapes,
|
||||||
|
indexOf = [].indexOf;
|
||||||
|
|
||||||
exports.starts = function(string, literal, start) {
|
exports.starts = function(string, literal, start) {
|
||||||
return literal === string.substr(start, literal.length);
|
return literal === string.substr(start, literal.length);
|
||||||
@@ -79,17 +80,7 @@
|
|||||||
// Return a flattened version of an array.
|
// Return a flattened version of an array.
|
||||||
// Handy for getting a list of `children` from the nodes.
|
// Handy for getting a list of `children` from the nodes.
|
||||||
exports.flatten = flatten = function(array) {
|
exports.flatten = flatten = function(array) {
|
||||||
var element, flattened, i, len1;
|
return array.flat(2e308);
|
||||||
flattened = [];
|
|
||||||
for (i = 0, len1 = array.length; i < len1; i++) {
|
|
||||||
element = array[i];
|
|
||||||
if ('[object Array]' === Object.prototype.toString.call(element)) {
|
|
||||||
flattened = flattened.concat(flatten(element));
|
|
||||||
} else {
|
|
||||||
flattened.push(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flattened;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Delete a key from an object, returning the value. Useful when a node is
|
// Delete a key from an object, returning the value. Useful when a node is
|
||||||
@@ -156,23 +147,55 @@
|
|||||||
first_line: first.first_line,
|
first_line: first.first_line,
|
||||||
first_column: first.first_column,
|
first_column: first.first_column,
|
||||||
last_line: last.last_line,
|
last_line: last.last_line,
|
||||||
last_column: last.last_column
|
last_column: last.last_column,
|
||||||
|
last_line_exclusive: last.last_line_exclusive,
|
||||||
|
last_column_exclusive: last.last_column_exclusive,
|
||||||
|
range: [first.range[0], last.range[1]]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Build a list of all comments attached to tokens.
|
||||||
|
exports.extractAllCommentTokens = function(tokens) {
|
||||||
|
var allCommentsObj, comment, commentKey, i, j, k, key, len1, len2, len3, ref1, results, sortedKeys, token;
|
||||||
|
allCommentsObj = {};
|
||||||
|
for (i = 0, len1 = tokens.length; i < len1; i++) {
|
||||||
|
token = tokens[i];
|
||||||
|
if (token.comments) {
|
||||||
|
ref1 = token.comments;
|
||||||
|
for (j = 0, len2 = ref1.length; j < len2; j++) {
|
||||||
|
comment = ref1[j];
|
||||||
|
commentKey = comment.locationData.range[0];
|
||||||
|
allCommentsObj[commentKey] = comment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sortedKeys = Object.keys(allCommentsObj).sort(function(a, b) {
|
||||||
|
return a - b;
|
||||||
|
});
|
||||||
|
results = [];
|
||||||
|
for (k = 0, len3 = sortedKeys.length; k < len3; k++) {
|
||||||
|
key = sortedKeys[k];
|
||||||
|
results.push(allCommentsObj[key]);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get a lookup hash for a token based on its location data.
|
||||||
|
// Multiple tokens might have the same location hash, but using exclusive
|
||||||
|
// location data distinguishes e.g. zero-length generated tokens from
|
||||||
|
// actual source tokens.
|
||||||
buildLocationHash = function(loc) {
|
buildLocationHash = function(loc) {
|
||||||
return `${loc.first_line}x${loc.first_column}-${loc.last_line}x${loc.last_column}`;
|
return `${loc.range[0]}-${loc.range[1]}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build a dictionary of extra token properties organized by tokens’ locations
|
// Build a dictionary of extra token properties organized by tokens’ locations
|
||||||
// used as lookup hashes.
|
// used as lookup hashes.
|
||||||
buildTokenDataDictionary = function(parserState) {
|
exports.buildTokenDataDictionary = buildTokenDataDictionary = function(tokens) {
|
||||||
var base, i, len1, ref1, token, tokenData, tokenHash;
|
var base1, i, len1, token, tokenData, tokenHash;
|
||||||
tokenData = {};
|
tokenData = {};
|
||||||
ref1 = parserState.parser.tokens;
|
for (i = 0, len1 = tokens.length; i < len1; i++) {
|
||||||
for (i = 0, len1 = ref1.length; i < len1; i++) {
|
token = tokens[i];
|
||||||
token = ref1[i];
|
|
||||||
if (!token.comments) {
|
if (!token.comments) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -188,7 +211,7 @@
|
|||||||
// and therefore matching `tokenHash`es, merge the comments from both/all
|
// and therefore matching `tokenHash`es, merge the comments from both/all
|
||||||
// tokens together into one array, even if there are duplicate comments;
|
// tokens together into one array, even if there are duplicate comments;
|
||||||
// they will get sorted out later.
|
// they will get sorted out later.
|
||||||
((base = tokenData[tokenHash]).comments != null ? base.comments : base.comments = []).push(...token.comments);
|
((base1 = tokenData[tokenHash]).comments != null ? base1.comments : base1.comments = []).push(...token.comments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tokenData;
|
return tokenData;
|
||||||
@@ -197,21 +220,24 @@
|
|||||||
// This returns a function which takes an object as a parameter, and if that
|
// This returns a function which takes an object as a parameter, and if that
|
||||||
// object is an AST node, updates that object's locationData.
|
// object is an AST node, updates that object's locationData.
|
||||||
// The object is returned either way.
|
// The object is returned either way.
|
||||||
exports.addDataToNode = function(parserState, first, last) {
|
exports.addDataToNode = function(parserState, firstLocationData, firstValue, lastLocationData, lastValue, forceUpdateLocation = true) {
|
||||||
return function(obj) {
|
return function(obj) {
|
||||||
var objHash, ref1;
|
var locationData, objHash, ref1, ref2, ref3;
|
||||||
// Add location data.
|
// Add location data.
|
||||||
if (((obj != null ? obj.updateLocationDataIfMissing : void 0) != null) && (first != null)) {
|
locationData = buildLocationData((ref1 = firstValue != null ? firstValue.locationData : void 0) != null ? ref1 : firstLocationData, (ref2 = lastValue != null ? lastValue.locationData : void 0) != null ? ref2 : lastLocationData);
|
||||||
obj.updateLocationDataIfMissing(buildLocationData(first, last));
|
if (((obj != null ? obj.updateLocationDataIfMissing : void 0) != null) && (firstLocationData != null)) {
|
||||||
|
obj.updateLocationDataIfMissing(locationData, forceUpdateLocation);
|
||||||
|
} else {
|
||||||
|
obj.locationData = locationData;
|
||||||
}
|
}
|
||||||
// Add comments, building the dictionary of token data if it hasn’t been
|
// Add comments, building the dictionary of token data if it hasn’t been
|
||||||
// built yet.
|
// built yet.
|
||||||
if (parserState.tokenData == null) {
|
if (parserState.tokenData == null) {
|
||||||
parserState.tokenData = buildTokenDataDictionary(parserState);
|
parserState.tokenData = buildTokenDataDictionary(parserState.parser.tokens);
|
||||||
}
|
}
|
||||||
if (obj.locationData != null) {
|
if (obj.locationData != null) {
|
||||||
objHash = buildLocationHash(obj.locationData);
|
objHash = buildLocationHash(obj.locationData);
|
||||||
if (((ref1 = parserState.tokenData[objHash]) != null ? ref1.comments : void 0) != null) {
|
if (((ref3 = parserState.tokenData[objHash]) != null ? ref3.comments : void 0) != null) {
|
||||||
attachCommentsToNode(parserState.tokenData[objHash].comments, obj);
|
attachCommentsToNode(parserState.tokenData[objHash].comments, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,6 +271,16 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Generate a unique anonymous file name so we can distinguish source map cache
|
||||||
|
// entries for any number of anonymous scripts.
|
||||||
|
exports.anonymousFileName = (function() {
|
||||||
|
var n;
|
||||||
|
n = 0;
|
||||||
|
return function() {
|
||||||
|
return `<anonymous-${n++}>`;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
// A `.coffee.md` compatible version of `basename`, that returns the file sans-extension.
|
// A `.coffee.md` compatible version of `basename`, that returns the file sans-extension.
|
||||||
exports.baseFileName = function(file, stripExt = false, useWinPathSep = false) {
|
exports.baseFileName = function(file, stripExt = false, useWinPathSep = false) {
|
||||||
var parts, pathSep;
|
var parts, pathSep;
|
||||||
@@ -301,7 +337,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
syntaxErrorToString = function() {
|
syntaxErrorToString = function() {
|
||||||
var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, ref1, ref2, ref3, start;
|
var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, ref1, ref2, ref3, ref4, start;
|
||||||
if (!(this.code && this.location)) {
|
if (!(this.code && this.location)) {
|
||||||
return Error.prototype.toString.call(this);
|
return Error.prototype.toString.call(this);
|
||||||
}
|
}
|
||||||
@@ -312,7 +348,11 @@
|
|||||||
if (last_column == null) {
|
if (last_column == null) {
|
||||||
last_column = first_column;
|
last_column = first_column;
|
||||||
}
|
}
|
||||||
filename = this.filename || '[stdin]';
|
if ((ref1 = this.filename) != null ? ref1.startsWith('<anonymous') : void 0) {
|
||||||
|
filename = '[stdin]';
|
||||||
|
} else {
|
||||||
|
filename = this.filename || '[stdin]';
|
||||||
|
}
|
||||||
codeLine = this.code.split('\n')[first_line];
|
codeLine = this.code.split('\n')[first_line];
|
||||||
start = first_column;
|
start = first_column;
|
||||||
// Show only the first line on multi-line errors.
|
// Show only the first line on multi-line errors.
|
||||||
@@ -320,16 +360,18 @@
|
|||||||
marker = codeLine.slice(0, start).replace(/[^\s]/g, ' ') + repeat('^', end - start);
|
marker = codeLine.slice(0, start).replace(/[^\s]/g, ' ') + repeat('^', end - start);
|
||||||
// Check to see if we're running on a color-enabled TTY.
|
// Check to see if we're running on a color-enabled TTY.
|
||||||
if (typeof process !== "undefined" && process !== null) {
|
if (typeof process !== "undefined" && process !== null) {
|
||||||
colorsEnabled = ((ref1 = process.stdout) != null ? ref1.isTTY : void 0) && !((ref2 = process.env) != null ? ref2.NODE_DISABLE_COLORS : void 0);
|
colorsEnabled = ((ref2 = process.stdout) != null ? ref2.isTTY : void 0) && !((ref3 = process.env) != null ? ref3.NODE_DISABLE_COLORS : void 0);
|
||||||
}
|
}
|
||||||
if ((ref3 = this.colorful) != null ? ref3 : colorsEnabled) {
|
if ((ref4 = this.colorful) != null ? ref4 : colorsEnabled) {
|
||||||
colorize = function(str) {
|
colorize = function(str) {
|
||||||
return `\x1B[1;31m${str}\x1B[0m`;
|
return `\x1B[1;31m${str}\x1B[0m`;
|
||||||
};
|
};
|
||||||
codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end);
|
codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end);
|
||||||
marker = colorize(marker);
|
marker = colorize(marker);
|
||||||
}
|
}
|
||||||
return `${filename}:${first_line + 1}:${first_column + 1}: error: ${this.message}\n${codeLine}\n${marker}`;
|
return `${filename}:${first_line + 1}:${first_column + 1}: error: ${this.message}
|
||||||
|
${codeLine}
|
||||||
|
${marker}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.nameWhitespaceCharacter = function(string) {
|
exports.nameWhitespaceCharacter = function(string) {
|
||||||
@@ -347,4 +389,89 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.parseNumber = function(string) {
|
||||||
|
var base;
|
||||||
|
if (string == null) {
|
||||||
|
return 0/0;
|
||||||
|
}
|
||||||
|
base = (function() {
|
||||||
|
switch (string.charAt(1)) {
|
||||||
|
case 'b':
|
||||||
|
return 2;
|
||||||
|
case 'o':
|
||||||
|
return 8;
|
||||||
|
case 'x':
|
||||||
|
return 16;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
if (base != null) {
|
||||||
|
return parseInt(string.slice(2).replace(/_/g, ''), base);
|
||||||
|
} else {
|
||||||
|
return parseFloat(string.replace(/_/g, ''));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.isFunction = function(obj) {
|
||||||
|
return Object.prototype.toString.call(obj) === '[object Function]';
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.isNumber = isNumber = function(obj) {
|
||||||
|
return Object.prototype.toString.call(obj) === '[object Number]';
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.isString = isString = function(obj) {
|
||||||
|
return Object.prototype.toString.call(obj) === '[object String]';
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.isBoolean = isBoolean = function(obj) {
|
||||||
|
return obj === true || obj === false || Object.prototype.toString.call(obj) === '[object Boolean]';
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.isPlainObject = function(obj) {
|
||||||
|
return typeof obj === 'object' && !!obj && !Array.isArray(obj) && !isNumber(obj) && !isString(obj) && !isBoolean(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
unicodeCodePointToUnicodeEscapes = function(codePoint) {
|
||||||
|
var high, low, toUnicodeEscape;
|
||||||
|
toUnicodeEscape = function(val) {
|
||||||
|
var str;
|
||||||
|
str = val.toString(16);
|
||||||
|
return `\\u${repeat('0', 4 - str.length)}${str}`;
|
||||||
|
};
|
||||||
|
if (codePoint < 0x10000) {
|
||||||
|
return toUnicodeEscape(codePoint);
|
||||||
|
}
|
||||||
|
// surrogate pair
|
||||||
|
high = Math.floor((codePoint - 0x10000) / 0x400) + 0xD800;
|
||||||
|
low = (codePoint - 0x10000) % 0x400 + 0xDC00;
|
||||||
|
return `${toUnicodeEscape(high)}${toUnicodeEscape(low)}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Replace `\u{...}` with `\uxxxx[\uxxxx]` in regexes without `u` flag
|
||||||
|
exports.replaceUnicodeCodePointEscapes = function(str, {flags, error, delimiter = ''} = {}) {
|
||||||
|
var shouldReplace;
|
||||||
|
shouldReplace = (flags != null) && indexOf.call(flags, 'u') < 0;
|
||||||
|
return str.replace(UNICODE_CODE_POINT_ESCAPE, function(match, escapedBackslash, codePointHex, offset) {
|
||||||
|
var codePointDecimal;
|
||||||
|
if (escapedBackslash) {
|
||||||
|
return escapedBackslash;
|
||||||
|
}
|
||||||
|
codePointDecimal = parseInt(codePointHex, 16);
|
||||||
|
if (codePointDecimal > 0x10ffff) {
|
||||||
|
error("unicode code point escapes greater than \\u{10ffff} are not allowed", {
|
||||||
|
offset: offset + delimiter.length,
|
||||||
|
length: codePointHex.length + 4
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!shouldReplace) {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
return unicodeCodePointToUnicodeEscapes(codePointDecimal);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
UNICODE_CODE_POINT_ESCAPE = /(\\\\)|\\u\{([\da-fA-F]+)\}/g; // Make sure the escape isn’t escaped.
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
// Node.js Implementation
|
// Node.js Implementation
|
||||||
var CoffeeScript, ext, fs, helpers, i, len, path, ref, universalCompile, vm,
|
var CoffeeScript, ext, fs, helpers, i, len, path, ref, universalCompile, vm,
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
var answer, dir, mainModule, ref;
|
var answer, dir, mainModule, ref;
|
||||||
mainModule = require.main;
|
mainModule = require.main;
|
||||||
// Set the filename.
|
// Set the filename.
|
||||||
mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '<anonymous>';
|
mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : helpers.anonymousFileName();
|
||||||
// Clear the module cache.
|
// Clear the module cache.
|
||||||
mainModule.moduleCache && (mainModule.moduleCache = {});
|
mainModule.moduleCache && (mainModule.moduleCache = {});
|
||||||
// Assign paths for node_modules loading
|
// Assign paths for node_modules loading
|
||||||
@@ -59,11 +59,11 @@
|
|||||||
mainModule.paths = require('module')._nodeModulePaths(dir);
|
mainModule.paths = require('module')._nodeModulePaths(dir);
|
||||||
// Save the options for compiling child imports.
|
// Save the options for compiling child imports.
|
||||||
mainModule.options = options;
|
mainModule.options = options;
|
||||||
|
options.filename = mainModule.filename;
|
||||||
|
options.inlineMap = true;
|
||||||
// Compile.
|
// Compile.
|
||||||
if (!helpers.isCoffee(mainModule.filename) || require.extensions) {
|
answer = CoffeeScript.compile(code, options);
|
||||||
answer = CoffeeScript.compile(code, options);
|
code = (ref = answer.js) != null ? ref : answer;
|
||||||
code = (ref = answer.js) != null ? ref : answer;
|
|
||||||
}
|
|
||||||
return mainModule._compile(code, mainModule.filename);
|
return mainModule._compile(code, mainModule.filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -152,16 +152,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CoffeeScript._compileFile = function(filename, options = {}) {
|
CoffeeScript._compileRawFileContent = function(raw, filename, options = {}) {
|
||||||
var answer, err, raw, stripped;
|
var answer, err, stripped;
|
||||||
raw = fs.readFileSync(filename, 'utf8');
|
|
||||||
// Strip the Unicode byte order mark, if this file begins with one.
|
// Strip the Unicode byte order mark, if this file begins with one.
|
||||||
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
|
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
|
||||||
options = Object.assign({}, options, {
|
options = Object.assign({}, options, {
|
||||||
filename: filename,
|
filename: filename,
|
||||||
literate: helpers.isLiterate(filename),
|
literate: helpers.isLiterate(filename),
|
||||||
sourceFiles: [filename],
|
sourceFiles: [filename]
|
||||||
inlineMap: true // Always generate a source map, so that stack traces line up.
|
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
answer = CoffeeScript.compile(stripped, options);
|
answer = CoffeeScript.compile(stripped, options);
|
||||||
@@ -175,6 +173,45 @@
|
|||||||
return answer;
|
return answer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CoffeeScript._compileFile = function(filename, options = {}) {
|
||||||
|
var raw;
|
||||||
|
raw = fs.readFileSync(filename, 'utf8');
|
||||||
|
return CoffeeScript._compileRawFileContent(raw, filename, options);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = CoffeeScript;
|
module.exports = CoffeeScript;
|
||||||
|
|
||||||
|
// Explicitly define all named exports so that Node’s automatic detection of
|
||||||
|
// named exports from CommonJS packages finds all of them. This enables consuming
|
||||||
|
// packages to write code like `import { compile } from 'coffeescript'`.
|
||||||
|
// Don’t simplify this into a loop or similar; the `module.exports.name` part is
|
||||||
|
// essential for Node’s algorithm to successfully detect the name.
|
||||||
|
module.exports.VERSION = CoffeeScript.VERSION;
|
||||||
|
|
||||||
|
module.exports.FILE_EXTENSIONS = CoffeeScript.FILE_EXTENSIONS;
|
||||||
|
|
||||||
|
module.exports.helpers = CoffeeScript.helpers;
|
||||||
|
|
||||||
|
module.exports.registerCompiled = CoffeeScript.registerCompiled;
|
||||||
|
|
||||||
|
module.exports.compile = CoffeeScript.compile;
|
||||||
|
|
||||||
|
module.exports.tokens = CoffeeScript.tokens;
|
||||||
|
|
||||||
|
module.exports.nodes = CoffeeScript.nodes;
|
||||||
|
|
||||||
|
module.exports.register = CoffeeScript.register;
|
||||||
|
|
||||||
|
module.exports.eval = CoffeeScript.eval;
|
||||||
|
|
||||||
|
module.exports.run = CoffeeScript.run;
|
||||||
|
|
||||||
|
module.exports.transpile = CoffeeScript.transpile;
|
||||||
|
|
||||||
|
module.exports.patchStackTrace = CoffeeScript.patchStackTrace;
|
||||||
|
|
||||||
|
module.exports._compileRawFileContent = CoffeeScript._compileRawFileContent;
|
||||||
|
|
||||||
|
module.exports._compileFile = CoffeeScript._compileFile;
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat,
|
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat,
|
||||||
splice = [].splice;
|
splice = [].splice;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, getRootModule, helpers, i, len, loadFile, path, ref;
|
var CoffeeScript, Module, binary, cacheSourceMaps, child_process, ext, findExtension, fork, getRootModule, helpers, i, len, loadFile, nodeSourceMapsSupportEnabled, patchStackTrace, path, ref, ref1;
|
||||||
|
|
||||||
CoffeeScript = require('./');
|
CoffeeScript = require('./');
|
||||||
|
|
||||||
@@ -10,20 +10,35 @@
|
|||||||
|
|
||||||
path = require('path');
|
path = require('path');
|
||||||
|
|
||||||
|
({patchStackTrace} = CoffeeScript);
|
||||||
|
|
||||||
|
// Check if Node's built-in source map stack trace transformations are enabled.
|
||||||
|
nodeSourceMapsSupportEnabled = (typeof process !== "undefined" && process !== null) && (process.execArgv.includes('--enable-source-maps') || ((ref = process.env.NODE_OPTIONS) != null ? ref.includes('--enable-source-maps') : void 0));
|
||||||
|
|
||||||
|
if (!(Error.prepareStackTrace || nodeSourceMapsSupportEnabled)) {
|
||||||
|
cacheSourceMaps = true;
|
||||||
|
patchStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
// Load and run a CoffeeScript file for Node, stripping any `BOM`s.
|
// Load and run a CoffeeScript file for Node, stripping any `BOM`s.
|
||||||
loadFile = function(module, filename) {
|
loadFile = function(module, filename) {
|
||||||
var answer, options;
|
var js, options;
|
||||||
options = module.options || getRootModule(module).options;
|
options = module.options || getRootModule(module).options || {};
|
||||||
answer = CoffeeScript._compileFile(filename, options);
|
// Currently `CoffeeScript.compile` caches all source maps if present. They
|
||||||
return module._compile(answer, filename);
|
// are available in `getSourceMap` retrieved by `filename`.
|
||||||
|
if (cacheSourceMaps || nodeSourceMapsSupportEnabled) {
|
||||||
|
options.inlineMap = true;
|
||||||
|
}
|
||||||
|
js = CoffeeScript._compileFile(filename, options);
|
||||||
|
return module._compile(js, filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the installed version of Node supports `require.extensions`, register
|
// If the installed version of Node supports `require.extensions`, register
|
||||||
// CoffeeScript as an extension.
|
// CoffeeScript as an extension.
|
||||||
if (require.extensions) {
|
if (require.extensions) {
|
||||||
ref = CoffeeScript.FILE_EXTENSIONS;
|
ref1 = CoffeeScript.FILE_EXTENSIONS;
|
||||||
for (i = 0, len = ref.length; i < len; i++) {
|
for (i = 0, len = ref1.length; i < len; i++) {
|
||||||
ext = ref[i];
|
ext = ref1[i];
|
||||||
require.extensions[ext] = loadFile;
|
require.extensions[ext] = loadFile;
|
||||||
}
|
}
|
||||||
// Patch Node's module loader to be able to handle multi-dot extensions.
|
// Patch Node's module loader to be able to handle multi-dot extensions.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, replDefaults, runInContext, sawSIGINT, transpile, updateSyntaxError, vm;
|
var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, replDefaults, runInContext, sawSIGINT, transpile, updateSyntaxError, vm;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
})(),
|
})(),
|
||||||
historyMaxInputSize: 10240,
|
historyMaxInputSize: 10240,
|
||||||
eval: function(input, context, filename, cb) {
|
eval: function(input, context, filename, cb) {
|
||||||
var Assign, Block, Call, Code, Literal, Value, ast, err, isAsync, js, ref, ref1, referencedVars, result, token, tokens;
|
var Assign, Block, Call, Code, Literal, Root, Value, ast, err, isAsync, js, ref, ref1, referencedVars, result, token, tokens;
|
||||||
// XXX: multiline hack.
|
// XXX: multiline hack.
|
||||||
input = input.replace(/\uFF00/g, '\n');
|
input = input.replace(/\uFF00/g, '\n');
|
||||||
// Node's REPL sends the input ending with a newline and then wrapped in
|
// Node's REPL sends the input ending with a newline and then wrapped in
|
||||||
@@ -39,15 +39,15 @@
|
|||||||
// Unwrap that too.
|
// Unwrap that too.
|
||||||
input = input.replace(/^\s*try\s*{([\s\S]*)}\s*catch.*$/m, '$1');
|
input = input.replace(/^\s*try\s*{([\s\S]*)}\s*catch.*$/m, '$1');
|
||||||
// Require AST nodes to do some AST manipulation.
|
// Require AST nodes to do some AST manipulation.
|
||||||
({Block, Assign, Value, Literal, Call, Code} = require('./nodes'));
|
({Block, Assign, Value, Literal, Call, Code, Root} = require('./nodes'));
|
||||||
try {
|
try {
|
||||||
// Tokenize the clean input.
|
// Tokenize the clean input.
|
||||||
tokens = CoffeeScript.tokens(input);
|
tokens = CoffeeScript.tokens(input);
|
||||||
// Filter out tokens generated just to hold comments.
|
// Filter out tokens generated just to hold comments.
|
||||||
if (tokens.length >= 2 && tokens[0].generated && ((ref = tokens[0].comments) != null ? ref.length : void 0) !== 0 && tokens[0][1] === '' && tokens[1][0] === 'TERMINATOR') {
|
if (tokens.length >= 2 && tokens[0].generated && ((ref = tokens[0].comments) != null ? ref.length : void 0) !== 0 && `${tokens[0][1]}` === '' && tokens[1][0] === 'TERMINATOR') {
|
||||||
tokens = tokens.slice(2);
|
tokens = tokens.slice(2);
|
||||||
}
|
}
|
||||||
if (tokens.length >= 1 && tokens[tokens.length - 1].generated && ((ref1 = tokens[tokens.length - 1].comments) != null ? ref1.length : void 0) !== 0 && tokens[tokens.length - 1][1] === '') {
|
if (tokens.length >= 1 && tokens[tokens.length - 1].generated && ((ref1 = tokens[tokens.length - 1].comments) != null ? ref1.length : void 0) !== 0 && `${tokens[tokens.length - 1][1]}` === '') {
|
||||||
tokens.pop();
|
tokens.pop();
|
||||||
}
|
}
|
||||||
// Collect referenced variable names just like in `CoffeeScript.compile`.
|
// Collect referenced variable names just like in `CoffeeScript.compile`.
|
||||||
@@ -63,14 +63,14 @@
|
|||||||
return results;
|
return results;
|
||||||
})();
|
})();
|
||||||
// Generate the AST of the tokens.
|
// Generate the AST of the tokens.
|
||||||
ast = CoffeeScript.nodes(tokens);
|
ast = CoffeeScript.nodes(tokens).body;
|
||||||
// Add assignment to `__` variable to force the input to be an expression.
|
// Add assignment to `__` variable to force the input to be an expression.
|
||||||
ast = new Block([new Assign(new Value(new Literal('__')), ast, '=')]);
|
ast = new Block([new Assign(new Value(new Literal('__')), ast, '=')]);
|
||||||
// Wrap the expression in a closure to support top-level `await`.
|
// Wrap the expression in a closure to support top-level `await`.
|
||||||
ast = new Code([], ast);
|
ast = new Code([], ast);
|
||||||
isAsync = ast.isAsync;
|
isAsync = ast.isAsync;
|
||||||
// Invoke the wrapping closure.
|
// Invoke the wrapping closure.
|
||||||
ast = new Block([new Call(ast)]);
|
ast = new Root(new Block([new Call(ast)]));
|
||||||
js = ast.compile({
|
js = ast.compile({
|
||||||
bare: true,
|
bare: true,
|
||||||
locals: Object.keys(context),
|
locals: Object.keys(context),
|
||||||
@@ -113,8 +113,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
addMultilineHandler = function(repl) {
|
addMultilineHandler = function(repl) {
|
||||||
var inputStream, multiline, nodeLineListener, origPrompt, outputStream, ref, rli;
|
var inputStream, multiline, nodeLineListener, origPrompt, outputStream, ref;
|
||||||
({rli, inputStream, outputStream} = repl);
|
({inputStream, outputStream} = repl);
|
||||||
// Node 0.11.12 changed API, prompt is now _prompt.
|
// Node 0.11.12 changed API, prompt is now _prompt.
|
||||||
origPrompt = (ref = repl._prompt) != null ? ref : repl.prompt;
|
origPrompt = (ref = repl._prompt) != null ? ref : repl.prompt;
|
||||||
multiline = {
|
multiline = {
|
||||||
@@ -128,15 +128,15 @@
|
|||||||
buffer: ''
|
buffer: ''
|
||||||
};
|
};
|
||||||
// Proxy node's line listener
|
// Proxy node's line listener
|
||||||
nodeLineListener = rli.listeners('line')[0];
|
nodeLineListener = repl.listeners('line')[0];
|
||||||
rli.removeListener('line', nodeLineListener);
|
repl.removeListener('line', nodeLineListener);
|
||||||
rli.on('line', function(cmd) {
|
repl.on('line', function(cmd) {
|
||||||
if (multiline.enabled) {
|
if (multiline.enabled) {
|
||||||
multiline.buffer += `${cmd}\n`;
|
multiline.buffer += `${cmd}\n`;
|
||||||
rli.setPrompt(multiline.prompt);
|
repl.setPrompt(multiline.prompt);
|
||||||
rli.prompt(true);
|
repl.prompt(true);
|
||||||
} else {
|
} else {
|
||||||
rli.setPrompt(origPrompt);
|
repl.setPrompt(origPrompt);
|
||||||
nodeLineListener(cmd);
|
nodeLineListener(cmd);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -149,28 +149,28 @@
|
|||||||
// allow arbitrarily switching between modes any time before multiple lines are entered
|
// allow arbitrarily switching between modes any time before multiple lines are entered
|
||||||
if (!multiline.buffer.match(/\n/)) {
|
if (!multiline.buffer.match(/\n/)) {
|
||||||
multiline.enabled = !multiline.enabled;
|
multiline.enabled = !multiline.enabled;
|
||||||
rli.setPrompt(origPrompt);
|
repl.setPrompt(origPrompt);
|
||||||
rli.prompt(true);
|
repl.prompt(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// no-op unless the current line is empty
|
// no-op unless the current line is empty
|
||||||
if ((rli.line != null) && !rli.line.match(/^\s*$/)) {
|
if ((repl.line != null) && !repl.line.match(/^\s*$/)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// eval, print, loop
|
// eval, print, loop
|
||||||
multiline.enabled = !multiline.enabled;
|
multiline.enabled = !multiline.enabled;
|
||||||
rli.line = '';
|
repl.line = '';
|
||||||
rli.cursor = 0;
|
repl.cursor = 0;
|
||||||
rli.output.cursorTo(0);
|
repl.output.cursorTo(0);
|
||||||
rli.output.clearLine(1);
|
repl.output.clearLine(1);
|
||||||
// XXX: multiline hack
|
// XXX: multiline hack
|
||||||
multiline.buffer = multiline.buffer.replace(/\n/g, '\uFF00');
|
multiline.buffer = multiline.buffer.replace(/\n/g, '\uFF00');
|
||||||
rli.emit('line', multiline.buffer);
|
repl.emit('line', multiline.buffer);
|
||||||
multiline.buffer = '';
|
multiline.buffer = '';
|
||||||
} else {
|
} else {
|
||||||
multiline.enabled = !multiline.enabled;
|
multiline.enabled = !multiline.enabled;
|
||||||
rli.setPrompt(multiline.initialPrompt);
|
repl.setPrompt(multiline.initialPrompt);
|
||||||
rli.prompt(true);
|
repl.prompt(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -189,20 +189,20 @@
|
|||||||
fs.readSync(readFd, buffer, 0, size, stat.size - size);
|
fs.readSync(readFd, buffer, 0, size, stat.size - size);
|
||||||
fs.closeSync(readFd);
|
fs.closeSync(readFd);
|
||||||
// Set the history on the interpreter
|
// Set the history on the interpreter
|
||||||
repl.rli.history = buffer.toString().split('\n').reverse();
|
repl.history = buffer.toString().split('\n').reverse();
|
||||||
if (stat.size > maxSize) {
|
if (stat.size > maxSize) {
|
||||||
// If the history file was truncated we should pop off a potential partial line
|
// If the history file was truncated we should pop off a potential partial line
|
||||||
repl.rli.history.pop();
|
repl.history.pop();
|
||||||
}
|
}
|
||||||
if (repl.rli.history[0] === '') {
|
if (repl.history[0] === '') {
|
||||||
// Shift off the final blank newline
|
// Shift off the final blank newline
|
||||||
repl.rli.history.shift();
|
repl.history.shift();
|
||||||
}
|
}
|
||||||
repl.rli.historyIndex = -1;
|
repl.historyIndex = -1;
|
||||||
lastLine = repl.rli.history[0];
|
lastLine = repl.history[0];
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
fd = fs.openSync(filename, 'a');
|
fd = fs.openSync(filename, 'a');
|
||||||
repl.rli.addListener('line', function(code) {
|
repl.addListener('line', function(code) {
|
||||||
if (code && code.length && code !== '.history' && code !== '.exit' && lastLine !== code) {
|
if (code && code.length && code !== '.history' && code !== '.exit' && lastLine !== code) {
|
||||||
// Save the latest command in the file
|
// Save the latest command in the file
|
||||||
fs.writeSync(fd, `${code}\n`);
|
fs.writeSync(fd, `${code}\n`);
|
||||||
@@ -220,7 +220,7 @@
|
|||||||
return repl.commands[getCommandId(repl, 'history')] = {
|
return repl.commands[getCommandId(repl, 'history')] = {
|
||||||
help: 'Show command history',
|
help: 'Show command history',
|
||||||
action: function() {
|
action: function() {
|
||||||
repl.outputStream.write(`${repl.rli.history.slice(0).reverse().join('\n')}\n`);
|
repl.outputStream.write(`${repl.history.slice(0).reverse().join('\n')}\n`);
|
||||||
return repl.displayPrompt();
|
return repl.displayPrompt();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -257,7 +257,12 @@
|
|||||||
try {
|
try {
|
||||||
transpile.transpile = require('babel-core').transform;
|
transpile.transpile = require('babel-core').transform;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('To use --transpile with an interactive REPL, @babel/core must be installed either in the current folder or globally:\n npm install --save-dev @babel/core\nor\n npm install --global @babel/core\nAnd you must save options to configure Babel in one of the places it looks to find its options.\nSee https://coffeescript.org/#transpilation');
|
console.error(`To use --transpile with an interactive REPL, @babel/core must be installed either in the current folder or globally:
|
||||||
|
npm install --save-dev @babel/core
|
||||||
|
or
|
||||||
|
npm install --global @babel/core
|
||||||
|
And you must save options to configure Babel in one of the places it looks to find its options.
|
||||||
|
See https://coffeescript.org/#transpilation`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,7 +288,7 @@
|
|||||||
runInContext(opts.prelude, repl.context, 'prelude');
|
runInContext(opts.prelude, repl.context, 'prelude');
|
||||||
}
|
}
|
||||||
repl.on('exit', function() {
|
repl.on('exit', function() {
|
||||||
if (!repl.rli.closed) {
|
if (!repl.closed) {
|
||||||
return repl.outputStream.write('\n');
|
return repl.outputStream.write('\n');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
// The CoffeeScript language has a good deal of optional syntax, implicit syntax,
|
// The CoffeeScript language has a good deal of optional syntax, implicit syntax,
|
||||||
// and shorthand syntax. This can greatly complicate a grammar and bloat
|
// and shorthand syntax. This can greatly complicate a grammar and bloat
|
||||||
@@ -6,10 +6,11 @@
|
|||||||
// a series of passes over the token stream, using this **Rewriter** to convert
|
// a series of passes over the token stream, using this **Rewriter** to convert
|
||||||
// shorthand into the unambiguous long form, add implicit indentation and
|
// shorthand into the unambiguous long form, add implicit indentation and
|
||||||
// parentheses, and generally clean things up.
|
// parentheses, and generally clean things up.
|
||||||
var BALANCED_PAIRS, CALL_CLOSERS, CONTROL_IN_IMPLICIT, DISCARDED, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, generate, k, left, len, moveComments, right, throwSyntaxError,
|
var BALANCED_PAIRS, CALL_CLOSERS, CONTROL_IN_IMPLICIT, DISCARDED, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, UNFINISHED, extractAllCommentTokens, generate, k, left, len, moveComments, right, throwSyntaxError,
|
||||||
indexOf = [].indexOf;
|
indexOf = [].indexOf,
|
||||||
|
hasProp = {}.hasOwnProperty;
|
||||||
|
|
||||||
({throwSyntaxError} = require('./helpers'));
|
({throwSyntaxError, extractAllCommentTokens} = require('./helpers'));
|
||||||
|
|
||||||
// Move attached comments from one token to another.
|
// Move attached comments from one token to another.
|
||||||
moveComments = function(fromToken, toToken) {
|
moveComments = function(fromToken, toToken) {
|
||||||
@@ -86,11 +87,11 @@
|
|||||||
this.normalizeLines();
|
this.normalizeLines();
|
||||||
this.tagPostfixConditionals();
|
this.tagPostfixConditionals();
|
||||||
this.addImplicitBracesAndParens();
|
this.addImplicitBracesAndParens();
|
||||||
this.addParensToChainedDoIife();
|
|
||||||
this.rescueStowawayComments();
|
this.rescueStowawayComments();
|
||||||
this.addLocationDataToGeneratedTokens();
|
this.addLocationDataToGeneratedTokens();
|
||||||
this.enforceValidCSXAttributes();
|
this.enforceValidJSXAttributes();
|
||||||
this.fixOutdentLocationData();
|
this.fixIndentationLocationData();
|
||||||
|
this.exposeTokenDataToGrammar();
|
||||||
if (typeof process !== "undefined" && process !== null ? (ref1 = process.env) != null ? ref1.DEBUG_REWRITTEN_TOKEN_STREAM : void 0 : void 0) {
|
if (typeof process !== "undefined" && process !== null ? (ref1 = process.env) != null ? ref1.DEBUG_REWRITTEN_TOKEN_STREAM : void 0 : void 0) {
|
||||||
if (process.env.DEBUG_TOKEN_STREAM) {
|
if (process.env.DEBUG_TOKEN_STREAM) {
|
||||||
console.log('Rewritten token stream:');
|
console.log('Rewritten token stream:');
|
||||||
@@ -196,16 +197,23 @@
|
|||||||
// The lexer has tagged the opening bracket of an indexing operation call.
|
// The lexer has tagged the opening bracket of an indexing operation call.
|
||||||
// Match it with its paired close.
|
// Match it with its paired close.
|
||||||
closeOpenIndexes() {
|
closeOpenIndexes() {
|
||||||
var action, condition;
|
var action, condition, startToken;
|
||||||
|
startToken = null;
|
||||||
condition = function(token, i) {
|
condition = function(token, i) {
|
||||||
var ref;
|
var ref;
|
||||||
return (ref = token[0]) === ']' || ref === 'INDEX_END';
|
return (ref = token[0]) === ']' || ref === 'INDEX_END';
|
||||||
};
|
};
|
||||||
action = function(token, i) {
|
action = function(token, i) {
|
||||||
return token[0] = 'INDEX_END';
|
if (this.tokens.length >= i && this.tokens[i + 1][0] === ':') {
|
||||||
|
startToken[0] = '[';
|
||||||
|
return token[0] = ']';
|
||||||
|
} else {
|
||||||
|
return token[0] = 'INDEX_END';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return this.scanTokens(function(token, i) {
|
return this.scanTokens(function(token, i) {
|
||||||
if (token[0] === 'INDEX_START') {
|
if (token[0] === 'INDEX_START') {
|
||||||
|
startToken = token;
|
||||||
this.detectEnd(i + 1, condition, action);
|
this.detectEnd(i + 1, condition, action);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -281,7 +289,7 @@
|
|||||||
stack = [];
|
stack = [];
|
||||||
start = null;
|
start = null;
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
return this.scanTokens(function(token, i, tokens) {
|
||||||
var endImplicitCall, endImplicitObject, forward, implicitObjectContinues, inControlFlow, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, isImplicit, isImplicitCall, isImplicitObject, k, newLine, nextTag, nextToken, offset, prevTag, prevToken, ref, ref1, ref2, s, sameLine, stackIdx, stackItem, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag;
|
var endImplicitCall, endImplicitObject, forward, implicitObjectContinues, implicitObjectIndent, inControlFlow, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, isImplicit, isImplicitCall, isImplicitObject, k, newLine, nextTag, nextToken, offset, preContinuationLineIndent, preObjectToken, prevTag, prevToken, ref, ref1, ref2, ref3, ref4, ref5, s, sameLine, stackIdx, stackItem, stackNext, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startIndex, startTag, startsLine, tag;
|
||||||
[tag] = token;
|
[tag] = token;
|
||||||
[prevTag] = prevToken = i > 0 ? tokens[i - 1] : [];
|
[prevTag] = prevToken = i > 0 ? tokens[i - 1] : [];
|
||||||
[nextTag] = nextToken = i < tokens.length - 1 ? tokens[i + 1] : [];
|
[nextTag] = nextToken = i < tokens.length - 1 ? tokens[i + 1] : [];
|
||||||
@@ -335,7 +343,7 @@
|
|||||||
tokens.splice(i, 0, generate('CALL_END', ')', ['', 'end of input', token[2]], prevToken));
|
tokens.splice(i, 0, generate('CALL_END', ')', ['', 'end of input', token[2]], prevToken));
|
||||||
return i += 1;
|
return i += 1;
|
||||||
};
|
};
|
||||||
startImplicitObject = function(idx, startsLine = true) {
|
startImplicitObject = function(idx, {startsLine = true, continuationLineIndent} = {}) {
|
||||||
var val;
|
var val;
|
||||||
stack.push([
|
stack.push([
|
||||||
'{',
|
'{',
|
||||||
@@ -343,7 +351,8 @@
|
|||||||
{
|
{
|
||||||
sameLine: true,
|
sameLine: true,
|
||||||
startsLine: startsLine,
|
startsLine: startsLine,
|
||||||
ours: true
|
ours: true,
|
||||||
|
continuationLineIndent: continuationLineIndent
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
val = new String('{');
|
val = new String('{');
|
||||||
@@ -467,9 +476,9 @@
|
|||||||
// if f(a: 1)
|
// if f(a: 1)
|
||||||
|
|
||||||
// which is probably always unintended.
|
// which is probably always unintended.
|
||||||
// Furthermore don’t allow this in literal arrays, as
|
// Furthermore don’t allow this in the first line of a literal array
|
||||||
// that creates grammatical ambiguities.
|
// or explicit object, as that creates grammatical ambiguities (#5368).
|
||||||
if (indexOf.call(IMPLICIT_FUNC, tag) >= 0 && this.indexOfTag(i + 1, 'INDENT') > -1 && this.looksObjectish(i + 2) && !this.findTagsBackwards(i, ['CLASS', 'EXTENDS', 'IF', 'CATCH', 'SWITCH', 'LEADING_WHEN', 'FOR', 'WHILE', 'UNTIL'])) {
|
if (indexOf.call(IMPLICIT_FUNC, tag) >= 0 && this.indexOfTag(i + 1, 'INDENT') > -1 && this.looksObjectish(i + 2) && !this.findTagsBackwards(i, ['CLASS', 'EXTENDS', 'IF', 'CATCH', 'SWITCH', 'LEADING_WHEN', 'FOR', 'WHILE', 'UNTIL']) && !(((ref1 = (s = (ref2 = stackTop()) != null ? ref2[0] : void 0)) === '{' || ref1 === '[') && !isImplicit(stackTop()) && this.findTagsBackwards(i, s))) {
|
||||||
startImplicitCall(i + 1);
|
startImplicitCall(i + 1);
|
||||||
stack.push(['INDENT', i + 2]);
|
stack.push(['INDENT', i + 2]);
|
||||||
return forward(3);
|
return forward(3);
|
||||||
@@ -478,25 +487,37 @@
|
|||||||
if (tag === ':') {
|
if (tag === ':') {
|
||||||
// Go back to the (implicit) start of the object.
|
// Go back to the (implicit) start of the object.
|
||||||
s = (function() {
|
s = (function() {
|
||||||
var ref1;
|
var ref3;
|
||||||
switch (false) {
|
switch (false) {
|
||||||
case ref1 = this.tag(i - 1), indexOf.call(EXPRESSION_END, ref1) < 0:
|
case ref3 = this.tag(i - 1), indexOf.call(EXPRESSION_END, ref3) < 0:
|
||||||
return start[1];
|
[startTag, startIndex] = start;
|
||||||
|
if (startTag === '[' && startIndex > 0 && this.tag(startIndex - 1) === '@' && !tokens[startIndex - 1].spaced) {
|
||||||
|
return startIndex - 1;
|
||||||
|
} else {
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case this.tag(i - 2) !== '@':
|
case this.tag(i - 2) !== '@':
|
||||||
return i - 2;
|
return i - 2;
|
||||||
default:
|
default:
|
||||||
return i - 1;
|
return i - 1;
|
||||||
}
|
}
|
||||||
}).call(this);
|
}).call(this);
|
||||||
startsLine = s <= 0 || (ref1 = this.tag(s - 1), indexOf.call(LINEBREAKS, ref1) >= 0) || tokens[s - 1].newLine;
|
startsLine = s <= 0 || (ref3 = this.tag(s - 1), indexOf.call(LINEBREAKS, ref3) >= 0) || tokens[s - 1].newLine;
|
||||||
// Are we just continuing an already declared object?
|
// Are we just continuing an already declared object?
|
||||||
|
// Including the case where we indent on the line after an explicit '{'.
|
||||||
if (stackTop()) {
|
if (stackTop()) {
|
||||||
[stackTag, stackIdx] = stackTop();
|
[stackTag, stackIdx] = stackTop();
|
||||||
if ((stackTag === '{' || stackTag === 'INDENT' && this.tag(stackIdx - 1) === '{') && (startsLine || this.tag(s - 1) === ',' || this.tag(s - 1) === '{')) {
|
stackNext = stack[stack.length - 2];
|
||||||
|
if ((stackTag === '{' || stackTag === 'INDENT' && (stackNext != null ? stackNext[0] : void 0) === '{' && !isImplicit(stackNext) && this.findTagsBackwards(stackIdx - 1, ['{'])) && (startsLine || this.tag(s - 1) === ',' || this.tag(s - 1) === '{') && (ref4 = this.tag(s - 1), indexOf.call(UNFINISHED, ref4) < 0)) {
|
||||||
return forward(1);
|
return forward(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startImplicitObject(s, !!startsLine);
|
preObjectToken = i > 1 ? tokens[i - 2] : [];
|
||||||
|
startImplicitObject(s, {
|
||||||
|
startsLine: !!startsLine,
|
||||||
|
continuationLineIndent: preObjectToken.continuationLineIndent
|
||||||
|
});
|
||||||
return forward(2);
|
return forward(2);
|
||||||
}
|
}
|
||||||
// End implicit calls when chaining method calls
|
// End implicit calls when chaining method calls
|
||||||
@@ -526,6 +547,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// End indented-continuation-line implicit objects once that indentation is over.
|
||||||
|
if (tag === 'TERMINATOR' && token.endsContinuationLineIndentation) {
|
||||||
|
({preContinuationLineIndent} = token.endsContinuationLineIndentation);
|
||||||
|
while (inImplicitObject() && ((implicitObjectIndent = stackTop()[2].continuationLineIndent) != null) && implicitObjectIndent > preContinuationLineIndent) {
|
||||||
|
endImplicitObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
newLine = prevTag === 'OUTDENT' || prevToken.newLine;
|
newLine = prevTag === 'OUTDENT' || prevToken.newLine;
|
||||||
if (indexOf.call(IMPLICIT_END, tag) >= 0 || (indexOf.call(CALL_CLOSERS, tag) >= 0 && newLine) || ((tag === '..' || tag === '...') && this.findTagsBackwards(i, ["INDEX_START"]))) {
|
if (indexOf.call(IMPLICIT_END, tag) >= 0 || (indexOf.call(CALL_CLOSERS, tag) >= 0 && newLine) || ((tag === '..' || tag === '...') && this.findTagsBackwards(i, ["INDEX_START"]))) {
|
||||||
while (inImplicit()) {
|
while (inImplicit()) {
|
||||||
@@ -562,7 +590,7 @@
|
|||||||
|
|
||||||
// f a, b: c, d: e, f, g: h: i, j
|
// f a, b: c, d: e, f, g: h: i, j
|
||||||
|
|
||||||
if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && !((ref2 = this.tag(i + 2)) === 'FOROF' || ref2 === 'FORIN') && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) {
|
if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && !((ref5 = this.tag(i + 2)) === 'FOROF' || ref5 === 'FORIN') && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) {
|
||||||
// When nextTag is OUTDENT the comma is insignificant and
|
// When nextTag is OUTDENT the comma is insignificant and
|
||||||
// should just be ignored so embed it in the implicit object.
|
// should just be ignored so embed it in the implicit object.
|
||||||
|
|
||||||
@@ -577,11 +605,11 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure only strings and wrapped expressions are used in CSX attributes.
|
// Make sure only strings and wrapped expressions are used in JSX attributes.
|
||||||
enforceValidCSXAttributes() {
|
enforceValidJSXAttributes() {
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
return this.scanTokens(function(token, i, tokens) {
|
||||||
var next, ref;
|
var next, ref;
|
||||||
if (token.csxColon) {
|
if (token.jsxColon) {
|
||||||
next = tokens[i + 1];
|
next = tokens[i + 1];
|
||||||
if ((ref = next[0]) !== 'STRING_START' && ref !== 'STRING' && ref !== '(') {
|
if ((ref = next[0]) !== 'STRING_START' && ref !== 'STRING' && ref !== '(') {
|
||||||
throwSyntaxError('expected wrapped or quoted JSX attribute', next[2]);
|
throwSyntaxError('expected wrapped or quoted JSX attribute', next[2]);
|
||||||
@@ -595,13 +623,24 @@
|
|||||||
// lost into the ether, find comments attached to doomed tokens and move them
|
// lost into the ether, find comments attached to doomed tokens and move them
|
||||||
// to a token that will make it to the other side.
|
// to a token that will make it to the other side.
|
||||||
rescueStowawayComments() {
|
rescueStowawayComments() {
|
||||||
var insertPlaceholder, shiftCommentsBackward, shiftCommentsForward;
|
var dontShiftForward, insertPlaceholder, shiftCommentsBackward, shiftCommentsForward;
|
||||||
insertPlaceholder = function(token, j, tokens, method) {
|
insertPlaceholder = function(token, j, tokens, method) {
|
||||||
if (tokens[j][0] !== 'TERMINATOR') {
|
if (tokens[j][0] !== 'TERMINATOR') {
|
||||||
tokens[method](generate('TERMINATOR', '\n', tokens[j]));
|
tokens[method](generate('TERMINATOR', '\n', tokens[j]));
|
||||||
}
|
}
|
||||||
return tokens[method](generate('JS', '', tokens[j], token));
|
return tokens[method](generate('JS', '', tokens[j], token));
|
||||||
};
|
};
|
||||||
|
dontShiftForward = function(i, tokens) {
|
||||||
|
var j, ref;
|
||||||
|
j = i + 1;
|
||||||
|
while (j !== tokens.length && (ref = tokens[j][0], indexOf.call(DISCARDED, ref) >= 0)) {
|
||||||
|
if (tokens[j][0] === 'INTERPOLATION_END') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
shiftCommentsForward = function(token, i, tokens) {
|
shiftCommentsForward = function(token, i, tokens) {
|
||||||
var comment, j, k, len, ref, ref1, ref2;
|
var comment, j, k, len, ref, ref1, ref2;
|
||||||
// Find the next surviving token and attach this token’s comments to it,
|
// Find the next surviving token and attach this token’s comments to it,
|
||||||
@@ -671,7 +710,7 @@
|
|||||||
if (token.comments.length !== 0) {
|
if (token.comments.length !== 0) {
|
||||||
shiftCommentsForward(token, i, tokens);
|
shiftCommentsForward(token, i, tokens);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!dontShiftForward(i, tokens)) {
|
||||||
// If any of this token’s comments start a line—there’s only
|
// If any of this token’s comments start a line—there’s only
|
||||||
// whitespace between the preceding newline and the start of the
|
// whitespace between the preceding newline and the start of the
|
||||||
// comment—and this isn’t one of the special `JS` tokens, then
|
// comment—and this isn’t one of the special `JS` tokens, then
|
||||||
@@ -708,31 +747,42 @@
|
|||||||
// Add location data to all tokens generated by the rewriter.
|
// Add location data to all tokens generated by the rewriter.
|
||||||
addLocationDataToGeneratedTokens() {
|
addLocationDataToGeneratedTokens() {
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
return this.scanTokens(function(token, i, tokens) {
|
||||||
var column, line, nextLocation, prevLocation, ref, ref1;
|
var column, line, nextLocation, prevLocation, rangeIndex, ref, ref1;
|
||||||
if (token[2]) {
|
if (token[2]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!(token.generated || token.explicit)) {
|
if (!(token.generated || token.explicit)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (token.fromThen && token[0] === 'INDENT') {
|
||||||
|
token[2] = token.origin[2];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (token[0] === '{' && (nextLocation = (ref = tokens[i + 1]) != null ? ref[2] : void 0)) {
|
if (token[0] === '{' && (nextLocation = (ref = tokens[i + 1]) != null ? ref[2] : void 0)) {
|
||||||
({
|
({
|
||||||
first_line: line,
|
first_line: line,
|
||||||
first_column: column
|
first_column: column,
|
||||||
|
range: [rangeIndex]
|
||||||
} = nextLocation);
|
} = nextLocation);
|
||||||
} else if (prevLocation = (ref1 = tokens[i - 1]) != null ? ref1[2] : void 0) {
|
} else if (prevLocation = (ref1 = tokens[i - 1]) != null ? ref1[2] : void 0) {
|
||||||
({
|
({
|
||||||
last_line: line,
|
last_line: line,
|
||||||
last_column: column
|
last_column: column,
|
||||||
|
range: [, rangeIndex]
|
||||||
} = prevLocation);
|
} = prevLocation);
|
||||||
|
column += 1;
|
||||||
} else {
|
} else {
|
||||||
line = column = 0;
|
line = column = 0;
|
||||||
|
rangeIndex = 0;
|
||||||
}
|
}
|
||||||
token[2] = {
|
token[2] = {
|
||||||
first_line: line,
|
first_line: line,
|
||||||
first_column: column,
|
first_column: column,
|
||||||
last_line: line,
|
last_line: line,
|
||||||
last_column: column
|
last_column: column,
|
||||||
|
last_line_exclusive: line,
|
||||||
|
last_column_exclusive: column,
|
||||||
|
range: [rangeIndex, rangeIndex]
|
||||||
};
|
};
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
@@ -741,63 +791,104 @@
|
|||||||
// `OUTDENT` tokens should always be positioned at the last character of the
|
// `OUTDENT` tokens should always be positioned at the last character of the
|
||||||
// previous token, so that AST nodes ending in an `OUTDENT` token end up with a
|
// previous token, so that AST nodes ending in an `OUTDENT` token end up with a
|
||||||
// location corresponding to the last “real” token under the node.
|
// location corresponding to the last “real” token under the node.
|
||||||
fixOutdentLocationData() {
|
fixIndentationLocationData() {
|
||||||
|
var findPrecedingComment;
|
||||||
|
if (this.allComments == null) {
|
||||||
|
this.allComments = extractAllCommentTokens(this.tokens);
|
||||||
|
}
|
||||||
|
findPrecedingComment = (token, {afterPosition, indentSize, first, indented}) => {
|
||||||
|
var comment, k, l, lastMatching, matches, ref, ref1, tokenStart;
|
||||||
|
tokenStart = token[2].range[0];
|
||||||
|
matches = function(comment) {
|
||||||
|
if (comment.outdented) {
|
||||||
|
if (!((indentSize != null) && comment.indentSize > indentSize)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (indented && !comment.indented) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(comment.locationData.range[0] < tokenStart)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(comment.locationData.range[0] > afterPosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
if (first) {
|
||||||
|
lastMatching = null;
|
||||||
|
ref = this.allComments;
|
||||||
|
for (k = ref.length - 1; k >= 0; k += -1) {
|
||||||
|
comment = ref[k];
|
||||||
|
if (matches(comment)) {
|
||||||
|
lastMatching = comment;
|
||||||
|
} else if (lastMatching) {
|
||||||
|
return lastMatching;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastMatching;
|
||||||
|
}
|
||||||
|
ref1 = this.allComments;
|
||||||
|
for (l = ref1.length - 1; l >= 0; l += -1) {
|
||||||
|
comment = ref1[l];
|
||||||
|
if (matches(comment)) {
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
return this.scanTokens(function(token, i, tokens) {
|
||||||
var prevLocationData;
|
var isIndent, nextToken, nextTokenIndex, precedingComment, prevLocationData, prevToken, ref, ref1, ref2, useNextToken;
|
||||||
if (!(token[0] === 'OUTDENT' || (token.generated && token[0] === 'CALL_END') || (token.generated && token[0] === '}'))) {
|
if (!(((ref = token[0]) === 'INDENT' || ref === 'OUTDENT') || (token.generated && token[0] === 'CALL_END' && !((ref1 = token.data) != null ? ref1.closingTagNameToken : void 0)) || (token.generated && token[0] === '}'))) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
prevLocationData = tokens[i - 1][2];
|
isIndent = token[0] === 'INDENT';
|
||||||
|
prevToken = (ref2 = token.prevToken) != null ? ref2 : tokens[i - 1];
|
||||||
|
prevLocationData = prevToken[2];
|
||||||
|
// addLocationDataToGeneratedTokens() set the outdent’s location data
|
||||||
|
// to the preceding token’s, but in order to detect comments inside an
|
||||||
|
// empty "block" we want to look for comments preceding the next token.
|
||||||
|
useNextToken = token.explicit || token.generated;
|
||||||
|
if (useNextToken) {
|
||||||
|
nextToken = token;
|
||||||
|
nextTokenIndex = i;
|
||||||
|
while ((nextToken.explicit || nextToken.generated) && nextTokenIndex !== tokens.length - 1) {
|
||||||
|
nextToken = tokens[nextTokenIndex++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
precedingComment = findPrecedingComment(useNextToken ? nextToken : token, {
|
||||||
|
afterPosition: prevLocationData.range[0],
|
||||||
|
indentSize: token.indentSize,
|
||||||
|
first: isIndent,
|
||||||
|
indented: useNextToken
|
||||||
|
});
|
||||||
|
if (isIndent) {
|
||||||
|
if (!(precedingComment != null ? precedingComment.newLine : void 0)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (token.generated && token[0] === 'CALL_END' && (precedingComment != null ? precedingComment.indented : void 0)) {
|
||||||
|
// We don’t want e.g. an implicit call at the end of an `if` condition to
|
||||||
|
// include a following indented comment.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (precedingComment != null) {
|
||||||
|
prevLocationData = precedingComment.locationData;
|
||||||
|
}
|
||||||
token[2] = {
|
token[2] = {
|
||||||
first_line: prevLocationData.last_line,
|
first_line: precedingComment != null ? prevLocationData.first_line : prevLocationData.last_line,
|
||||||
first_column: prevLocationData.last_column,
|
first_column: precedingComment != null ? isIndent ? 0 : prevLocationData.first_column : prevLocationData.last_column,
|
||||||
last_line: prevLocationData.last_line,
|
last_line: prevLocationData.last_line,
|
||||||
last_column: prevLocationData.last_column
|
last_column: prevLocationData.last_column,
|
||||||
|
last_line_exclusive: prevLocationData.last_line_exclusive,
|
||||||
|
last_column_exclusive: prevLocationData.last_column_exclusive,
|
||||||
|
range: isIndent && (precedingComment != null) ? [prevLocationData.range[0] - precedingComment.indentSize, prevLocationData.range[1]] : prevLocationData.range
|
||||||
};
|
};
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add parens around a `do` IIFE followed by a chained `.` so that the
|
|
||||||
// chaining applies to the executed function rather than the function
|
|
||||||
// object (see #3736)
|
|
||||||
addParensToChainedDoIife() {
|
|
||||||
var action, condition, doIndex;
|
|
||||||
condition = function(token, i) {
|
|
||||||
return this.tag(i - 1) === 'OUTDENT';
|
|
||||||
};
|
|
||||||
action = function(token, i) {
|
|
||||||
var ref;
|
|
||||||
if (ref = token[0], indexOf.call(CALL_CLOSERS, ref) < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.tokens.splice(doIndex, 0, generate('(', '(', this.tokens[doIndex]));
|
|
||||||
return this.tokens.splice(i + 1, 0, generate(')', ')', this.tokens[i]));
|
|
||||||
};
|
|
||||||
doIndex = null;
|
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
|
||||||
var glyphIndex, ref;
|
|
||||||
if (token[1] !== 'do') {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
doIndex = i;
|
|
||||||
glyphIndex = i + 1;
|
|
||||||
if (this.tag(i + 1) === 'PARAM_START') {
|
|
||||||
glyphIndex = null;
|
|
||||||
this.detectEnd(i + 1, function(token, i) {
|
|
||||||
return this.tag(i - 1) === 'PARAM_END';
|
|
||||||
}, function(token, i) {
|
|
||||||
return glyphIndex = i;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!((glyphIndex != null) && ((ref = this.tag(glyphIndex)) === '->' || ref === '=>') && this.tag(glyphIndex + 1) === 'INDENT')) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
this.detectEnd(glyphIndex + 1, condition, action);
|
|
||||||
return 2;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because our grammar is LALR(1), it can’t handle some single-line
|
// Because our grammar is LALR(1), it can’t handle some single-line
|
||||||
// expressions that lack ending delimiters. The **Rewriter** adds the implicit
|
// expressions that lack ending delimiters. The **Rewriter** adds the implicit
|
||||||
// blocks, so it doesn’t need to. To keep the grammar clean and tidy, trailing
|
// blocks, so it doesn’t need to. To keep the grammar clean and tidy, trailing
|
||||||
@@ -846,7 +937,7 @@
|
|||||||
return i + 2;
|
return i + 2;
|
||||||
};
|
};
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
return this.scanTokens(function(token, i, tokens) {
|
||||||
var conditionTag, j, k, ref, ref1, tag;
|
var conditionTag, j, k, ref, ref1, ref2, tag;
|
||||||
[tag] = token;
|
[tag] = token;
|
||||||
conditionTag = (tag === '->' || tag === '=>') && this.findTagsBackwards(i, ['IF', 'WHILE', 'FOR', 'UNTIL', 'SWITCH', 'WHEN', 'LEADING_WHEN', '[', 'INDEX_START']) && !(this.findTagsBackwards(i, ['THEN', '..', '...']));
|
conditionTag = (tag === '->' || tag === '=>') && this.findTagsBackwards(i, ['IF', 'WHILE', 'FOR', 'UNTIL', 'SWITCH', 'WHEN', 'LEADING_WHEN', '[', 'INDEX_START']) && !(this.findTagsBackwards(i, ['THEN', '..', '...']));
|
||||||
if (tag === 'TERMINATOR') {
|
if (tag === 'TERMINATOR') {
|
||||||
@@ -855,6 +946,10 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (ref = this.tag(i + 1), indexOf.call(EXPRESSION_CLOSE, ref) >= 0) {
|
if (ref = this.tag(i + 1), indexOf.call(EXPRESSION_CLOSE, ref) >= 0) {
|
||||||
|
if (token[1] === ';' && this.tag(i + 1) === 'OUTDENT') {
|
||||||
|
tokens[i + 1].prevToken = token;
|
||||||
|
moveComments(token, tokens[i + 1]);
|
||||||
|
}
|
||||||
tokens.splice(i, 1);
|
tokens.splice(i, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -868,7 +963,7 @@
|
|||||||
return 2 + j;
|
return 2 + j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((tag === '->' || tag === '=>') && (this.tag(i + 1) === ',' || this.tag(i + 1) === '.' && token.newLine)) {
|
if ((tag === '->' || tag === '=>') && (((ref2 = this.tag(i + 1)) === ',' || ref2 === ']') || this.tag(i + 1) === '.' && token.newLine)) {
|
||||||
[indent, outdent] = this.indentation(tokens[i]);
|
[indent, outdent] = this.indentation(tokens[i]);
|
||||||
tokens.splice(i + 1, 0, indent, outdent);
|
tokens.splice(i + 1, 0, indent, outdent);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -927,6 +1022,30 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For tokens with extra data, we want to make that data visible to the grammar
|
||||||
|
// by wrapping the token value as a String() object and setting the data as
|
||||||
|
// properties of that object. The grammar should then be responsible for
|
||||||
|
// cleaning this up for the node constructor: unwrapping the token value to a
|
||||||
|
// primitive string and separately passing any expected token data properties
|
||||||
|
exposeTokenDataToGrammar() {
|
||||||
|
return this.scanTokens(function(token, i) {
|
||||||
|
var key, ref, ref1, val;
|
||||||
|
if (token.generated || (token.data && Object.keys(token.data).length !== 0)) {
|
||||||
|
token[1] = new String(token[1]);
|
||||||
|
ref1 = (ref = token.data) != null ? ref : {};
|
||||||
|
for (key in ref1) {
|
||||||
|
if (!hasProp.call(ref1, key)) continue;
|
||||||
|
val = ref1[key];
|
||||||
|
token[1][key] = val;
|
||||||
|
}
|
||||||
|
if (token.generated) {
|
||||||
|
token[1].generated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Generate the indentation tokens, based on another token on the same line.
|
// Generate the indentation tokens, based on another token on the same line.
|
||||||
indentation(origin) {
|
indentation(origin) {
|
||||||
var indent, outdent;
|
var indent, outdent;
|
||||||
@@ -959,7 +1078,7 @@
|
|||||||
// ---------
|
// ---------
|
||||||
|
|
||||||
// List of the token pairs that must be balanced.
|
// List of the token pairs that must be balanced.
|
||||||
BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END'], ['STRING_START', 'STRING_END'], ['REGEX_START', 'REGEX_END']];
|
BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END'], ['STRING_START', 'STRING_END'], ['INTERPOLATION_START', 'INTERPOLATION_END'], ['REGEX_START', 'REGEX_END']];
|
||||||
|
|
||||||
// The inverse mappings of `BALANCED_PAIRS` we’re trying to fix up, so we can
|
// The inverse mappings of `BALANCED_PAIRS` we’re trying to fix up, so we can
|
||||||
// look things up from either end.
|
// look things up from either end.
|
||||||
@@ -983,7 +1102,7 @@
|
|||||||
IMPLICIT_FUNC = ['IDENTIFIER', 'PROPERTY', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
IMPLICIT_FUNC = ['IDENTIFIER', 'PROPERTY', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
||||||
|
|
||||||
// If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
|
// If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
|
||||||
IMPLICIT_CALL = ['IDENTIFIER', 'CSX_TAG', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'UNDEFINED', 'NULL', 'BOOL', 'UNARY', 'YIELD', 'AWAIT', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
|
IMPLICIT_CALL = ['IDENTIFIER', 'JSX_TAG', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'DYNAMIC_IMPORT', 'IMPORT_META', 'NEW_TARGET', 'UNDEFINED', 'NULL', 'BOOL', 'UNARY', 'DO', 'DO_IIFE', 'YIELD', 'AWAIT', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
|
||||||
|
|
||||||
IMPLICIT_UNSPACED_CALL = ['+', '-'];
|
IMPLICIT_UNSPACED_CALL = ['+', '-'];
|
||||||
|
|
||||||
@@ -1011,6 +1130,9 @@
|
|||||||
// `STRING_START` isn’t on this list because its `locationData` matches that of
|
// `STRING_START` isn’t on this list because its `locationData` matches that of
|
||||||
// the node that becomes `StringWithInterpolations`, and therefore
|
// the node that becomes `StringWithInterpolations`, and therefore
|
||||||
// `addDataToNode` attaches `STRING_START`’s tokens to that node.
|
// `addDataToNode` attaches `STRING_START`’s tokens to that node.
|
||||||
DISCARDED = ['(', ')', '[', ']', '{', '}', '.', '..', '...', ',', '=', '++', '--', '?', 'AS', 'AWAIT', 'CALL_START', 'CALL_END', 'DEFAULT', 'ELSE', 'EXTENDS', 'EXPORT', 'FORIN', 'FOROF', 'FORFROM', 'IMPORT', 'INDENT', 'INDEX_SOAK', 'LEADING_WHEN', 'OUTDENT', 'PARAM_END', 'REGEX_START', 'REGEX_END', 'RETURN', 'STRING_END', 'THROW', 'UNARY', 'YIELD'].concat(IMPLICIT_UNSPACED_CALL.concat(IMPLICIT_END.concat(CALL_CLOSERS.concat(CONTROL_IN_IMPLICIT))));
|
DISCARDED = ['(', ')', '[', ']', '{', '}', ':', '.', '..', '...', ',', '=', '++', '--', '?', 'AS', 'AWAIT', 'CALL_START', 'CALL_END', 'DEFAULT', 'DO', 'DO_IIFE', 'ELSE', 'EXTENDS', 'EXPORT', 'FORIN', 'FOROF', 'FORFROM', 'IMPORT', 'INDENT', 'INDEX_SOAK', 'INTERPOLATION_START', 'INTERPOLATION_END', 'LEADING_WHEN', 'OUTDENT', 'PARAM_END', 'REGEX_START', 'REGEX_END', 'RETURN', 'STRING_END', 'THROW', 'UNARY', 'YIELD'].concat(IMPLICIT_UNSPACED_CALL.concat(IMPLICIT_END.concat(CALL_CLOSERS.concat(CONTROL_IN_IMPLICIT))));
|
||||||
|
|
||||||
|
// Tokens that, when appearing at the end of a line, suppress a following TERMINATOR/INDENT token
|
||||||
|
exports.UNFINISHED = UNFINISHED = ['\\', '.', '?.', '?::', 'UNARY', 'DO', 'DO_IIFE', 'MATH', 'UNARY_MATH', '+', '-', '**', 'SHIFT', 'RELATION', 'COMPARE', '&', '^', '|', '&&', '||', 'BIN?', 'EXTENDS'];
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
// The **Scope** class regulates lexical scoping within CoffeeScript. As you
|
// The **Scope** class regulates lexical scoping within CoffeeScript. As you
|
||||||
// generate code, you create a tree of scopes in the same shape as the nested
|
// generate code, you create a tree of scopes in the same shape as the nested
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.3.2
|
// Generated by CoffeeScript 2.7.0
|
||||||
(function() {
|
(function() {
|
||||||
// Source maps allow JavaScript runtimes to match running JavaScript back to
|
// Source maps allow JavaScript runtimes to match running JavaScript back to
|
||||||
// the original source code that corresponds to it. This can be minified
|
// the original source code that corresponds to it. This can be minified
|
||||||
@@ -53,10 +53,10 @@
|
|||||||
// SourceMap
|
// SourceMap
|
||||||
// ---------
|
// ---------
|
||||||
|
|
||||||
// Maps locations in a single generated JavaScript file back to locations in
|
// Maps locations in a single generated JavaScript file back to locations in
|
||||||
// the original CoffeeScript source file.
|
// the original CoffeeScript source file.
|
||||||
|
|
||||||
// This is intentionally agnostic towards how a source map might be represented on
|
// This is intentionally agnostic towards how a source map might be represented on
|
||||||
// disk. Once the compiler is ready to produce a "v3"-style source map, we can walk
|
// disk. Once the compiler is ready to produce a "v3"-style source map, we can walk
|
||||||
// through the arrays of line and column buffer to produce it.
|
// through the arrays of line and column buffer to produce it.
|
||||||
class SourceMap {
|
class SourceMap {
|
||||||
@@ -85,10 +85,20 @@
|
|||||||
return lineMap && lineMap.sourceLocation(column);
|
return lineMap && lineMap.sourceLocation(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static registerCompiled(filename, source, sourcemap) {
|
||||||
|
if (sourcemap != null) {
|
||||||
|
return SourceMap.sourceMaps[filename] = sourcemap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSourceMap(filename) {
|
||||||
|
return SourceMap.sourceMaps[filename];
|
||||||
|
}
|
||||||
|
|
||||||
// V3 SourceMap Generation
|
// V3 SourceMap Generation
|
||||||
// -----------------------
|
// -----------------------
|
||||||
|
|
||||||
// Builds up a V3 source map, returning the generated JSON as a string.
|
// Builds up a V3 source map, returning the generated JSON as a string.
|
||||||
// `options.sourceRoot` may be used to specify the sourceRoot written to the source
|
// `options.sourceRoot` may be used to specify the sourceRoot written to the source
|
||||||
// map. Also, `options.sourceFiles` and `options.generatedFile` may be passed to
|
// map. Also, `options.sourceFiles` and `options.generatedFile` may be passed to
|
||||||
// set "sources" and "file", respectively.
|
// set "sources" and "file", respectively.
|
||||||
@@ -183,6 +193,14 @@
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Caching
|
||||||
|
// -------
|
||||||
|
|
||||||
|
// A static source maps cache `filename`: `map`. These are used for transforming
|
||||||
|
// stack traces and are currently set in `CoffeeScript.compile` for all files
|
||||||
|
// compiled with the source maps option.
|
||||||
|
SourceMap.sourceMaps = Object.create(null);
|
||||||
|
|
||||||
// Base64 VLQ Encoding
|
// Base64 VLQ Encoding
|
||||||
// -------------------
|
// -------------------
|
||||||
|
|
||||||
|
|||||||
10371
package-lock.json
generated
10371
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
29
package.json
29
package.json
@@ -8,7 +8,7 @@
|
|||||||
"compiler"
|
"compiler"
|
||||||
],
|
],
|
||||||
"author": "Jeremy Ashkenas",
|
"author": "Jeremy Ashkenas",
|
||||||
"version": "2.3.2",
|
"version": "2.7.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
@@ -17,7 +17,8 @@
|
|||||||
"lib": "./lib/coffeescript"
|
"lib": "./lib/coffeescript"
|
||||||
},
|
},
|
||||||
"main": "./lib/coffeescript/index",
|
"main": "./lib/coffeescript/index",
|
||||||
"browser": "./lib/coffeescript/browser",
|
"module": "./lib/coffeescript-browser-compiler-modern/coffeescript.js",
|
||||||
|
"browser": "./lib/coffeescript-browser-compiler-legacy/coffeescript.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"coffee": "./bin/coffee",
|
"coffee": "./bin/coffee",
|
||||||
"cake": "./bin/cake"
|
"cake": "./bin/cake"
|
||||||
@@ -39,16 +40,16 @@
|
|||||||
"url": "git://github.com/jashkenas/coffeescript.git"
|
"url": "git://github.com/jashkenas/coffeescript.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.0.0",
|
"@babel/core": "~7.17.9",
|
||||||
"@babel/preset-env": "^7.0.0",
|
"@babel/preset-env": "~7.16.11",
|
||||||
"babel-preset-minify": "^0.4.3",
|
"babel-preset-minify": "~0.5.1",
|
||||||
"codemirror": "^5.39.2",
|
"codemirror": "~5.65.3",
|
||||||
"docco": "~0.8.0",
|
"docco": "~0.9.1",
|
||||||
"highlight.js": "~9.12.0",
|
"highlight.js": "~11.5.1",
|
||||||
"jison": ">=0.4.18",
|
"jison": "~0.4.18",
|
||||||
"markdown-it": "~8.4.2",
|
"markdown-it": "~13.0.0",
|
||||||
"underscore": "~1.9.1",
|
"puppeteer": "~13.6.0",
|
||||||
"webpack": "~4.17.2"
|
"underscore": "~1.13.3",
|
||||||
},
|
"webpack": "~5.72.0"
|
||||||
"dependencies": {}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ CoffeeScript.load = (url, callback, options = {}, hold = false) ->
|
|||||||
# Activate CoffeeScript in the browser by having it compile and evaluate
|
# Activate CoffeeScript in the browser by having it compile and evaluate
|
||||||
# all script tags with a content-type of `text/coffeescript`.
|
# all script tags with a content-type of `text/coffeescript`.
|
||||||
# This happens on page load.
|
# This happens on page load.
|
||||||
runScripts = ->
|
CoffeeScript.runScripts = ->
|
||||||
scripts = window.document.getElementsByTagName 'script'
|
scripts = window.document.getElementsByTagName 'script'
|
||||||
coffeetypes = ['text/coffeescript', 'text/literate-coffeescript']
|
coffeetypes = ['text/coffeescript', 'text/literate-coffeescript']
|
||||||
coffees = (s for s in scripts when s.type in coffeetypes)
|
coffees = (s for s in scripts when s.type in coffeetypes)
|
||||||
@@ -96,7 +96,12 @@ runScripts = ->
|
|||||||
execute()
|
execute()
|
||||||
|
|
||||||
# Listen for window load, both in decent browsers and in IE.
|
# Listen for window load, both in decent browsers and in IE.
|
||||||
if window.addEventListener
|
# Only attach this event handler on startup for the
|
||||||
window.addEventListener 'DOMContentLoaded', runScripts, no
|
# non-ES module version of the browser compiler, to preserve
|
||||||
else
|
# backward compatibility while letting the ES module version
|
||||||
window.attachEvent 'onload', runScripts
|
# be importable without side effects.
|
||||||
|
if this is window
|
||||||
|
if window.addEventListener
|
||||||
|
window.addEventListener 'DOMContentLoaded', CoffeeScript.runScripts, no
|
||||||
|
else
|
||||||
|
window.attachEvent 'onload', CoffeeScript.runScripts
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ exports.FILE_EXTENSIONS = FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.m
|
|||||||
# Expose helpers for testing.
|
# Expose helpers for testing.
|
||||||
exports.helpers = helpers
|
exports.helpers = helpers
|
||||||
|
|
||||||
|
{getSourceMap, registerCompiled} = SourceMap
|
||||||
|
# This is exported to enable an external module to implement caching of
|
||||||
|
# sourcemaps. This is used only when `patchStackTrace` has been called to adjust
|
||||||
|
# stack traces for files with cached source maps.
|
||||||
|
exports.registerCompiled = registerCompiled
|
||||||
|
|
||||||
# Function that allows for btoa in both nodejs and the browser.
|
# Function that allows for btoa in both nodejs and the browser.
|
||||||
base64encode = (src) -> switch
|
base64encode = (src) -> switch
|
||||||
when typeof Buffer is 'function'
|
when typeof Buffer is 'function'
|
||||||
@@ -43,17 +49,6 @@ withPrettyErrors = (fn) ->
|
|||||||
throw err if typeof code isnt 'string' # Support `CoffeeScript.nodes(tokens)`.
|
throw err if typeof code isnt 'string' # Support `CoffeeScript.nodes(tokens)`.
|
||||||
throw helpers.updateSyntaxError err, code, options.filename
|
throw helpers.updateSyntaxError err, code, options.filename
|
||||||
|
|
||||||
# For each compiled file, save its source in memory in case we need to
|
|
||||||
# recompile it later. We might need to recompile if the first compilation
|
|
||||||
# didn’t create a source map (faster) but something went wrong and we need
|
|
||||||
# a stack trace. Assuming that most of the time, code isn’t throwing
|
|
||||||
# exceptions, it’s probably more efficient to compile twice only when we
|
|
||||||
# need a stack trace, rather than always generating a source map even when
|
|
||||||
# it’s not likely to be used. Save in form of `filename`: [`(source)`]
|
|
||||||
sources = {}
|
|
||||||
# Also save source maps if generated, in form of `(source)`: [`(source map)`].
|
|
||||||
sourceMaps = {}
|
|
||||||
|
|
||||||
# Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.
|
# Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.
|
||||||
#
|
#
|
||||||
# If `options.sourceMap` is specified, then `options.filename` must also be
|
# If `options.sourceMap` is specified, then `options.filename` must also be
|
||||||
@@ -67,16 +62,12 @@ sourceMaps = {}
|
|||||||
exports.compile = compile = withPrettyErrors (code, options = {}) ->
|
exports.compile = compile = withPrettyErrors (code, options = {}) ->
|
||||||
# Clone `options`, to avoid mutating the `options` object passed in.
|
# Clone `options`, to avoid mutating the `options` object passed in.
|
||||||
options = Object.assign {}, options
|
options = Object.assign {}, options
|
||||||
# Always generate a source map if no filename is passed in, since without a
|
|
||||||
# a filename we have no way to retrieve this source later in the event that
|
|
||||||
# we need to recompile it to get a source map for `prepareStackTrace`.
|
|
||||||
generateSourceMap = options.sourceMap or options.inlineMap or not options.filename?
|
generateSourceMap = options.sourceMap or options.inlineMap or not options.filename?
|
||||||
filename = options.filename or '<anonymous>'
|
filename = options.filename or helpers.anonymousFileName()
|
||||||
|
|
||||||
checkShebangLine filename, code
|
checkShebangLine filename, code
|
||||||
|
|
||||||
sources[filename] ?= []
|
|
||||||
sources[filename].push code
|
|
||||||
map = new SourceMap if generateSourceMap
|
map = new SourceMap if generateSourceMap
|
||||||
|
|
||||||
tokens = lexer.tokenize code, options
|
tokens = lexer.tokenize code, options
|
||||||
@@ -94,7 +85,28 @@ exports.compile = compile = withPrettyErrors (code, options = {}) ->
|
|||||||
options.bare = yes
|
options.bare = yes
|
||||||
break
|
break
|
||||||
|
|
||||||
fragments = parser.parse(tokens).compileToFragments options
|
nodes = parser.parse tokens
|
||||||
|
# If all that was requested was a POJO representation of the nodes, e.g.
|
||||||
|
# the abstract syntax tree (AST), we can stop now and just return that
|
||||||
|
# (after fixing the location data for the root/`File`»`Program` node,
|
||||||
|
# which might’ve gotten misaligned from the original source due to the
|
||||||
|
# `clean` function in the lexer).
|
||||||
|
if options.ast
|
||||||
|
nodes.allCommentTokens = helpers.extractAllCommentTokens tokens
|
||||||
|
sourceCodeNumberOfLines = (code.match(/\r?\n/g) or '').length + 1
|
||||||
|
sourceCodeLastLine = /.*$/.exec(code)[0] # `.*` matches all but line break characters.
|
||||||
|
ast = nodes.ast options
|
||||||
|
range = [0, code.length]
|
||||||
|
ast.start = ast.program.start = range[0]
|
||||||
|
ast.end = ast.program.end = range[1]
|
||||||
|
ast.range = ast.program.range = range
|
||||||
|
ast.loc.start = ast.program.loc.start = {line: 1, column: 0}
|
||||||
|
ast.loc.end.line = ast.program.loc.end.line = sourceCodeNumberOfLines
|
||||||
|
ast.loc.end.column = ast.program.loc.end.column = sourceCodeLastLine.length
|
||||||
|
ast.tokens = tokens
|
||||||
|
return ast
|
||||||
|
|
||||||
|
fragments = nodes.compileToFragments options
|
||||||
|
|
||||||
currentLine = 0
|
currentLine = 0
|
||||||
currentLine += 1 if options.header
|
currentLine += 1 if options.header
|
||||||
@@ -126,8 +138,6 @@ exports.compile = compile = withPrettyErrors (code, options = {}) ->
|
|||||||
|
|
||||||
if generateSourceMap
|
if generateSourceMap
|
||||||
v3SourceMap = map.generate options, code
|
v3SourceMap = map.generate options, code
|
||||||
sourceMaps[filename] ?= []
|
|
||||||
sourceMaps[filename].push map
|
|
||||||
|
|
||||||
if options.transpile
|
if options.transpile
|
||||||
if typeof options.transpile isnt 'object'
|
if typeof options.transpile isnt 'object'
|
||||||
@@ -155,9 +165,11 @@ exports.compile = compile = withPrettyErrors (code, options = {}) ->
|
|||||||
if options.inlineMap
|
if options.inlineMap
|
||||||
encoded = base64encode JSON.stringify v3SourceMap
|
encoded = base64encode JSON.stringify v3SourceMap
|
||||||
sourceMapDataURI = "//# sourceMappingURL=data:application/json;base64,#{encoded}"
|
sourceMapDataURI = "//# sourceMappingURL=data:application/json;base64,#{encoded}"
|
||||||
sourceURL = "//# sourceURL=#{options.filename ? 'coffeescript'}"
|
sourceURL = "//# sourceURL=#{filename}"
|
||||||
js = "#{js}\n#{sourceMapDataURI}\n#{sourceURL}"
|
js = "#{js}\n#{sourceMapDataURI}\n#{sourceURL}"
|
||||||
|
|
||||||
|
registerCompiled filename, code, map
|
||||||
|
|
||||||
if options.sourceMap
|
if options.sourceMap
|
||||||
{
|
{
|
||||||
js
|
js
|
||||||
@@ -175,10 +187,8 @@ exports.tokens = withPrettyErrors (code, options) ->
|
|||||||
# return the AST. You can then compile it by calling `.compile()` on the root,
|
# return the AST. You can then compile it by calling `.compile()` on the root,
|
||||||
# or traverse it by using `.traverseChildren()` with a callback.
|
# or traverse it by using `.traverseChildren()` with a callback.
|
||||||
exports.nodes = withPrettyErrors (source, options) ->
|
exports.nodes = withPrettyErrors (source, options) ->
|
||||||
if typeof source is 'string'
|
source = lexer.tokenize source, options if typeof source is 'string'
|
||||||
parser.parse lexer.tokenize source, options
|
parser.parse source
|
||||||
else
|
|
||||||
parser.parse source
|
|
||||||
|
|
||||||
# This file used to export these methods; leave stubs that throw warnings
|
# This file used to export these methods; leave stubs that throw warnings
|
||||||
# instead. These methods have been moved into `index.coffee` to provide
|
# instead. These methods have been moved into `index.coffee` to provide
|
||||||
@@ -195,6 +205,10 @@ lexer = new Lexer
|
|||||||
# thin wrapper around it, compatible with the Jison API. We can then pass it
|
# thin wrapper around it, compatible with the Jison API. We can then pass it
|
||||||
# directly as a “Jison lexer.”
|
# directly as a “Jison lexer.”
|
||||||
parser.lexer =
|
parser.lexer =
|
||||||
|
yylloc:
|
||||||
|
range: []
|
||||||
|
options:
|
||||||
|
ranges: yes
|
||||||
lex: ->
|
lex: ->
|
||||||
token = parser.tokens[@pos++]
|
token = parser.tokens[@pos++]
|
||||||
if token
|
if token
|
||||||
@@ -236,114 +250,80 @@ parser.yy.parseError = (message, {token}) ->
|
|||||||
# from the lexer.
|
# from the lexer.
|
||||||
helpers.throwSyntaxError "unexpected #{errorText}", errorLoc
|
helpers.throwSyntaxError "unexpected #{errorText}", errorLoc
|
||||||
|
|
||||||
# Based on http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js
|
exports.patchStackTrace = ->
|
||||||
# Modified to handle sourceMap
|
# Based on http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js
|
||||||
formatSourcePosition = (frame, getSourceMapping) ->
|
# Modified to handle sourceMap
|
||||||
filename = undefined
|
formatSourcePosition = (frame, getSourceMapping) ->
|
||||||
fileLocation = ''
|
filename = undefined
|
||||||
|
fileLocation = ''
|
||||||
|
|
||||||
if frame.isNative()
|
if frame.isNative()
|
||||||
fileLocation = "native"
|
fileLocation = "native"
|
||||||
else
|
|
||||||
if frame.isEval()
|
|
||||||
filename = frame.getScriptNameOrSourceURL()
|
|
||||||
fileLocation = "#{frame.getEvalOrigin()}, " unless filename
|
|
||||||
else
|
else
|
||||||
filename = frame.getFileName()
|
if frame.isEval()
|
||||||
|
filename = frame.getScriptNameOrSourceURL()
|
||||||
filename or= "<anonymous>"
|
fileLocation = "#{frame.getEvalOrigin()}, " unless filename
|
||||||
|
|
||||||
line = frame.getLineNumber()
|
|
||||||
column = frame.getColumnNumber()
|
|
||||||
|
|
||||||
# Check for a sourceMap position
|
|
||||||
source = getSourceMapping filename, line, column
|
|
||||||
fileLocation =
|
|
||||||
if source
|
|
||||||
"#{filename}:#{source[0]}:#{source[1]}"
|
|
||||||
else
|
else
|
||||||
"#{filename}:#{line}:#{column}"
|
filename = frame.getFileName()
|
||||||
|
|
||||||
functionName = frame.getFunctionName()
|
filename or= "<anonymous>"
|
||||||
isConstructor = frame.isConstructor()
|
|
||||||
isMethodCall = not (frame.isToplevel() or isConstructor)
|
|
||||||
|
|
||||||
if isMethodCall
|
line = frame.getLineNumber()
|
||||||
methodName = frame.getMethodName()
|
column = frame.getColumnNumber()
|
||||||
typeName = frame.getTypeName()
|
|
||||||
|
|
||||||
if functionName
|
# Check for a sourceMap position
|
||||||
tp = as = ''
|
source = getSourceMapping filename, line, column
|
||||||
if typeName and functionName.indexOf typeName
|
fileLocation =
|
||||||
tp = "#{typeName}."
|
if source
|
||||||
if methodName and functionName.indexOf(".#{methodName}") isnt functionName.length - methodName.length - 1
|
"#{filename}:#{source[0]}:#{source[1]}"
|
||||||
as = " [as #{methodName}]"
|
else
|
||||||
|
"#{filename}:#{line}:#{column}"
|
||||||
|
|
||||||
"#{tp}#{functionName}#{as} (#{fileLocation})"
|
functionName = frame.getFunctionName()
|
||||||
|
isConstructor = frame.isConstructor()
|
||||||
|
isMethodCall = not (frame.isToplevel() or isConstructor)
|
||||||
|
|
||||||
|
if isMethodCall
|
||||||
|
methodName = frame.getMethodName()
|
||||||
|
typeName = frame.getTypeName()
|
||||||
|
|
||||||
|
if functionName
|
||||||
|
tp = as = ''
|
||||||
|
if typeName and functionName.indexOf typeName
|
||||||
|
tp = "#{typeName}."
|
||||||
|
if methodName and functionName.indexOf(".#{methodName}") isnt functionName.length - methodName.length - 1
|
||||||
|
as = " [as #{methodName}]"
|
||||||
|
|
||||||
|
"#{tp}#{functionName}#{as} (#{fileLocation})"
|
||||||
|
else
|
||||||
|
"#{typeName}.#{methodName or '<anonymous>'} (#{fileLocation})"
|
||||||
|
else if isConstructor
|
||||||
|
"new #{functionName or '<anonymous>'} (#{fileLocation})"
|
||||||
|
else if functionName
|
||||||
|
"#{functionName} (#{fileLocation})"
|
||||||
else
|
else
|
||||||
"#{typeName}.#{methodName or '<anonymous>'} (#{fileLocation})"
|
fileLocation
|
||||||
else if isConstructor
|
|
||||||
"new #{functionName or '<anonymous>'} (#{fileLocation})"
|
|
||||||
else if functionName
|
|
||||||
"#{functionName} (#{fileLocation})"
|
|
||||||
else
|
|
||||||
fileLocation
|
|
||||||
|
|
||||||
getSourceMap = (filename, line, column) ->
|
|
||||||
# Skip files that we didn’t compile, like Node system files that appear in
|
|
||||||
# the stack trace, as they never have source maps.
|
|
||||||
return null unless filename is '<anonymous>' or filename.slice(filename.lastIndexOf('.')) in FILE_EXTENSIONS
|
|
||||||
|
|
||||||
if filename isnt '<anonymous>' and sourceMaps[filename]?
|
|
||||||
return sourceMaps[filename][sourceMaps[filename].length - 1]
|
|
||||||
# CoffeeScript compiled in a browser or via `CoffeeScript.compile` or `.run`
|
|
||||||
# may get compiled with `options.filename` that’s missing, which becomes
|
|
||||||
# `<anonymous>`; but the runtime might request the stack trace with the
|
|
||||||
# filename of the script file. See if we have a source map cached under
|
|
||||||
# `<anonymous>` that matches the error.
|
|
||||||
else if sourceMaps['<anonymous>']?
|
|
||||||
# Work backwards from the most recent anonymous source maps, until we find
|
|
||||||
# one that works. This isn’t foolproof; there is a chance that multiple
|
|
||||||
# source maps will have line/column pairs that match. But we have no other
|
|
||||||
# way to match them. `frame.getFunction().toString()` doesn’t always work,
|
|
||||||
# and it’s not foolproof either.
|
|
||||||
for map in sourceMaps['<anonymous>'] by -1
|
|
||||||
sourceLocation = map.sourceLocation [line - 1, column - 1]
|
|
||||||
return map if sourceLocation?[0]? and sourceLocation[1]?
|
|
||||||
|
|
||||||
# If all else fails, recompile this source to get a source map. We need the
|
|
||||||
# previous section (for `<anonymous>`) despite this option, because after it
|
|
||||||
# gets compiled we will still need to look it up from
|
|
||||||
# `sourceMaps['<anonymous>']` in order to find and return it. That’s why we
|
|
||||||
# start searching from the end in the previous block, because most of the
|
|
||||||
# time the source map we want is the last one.
|
|
||||||
if sources[filename]?
|
|
||||||
answer = compile sources[filename][sources[filename].length - 1],
|
|
||||||
filename: filename
|
|
||||||
sourceMap: yes
|
|
||||||
literate: helpers.isLiterate filename
|
|
||||||
answer.sourceMap
|
|
||||||
else
|
|
||||||
null
|
|
||||||
|
|
||||||
# Based on [michaelficarra/CoffeeScriptRedux](http://goo.gl/ZTx1p)
|
|
||||||
# NodeJS / V8 have no support for transforming positions in stack traces using
|
|
||||||
# sourceMap, so we must monkey-patch Error to display CoffeeScript source
|
|
||||||
# positions.
|
|
||||||
Error.prepareStackTrace = (err, stack) ->
|
|
||||||
getSourceMapping = (filename, line, column) ->
|
getSourceMapping = (filename, line, column) ->
|
||||||
sourceMap = getSourceMap filename, line, column
|
sourceMap = getSourceMap filename, line, column
|
||||||
|
|
||||||
answer = sourceMap.sourceLocation [line - 1, column - 1] if sourceMap?
|
answer = sourceMap.sourceLocation [line - 1, column - 1] if sourceMap?
|
||||||
if answer? then [answer[0] + 1, answer[1] + 1] else null
|
if answer? then [answer[0] + 1, answer[1] + 1] else null
|
||||||
|
|
||||||
frames = for frame in stack
|
# Based on [michaelficarra/CoffeeScriptRedux](http://goo.gl/ZTx1p)
|
||||||
break if frame.getFunction() is exports.run
|
# NodeJS / V8 have no support for transforming positions in stack traces using
|
||||||
" at #{formatSourcePosition frame, getSourceMapping}"
|
# sourceMap, so we must monkey-patch Error to display CoffeeScript source
|
||||||
|
# positions.
|
||||||
|
Error.prepareStackTrace = (err, stack) ->
|
||||||
|
frames = for frame in stack
|
||||||
|
# Don’t display stack frames deeper than `CoffeeScript.run`.
|
||||||
|
break if frame.getFunction() is exports.run
|
||||||
|
" at #{formatSourcePosition frame, getSourceMapping}"
|
||||||
|
|
||||||
"#{err.toString()}\n#{frames.join '\n'}\n"
|
"#{err.toString()}\n#{frames.join '\n'}\n"
|
||||||
|
|
||||||
checkShebangLine = (file, input) ->
|
checkShebangLine = (file, input) ->
|
||||||
firstLine = input.split(/$/m)[0]
|
firstLine = input.split(/$/m, 1)[0]
|
||||||
rest = firstLine?.match(/^#!\s*([^\s]+\s*)(.*)/)
|
rest = firstLine?.match(/^#!\s*([^\s]+\s*)(.*)/)
|
||||||
args = rest?[2]?.split(/\s/).filter (s) -> s isnt ''
|
args = rest?[2]?.split(/\s/).filter (s) -> s isnt ''
|
||||||
if args?.length > 1
|
if args?.length > 1
|
||||||
|
|||||||
@@ -32,12 +32,14 @@ BANNER = '''
|
|||||||
|
|
||||||
# The list of all the valid option flags that `coffee` knows how to handle.
|
# The list of all the valid option flags that `coffee` knows how to handle.
|
||||||
SWITCHES = [
|
SWITCHES = [
|
||||||
|
[ '--ast', 'generate an abstract syntax tree of nodes']
|
||||||
['-b', '--bare', 'compile without a top-level function wrapper']
|
['-b', '--bare', 'compile without a top-level function wrapper']
|
||||||
['-c', '--compile', 'compile to JavaScript and save as .js files']
|
['-c', '--compile', 'compile to JavaScript and save as .js files']
|
||||||
['-e', '--eval', 'pass a string from the command line as input']
|
['-e', '--eval', 'pass a string from the command line as input']
|
||||||
['-h', '--help', 'display this help message']
|
['-h', '--help', 'display this help message']
|
||||||
['-i', '--interactive', 'run an interactive CoffeeScript REPL']
|
['-i', '--interactive', 'run an interactive CoffeeScript REPL']
|
||||||
['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling']
|
['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling']
|
||||||
|
['-l', '--literate', 'treat stdio as literate style coffeescript']
|
||||||
['-m', '--map', 'generate source map and save as .js.map files']
|
['-m', '--map', 'generate source map and save as .js.map files']
|
||||||
['-M', '--inline-map', 'generate source map and include it directly in output']
|
['-M', '--inline-map', 'generate source map and include it directly in output']
|
||||||
['-n', '--nodes', 'print out the parse tree that the parser produces']
|
['-n', '--nodes', 'print out the parse tree that the parser produces']
|
||||||
@@ -47,7 +49,6 @@ SWITCHES = [
|
|||||||
['-p', '--print', 'print out the compiled JavaScript']
|
['-p', '--print', 'print out the compiled JavaScript']
|
||||||
['-r', '--require [MODULE*]', 'require the given module before eval or REPL']
|
['-r', '--require [MODULE*]', 'require the given module before eval or REPL']
|
||||||
['-s', '--stdio', 'listen for and compile scripts over stdio']
|
['-s', '--stdio', 'listen for and compile scripts over stdio']
|
||||||
['-l', '--literate', 'treat stdio as literate style coffeescript']
|
|
||||||
['-t', '--transpile', 'pipe generated JavaScript through Babel']
|
['-t', '--transpile', 'pipe generated JavaScript through Babel']
|
||||||
[ '--tokens', 'print out the tokens that the lexer/rewriter produce']
|
[ '--tokens', 'print out the tokens that the lexer/rewriter produce']
|
||||||
['-v', '--version', 'display the version number']
|
['-v', '--version', 'display the version number']
|
||||||
@@ -207,6 +208,9 @@ compileScript = (file, input, base = null) ->
|
|||||||
printTokens CoffeeScript.tokens task.input, task.options
|
printTokens CoffeeScript.tokens task.input, task.options
|
||||||
else if opts.nodes
|
else if opts.nodes
|
||||||
printLine CoffeeScript.nodes(task.input, task.options).toString().trim()
|
printLine CoffeeScript.nodes(task.input, task.options).toString().trim()
|
||||||
|
else if opts.ast
|
||||||
|
compiled = CoffeeScript.compile task.input, task.options
|
||||||
|
printLine JSON.stringify(compiled, null, 2)
|
||||||
else if opts.run
|
else if opts.run
|
||||||
CoffeeScript.register()
|
CoffeeScript.register()
|
||||||
CoffeeScript.eval opts.prelude, task.options if opts.prelude
|
CoffeeScript.eval opts.prelude, task.options if opts.prelude
|
||||||
@@ -502,6 +506,7 @@ compileOptions = (filename, base) ->
|
|||||||
transpile: opts.transpile
|
transpile: opts.transpile
|
||||||
sourceMap: opts.map
|
sourceMap: opts.map
|
||||||
inlineMap: opts['inline-map']
|
inlineMap: opts['inline-map']
|
||||||
|
ast: opts.ast
|
||||||
|
|
||||||
if filename
|
if filename
|
||||||
if base
|
if base
|
||||||
@@ -510,7 +515,7 @@ compileOptions = (filename, base) ->
|
|||||||
jsDir = path.dirname jsPath
|
jsDir = path.dirname jsPath
|
||||||
answer = helpers.merge answer, {
|
answer = helpers.merge answer, {
|
||||||
jsPath
|
jsPath
|
||||||
sourceRoot: path.relative jsDir, cwd
|
sourceRoot: path.relative(jsDir, cwd) + path.sep
|
||||||
sourceFiles: [path.relative cwd, filename]
|
sourceFiles: [path.relative cwd, filename]
|
||||||
generatedFile: helpers.baseFileName(jsPath, no, useWinPathSep)
|
generatedFile: helpers.baseFileName(jsPath, no, useWinPathSep)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ o = (patternString, action, options) ->
|
|||||||
patternString = patternString.replace /\s{2,}/g, ' '
|
patternString = patternString.replace /\s{2,}/g, ' '
|
||||||
patternCount = patternString.split(' ').length
|
patternCount = patternString.split(' ').length
|
||||||
if action
|
if action
|
||||||
|
# This code block does string replacements in the generated `parser.js`
|
||||||
|
# file, replacing the calls to the `LOC` function and other strings as
|
||||||
|
# listed below.
|
||||||
action = if match = unwrap.exec action then match[1] else "(#{action}())"
|
action = if match = unwrap.exec action then match[1] else "(#{action}())"
|
||||||
|
|
||||||
# All runtime functions we need are defined on `yy`
|
# All runtime functions we need are defined on `yy`
|
||||||
@@ -44,12 +47,38 @@ o = (patternString, action, options) ->
|
|||||||
# that nodes may have, such as comments or location data. Location data
|
# that nodes may have, such as comments or location data. Location data
|
||||||
# is added to the first parameter passed in, and the parameter is returned.
|
# is added to the first parameter passed in, and the parameter is returned.
|
||||||
# If the parameter is not a node, it will just be passed through unaffected.
|
# If the parameter is not a node, it will just be passed through unaffected.
|
||||||
getAddDataToNodeFunctionString = (first, last) ->
|
getAddDataToNodeFunctionString = (first, last, forceUpdateLocation = yes) ->
|
||||||
"yy.addDataToNode(yy, @#{first}#{if last then ", @#{last}" else ''})"
|
"yy.addDataToNode(yy, @#{first}, #{if first[0] is '$' then '$$' else '$'}#{first}, #{if last then "@#{last}, #{if last[0] is '$' then '$$' else '$'}#{last}" else 'null, null'}, #{if forceUpdateLocation then 'true' else 'false'})"
|
||||||
|
|
||||||
|
# This code replaces the calls to `LOC` with the `yy.addDataToNode` string
|
||||||
|
# defined above. The `LOC` function, when used below in the grammar rules,
|
||||||
|
# is used to make sure that newly created node class objects get correct
|
||||||
|
# location data assigned to them. By default, the grammar will assign the
|
||||||
|
# location data spanned by *all* of the tokens on the left (e.g. a string
|
||||||
|
# such as `'Body TERMINATOR Line'`) to the “top-level” node returned by
|
||||||
|
# the grammar rule (the function on the right). But for “inner” node class
|
||||||
|
# objects created by grammar rules, they won’t get correct location data
|
||||||
|
# assigned to them without adding `LOC`.
|
||||||
|
|
||||||
|
# For example, consider the grammar rule `'NEW_TARGET . Property'`, which
|
||||||
|
# is handled by a function that returns
|
||||||
|
# `new MetaProperty LOC(1)(new IdentifierLiteral $1), LOC(3)(new Access $3)`.
|
||||||
|
# The `1` in `LOC(1)` refers to the first token (`NEW_TARGET`) and the `3`
|
||||||
|
# in `LOC(3)` refers to the third token (`Property`). In order for the
|
||||||
|
# `new IdentifierLiteral` to get assigned the location data corresponding
|
||||||
|
# to `new` in the source code, we use
|
||||||
|
# `LOC(1)(new IdentifierLiteral ...)` to mean “assign the location data of
|
||||||
|
# the *first* token of this grammar rule (`NEW_TARGET`) to this
|
||||||
|
# `new IdentifierLiteral`”. The `LOC(3)` means “assign the location data of
|
||||||
|
# the *third* token of this grammar rule (`Property`) to this
|
||||||
|
# `new Access`”.
|
||||||
|
returnsLoc = /^LOC/.test action
|
||||||
action = action.replace /LOC\(([0-9]*)\)/g, getAddDataToNodeFunctionString('$1')
|
action = action.replace /LOC\(([0-9]*)\)/g, getAddDataToNodeFunctionString('$1')
|
||||||
|
# A call to `LOC` with two arguments, e.g. `LOC(2,4)`, sets the location
|
||||||
|
# data for the generated node on both of the referenced tokens (the second
|
||||||
|
# and fourth in this example).
|
||||||
action = action.replace /LOC\(([0-9]*),\s*([0-9]*)\)/g, getAddDataToNodeFunctionString('$1', '$2')
|
action = action.replace /LOC\(([0-9]*),\s*([0-9]*)\)/g, getAddDataToNodeFunctionString('$1', '$2')
|
||||||
performActionFunctionString = "$$ = #{getAddDataToNodeFunctionString(1, patternCount)}(#{action});"
|
performActionFunctionString = "$$ = #{getAddDataToNodeFunctionString(1, patternCount, not returnsLoc)}(#{action});"
|
||||||
else
|
else
|
||||||
performActionFunctionString = '$$ = $1;'
|
performActionFunctionString = '$$ = $1;'
|
||||||
|
|
||||||
@@ -73,8 +102,8 @@ grammar =
|
|||||||
# The **Root** is the top-level node in the syntax tree. Since we parse bottom-up,
|
# The **Root** is the top-level node in the syntax tree. Since we parse bottom-up,
|
||||||
# all parsing must end here.
|
# all parsing must end here.
|
||||||
Root: [
|
Root: [
|
||||||
o '', -> new Block
|
o '', -> new Root new Block
|
||||||
o 'Body'
|
o 'Body', -> new Root $1
|
||||||
]
|
]
|
||||||
|
|
||||||
# Any list of statements and expressions, separated by line breaks or semicolons.
|
# Any list of statements and expressions, separated by line breaks or semicolons.
|
||||||
@@ -84,7 +113,7 @@ grammar =
|
|||||||
o 'Body TERMINATOR'
|
o 'Body TERMINATOR'
|
||||||
]
|
]
|
||||||
|
|
||||||
# Block and statements, which make up a line in a body. YieldReturn is a
|
# Block and statements, which make up a line in a body. FuncDirective is a
|
||||||
# statement, but not included in Statement because that results in an ambiguous
|
# statement, but not included in Statement because that results in an ambiguous
|
||||||
# grammar.
|
# grammar.
|
||||||
Line: [
|
Line: [
|
||||||
@@ -152,40 +181,68 @@ grammar =
|
|||||||
|
|
||||||
Identifier: [
|
Identifier: [
|
||||||
o 'IDENTIFIER', -> new IdentifierLiteral $1
|
o 'IDENTIFIER', -> new IdentifierLiteral $1
|
||||||
o 'CSX_TAG', -> new CSXTag $1
|
o 'JSX_TAG', -> new JSXTag $1.toString(),
|
||||||
|
tagNameLocationData: $1.tagNameToken[2]
|
||||||
|
closingTagOpeningBracketLocationData: $1.closingTagOpeningBracketToken?[2]
|
||||||
|
closingTagSlashLocationData: $1.closingTagSlashToken?[2]
|
||||||
|
closingTagNameLocationData: $1.closingTagNameToken?[2]
|
||||||
|
closingTagClosingBracketLocationData: $1.closingTagClosingBracketToken?[2]
|
||||||
]
|
]
|
||||||
|
|
||||||
Property: [
|
Property: [
|
||||||
o 'PROPERTY', -> new PropertyName $1
|
o 'PROPERTY', -> new PropertyName $1.toString()
|
||||||
]
|
]
|
||||||
|
|
||||||
# Alphanumerics are separated from the other **Literal** matchers because
|
# Alphanumerics are separated from the other **Literal** matchers because
|
||||||
# they can also serve as keys in object literals.
|
# they can also serve as keys in object literals.
|
||||||
AlphaNumeric: [
|
AlphaNumeric: [
|
||||||
o 'NUMBER', -> new NumberLiteral $1
|
o 'NUMBER', -> new NumberLiteral $1.toString(), parsedValue: $1.parsedValue
|
||||||
o 'String'
|
o 'String'
|
||||||
]
|
]
|
||||||
|
|
||||||
String: [
|
String: [
|
||||||
o 'STRING', -> new StringLiteral $1
|
o 'STRING', ->
|
||||||
o 'STRING_START Body STRING_END', -> new StringWithInterpolations $2
|
new StringLiteral(
|
||||||
|
$1.slice 1, -1 # strip artificial quotes and unwrap to primitive string
|
||||||
|
quote: $1.quote
|
||||||
|
initialChunk: $1.initialChunk
|
||||||
|
finalChunk: $1.finalChunk
|
||||||
|
indent: $1.indent
|
||||||
|
double: $1.double
|
||||||
|
heregex: $1.heregex
|
||||||
|
)
|
||||||
|
o 'STRING_START Interpolations STRING_END', -> new StringWithInterpolations Block.wrap($2), quote: $1.quote, startQuote: LOC(1)(new Literal $1.toString())
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Interpolations: [
|
||||||
|
o 'InterpolationChunk', -> [$1]
|
||||||
|
o 'Interpolations InterpolationChunk', -> $1.concat $2
|
||||||
|
]
|
||||||
|
|
||||||
|
InterpolationChunk: [
|
||||||
|
o 'INTERPOLATION_START Body INTERPOLATION_END', -> new Interpolation $2
|
||||||
|
o 'INTERPOLATION_START INDENT Body OUTDENT INTERPOLATION_END', -> new Interpolation $3
|
||||||
|
o 'INTERPOLATION_START INTERPOLATION_END', -> new Interpolation
|
||||||
|
o 'String', -> $1
|
||||||
|
]
|
||||||
|
|
||||||
|
# The .toString() calls here and elsewhere are to convert `String` objects
|
||||||
|
# back to primitive strings now that we've retrieved stowaway extra properties
|
||||||
Regex: [
|
Regex: [
|
||||||
o 'REGEX', -> new RegexLiteral $1
|
o 'REGEX', -> new RegexLiteral $1.toString(), delimiter: $1.delimiter, heregexCommentTokens: $1.heregexCommentTokens
|
||||||
o 'REGEX_START Invocation REGEX_END', -> new RegexWithInterpolations $2.args
|
o 'REGEX_START Invocation REGEX_END', -> new RegexWithInterpolations $2, heregexCommentTokens: $3.heregexCommentTokens
|
||||||
]
|
]
|
||||||
|
|
||||||
# All of our immediate values. Generally these can be passed straight
|
# All of our immediate values. Generally these can be passed straight
|
||||||
# through and printed to JavaScript.
|
# through and printed to JavaScript.
|
||||||
Literal: [
|
Literal: [
|
||||||
o 'AlphaNumeric'
|
o 'AlphaNumeric'
|
||||||
o 'JS', -> new PassthroughLiteral $1
|
o 'JS', -> new PassthroughLiteral $1.toString(), here: $1.here, generated: $1.generated
|
||||||
o 'Regex'
|
o 'Regex'
|
||||||
o 'UNDEFINED', -> new UndefinedLiteral $1
|
o 'UNDEFINED', -> new UndefinedLiteral $1
|
||||||
o 'NULL', -> new NullLiteral $1
|
o 'NULL', -> new NullLiteral $1
|
||||||
o 'BOOL', -> new BooleanLiteral $1
|
o 'BOOL', -> new BooleanLiteral $1.toString(), originalValue: $1.original
|
||||||
o 'INFINITY', -> new InfinityLiteral $1
|
o 'INFINITY', -> new InfinityLiteral $1.toString(), originalValue: $1.original
|
||||||
o 'NAN', -> new NaNLiteral $1
|
o 'NAN', -> new NaNLiteral $1
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -222,15 +279,16 @@ grammar =
|
|||||||
ObjAssignable: [
|
ObjAssignable: [
|
||||||
o 'SimpleObjAssignable'
|
o 'SimpleObjAssignable'
|
||||||
o '[ Expression ]', -> new Value new ComputedPropertyName $2
|
o '[ Expression ]', -> new Value new ComputedPropertyName $2
|
||||||
|
o '@ [ Expression ]', -> new Value LOC(1)(new ThisLiteral $1), [LOC(3)(new ComputedPropertyName($3))], 'this'
|
||||||
o 'AlphaNumeric'
|
o 'AlphaNumeric'
|
||||||
]
|
]
|
||||||
|
|
||||||
# Object literal spread properties.
|
# Object literal spread properties.
|
||||||
ObjRestValue: [
|
ObjRestValue: [
|
||||||
o 'SimpleObjAssignable ...', -> new Splat new Value $1
|
o 'SimpleObjAssignable ...', -> new Splat new Value $1
|
||||||
o '... SimpleObjAssignable', -> new Splat new Value $2
|
o '... SimpleObjAssignable', -> new Splat new Value($2), postfix: no
|
||||||
o 'ObjSpreadExpr ...', -> new Splat $1
|
o 'ObjSpreadExpr ...', -> new Splat $1
|
||||||
o '... ObjSpreadExpr', -> new Splat $2
|
o '... ObjSpreadExpr', -> new Splat $2, postfix: no
|
||||||
]
|
]
|
||||||
|
|
||||||
ObjSpreadExpr: [
|
ObjSpreadExpr: [
|
||||||
@@ -239,19 +297,15 @@ grammar =
|
|||||||
o 'Parenthetical'
|
o 'Parenthetical'
|
||||||
o 'Super'
|
o 'Super'
|
||||||
o 'This'
|
o 'This'
|
||||||
o 'SUPER Arguments', -> new SuperCall LOC(1)(new Super), $2, no, $1
|
o 'SUPER OptFuncExist Arguments', -> new SuperCall LOC(1)(new Super), $3, $2.soak, $1
|
||||||
o 'SimpleObjAssignable Arguments', -> new Call (new Value $1), $2
|
o 'DYNAMIC_IMPORT Arguments', -> new DynamicImportCall LOC(1)(new DynamicImport), $2
|
||||||
o 'ObjSpreadExpr Arguments', -> new Call $1, $2
|
o 'SimpleObjAssignable OptFuncExist Arguments', -> new Call (new Value $1), $3, $2.soak
|
||||||
|
o 'ObjSpreadExpr OptFuncExist Arguments', -> new Call $1, $3, $2.soak
|
||||||
]
|
]
|
||||||
|
|
||||||
ObjSpreadIdentifier: [
|
ObjSpreadIdentifier: [
|
||||||
o 'SimpleObjAssignable ObjSpreadAccessor', -> (new Value $1).add $2
|
o 'SimpleObjAssignable Accessor', -> (new Value $1).add $2
|
||||||
o 'ObjSpreadExpr ObjSpreadAccessor', -> (new Value $1).add $2
|
o 'ObjSpreadExpr Accessor', -> (new Value $1).add $2
|
||||||
]
|
|
||||||
|
|
||||||
ObjSpreadAccessor: [
|
|
||||||
o '. Property', -> new Access $2
|
|
||||||
o 'INDEX_START IndexValue INDEX_END', -> $2
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# A return statement from a function body.
|
# A return statement from a function body.
|
||||||
@@ -262,16 +316,16 @@ grammar =
|
|||||||
]
|
]
|
||||||
|
|
||||||
YieldReturn: [
|
YieldReturn: [
|
||||||
o 'YIELD RETURN Expression', -> new YieldReturn $3
|
o 'YIELD RETURN Expression', -> new YieldReturn $3, returnKeyword: LOC(2)(new Literal $2)
|
||||||
o 'YIELD RETURN', -> new YieldReturn
|
o 'YIELD RETURN', -> new YieldReturn null, returnKeyword: LOC(2)(new Literal $2)
|
||||||
]
|
]
|
||||||
|
|
||||||
AwaitReturn: [
|
AwaitReturn: [
|
||||||
o 'AWAIT RETURN Expression', -> new AwaitReturn $3
|
o 'AWAIT RETURN Expression', -> new AwaitReturn $3, returnKeyword: LOC(2)(new Literal $2)
|
||||||
o 'AWAIT RETURN', -> new AwaitReturn
|
o 'AWAIT RETURN', -> new AwaitReturn null, returnKeyword: LOC(2)(new Literal $2)
|
||||||
]
|
]
|
||||||
|
|
||||||
# The **Code** node is the function literal. It's defined by an indented block
|
# The **Code** node is the function literal. It’s defined by an indented block
|
||||||
# of **Block** preceded by a function arrow, with an optional parameter list.
|
# of **Block** preceded by a function arrow, with an optional parameter list.
|
||||||
Code: [
|
Code: [
|
||||||
o 'PARAM_START ParamList PARAM_END FuncGlyph Block', -> new Code $2, $5, $4, LOC(1)(new Literal $1)
|
o 'PARAM_START ParamList PARAM_END FuncGlyph Block', -> new Code $2, $5, $4, LOC(1)(new Literal $1)
|
||||||
@@ -312,7 +366,7 @@ grammar =
|
|||||||
Param: [
|
Param: [
|
||||||
o 'ParamVar', -> new Param $1
|
o 'ParamVar', -> new Param $1
|
||||||
o 'ParamVar ...', -> new Param $1, null, on
|
o 'ParamVar ...', -> new Param $1, null, on
|
||||||
o '... ParamVar', -> new Param $2, null, on
|
o '... ParamVar', -> new Param $2, null, postfix: no
|
||||||
o 'ParamVar = Expression', -> new Param $1, $3
|
o 'ParamVar = Expression', -> new Param $1, $3
|
||||||
o '...', -> new Expansion
|
o '...', -> new Expansion
|
||||||
]
|
]
|
||||||
@@ -328,7 +382,7 @@ grammar =
|
|||||||
# A splat that occurs outside of a parameter list.
|
# A splat that occurs outside of a parameter list.
|
||||||
Splat: [
|
Splat: [
|
||||||
o 'Expression ...', -> new Splat $1
|
o 'Expression ...', -> new Splat $1
|
||||||
o '... Expression', -> new Splat $2
|
o '... Expression', -> new Splat $2, {postfix: no}
|
||||||
]
|
]
|
||||||
|
|
||||||
# Variables and properties that can be assigned to.
|
# Variables and properties that can be assigned to.
|
||||||
@@ -354,32 +408,43 @@ grammar =
|
|||||||
o 'Parenthetical', -> new Value $1
|
o 'Parenthetical', -> new Value $1
|
||||||
o 'Range', -> new Value $1
|
o 'Range', -> new Value $1
|
||||||
o 'Invocation', -> new Value $1
|
o 'Invocation', -> new Value $1
|
||||||
|
o 'DoIife', -> new Value $1
|
||||||
o 'This'
|
o 'This'
|
||||||
o 'Super', -> new Value $1
|
o 'Super', -> new Value $1
|
||||||
|
o 'MetaProperty', -> new Value $1
|
||||||
]
|
]
|
||||||
|
|
||||||
# A `super`-based expression that can be used as a value.
|
# A `super`-based expression that can be used as a value.
|
||||||
Super: [
|
Super: [
|
||||||
o 'SUPER . Property', -> new Super LOC(3)(new Access $3), [], no, $1
|
o 'SUPER . Property', -> new Super LOC(3)(new Access $3), LOC(1)(new Literal $1)
|
||||||
o 'SUPER INDEX_START Expression INDEX_END', -> new Super LOC(3)(new Index $3), [], no, $1
|
o 'SUPER INDEX_START Expression INDEX_END', -> new Super LOC(3)(new Index $3), LOC(1)(new Literal $1)
|
||||||
|
o 'SUPER INDEX_START INDENT Expression OUTDENT INDEX_END', -> new Super LOC(4)(new Index $4), LOC(1)(new Literal $1)
|
||||||
|
]
|
||||||
|
|
||||||
|
# A “meta-property” access e.g. `new.target` or `import.meta`, where
|
||||||
|
# something that looks like a property is referenced on a keyword.
|
||||||
|
MetaProperty: [
|
||||||
|
o 'NEW_TARGET . Property', -> new MetaProperty LOC(1)(new IdentifierLiteral $1), LOC(3)(new Access $3)
|
||||||
|
o 'IMPORT_META . Property', -> new MetaProperty LOC(1)(new IdentifierLiteral $1), LOC(3)(new Access $3)
|
||||||
]
|
]
|
||||||
|
|
||||||
# The general group of accessors into an object, by property, by prototype
|
# The general group of accessors into an object, by property, by prototype
|
||||||
# or by array index or slice.
|
# or by array index or slice.
|
||||||
Accessor: [
|
Accessor: [
|
||||||
o '. Property', -> new Access $2
|
o '. Property', -> new Access $2
|
||||||
o '?. Property', -> new Access $2, 'soak'
|
o '?. Property', -> new Access $2, soak: yes
|
||||||
o ':: Property', -> [LOC(1)(new Access new PropertyName('prototype')), LOC(2)(new Access $2)]
|
o ':: Property', -> [LOC(1)(new Access new PropertyName('prototype'), shorthand: yes), LOC(2)(new Access $2)]
|
||||||
o '?:: Property', -> [LOC(1)(new Access new PropertyName('prototype'), 'soak'), LOC(2)(new Access $2)]
|
o '?:: Property', -> [LOC(1)(new Access new PropertyName('prototype'), shorthand: yes, soak: yes), LOC(2)(new Access $2)]
|
||||||
o '::', -> new Access new PropertyName 'prototype'
|
o '::', -> new Access new PropertyName('prototype'), shorthand: yes
|
||||||
o '?::', -> new Access new PropertyName('prototype'), 'soak'
|
o '?::', -> new Access new PropertyName('prototype'), shorthand: yes, soak: yes
|
||||||
o 'Index'
|
o 'Index'
|
||||||
]
|
]
|
||||||
|
|
||||||
# Indexing into an object or array using bracket notation.
|
# Indexing into an object or array using bracket notation.
|
||||||
Index: [
|
Index: [
|
||||||
o 'INDEX_START IndexValue INDEX_END', -> $2
|
o 'INDEX_START IndexValue INDEX_END', -> $2
|
||||||
o 'INDEX_SOAK Index', -> extend $2, soak: yes
|
o 'INDEX_START INDENT IndexValue OUTDENT INDEX_END', -> $3
|
||||||
|
o 'INDEX_SOAK Index', -> extend $2, soak: yes
|
||||||
]
|
]
|
||||||
|
|
||||||
IndexValue: [
|
IndexValue: [
|
||||||
@@ -416,13 +481,20 @@ grammar =
|
|||||||
]
|
]
|
||||||
|
|
||||||
Import: [
|
Import: [
|
||||||
o 'IMPORT String', -> new ImportDeclaration null, $2
|
o 'IMPORT String', -> new ImportDeclaration null, $2
|
||||||
o 'IMPORT ImportDefaultSpecifier FROM String', -> new ImportDeclaration new ImportClause($2, null), $4
|
o 'IMPORT String ASSERT Object', -> new ImportDeclaration null, $2, $4
|
||||||
o 'IMPORT ImportNamespaceSpecifier FROM String', -> new ImportDeclaration new ImportClause(null, $2), $4
|
o 'IMPORT ImportDefaultSpecifier FROM String', -> new ImportDeclaration new ImportClause($2, null), $4
|
||||||
o 'IMPORT { } FROM String', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList []), $5
|
o 'IMPORT ImportDefaultSpecifier FROM String ASSERT Object', -> new ImportDeclaration new ImportClause($2, null), $4, $6
|
||||||
o 'IMPORT { ImportSpecifierList OptComma } FROM String', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList $3), $7
|
o 'IMPORT ImportNamespaceSpecifier FROM String', -> new ImportDeclaration new ImportClause(null, $2), $4
|
||||||
o 'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String', -> new ImportDeclaration new ImportClause($2, $4), $6
|
o 'IMPORT ImportNamespaceSpecifier FROM String ASSERT Object', -> new ImportDeclaration new ImportClause(null, $2), $4, $6
|
||||||
o 'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String', -> new ImportDeclaration new ImportClause($2, new ImportSpecifierList $5), $9
|
o 'IMPORT { } FROM String', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList []), $5
|
||||||
|
o 'IMPORT { } FROM String ASSERT Object', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList []), $5, $7
|
||||||
|
o 'IMPORT { ImportSpecifierList OptComma } FROM String', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList $3), $7
|
||||||
|
o 'IMPORT { ImportSpecifierList OptComma } FROM String ASSERT Object', -> new ImportDeclaration new ImportClause(null, new ImportSpecifierList $3), $7, $9
|
||||||
|
o 'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String', -> new ImportDeclaration new ImportClause($2, $4), $6
|
||||||
|
o 'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String ASSERT Object', -> new ImportDeclaration new ImportClause($2, $4), $6, $8
|
||||||
|
o 'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String', -> new ImportDeclaration new ImportClause($2, new ImportSpecifierList $5), $9
|
||||||
|
o 'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String ASSERT Object', -> new ImportDeclaration new ImportClause($2, new ImportSpecifierList $5), $9, $11
|
||||||
]
|
]
|
||||||
|
|
||||||
ImportSpecifierList: [
|
ImportSpecifierList: [
|
||||||
@@ -436,8 +508,8 @@ grammar =
|
|||||||
ImportSpecifier: [
|
ImportSpecifier: [
|
||||||
o 'Identifier', -> new ImportSpecifier $1
|
o 'Identifier', -> new ImportSpecifier $1
|
||||||
o 'Identifier AS Identifier', -> new ImportSpecifier $1, $3
|
o 'Identifier AS Identifier', -> new ImportSpecifier $1, $3
|
||||||
o 'DEFAULT', -> new ImportSpecifier new Literal $1
|
o 'DEFAULT', -> new ImportSpecifier LOC(1)(new DefaultLiteral $1)
|
||||||
o 'DEFAULT AS Identifier', -> new ImportSpecifier new Literal($1), $3
|
o 'DEFAULT AS Identifier', -> new ImportSpecifier LOC(1)(new DefaultLiteral($1)), $3
|
||||||
]
|
]
|
||||||
|
|
||||||
ImportDefaultSpecifier: [
|
ImportDefaultSpecifier: [
|
||||||
@@ -449,19 +521,23 @@ grammar =
|
|||||||
]
|
]
|
||||||
|
|
||||||
Export: [
|
Export: [
|
||||||
o 'EXPORT { }', -> new ExportNamedDeclaration new ExportSpecifierList []
|
o 'EXPORT { }', -> new ExportNamedDeclaration new ExportSpecifierList []
|
||||||
o 'EXPORT { ExportSpecifierList OptComma }', -> new ExportNamedDeclaration new ExportSpecifierList $3
|
o 'EXPORT { ExportSpecifierList OptComma }', -> new ExportNamedDeclaration new ExportSpecifierList $3
|
||||||
o 'EXPORT Class', -> new ExportNamedDeclaration $2
|
o 'EXPORT Class', -> new ExportNamedDeclaration $2
|
||||||
o 'EXPORT Identifier = Expression', -> new ExportNamedDeclaration new Assign $2, $4, null,
|
o 'EXPORT Identifier = Expression', -> new ExportNamedDeclaration LOC(2,4)(new Assign $2, $4, null,
|
||||||
moduleDeclaration: 'export'
|
moduleDeclaration: 'export')
|
||||||
o 'EXPORT Identifier = TERMINATOR Expression', -> new ExportNamedDeclaration new Assign $2, $5, null,
|
o 'EXPORT Identifier = TERMINATOR Expression', -> new ExportNamedDeclaration LOC(2,5)(new Assign $2, $5, null,
|
||||||
moduleDeclaration: 'export'
|
moduleDeclaration: 'export')
|
||||||
o 'EXPORT Identifier = INDENT Expression OUTDENT', -> new ExportNamedDeclaration new Assign $2, $5, null,
|
o 'EXPORT Identifier = INDENT Expression OUTDENT', -> new ExportNamedDeclaration LOC(2,6)(new Assign $2, $5, null,
|
||||||
moduleDeclaration: 'export'
|
moduleDeclaration: 'export')
|
||||||
o 'EXPORT DEFAULT Expression', -> new ExportDefaultDeclaration $3
|
o 'EXPORT DEFAULT Expression', -> new ExportDefaultDeclaration $3
|
||||||
o 'EXPORT DEFAULT INDENT Object OUTDENT', -> new ExportDefaultDeclaration new Value $4
|
o 'EXPORT DEFAULT INDENT Object OUTDENT', -> new ExportDefaultDeclaration new Value $4
|
||||||
o 'EXPORT EXPORT_ALL FROM String', -> new ExportAllDeclaration new Literal($2), $4
|
o 'EXPORT EXPORT_ALL FROM String', -> new ExportAllDeclaration new Literal($2), $4
|
||||||
o 'EXPORT { ExportSpecifierList OptComma } FROM String', -> new ExportNamedDeclaration new ExportSpecifierList($3), $7
|
o 'EXPORT EXPORT_ALL FROM String ASSERT Object', -> new ExportAllDeclaration new Literal($2), $4, $6
|
||||||
|
o 'EXPORT { } FROM String', -> new ExportNamedDeclaration new ExportSpecifierList([]), $5
|
||||||
|
o 'EXPORT { } FROM String ASSERT Object', -> new ExportNamedDeclaration new ExportSpecifierList([]), $5, $7
|
||||||
|
o 'EXPORT { ExportSpecifierList OptComma } FROM String', -> new ExportNamedDeclaration new ExportSpecifierList($3), $7
|
||||||
|
o 'EXPORT { ExportSpecifierList OptComma } FROM String ASSERT Object', -> new ExportNamedDeclaration new ExportSpecifierList($3), $7, $9
|
||||||
]
|
]
|
||||||
|
|
||||||
ExportSpecifierList: [
|
ExportSpecifierList: [
|
||||||
@@ -475,28 +551,29 @@ grammar =
|
|||||||
ExportSpecifier: [
|
ExportSpecifier: [
|
||||||
o 'Identifier', -> new ExportSpecifier $1
|
o 'Identifier', -> new ExportSpecifier $1
|
||||||
o 'Identifier AS Identifier', -> new ExportSpecifier $1, $3
|
o 'Identifier AS Identifier', -> new ExportSpecifier $1, $3
|
||||||
o 'Identifier AS DEFAULT', -> new ExportSpecifier $1, new Literal $3
|
o 'Identifier AS DEFAULT', -> new ExportSpecifier $1, LOC(3)(new DefaultLiteral $3)
|
||||||
o 'DEFAULT', -> new ExportSpecifier new Literal $1
|
o 'DEFAULT', -> new ExportSpecifier LOC(1)(new DefaultLiteral $1)
|
||||||
o 'DEFAULT AS Identifier', -> new ExportSpecifier new Literal($1), $3
|
o 'DEFAULT AS Identifier', -> new ExportSpecifier LOC(1)(new DefaultLiteral($1)), $3
|
||||||
]
|
]
|
||||||
|
|
||||||
# Ordinary function invocation, or a chained series of calls.
|
# Ordinary function invocation, or a chained series of calls.
|
||||||
Invocation: [
|
Invocation: [
|
||||||
o 'Value OptFuncExist String', -> new TaggedTemplateCall $1, $3, $2
|
o 'Value OptFuncExist String', -> new TaggedTemplateCall $1, $3, $2.soak
|
||||||
o 'Value OptFuncExist Arguments', -> new Call $1, $3, $2
|
o 'Value OptFuncExist Arguments', -> new Call $1, $3, $2.soak
|
||||||
o 'SUPER OptFuncExist Arguments', -> new SuperCall LOC(1)(new Super), $3, $2, $1
|
o 'SUPER OptFuncExist Arguments', -> new SuperCall LOC(1)(new Super), $3, $2.soak, $1
|
||||||
|
o 'DYNAMIC_IMPORT Arguments', -> new DynamicImportCall LOC(1)(new DynamicImport), $2
|
||||||
]
|
]
|
||||||
|
|
||||||
# An optional existence check on a function.
|
# An optional existence check on a function.
|
||||||
OptFuncExist: [
|
OptFuncExist: [
|
||||||
o '', -> no
|
o '', -> soak: no
|
||||||
o 'FUNC_EXIST', -> yes
|
o 'FUNC_EXIST', -> soak: yes
|
||||||
]
|
]
|
||||||
|
|
||||||
# The list of arguments to a function call.
|
# The list of arguments to a function call.
|
||||||
Arguments: [
|
Arguments: [
|
||||||
o 'CALL_START CALL_END', -> []
|
o 'CALL_START CALL_END', -> []
|
||||||
o 'CALL_START ArgList OptComma CALL_END', -> $2
|
o 'CALL_START ArgList OptComma CALL_END', -> $2.implicit = $1.generated; $2
|
||||||
]
|
]
|
||||||
|
|
||||||
# A reference to the *this* current object.
|
# A reference to the *this* current object.
|
||||||
@@ -519,24 +596,24 @@ grammar =
|
|||||||
|
|
||||||
# Inclusive and exclusive range dots.
|
# Inclusive and exclusive range dots.
|
||||||
RangeDots: [
|
RangeDots: [
|
||||||
o '..', -> 'inclusive'
|
o '..', -> exclusive: no
|
||||||
o '...', -> 'exclusive'
|
o '...', -> exclusive: yes
|
||||||
]
|
]
|
||||||
|
|
||||||
# The CoffeeScript range literal.
|
# The CoffeeScript range literal.
|
||||||
Range: [
|
Range: [
|
||||||
o '[ Expression RangeDots Expression ]', -> new Range $2, $4, $3
|
o '[ Expression RangeDots Expression ]', -> new Range $2, $4, if $3.exclusive then 'exclusive' else 'inclusive'
|
||||||
o '[ ExpressionLine RangeDots Expression ]', -> new Range $2, $4, $3
|
o '[ ExpressionLine RangeDots Expression ]', -> new Range $2, $4, if $3.exclusive then 'exclusive' else 'inclusive'
|
||||||
]
|
]
|
||||||
|
|
||||||
# Array slice literals.
|
# Array slice literals.
|
||||||
Slice: [
|
Slice: [
|
||||||
o 'Expression RangeDots Expression', -> new Range $1, $3, $2
|
o 'Expression RangeDots Expression', -> new Range $1, $3, if $2.exclusive then 'exclusive' else 'inclusive'
|
||||||
o 'Expression RangeDots', -> new Range $1, null, $2
|
o 'Expression RangeDots', -> new Range $1, null, if $2.exclusive then 'exclusive' else 'inclusive'
|
||||||
o 'ExpressionLine RangeDots Expression', -> new Range $1, $3, $2
|
o 'ExpressionLine RangeDots Expression', -> new Range $1, $3, if $2.exclusive then 'exclusive' else 'inclusive'
|
||||||
o 'ExpressionLine RangeDots', -> new Range $1, null, $2
|
o 'ExpressionLine RangeDots', -> new Range $1, null, if $2.exclusive then 'exclusive' else 'inclusive'
|
||||||
o 'RangeDots Expression', -> new Range null, $2, $1
|
o 'RangeDots Expression', -> new Range null, $2, if $1.exclusive then 'exclusive' else 'inclusive'
|
||||||
o 'RangeDots', -> new Range null, null, $1
|
o 'RangeDots', -> new Range null, null, if $1.exclusive then 'exclusive' else 'inclusive'
|
||||||
]
|
]
|
||||||
|
|
||||||
# The **ArgList** is the list of objects passed into a function call
|
# The **ArgList** is the list of objects passed into a function call
|
||||||
@@ -562,7 +639,7 @@ grammar =
|
|||||||
ArgElisionList: [
|
ArgElisionList: [
|
||||||
o 'ArgElision'
|
o 'ArgElision'
|
||||||
o 'ArgElisionList , ArgElision', -> $1.concat $3
|
o 'ArgElisionList , ArgElision', -> $1.concat $3
|
||||||
o 'ArgElisionList OptElisions TERMINATOR ArgElision', -> $1.concat $2, $4
|
o 'ArgElisionList OptComma TERMINATOR ArgElision', -> $1.concat $4
|
||||||
o 'INDENT ArgElisionList OptElisions OUTDENT', -> $2.concat $3
|
o 'INDENT ArgElisionList OptElisions OUTDENT', -> $2.concat $3
|
||||||
o 'ArgElisionList OptElisions INDENT ArgElisionList OptElisions OUTDENT', -> $1.concat $2, $4, $5
|
o 'ArgElisionList OptElisions INDENT ArgElisionList OptElisions OUTDENT', -> $1.concat $2, $4, $5
|
||||||
]
|
]
|
||||||
@@ -584,6 +661,7 @@ grammar =
|
|||||||
|
|
||||||
Elision: [
|
Elision: [
|
||||||
o ',', -> new Elision
|
o ',', -> new Elision
|
||||||
|
o 'Elision TERMINATOR', -> $1
|
||||||
]
|
]
|
||||||
|
|
||||||
# Just simple, comma-separated, required arguments (no fancy syntax). We need
|
# Just simple, comma-separated, required arguments (no fancy syntax). We need
|
||||||
@@ -599,16 +677,16 @@ grammar =
|
|||||||
# The variants of *try/catch/finally* exception handling blocks.
|
# The variants of *try/catch/finally* exception handling blocks.
|
||||||
Try: [
|
Try: [
|
||||||
o 'TRY Block', -> new Try $2
|
o 'TRY Block', -> new Try $2
|
||||||
o 'TRY Block Catch', -> new Try $2, $3[0], $3[1]
|
o 'TRY Block Catch', -> new Try $2, $3
|
||||||
o 'TRY Block FINALLY Block', -> new Try $2, null, null, $4
|
o 'TRY Block FINALLY Block', -> new Try $2, null, $4, LOC(3)(new Literal $3)
|
||||||
o 'TRY Block Catch FINALLY Block', -> new Try $2, $3[0], $3[1], $5
|
o 'TRY Block Catch FINALLY Block', -> new Try $2, $3, $5, LOC(4)(new Literal $4)
|
||||||
]
|
]
|
||||||
|
|
||||||
# A catch clause names its error and runs a block of code.
|
# A catch clause names its error and runs a block of code.
|
||||||
Catch: [
|
Catch: [
|
||||||
o 'CATCH Identifier Block', -> [$2, $3]
|
o 'CATCH Identifier Block', -> new Catch $3, $2
|
||||||
o 'CATCH Object Block', -> [LOC(2)(new Value($2)), $3]
|
o 'CATCH Object Block', -> new Catch $3, LOC(2)(new Value($2))
|
||||||
o 'CATCH Block', -> [null, $2]
|
o 'CATCH Block', -> new Catch $2
|
||||||
]
|
]
|
||||||
|
|
||||||
# Throw an exception object.
|
# Throw an exception object.
|
||||||
@@ -648,22 +726,22 @@ grammar =
|
|||||||
While: [
|
While: [
|
||||||
o 'WhileSource Block', -> $1.addBody $2
|
o 'WhileSource Block', -> $1.addBody $2
|
||||||
o 'WhileLineSource Block', -> $1.addBody $2
|
o 'WhileLineSource Block', -> $1.addBody $2
|
||||||
o 'Statement WhileSource', -> $2.addBody LOC(1) Block.wrap([$1])
|
o 'Statement WhileSource', -> (Object.assign $2, postfix: yes).addBody LOC(1) Block.wrap([$1])
|
||||||
o 'Expression WhileSource', -> $2.addBody LOC(1) Block.wrap([$1])
|
o 'Expression WhileSource', -> (Object.assign $2, postfix: yes).addBody LOC(1) Block.wrap([$1])
|
||||||
o 'Loop', -> $1
|
o 'Loop', -> $1
|
||||||
]
|
]
|
||||||
|
|
||||||
Loop: [
|
Loop: [
|
||||||
o 'LOOP Block', -> new While(LOC(1) new BooleanLiteral 'true').addBody $2
|
o 'LOOP Block', -> new While(LOC(1)(new BooleanLiteral 'true'), isLoop: yes).addBody $2
|
||||||
o 'LOOP Expression', -> new While(LOC(1) new BooleanLiteral 'true').addBody LOC(2) Block.wrap [$2]
|
o 'LOOP Expression', -> new While(LOC(1)(new BooleanLiteral 'true'), isLoop: yes).addBody LOC(2) Block.wrap [$2]
|
||||||
]
|
]
|
||||||
|
|
||||||
# Array, object, and range comprehensions, at the most generic level.
|
# Array, object, and range comprehensions, at the most generic level.
|
||||||
# Comprehensions can either be normal, with a block of expressions to execute,
|
# Comprehensions can either be normal, with a block of expressions to execute,
|
||||||
# or postfix, with a single expression.
|
# or postfix, with a single expression.
|
||||||
For: [
|
For: [
|
||||||
o 'Statement ForBody', -> $2.addBody $1
|
o 'Statement ForBody', -> $2.postfix = yes; $2.addBody $1
|
||||||
o 'Expression ForBody', -> $2.addBody $1
|
o 'Expression ForBody', -> $2.postfix = yes; $2.addBody $1
|
||||||
o 'ForBody Block', -> $1.addBody $2
|
o 'ForBody Block', -> $1.addBody $2
|
||||||
o 'ForLineBody Block', -> $1.addBody $2
|
o 'ForLineBody Block', -> $1.addBody $2
|
||||||
]
|
]
|
||||||
@@ -707,7 +785,7 @@ grammar =
|
|||||||
]
|
]
|
||||||
|
|
||||||
# The source of a comprehension is an array or object with an optional guard
|
# The source of a comprehension is an array or object with an optional guard
|
||||||
# clause. If it's an array comprehension, you can also choose to step through
|
# clause. If it’s an array comprehension, you can also choose to step through
|
||||||
# in fixed-size increments.
|
# in fixed-size increments.
|
||||||
ForSource: [
|
ForSource: [
|
||||||
o 'FORIN Expression', -> source: $2
|
o 'FORIN Expression', -> source: $2
|
||||||
@@ -756,21 +834,21 @@ grammar =
|
|||||||
Switch: [
|
Switch: [
|
||||||
o 'SWITCH Expression INDENT Whens OUTDENT', -> new Switch $2, $4
|
o 'SWITCH Expression INDENT Whens OUTDENT', -> new Switch $2, $4
|
||||||
o 'SWITCH ExpressionLine INDENT Whens OUTDENT', -> new Switch $2, $4
|
o 'SWITCH ExpressionLine INDENT Whens OUTDENT', -> new Switch $2, $4
|
||||||
o 'SWITCH Expression INDENT Whens ELSE Block OUTDENT', -> new Switch $2, $4, $6
|
o 'SWITCH Expression INDENT Whens ELSE Block OUTDENT', -> new Switch $2, $4, LOC(5,6) $6
|
||||||
o 'SWITCH ExpressionLine INDENT Whens ELSE Block OUTDENT', -> new Switch $2, $4, $6
|
o 'SWITCH ExpressionLine INDENT Whens ELSE Block OUTDENT', -> new Switch $2, $4, LOC(5,6) $6
|
||||||
o 'SWITCH INDENT Whens OUTDENT', -> new Switch null, $3
|
o 'SWITCH INDENT Whens OUTDENT', -> new Switch null, $3
|
||||||
o 'SWITCH INDENT Whens ELSE Block OUTDENT', -> new Switch null, $3, $5
|
o 'SWITCH INDENT Whens ELSE Block OUTDENT', -> new Switch null, $3, LOC(4,5) $5
|
||||||
]
|
]
|
||||||
|
|
||||||
Whens: [
|
Whens: [
|
||||||
o 'When'
|
o 'When', -> [$1]
|
||||||
o 'Whens When', -> $1.concat $2
|
o 'Whens When', -> $1.concat $2
|
||||||
]
|
]
|
||||||
|
|
||||||
# An individual **When** clause, with action.
|
# An individual **When** clause, with action.
|
||||||
When: [
|
When: [
|
||||||
o 'LEADING_WHEN SimpleArgs Block', -> [[$2, $3]]
|
o 'LEADING_WHEN SimpleArgs Block', -> new SwitchWhen $2, $3
|
||||||
o 'LEADING_WHEN SimpleArgs Block TERMINATOR', -> [[$2, $3]]
|
o 'LEADING_WHEN SimpleArgs Block TERMINATOR', -> LOC(1, 3) new SwitchWhen $2, $3
|
||||||
]
|
]
|
||||||
|
|
||||||
# The most basic form of *if* is a condition and an action. The following
|
# The most basic form of *if* is a condition and an action. The following
|
||||||
@@ -786,8 +864,8 @@ grammar =
|
|||||||
If: [
|
If: [
|
||||||
o 'IfBlock'
|
o 'IfBlock'
|
||||||
o 'IfBlock ELSE Block', -> $1.addElse $3
|
o 'IfBlock ELSE Block', -> $1.addElse $3
|
||||||
o 'Statement POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
|
o 'Statement POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, postfix: true
|
||||||
o 'Expression POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
|
o 'Expression POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, postfix: true
|
||||||
]
|
]
|
||||||
|
|
||||||
IfBlockLine: [
|
IfBlockLine: [
|
||||||
@@ -798,8 +876,8 @@ grammar =
|
|||||||
IfLine: [
|
IfLine: [
|
||||||
o 'IfBlockLine'
|
o 'IfBlockLine'
|
||||||
o 'IfBlockLine ELSE Block', -> $1.addElse $3
|
o 'IfBlockLine ELSE Block', -> $1.addElse $3
|
||||||
o 'Statement POST_IF ExpressionLine', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
|
o 'Statement POST_IF ExpressionLine', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, postfix: true
|
||||||
o 'Expression POST_IF ExpressionLine', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
|
o 'Expression POST_IF ExpressionLine', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, postfix: true
|
||||||
]
|
]
|
||||||
|
|
||||||
# Arithmetic and logical operators, working on one or more operands.
|
# Arithmetic and logical operators, working on one or more operands.
|
||||||
@@ -810,11 +888,14 @@ grammar =
|
|||||||
# rules are necessary.
|
# rules are necessary.
|
||||||
OperationLine: [
|
OperationLine: [
|
||||||
o 'UNARY ExpressionLine', -> new Op $1, $2
|
o 'UNARY ExpressionLine', -> new Op $1, $2
|
||||||
|
o 'DO ExpressionLine', -> new Op $1, $2
|
||||||
|
o 'DO_IIFE CodeLine', -> new Op $1, $2
|
||||||
]
|
]
|
||||||
|
|
||||||
Operation: [
|
Operation: [
|
||||||
o 'UNARY Expression', -> new Op $1 , $2
|
o 'UNARY Expression', -> new Op $1.toString(), $2, undefined, undefined, originalOperator: $1.original
|
||||||
o 'UNARY_MATH Expression', -> new Op $1 , $2
|
o 'DO Expression', -> new Op $1, $2
|
||||||
|
o 'UNARY_MATH Expression', -> new Op $1, $2
|
||||||
o '- Expression', (-> new Op '-', $2), prec: 'UNARY_MATH'
|
o '- Expression', (-> new Op '-', $2), prec: 'UNARY_MATH'
|
||||||
o '+ Expression', (-> new Op '+', $2), prec: 'UNARY_MATH'
|
o '+ Expression', (-> new Op '+', $2), prec: 'UNARY_MATH'
|
||||||
|
|
||||||
@@ -835,25 +916,25 @@ grammar =
|
|||||||
o 'Expression MATH Expression', -> new Op $2, $1, $3
|
o 'Expression MATH Expression', -> new Op $2, $1, $3
|
||||||
o 'Expression ** Expression', -> new Op $2, $1, $3
|
o 'Expression ** Expression', -> new Op $2, $1, $3
|
||||||
o 'Expression SHIFT Expression', -> new Op $2, $1, $3
|
o 'Expression SHIFT Expression', -> new Op $2, $1, $3
|
||||||
o 'Expression COMPARE Expression', -> new Op $2, $1, $3
|
o 'Expression COMPARE Expression', -> new Op $2.toString(), $1, $3, undefined, originalOperator: $2.original
|
||||||
o 'Expression & Expression', -> new Op $2, $1, $3
|
o 'Expression & Expression', -> new Op $2, $1, $3
|
||||||
o 'Expression ^ Expression', -> new Op $2, $1, $3
|
o 'Expression ^ Expression', -> new Op $2, $1, $3
|
||||||
o 'Expression | Expression', -> new Op $2, $1, $3
|
o 'Expression | Expression', -> new Op $2, $1, $3
|
||||||
o 'Expression && Expression', -> new Op $2, $1, $3
|
o 'Expression && Expression', -> new Op $2.toString(), $1, $3, undefined, originalOperator: $2.original
|
||||||
o 'Expression || Expression', -> new Op $2, $1, $3
|
o 'Expression || Expression', -> new Op $2.toString(), $1, $3, undefined, originalOperator: $2.original
|
||||||
o 'Expression BIN? Expression', -> new Op $2, $1, $3
|
o 'Expression BIN? Expression', -> new Op $2, $1, $3
|
||||||
o 'Expression RELATION Expression', ->
|
o 'Expression RELATION Expression', -> new Op $2.toString(), $1, $3, undefined, invertOperator: $2.invert?.original ? $2.invert
|
||||||
if $2.charAt(0) is '!'
|
|
||||||
new Op($2[1..], $1, $3).invert()
|
|
||||||
else
|
|
||||||
new Op $2, $1, $3
|
|
||||||
|
|
||||||
o 'SimpleAssignable COMPOUND_ASSIGN
|
o 'SimpleAssignable COMPOUND_ASSIGN
|
||||||
Expression', -> new Assign $1, $3, $2
|
Expression', -> new Assign $1, $3, $2.toString(), originalContext: $2.original
|
||||||
o 'SimpleAssignable COMPOUND_ASSIGN
|
o 'SimpleAssignable COMPOUND_ASSIGN
|
||||||
INDENT Expression OUTDENT', -> new Assign $1, $4, $2
|
INDENT Expression OUTDENT', -> new Assign $1, $4, $2.toString(), originalContext: $2.original
|
||||||
o 'SimpleAssignable COMPOUND_ASSIGN TERMINATOR
|
o 'SimpleAssignable COMPOUND_ASSIGN TERMINATOR
|
||||||
Expression', -> new Assign $1, $4, $2
|
Expression', -> new Assign $1, $4, $2.toString(), originalContext: $2.original
|
||||||
|
]
|
||||||
|
|
||||||
|
DoIife: [
|
||||||
|
o 'DO_IIFE Code', -> new Op $1 , $2
|
||||||
]
|
]
|
||||||
|
|
||||||
# Precedence
|
# Precedence
|
||||||
@@ -868,11 +949,12 @@ grammar =
|
|||||||
#
|
#
|
||||||
# (2 + 3) * 4
|
# (2 + 3) * 4
|
||||||
operators = [
|
operators = [
|
||||||
|
['right', 'DO_IIFE']
|
||||||
['left', '.', '?.', '::', '?::']
|
['left', '.', '?.', '::', '?::']
|
||||||
['left', 'CALL_START', 'CALL_END']
|
['left', 'CALL_START', 'CALL_END']
|
||||||
['nonassoc', '++', '--']
|
['nonassoc', '++', '--']
|
||||||
['left', '?']
|
['left', '?']
|
||||||
['right', 'UNARY']
|
['right', 'UNARY', 'DO']
|
||||||
['right', 'AWAIT']
|
['right', 'AWAIT']
|
||||||
['right', '**']
|
['right', '**']
|
||||||
['right', 'UNARY_MATH']
|
['right', 'UNARY_MATH']
|
||||||
@@ -891,7 +973,7 @@ operators = [
|
|||||||
['right', 'YIELD']
|
['right', 'YIELD']
|
||||||
['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS']
|
['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS']
|
||||||
['right', 'FORIN', 'FOROF', 'FORFROM', 'BY', 'WHEN']
|
['right', 'FORIN', 'FOROF', 'FORFROM', 'BY', 'WHEN']
|
||||||
['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'IMPORT', 'EXPORT']
|
['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'IMPORT', 'EXPORT', 'DYNAMIC_IMPORT']
|
||||||
['left', 'POST_IF']
|
['left', 'POST_IF']
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -47,13 +47,7 @@ extend = exports.extend = (object, properties) ->
|
|||||||
# Return a flattened version of an array.
|
# Return a flattened version of an array.
|
||||||
# Handy for getting a list of `children` from the nodes.
|
# Handy for getting a list of `children` from the nodes.
|
||||||
exports.flatten = flatten = (array) ->
|
exports.flatten = flatten = (array) ->
|
||||||
flattened = []
|
array.flat(Infinity)
|
||||||
for element in array
|
|
||||||
if '[object Array]' is Object::toString.call element
|
|
||||||
flattened = flattened.concat flatten element
|
|
||||||
else
|
|
||||||
flattened.push element
|
|
||||||
flattened
|
|
||||||
|
|
||||||
# Delete a key from an object, returning the value. Useful when a node is
|
# Delete a key from an object, returning the value. Useful when a node is
|
||||||
# looking for a particular method in an options hash.
|
# looking for a particular method in an options hash.
|
||||||
@@ -107,15 +101,36 @@ buildLocationData = (first, last) ->
|
|||||||
first_column: first.first_column
|
first_column: first.first_column
|
||||||
last_line: last.last_line
|
last_line: last.last_line
|
||||||
last_column: last.last_column
|
last_column: last.last_column
|
||||||
|
last_line_exclusive: last.last_line_exclusive
|
||||||
|
last_column_exclusive: last.last_column_exclusive
|
||||||
|
range: [
|
||||||
|
first.range[0]
|
||||||
|
last.range[1]
|
||||||
|
]
|
||||||
|
|
||||||
|
# Build a list of all comments attached to tokens.
|
||||||
|
exports.extractAllCommentTokens = (tokens) ->
|
||||||
|
allCommentsObj = {}
|
||||||
|
for token in tokens when token.comments
|
||||||
|
for comment in token.comments
|
||||||
|
commentKey = comment.locationData.range[0]
|
||||||
|
allCommentsObj[commentKey] = comment
|
||||||
|
sortedKeys = Object.keys(allCommentsObj).sort (a, b) -> a - b
|
||||||
|
for key in sortedKeys
|
||||||
|
allCommentsObj[key]
|
||||||
|
|
||||||
|
# Get a lookup hash for a token based on its location data.
|
||||||
|
# Multiple tokens might have the same location hash, but using exclusive
|
||||||
|
# location data distinguishes e.g. zero-length generated tokens from
|
||||||
|
# actual source tokens.
|
||||||
buildLocationHash = (loc) ->
|
buildLocationHash = (loc) ->
|
||||||
"#{loc.first_line}x#{loc.first_column}-#{loc.last_line}x#{loc.last_column}"
|
"#{loc.range[0]}-#{loc.range[1]}"
|
||||||
|
|
||||||
# Build a dictionary of extra token properties organized by tokens’ locations
|
# Build a dictionary of extra token properties organized by tokens’ locations
|
||||||
# used as lookup hashes.
|
# used as lookup hashes.
|
||||||
buildTokenDataDictionary = (parserState) ->
|
exports.buildTokenDataDictionary = buildTokenDataDictionary = (tokens) ->
|
||||||
tokenData = {}
|
tokenData = {}
|
||||||
for token in parserState.parser.tokens when token.comments
|
for token in tokens when token.comments
|
||||||
tokenHash = buildLocationHash token[2]
|
tokenHash = buildLocationHash token[2]
|
||||||
# Multiple tokens might have the same location hash, such as the generated
|
# Multiple tokens might have the same location hash, such as the generated
|
||||||
# `JS` tokens added at the start or end of the token stream to hold
|
# `JS` tokens added at the start or end of the token stream to hold
|
||||||
@@ -132,15 +147,18 @@ buildTokenDataDictionary = (parserState) ->
|
|||||||
# This returns a function which takes an object as a parameter, and if that
|
# This returns a function which takes an object as a parameter, and if that
|
||||||
# object is an AST node, updates that object's locationData.
|
# object is an AST node, updates that object's locationData.
|
||||||
# The object is returned either way.
|
# The object is returned either way.
|
||||||
exports.addDataToNode = (parserState, first, last) ->
|
exports.addDataToNode = (parserState, firstLocationData, firstValue, lastLocationData, lastValue, forceUpdateLocation = yes) ->
|
||||||
(obj) ->
|
(obj) ->
|
||||||
# Add location data.
|
# Add location data.
|
||||||
if obj?.updateLocationDataIfMissing? and first?
|
locationData = buildLocationData(firstValue?.locationData ? firstLocationData, lastValue?.locationData ? lastLocationData)
|
||||||
obj.updateLocationDataIfMissing buildLocationData(first, last)
|
if obj?.updateLocationDataIfMissing? and firstLocationData?
|
||||||
|
obj.updateLocationDataIfMissing locationData, forceUpdateLocation
|
||||||
|
else
|
||||||
|
obj.locationData = locationData
|
||||||
|
|
||||||
# Add comments, building the dictionary of token data if it hasn’t been
|
# Add comments, building the dictionary of token data if it hasn’t been
|
||||||
# built yet.
|
# built yet.
|
||||||
parserState.tokenData ?= buildTokenDataDictionary parserState
|
parserState.tokenData ?= buildTokenDataDictionary parserState.parser.tokens
|
||||||
if obj.locationData?
|
if obj.locationData?
|
||||||
objHash = buildLocationHash obj.locationData
|
objHash = buildLocationHash obj.locationData
|
||||||
if parserState.tokenData[objHash]?.comments?
|
if parserState.tokenData[objHash]?.comments?
|
||||||
@@ -164,6 +182,13 @@ exports.locationDataToString = (obj) ->
|
|||||||
else
|
else
|
||||||
"No location data"
|
"No location data"
|
||||||
|
|
||||||
|
# Generate a unique anonymous file name so we can distinguish source map cache
|
||||||
|
# entries for any number of anonymous scripts.
|
||||||
|
exports.anonymousFileName = do ->
|
||||||
|
n = 0
|
||||||
|
->
|
||||||
|
"<anonymous-#{n++}>"
|
||||||
|
|
||||||
# A `.coffee.md` compatible version of `basename`, that returns the file sans-extension.
|
# A `.coffee.md` compatible version of `basename`, that returns the file sans-extension.
|
||||||
exports.baseFileName = (file, stripExt = no, useWinPathSep = no) ->
|
exports.baseFileName = (file, stripExt = no, useWinPathSep = no) ->
|
||||||
pathSep = if useWinPathSep then /\\|\// else /\//
|
pathSep = if useWinPathSep then /\\|\// else /\//
|
||||||
@@ -214,7 +239,11 @@ syntaxErrorToString = ->
|
|||||||
last_line ?= first_line
|
last_line ?= first_line
|
||||||
last_column ?= first_column
|
last_column ?= first_column
|
||||||
|
|
||||||
filename = @filename or '[stdin]'
|
if @filename?.startsWith '<anonymous'
|
||||||
|
filename = '[stdin]'
|
||||||
|
else
|
||||||
|
filename = @filename or '[stdin]'
|
||||||
|
|
||||||
codeLine = @code.split('\n')[first_line]
|
codeLine = @code.split('\n')[first_line]
|
||||||
start = first_column
|
start = first_column
|
||||||
# Show only the first line on multi-line errors.
|
# Show only the first line on multi-line errors.
|
||||||
@@ -243,3 +272,54 @@ exports.nameWhitespaceCharacter = (string) ->
|
|||||||
when '\r' then 'carriage return'
|
when '\r' then 'carriage return'
|
||||||
when '\t' then 'tab'
|
when '\t' then 'tab'
|
||||||
else string
|
else string
|
||||||
|
|
||||||
|
exports.parseNumber = (string) ->
|
||||||
|
return NaN unless string?
|
||||||
|
|
||||||
|
base = switch string.charAt 1
|
||||||
|
when 'b' then 2
|
||||||
|
when 'o' then 8
|
||||||
|
when 'x' then 16
|
||||||
|
else null
|
||||||
|
|
||||||
|
if base?
|
||||||
|
parseInt string[2..].replace(/_/g, ''), base
|
||||||
|
else
|
||||||
|
parseFloat string.replace(/_/g, '')
|
||||||
|
|
||||||
|
exports.isFunction = (obj) -> Object::toString.call(obj) is '[object Function]'
|
||||||
|
exports.isNumber = isNumber = (obj) -> Object::toString.call(obj) is '[object Number]'
|
||||||
|
exports.isString = isString = (obj) -> Object::toString.call(obj) is '[object String]'
|
||||||
|
exports.isBoolean = isBoolean = (obj) -> obj is yes or obj is no or Object::toString.call(obj) is '[object Boolean]'
|
||||||
|
exports.isPlainObject = (obj) -> typeof obj is 'object' and !!obj and not Array.isArray(obj) and not isNumber(obj) and not isString(obj) and not isBoolean(obj)
|
||||||
|
|
||||||
|
unicodeCodePointToUnicodeEscapes = (codePoint) ->
|
||||||
|
toUnicodeEscape = (val) ->
|
||||||
|
str = val.toString 16
|
||||||
|
"\\u#{repeat '0', 4 - str.length}#{str}"
|
||||||
|
return toUnicodeEscape(codePoint) if codePoint < 0x10000
|
||||||
|
# surrogate pair
|
||||||
|
high = Math.floor((codePoint - 0x10000) / 0x400) + 0xD800
|
||||||
|
low = (codePoint - 0x10000) % 0x400 + 0xDC00
|
||||||
|
"#{toUnicodeEscape(high)}#{toUnicodeEscape(low)}"
|
||||||
|
|
||||||
|
# Replace `\u{...}` with `\uxxxx[\uxxxx]` in regexes without `u` flag
|
||||||
|
exports.replaceUnicodeCodePointEscapes = (str, {flags, error, delimiter = ''} = {}) ->
|
||||||
|
shouldReplace = flags? and 'u' not in flags
|
||||||
|
str.replace UNICODE_CODE_POINT_ESCAPE, (match, escapedBackslash, codePointHex, offset) ->
|
||||||
|
return escapedBackslash if escapedBackslash
|
||||||
|
|
||||||
|
codePointDecimal = parseInt codePointHex, 16
|
||||||
|
if codePointDecimal > 0x10ffff
|
||||||
|
error "unicode code point escapes greater than \\u{10ffff} are not allowed",
|
||||||
|
offset: offset + delimiter.length
|
||||||
|
length: codePointHex.length + 4
|
||||||
|
return match unless shouldReplace
|
||||||
|
|
||||||
|
unicodeCodePointToUnicodeEscapes codePointDecimal
|
||||||
|
|
||||||
|
UNICODE_CODE_POINT_ESCAPE = ///
|
||||||
|
( \\\\ ) # Make sure the escape isn’t escaped.
|
||||||
|
|
|
||||||
|
\\u\{ ( [\da-fA-F]+ ) \}
|
||||||
|
///g
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ CoffeeScript.run = (code, options = {}) ->
|
|||||||
|
|
||||||
# Set the filename.
|
# Set the filename.
|
||||||
mainModule.filename = process.argv[1] =
|
mainModule.filename = process.argv[1] =
|
||||||
if options.filename then fs.realpathSync(options.filename) else '<anonymous>'
|
if options.filename then fs.realpathSync(options.filename) else helpers.anonymousFileName()
|
||||||
|
|
||||||
# Clear the module cache.
|
# Clear the module cache.
|
||||||
mainModule.moduleCache and= {}
|
mainModule.moduleCache and= {}
|
||||||
@@ -52,10 +52,12 @@ CoffeeScript.run = (code, options = {}) ->
|
|||||||
# Save the options for compiling child imports.
|
# Save the options for compiling child imports.
|
||||||
mainModule.options = options
|
mainModule.options = options
|
||||||
|
|
||||||
|
options.filename = mainModule.filename
|
||||||
|
options.inlineMap = true
|
||||||
|
|
||||||
# Compile.
|
# Compile.
|
||||||
if not helpers.isCoffee(mainModule.filename) or require.extensions
|
answer = CoffeeScript.compile code, options
|
||||||
answer = CoffeeScript.compile code, options
|
code = answer.js ? answer
|
||||||
code = answer.js ? answer
|
|
||||||
|
|
||||||
mainModule._compile code, mainModule.filename
|
mainModule._compile code, mainModule.filename
|
||||||
|
|
||||||
@@ -110,8 +112,8 @@ if require.extensions
|
|||||||
Use CoffeeScript.register() or require the coffeescript/register module to require #{ext} files.
|
Use CoffeeScript.register() or require the coffeescript/register module to require #{ext} files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
CoffeeScript._compileFile = (filename, options = {}) ->
|
CoffeeScript._compileRawFileContent = (raw, filename, options = {}) ->
|
||||||
raw = fs.readFileSync filename, 'utf8'
|
|
||||||
# Strip the Unicode byte order mark, if this file begins with one.
|
# Strip the Unicode byte order mark, if this file begins with one.
|
||||||
stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
|
stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
|
||||||
|
|
||||||
@@ -119,7 +121,6 @@ CoffeeScript._compileFile = (filename, options = {}) ->
|
|||||||
filename: filename
|
filename: filename
|
||||||
literate: helpers.isLiterate filename
|
literate: helpers.isLiterate filename
|
||||||
sourceFiles: [filename]
|
sourceFiles: [filename]
|
||||||
inlineMap: yes # Always generate a source map, so that stack traces line up.
|
|
||||||
|
|
||||||
try
|
try
|
||||||
answer = CoffeeScript.compile stripped, options
|
answer = CoffeeScript.compile stripped, options
|
||||||
@@ -131,4 +132,29 @@ CoffeeScript._compileFile = (filename, options = {}) ->
|
|||||||
|
|
||||||
answer
|
answer
|
||||||
|
|
||||||
|
CoffeeScript._compileFile = (filename, options = {}) ->
|
||||||
|
raw = fs.readFileSync filename, 'utf8'
|
||||||
|
|
||||||
|
CoffeeScript._compileRawFileContent raw, filename, options
|
||||||
|
|
||||||
module.exports = CoffeeScript
|
module.exports = CoffeeScript
|
||||||
|
|
||||||
|
# Explicitly define all named exports so that Node’s automatic detection of
|
||||||
|
# named exports from CommonJS packages finds all of them. This enables consuming
|
||||||
|
# packages to write code like `import { compile } from 'coffeescript'`.
|
||||||
|
# Don’t simplify this into a loop or similar; the `module.exports.name` part is
|
||||||
|
# essential for Node’s algorithm to successfully detect the name.
|
||||||
|
module.exports.VERSION = CoffeeScript.VERSION
|
||||||
|
module.exports.FILE_EXTENSIONS = CoffeeScript.FILE_EXTENSIONS
|
||||||
|
module.exports.helpers = CoffeeScript.helpers
|
||||||
|
module.exports.registerCompiled = CoffeeScript.registerCompiled
|
||||||
|
module.exports.compile = CoffeeScript.compile
|
||||||
|
module.exports.tokens = CoffeeScript.tokens
|
||||||
|
module.exports.nodes = CoffeeScript.nodes
|
||||||
|
module.exports.register = CoffeeScript.register
|
||||||
|
module.exports.eval = CoffeeScript.eval
|
||||||
|
module.exports.run = CoffeeScript.run
|
||||||
|
module.exports.transpile = CoffeeScript.transpile
|
||||||
|
module.exports.patchStackTrace = CoffeeScript.patchStackTrace
|
||||||
|
module.exports._compileRawFileContent = CoffeeScript._compileRawFileContent
|
||||||
|
module.exports._compileFile = CoffeeScript._compileFile
|
||||||
|
|||||||
786
src/lexer.coffee
786
src/lexer.coffee
File diff suppressed because it is too large
Load Diff
2985
src/nodes.coffee
2985
src/nodes.coffee
File diff suppressed because it is too large
Load Diff
@@ -3,11 +3,29 @@ child_process = require 'child_process'
|
|||||||
helpers = require './helpers'
|
helpers = require './helpers'
|
||||||
path = require 'path'
|
path = require 'path'
|
||||||
|
|
||||||
|
{patchStackTrace} = CoffeeScript
|
||||||
|
|
||||||
|
# Check if Node's built-in source map stack trace transformations are enabled.
|
||||||
|
nodeSourceMapsSupportEnabled = process? and (
|
||||||
|
process.execArgv.includes('--enable-source-maps') or
|
||||||
|
process.env.NODE_OPTIONS?.includes('--enable-source-maps')
|
||||||
|
)
|
||||||
|
|
||||||
|
unless Error.prepareStackTrace or nodeSourceMapsSupportEnabled
|
||||||
|
cacheSourceMaps = true
|
||||||
|
patchStackTrace()
|
||||||
|
|
||||||
# Load and run a CoffeeScript file for Node, stripping any `BOM`s.
|
# Load and run a CoffeeScript file for Node, stripping any `BOM`s.
|
||||||
loadFile = (module, filename) ->
|
loadFile = (module, filename) ->
|
||||||
options = module.options or getRootModule(module).options
|
options = module.options or getRootModule(module).options or {}
|
||||||
answer = CoffeeScript._compileFile filename, options
|
|
||||||
module._compile answer, filename
|
# Currently `CoffeeScript.compile` caches all source maps if present. They
|
||||||
|
# are available in `getSourceMap` retrieved by `filename`.
|
||||||
|
if cacheSourceMaps or nodeSourceMapsSupportEnabled
|
||||||
|
options.inlineMap = true
|
||||||
|
js = CoffeeScript._compileFile filename, options
|
||||||
|
|
||||||
|
module._compile js, filename
|
||||||
|
|
||||||
# If the installed version of Node supports `require.extensions`, register
|
# If the installed version of Node supports `require.extensions`, register
|
||||||
# CoffeeScript as an extension.
|
# CoffeeScript as an extension.
|
||||||
|
|||||||
@@ -25,30 +25,30 @@ replDefaults =
|
|||||||
input = input.replace /^\s*try\s*{([\s\S]*)}\s*catch.*$/m, '$1'
|
input = input.replace /^\s*try\s*{([\s\S]*)}\s*catch.*$/m, '$1'
|
||||||
|
|
||||||
# Require AST nodes to do some AST manipulation.
|
# Require AST nodes to do some AST manipulation.
|
||||||
{Block, Assign, Value, Literal, Call, Code} = require './nodes'
|
{Block, Assign, Value, Literal, Call, Code, Root} = require './nodes'
|
||||||
|
|
||||||
try
|
try
|
||||||
# Tokenize the clean input.
|
# Tokenize the clean input.
|
||||||
tokens = CoffeeScript.tokens input
|
tokens = CoffeeScript.tokens input
|
||||||
# Filter out tokens generated just to hold comments.
|
# Filter out tokens generated just to hold comments.
|
||||||
if tokens.length >= 2 and tokens[0].generated and
|
if tokens.length >= 2 and tokens[0].generated and
|
||||||
tokens[0].comments?.length isnt 0 and tokens[0][1] is '' and
|
tokens[0].comments?.length isnt 0 and "#{tokens[0][1]}" is '' and
|
||||||
tokens[1][0] is 'TERMINATOR'
|
tokens[1][0] is 'TERMINATOR'
|
||||||
tokens = tokens[2...]
|
tokens = tokens[2...]
|
||||||
if tokens.length >= 1 and tokens[tokens.length - 1].generated and
|
if tokens.length >= 1 and tokens[tokens.length - 1].generated and
|
||||||
tokens[tokens.length - 1].comments?.length isnt 0 and tokens[tokens.length - 1][1] is ''
|
tokens[tokens.length - 1].comments?.length isnt 0 and "#{tokens[tokens.length - 1][1]}" is ''
|
||||||
tokens.pop()
|
tokens.pop()
|
||||||
# Collect referenced variable names just like in `CoffeeScript.compile`.
|
# Collect referenced variable names just like in `CoffeeScript.compile`.
|
||||||
referencedVars = (token[1] for token in tokens when token[0] is 'IDENTIFIER')
|
referencedVars = (token[1] for token in tokens when token[0] is 'IDENTIFIER')
|
||||||
# Generate the AST of the tokens.
|
# Generate the AST of the tokens.
|
||||||
ast = CoffeeScript.nodes tokens
|
ast = CoffeeScript.nodes(tokens).body
|
||||||
# Add assignment to `__` variable to force the input to be an expression.
|
# Add assignment to `__` variable to force the input to be an expression.
|
||||||
ast = new Block [new Assign (new Value new Literal '__'), ast, '=']
|
ast = new Block [new Assign (new Value new Literal '__'), ast, '=']
|
||||||
# Wrap the expression in a closure to support top-level `await`.
|
# Wrap the expression in a closure to support top-level `await`.
|
||||||
ast = new Code [], ast
|
ast = new Code [], ast
|
||||||
isAsync = ast.isAsync
|
isAsync = ast.isAsync
|
||||||
# Invoke the wrapping closure.
|
# Invoke the wrapping closure.
|
||||||
ast = new Block [new Call ast]
|
ast = new Root new Block [new Call ast]
|
||||||
js = ast.compile {bare: yes, locals: Object.keys(context), referencedVars, sharedScope: yes}
|
js = ast.compile {bare: yes, locals: Object.keys(context), referencedVars, sharedScope: yes}
|
||||||
if transpile
|
if transpile
|
||||||
js = transpile.transpile(js, transpile.options).code
|
js = transpile.transpile(js, transpile.options).code
|
||||||
@@ -75,7 +75,7 @@ runInContext = (js, context, filename) ->
|
|||||||
vm.runInContext js, context, filename
|
vm.runInContext js, context, filename
|
||||||
|
|
||||||
addMultilineHandler = (repl) ->
|
addMultilineHandler = (repl) ->
|
||||||
{rli, inputStream, outputStream} = repl
|
{inputStream, outputStream} = repl
|
||||||
# Node 0.11.12 changed API, prompt is now _prompt.
|
# Node 0.11.12 changed API, prompt is now _prompt.
|
||||||
origPrompt = repl._prompt ? repl.prompt
|
origPrompt = repl._prompt ? repl.prompt
|
||||||
|
|
||||||
@@ -86,15 +86,15 @@ addMultilineHandler = (repl) ->
|
|||||||
buffer: ''
|
buffer: ''
|
||||||
|
|
||||||
# Proxy node's line listener
|
# Proxy node's line listener
|
||||||
nodeLineListener = rli.listeners('line')[0]
|
nodeLineListener = repl.listeners('line')[0]
|
||||||
rli.removeListener 'line', nodeLineListener
|
repl.removeListener 'line', nodeLineListener
|
||||||
rli.on 'line', (cmd) ->
|
repl.on 'line', (cmd) ->
|
||||||
if multiline.enabled
|
if multiline.enabled
|
||||||
multiline.buffer += "#{cmd}\n"
|
multiline.buffer += "#{cmd}\n"
|
||||||
rli.setPrompt multiline.prompt
|
repl.setPrompt multiline.prompt
|
||||||
rli.prompt true
|
repl.prompt true
|
||||||
else
|
else
|
||||||
rli.setPrompt origPrompt
|
repl.setPrompt origPrompt
|
||||||
nodeLineListener cmd
|
nodeLineListener cmd
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -105,25 +105,25 @@ addMultilineHandler = (repl) ->
|
|||||||
# allow arbitrarily switching between modes any time before multiple lines are entered
|
# allow arbitrarily switching between modes any time before multiple lines are entered
|
||||||
unless multiline.buffer.match /\n/
|
unless multiline.buffer.match /\n/
|
||||||
multiline.enabled = not multiline.enabled
|
multiline.enabled = not multiline.enabled
|
||||||
rli.setPrompt origPrompt
|
repl.setPrompt origPrompt
|
||||||
rli.prompt true
|
repl.prompt true
|
||||||
return
|
return
|
||||||
# no-op unless the current line is empty
|
# no-op unless the current line is empty
|
||||||
return if rli.line? and not rli.line.match /^\s*$/
|
return if repl.line? and not repl.line.match /^\s*$/
|
||||||
# eval, print, loop
|
# eval, print, loop
|
||||||
multiline.enabled = not multiline.enabled
|
multiline.enabled = not multiline.enabled
|
||||||
rli.line = ''
|
repl.line = ''
|
||||||
rli.cursor = 0
|
repl.cursor = 0
|
||||||
rli.output.cursorTo 0
|
repl.output.cursorTo 0
|
||||||
rli.output.clearLine 1
|
repl.output.clearLine 1
|
||||||
# XXX: multiline hack
|
# XXX: multiline hack
|
||||||
multiline.buffer = multiline.buffer.replace /\n/g, '\uFF00'
|
multiline.buffer = multiline.buffer.replace /\n/g, '\uFF00'
|
||||||
rli.emit 'line', multiline.buffer
|
repl.emit 'line', multiline.buffer
|
||||||
multiline.buffer = ''
|
multiline.buffer = ''
|
||||||
else
|
else
|
||||||
multiline.enabled = not multiline.enabled
|
multiline.enabled = not multiline.enabled
|
||||||
rli.setPrompt multiline.initialPrompt
|
repl.setPrompt multiline.initialPrompt
|
||||||
rli.prompt true
|
repl.prompt true
|
||||||
return
|
return
|
||||||
|
|
||||||
# Store and load command history from a file
|
# Store and load command history from a file
|
||||||
@@ -139,17 +139,17 @@ addHistory = (repl, filename, maxSize) ->
|
|||||||
fs.readSync readFd, buffer, 0, size, stat.size - size
|
fs.readSync readFd, buffer, 0, size, stat.size - size
|
||||||
fs.closeSync readFd
|
fs.closeSync readFd
|
||||||
# Set the history on the interpreter
|
# Set the history on the interpreter
|
||||||
repl.rli.history = buffer.toString().split('\n').reverse()
|
repl.history = buffer.toString().split('\n').reverse()
|
||||||
# If the history file was truncated we should pop off a potential partial line
|
# If the history file was truncated we should pop off a potential partial line
|
||||||
repl.rli.history.pop() if stat.size > maxSize
|
repl.history.pop() if stat.size > maxSize
|
||||||
# Shift off the final blank newline
|
# Shift off the final blank newline
|
||||||
repl.rli.history.shift() if repl.rli.history[0] is ''
|
repl.history.shift() if repl.history[0] is ''
|
||||||
repl.rli.historyIndex = -1
|
repl.historyIndex = -1
|
||||||
lastLine = repl.rli.history[0]
|
lastLine = repl.history[0]
|
||||||
|
|
||||||
fd = fs.openSync filename, 'a'
|
fd = fs.openSync filename, 'a'
|
||||||
|
|
||||||
repl.rli.addListener 'line', (code) ->
|
repl.addListener 'line', (code) ->
|
||||||
if code and code.length and code isnt '.history' and code isnt '.exit' and lastLine isnt code
|
if code and code.length and code isnt '.history' and code isnt '.exit' and lastLine isnt code
|
||||||
# Save the latest command in the file
|
# Save the latest command in the file
|
||||||
fs.writeSync fd, "#{code}\n"
|
fs.writeSync fd, "#{code}\n"
|
||||||
@@ -163,7 +163,7 @@ addHistory = (repl, filename, maxSize) ->
|
|||||||
repl.commands[getCommandId(repl, 'history')] =
|
repl.commands[getCommandId(repl, 'history')] =
|
||||||
help: 'Show command history'
|
help: 'Show command history'
|
||||||
action: ->
|
action: ->
|
||||||
repl.outputStream.write "#{repl.rli.history[..].reverse().join '\n'}\n"
|
repl.outputStream.write "#{repl.history[..].reverse().join '\n'}\n"
|
||||||
repl.displayPrompt()
|
repl.displayPrompt()
|
||||||
|
|
||||||
getCommandId = (repl, commandName) ->
|
getCommandId = (repl, commandName) ->
|
||||||
@@ -212,7 +212,7 @@ module.exports =
|
|||||||
opts = merge replDefaults, opts
|
opts = merge replDefaults, opts
|
||||||
repl = nodeREPL.start opts
|
repl = nodeREPL.start opts
|
||||||
runInContext opts.prelude, repl.context, 'prelude' if opts.prelude
|
runInContext opts.prelude, repl.context, 'prelude' if opts.prelude
|
||||||
repl.on 'exit', -> repl.outputStream.write '\n' if not repl.rli.closed
|
repl.on 'exit', -> repl.outputStream.write '\n' if not repl.closed
|
||||||
addMultilineHandler repl
|
addMultilineHandler repl
|
||||||
addHistory repl, opts.historyFile, opts.historyMaxInputSize if opts.historyFile
|
addHistory repl, opts.historyFile, opts.historyMaxInputSize if opts.historyFile
|
||||||
# Adapt help inherited from the node REPL
|
# Adapt help inherited from the node REPL
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user