2017-02-09 21:28:22 +00:00
|
|
|
// Generated by CoffeeScript 2.0.0-alpha1
|
2010-07-25 07:15:12 +00:00
|
|
|
(function() {
|
2017-04-06 16:59:11 +00:00
|
|
|
var buildLocationData, extend, flatten, md, ref, repeat, syntaxErrorToString;
|
2016-10-23 15:37:51 +00:00
|
|
|
|
2017-04-06 16:59:11 +00:00
|
|
|
md = require('markdown-it')();
|
2011-09-18 22:16:39 +00:00
|
|
|
|
2010-09-25 00:29:44 +00:00
|
|
|
exports.starts = function(string, literal, start) {
|
2010-09-25 00:18:47 +00:00
|
|
|
return literal === string.substr(start, literal.length);
|
|
|
|
};
|
2011-09-18 22:16:39 +00:00
|
|
|
|
2010-09-25 00:29:44 +00:00
|
|
|
exports.ends = function(string, literal, back) {
|
2010-09-26 14:28:48 +00:00
|
|
|
var len;
|
|
|
|
len = literal.length;
|
|
|
|
return literal === string.substr(string.length - len - (back || 0), len);
|
2010-09-25 00:18:47 +00:00
|
|
|
};
|
2011-09-18 22:16:39 +00:00
|
|
|
|
2013-03-05 04:13:46 +00:00
|
|
|
exports.repeat = repeat = function(str, n) {
|
2013-02-26 17:41:01 +00:00
|
|
|
var res;
|
|
|
|
res = '';
|
|
|
|
while (n > 0) {
|
|
|
|
if (n & 1) {
|
|
|
|
res += str;
|
|
|
|
}
|
|
|
|
n >>>= 1;
|
|
|
|
str += str;
|
|
|
|
}
|
|
|
|
return res;
|
2013-02-25 17:41:34 +00:00
|
|
|
};
|
|
|
|
|
2010-09-25 00:29:44 +00:00
|
|
|
exports.compact = function(array) {
|
2017-04-06 16:59:11 +00:00
|
|
|
var item, j, len1, results;
|
2015-01-30 19:33:03 +00:00
|
|
|
results = [];
|
2017-04-06 16:59:11 +00:00
|
|
|
for (j = 0, len1 = array.length; j < len1; j++) {
|
|
|
|
item = array[j];
|
2012-04-10 18:57:45 +00:00
|
|
|
if (item) {
|
2015-01-30 19:33:03 +00:00
|
|
|
results.push(item);
|
2012-04-10 18:57:45 +00:00
|
|
|
}
|
2010-03-10 02:24:30 +00:00
|
|
|
}
|
2015-01-30 19:33:03 +00:00
|
|
|
return results;
|
2010-09-25 00:18:47 +00:00
|
|
|
};
|
2011-09-18 22:16:39 +00:00
|
|
|
|
2010-12-13 10:51:57 +00:00
|
|
|
exports.count = function(string, substr) {
|
2010-03-10 02:24:30 +00:00
|
|
|
var num, pos;
|
2010-10-20 17:29:06 +00:00
|
|
|
num = pos = 0;
|
2012-04-10 18:57:45 +00:00
|
|
|
if (!substr.length) {
|
|
|
|
return 1 / 0;
|
|
|
|
}
|
2010-12-13 10:51:57 +00:00
|
|
|
while (pos = 1 + string.indexOf(substr, pos)) {
|
2010-09-25 00:18:47 +00:00
|
|
|
num++;
|
2010-03-10 02:24:30 +00:00
|
|
|
}
|
|
|
|
return num;
|
2010-09-25 00:18:47 +00:00
|
|
|
};
|
2011-09-18 22:16:39 +00:00
|
|
|
|
2010-09-25 00:29:44 +00:00
|
|
|
exports.merge = function(options, overrides) {
|
2010-09-25 00:18:47 +00:00
|
|
|
return extend(extend({}, options), overrides);
|
|
|
|
};
|
2011-09-18 22:16:39 +00:00
|
|
|
|
2010-10-20 17:29:06 +00:00
|
|
|
extend = exports.extend = function(object, properties) {
|
2010-10-19 15:07:10 +00:00
|
|
|
var key, val;
|
2010-10-01 22:26:37 +00:00
|
|
|
for (key in properties) {
|
|
|
|
val = properties[key];
|
2010-09-26 14:28:48 +00:00
|
|
|
object[key] = val;
|
2010-03-10 02:24:30 +00:00
|
|
|
}
|
2010-09-25 00:18:47 +00:00
|
|
|
return object;
|
2010-10-20 17:29:06 +00:00
|
|
|
};
|
2011-09-18 22:16:39 +00:00
|
|
|
|
2010-10-20 17:29:06 +00:00
|
|
|
exports.flatten = flatten = function(array) {
|
2017-04-06 16:59:11 +00:00
|
|
|
var element, flattened, j, len1;
|
2010-09-28 18:28:05 +00:00
|
|
|
flattened = [];
|
2017-04-06 16:59:11 +00:00
|
|
|
for (j = 0, len1 = array.length; j < len1; j++) {
|
|
|
|
element = array[j];
|
2015-05-21 01:46:01 +00:00
|
|
|
if ('[object Array]' === Object.prototype.toString.call(element)) {
|
2010-09-28 18:28:05 +00:00
|
|
|
flattened = flattened.concat(flatten(element));
|
|
|
|
} else {
|
|
|
|
flattened.push(element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return flattened;
|
2010-10-20 17:29:06 +00:00
|
|
|
};
|
2011-09-18 22:16:39 +00:00
|
|
|
|
2010-09-25 00:29:44 +00:00
|
|
|
exports.del = function(obj, key) {
|
2010-03-10 02:24:30 +00:00
|
|
|
var val;
|
|
|
|
val = obj[key];
|
|
|
|
delete obj[key];
|
|
|
|
return val;
|
2010-09-25 00:18:47 +00:00
|
|
|
};
|
2011-09-18 22:16:39 +00:00
|
|
|
|
2015-01-30 19:33:03 +00:00
|
|
|
exports.some = (ref = Array.prototype.some) != null ? ref : function(fn) {
|
2017-04-06 16:59:11 +00:00
|
|
|
var e, j, len1, ref1;
|
Refactor `Literal` into several subtypes
Previously, the parser created `Literal` nodes for many things. This resulted in
information loss. Instead of being able to check the node type, we had to use
regexes to tell the different types of `Literal`s apart. That was a bit like
parsing literals twice: Once in the lexer, and once (or more) in the compiler.
It also caused problems, such as `` `this` `` and `this` being indistinguishable
(fixes #2009).
Instead returning `new Literal` in the grammar, subtypes of it are now returned
instead, such as `NumberLiteral`, `StringLiteral` and `IdentifierLiteral`. `new
Literal` by itself is only used to represent code chunks that fit no category.
(While mentioning `NumberLiteral`, there's also `InfinityLiteral` now, which is
a subtype of `NumberLiteral`.)
`StringWithInterpolations` has been added as a subtype of `Parens`, and
`RegexWithInterpolations` as a subtype of `Call`. This makes it easier for other
programs to make use of CoffeeScript's "AST" (nodes). For example, it is now
possible to distinguish between `"a #{b} c"` and `"a " + b + " c"`. Fixes #4192.
`SuperCall` has been added as a subtype of `Call`.
Note, though, that some information is still lost, especially in the lexer. For
example, there is no way to distinguish a heredoc from a regular string, or a
heregex without interpolations from a regular regex. Binary and octal number
literals are indistinguishable from hexadecimal literals.
After the new subtypes were added, they were taken advantage of, removing most
regexes in nodes.coffee. `SIMPLENUM` (which matches non-hex integers) had to be
kept, though, because such numbers need special handling in JavaScript (for
example in `1..toString()`).
An especially nice hack to get rid of was using `new String()` for the token
value for reserved identifiers (to be able to set a property on them which could
survive through the parser). Now it's a good old regular string.
In range literals, slices, splices and for loop steps when number literals
are involved, CoffeeScript can do some optimizations, such as precomputing the
value of, say, `5 - 3` (outputting `2` instead of `5 - 3` literally). As a side
bonus, this now also works with hexadecimal number literals, such as `0x02`.
Finally, this also improves the output of `coffee --nodes`:
# Before:
$ bin/coffee -ne 'while true
"#{a}"
break'
Block
While
Value
Bool
Block
Value
Parens
Block
Op +
Value """"
Value
Parens
Block
Value "a" "break"
# After:
$ bin/coffee -ne 'while true
"#{a}"
break'
Block
While
Value BooleanLiteral: true
Block
Value
StringWithInterpolations
Block
Op +
Value StringLiteral: ""
Value
Parens
Block
Value IdentifierLiteral: a
StatementLiteral: break
2016-01-31 19:24:31 +00:00
|
|
|
ref1 = this;
|
2017-04-06 16:59:11 +00:00
|
|
|
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
|
|
|
e = ref1[j];
|
2012-05-16 19:50:34 +00:00
|
|
|
if (fn(e)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2013-03-05 02:45:57 +00:00
|
|
|
exports.invertLiterate = function(code) {
|
2017-04-06 16:59:11 +00:00
|
|
|
var out;
|
|
|
|
out = [];
|
|
|
|
md.renderer.rules = {
|
|
|
|
code_block: function(tokens, idx) {
|
|
|
|
var i, j, len1, line, lines, results, startLine;
|
|
|
|
startLine = tokens[idx].map[0];
|
|
|
|
lines = tokens[idx].content.split('\n');
|
|
|
|
results = [];
|
|
|
|
for (i = j = 0, len1 = lines.length; j < len1; i = ++j) {
|
|
|
|
line = lines[i];
|
|
|
|
results.push(out[startLine + i] = line);
|
|
|
|
}
|
|
|
|
return results;
|
2013-03-05 02:45:57 +00:00
|
|
|
}
|
2017-04-06 16:59:11 +00:00
|
|
|
};
|
|
|
|
md.render(code);
|
|
|
|
return out.join('\n');
|
2013-03-05 02:45:57 +00:00
|
|
|
};
|
|
|
|
|
2012-11-15 20:35:01 +00:00
|
|
|
buildLocationData = function(first, last) {
|
|
|
|
if (!last) {
|
|
|
|
return first;
|
|
|
|
} else {
|
|
|
|
return {
|
|
|
|
first_line: first.first_line,
|
|
|
|
first_column: first.first_column,
|
|
|
|
last_line: last.last_line,
|
|
|
|
last_column: last.last_column
|
|
|
|
};
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.addLocationDataFn = function(first, last) {
|
|
|
|
return function(obj) {
|
|
|
|
if (((typeof obj) === 'object') && (!!obj['updateLocationDataIfMissing'])) {
|
|
|
|
obj.updateLocationDataIfMissing(buildLocationData(first, last));
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2012-11-17 00:09:56 +00:00
|
|
|
exports.locationDataToString = function(obj) {
|
|
|
|
var locationData;
|
2013-01-14 20:20:35 +00:00
|
|
|
if (("2" in obj) && ("first_line" in obj[2])) {
|
|
|
|
locationData = obj[2];
|
2012-11-17 00:09:56 +00:00
|
|
|
} else if ("first_line" in obj) {
|
|
|
|
locationData = obj;
|
|
|
|
}
|
|
|
|
if (locationData) {
|
2016-11-28 14:05:51 +00:00
|
|
|
return `${locationData.first_line + 1}:${locationData.first_column + 1}-` + `${locationData.last_line + 1}:${locationData.last_column + 1}`;
|
2012-11-17 00:09:56 +00:00
|
|
|
} else {
|
|
|
|
return "No location data";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
[CS2] Output ES2015 arrow functions, default parameters, rest parameters (#4311)
* Eliminate wrapper around “bound” (arrow) functions; output `=>` for such functions
* Remove irrelevant (and breaking) tests
* Minor cleanup
* When a function parameter is a splat (i.e., it uses the ES2015 rest parameter syntax) output that parameter as ES2015
* Rearrange function parameters when one of the parameters is a splat and isn’t the last parameter (very WIP)
* Handle params like `@param`, adding assignment expressions for them when they appear; ensure splat parameter is last
* Add parameter names (not a text like `'\nValue IdentifierLiteral: a'`) to the scope, so that parameters can’t be deleted; move body-related lines together; more explanation of what’s going on
* For parameters with a default value, correctly add the parameter name to the function scope
* Handle expansions in function parameters: when an expansion is found, set the parameters to only be the original parameters left of the expansion, then an `...args` parameter; and in the function body define variables for the parameters to the right of the expansion, including setting default values
* Handle splat parameters the same way we handle expansions: if a splat parameter is found, it becomes the last parameter in the function definition, and all following parameters get declared in the function body. Fix the splat/rest parameter values after the post-splat parameters have been extracted from it. Clean up `Code.compileNode` so that we loop through the parameters only once, and we create all expressions using calls like `new IdentifierLiteral` rather than `@makeCode`.
* Fix parameter name when a parameter is a splat attached to `this` (e.g. `@param...`)
* Rather than assigning post-splat parameters based on index, use slice; passes test “Functions with splats being called with too few arguments”
* Dial back our w00t indentation
* Better parsing of parameter names (WIP)
* Refactor processing of splat/expansion parameters
* Fix assignment of default parameters for parameters that come after a splat
* Better check for whether a param is attached to `this`
* More understandable variable names
* For parameters after a splat or expansion, assign them similar to the 1.x destructuring method of using `arguments`, except only concern ourselves with the post-splat parameters instead of all parameters; and use the splat/expansion parameter name, since `arguments` in ES fat arrow functions refers to the parent function’s `arguments` rather than the fat arrow function’s arguments/parameters
* Don’t add unnamed parameters (like `[]` as a parameter) to the function scope
* Disallow multiple splat/expansion parameters in function definitions; disallow lone expansion parameters
* Fix `this` params not getting assigned if the parameter is after a splat parameter
* Allow names of function parameters attached to `this` to be reserved words
* Always add a statement to the function body defining a variable with its default value, if it has one, if the variable `== null`; this covers the case when ES doesn’t apply the default value when `null` is passed in as a value, but CoffeeScript expects `null` and `undefined` to act interchangeably
* Aftermath of having both `undefined` and `null` trigger the use of default values for parameters with default values
* More careful parsing of destructured parameters
* Fall back to processing destructured parameters in the function body, to account for `this` or default values within destructured objects
* Clean up comments
* Restore new bare function test, minus the arrow function part of it
* Test that bound/arrow functions aren’t overwriting the `arguments` object, which should refer to the parent scope’s `arguments` (like `this`)
* Follow ES2015 spec for parameter default values: `null` gets assigned as as `null`, not the default value
* Mimic ES default parameters behavior for parameters after a splat or expansion parameter
* Bound functions cannot be generators: remove no-longer-relevant test, add check to throw error if `yield` appears inside a bound (arrow) function
* Error for bound generator functions should underline the `yield`
2016-10-26 05:26:13 +00:00
|
|
|
exports.baseFileName = function(file, stripExt = false, useWinPathSep = false) {
|
2013-03-20 16:11:42 +00:00
|
|
|
var parts, pathSep;
|
|
|
|
pathSep = useWinPathSep ? /\\|\// : /\//;
|
2013-03-15 22:13:04 +00:00
|
|
|
parts = file.split(pathSep);
|
2013-03-04 21:40:39 +00:00
|
|
|
file = parts[parts.length - 1];
|
2013-10-20 22:09:55 +00:00
|
|
|
if (!(stripExt && file.indexOf('.') >= 0)) {
|
2013-03-04 22:07:16 +00:00
|
|
|
return file;
|
|
|
|
}
|
2013-03-04 21:40:39 +00:00
|
|
|
parts = file.split('.');
|
|
|
|
parts.pop();
|
2013-03-06 21:41:34 +00:00
|
|
|
if (parts[parts.length - 1] === 'coffee' && parts.length > 1) {
|
2013-03-04 21:40:39 +00:00
|
|
|
parts.pop();
|
|
|
|
}
|
|
|
|
return parts.join('.');
|
|
|
|
};
|
|
|
|
|
2013-02-28 02:54:17 +00:00
|
|
|
exports.isCoffee = function(file) {
|
|
|
|
return /\.((lit)?coffee|coffee\.md)$/.test(file);
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.isLiterate = function(file) {
|
|
|
|
return /\.(litcoffee|coffee\.md)$/.test(file);
|
|
|
|
};
|
|
|
|
|
2013-03-05 04:13:46 +00:00
|
|
|
exports.throwSyntaxError = function(message, location) {
|
2013-04-22 18:38:17 +00:00
|
|
|
var error;
|
2013-03-05 04:13:46 +00:00
|
|
|
error = new SyntaxError(message);
|
|
|
|
error.location = location;
|
2013-07-31 11:27:49 +00:00
|
|
|
error.toString = syntaxErrorToString;
|
2013-08-02 04:52:36 +00:00
|
|
|
error.stack = error.toString();
|
2013-03-05 04:13:46 +00:00
|
|
|
throw error;
|
|
|
|
};
|
|
|
|
|
2013-08-02 04:52:36 +00:00
|
|
|
exports.updateSyntaxError = function(error, code, filename) {
|
|
|
|
if (error.toString === syntaxErrorToString) {
|
|
|
|
error.code || (error.code = code);
|
|
|
|
error.filename || (error.filename = filename);
|
|
|
|
error.stack = error.toString();
|
|
|
|
}
|
|
|
|
return error;
|
|
|
|
};
|
|
|
|
|
2013-07-31 11:27:49 +00:00
|
|
|
syntaxErrorToString = function() {
|
2015-03-08 13:40:27 +00:00
|
|
|
var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, ref1, ref2, ref3, ref4, start;
|
2013-07-31 11:27:49 +00:00
|
|
|
if (!(this.code && this.location)) {
|
|
|
|
return Error.prototype.toString.call(this);
|
|
|
|
}
|
2015-01-30 19:33:03 +00:00
|
|
|
ref1 = this.location, first_line = ref1.first_line, first_column = ref1.first_column, last_line = ref1.last_line, last_column = ref1.last_column;
|
2013-07-31 11:27:49 +00:00
|
|
|
if (last_line == null) {
|
|
|
|
last_line = first_line;
|
2013-03-05 04:13:46 +00:00
|
|
|
}
|
2013-07-31 11:27:49 +00:00
|
|
|
if (last_column == null) {
|
|
|
|
last_column = first_column;
|
|
|
|
}
|
|
|
|
filename = this.filename || '[stdin]';
|
|
|
|
codeLine = this.code.split('\n')[first_line];
|
2013-03-05 04:13:46 +00:00
|
|
|
start = first_column;
|
|
|
|
end = first_line === last_line ? last_column + 1 : codeLine.length;
|
2014-07-16 09:56:07 +00:00
|
|
|
marker = codeLine.slice(0, start).replace(/[^\s]/g, ' ') + repeat('^', end - start);
|
2013-07-31 11:27:49 +00:00
|
|
|
if (typeof process !== "undefined" && process !== null) {
|
2015-03-08 13:40:27 +00:00
|
|
|
colorsEnabled = ((ref2 = process.stdout) != null ? ref2.isTTY : void 0) && !((ref3 = process.env) != null ? ref3.NODE_DISABLE_COLORS : void 0);
|
2013-07-31 11:27:49 +00:00
|
|
|
}
|
2015-03-08 13:40:27 +00:00
|
|
|
if ((ref4 = this.colorful) != null ? ref4 : colorsEnabled) {
|
2013-03-05 04:13:46 +00:00
|
|
|
colorize = function(str) {
|
2016-11-28 14:05:51 +00:00
|
|
|
return `\x1B[1;31m${str}\x1B[0m`;
|
2013-03-05 04:13:46 +00:00
|
|
|
};
|
|
|
|
codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end);
|
|
|
|
marker = colorize(marker);
|
|
|
|
}
|
2016-11-28 14:05:51 +00:00
|
|
|
return `${filename}:${first_line + 1}:${first_column + 1}: error: ${this.message}\n${codeLine}\n${marker}`;
|
2013-03-05 04:13:46 +00:00
|
|
|
};
|
|
|
|
|
2014-01-22 02:44:50 +00:00
|
|
|
exports.nameWhitespaceCharacter = function(string) {
|
|
|
|
switch (string) {
|
|
|
|
case ' ':
|
|
|
|
return 'space';
|
|
|
|
case '\n':
|
|
|
|
return 'newline';
|
|
|
|
case '\r':
|
|
|
|
return 'carriage return';
|
|
|
|
case '\t':
|
|
|
|
return 'tab';
|
|
|
|
default:
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2010-09-21 07:53:58 +00:00
|
|
|
}).call(this);
|