Allow variables named like helper functions

This commit is contained in:
Simon Lydell 2015-01-11 12:12:40 +01:00
parent 8ab15d7372
commit a46978640b
7 changed files with 41 additions and 12 deletions

View File

@ -813,7 +813,7 @@
COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES);
RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static'];
RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static'];
STRICT_PROSCRIBED = ['arguments', 'eval', 'yield*'];

View File

@ -1,8 +1,8 @@
// Generated by CoffeeScript 1.8.0
(function() {
var Access, Arr, Assign, Base, Block, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, HEXNUM, IDENTIFIER, IDENTIFIER_STR, IS_REGEX, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, NUMBER, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isLiteralArguments, isLiteralThis, last, locationDataToString, merge, multident, parseNum, some, starts, throwSyntaxError, unfoldSoak, utility, _ref, _ref1,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__hasProp = {}.hasOwnProperty,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__slice = [].slice;
@ -3145,9 +3145,13 @@
utility = function(name) {
var ref;
ref = "__" + name;
Scope.root.assign(ref, UTILITIES[name]());
return ref;
if (name in Scope.root.utilities) {
return Scope.root.utilities[name];
} else {
ref = Scope.root.freeVariable("_" + name);
Scope.root.assign(ref, UTILITIES[name]());
return Scope.root.utilities[name] = ref;
}
};
multident = function(code, tab) {

View File

@ -21,6 +21,7 @@
];
this.positions = {};
if (!this.parent) {
this.utilities = {};
Scope.root = this;
}
}

View File

@ -718,9 +718,8 @@ COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat COFFEE_ALIASES
# to avoid having a JavaScript error at runtime.
RESERVED = [
'case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum'
'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind'
'__indexOf', 'implements', 'interface', 'package', 'private', 'protected'
'public', 'static'
'export', 'import', 'native', 'implements', 'interface', 'package', 'private'
'protected', 'public', 'static'
]
STRICT_PROSCRIBED = ['arguments', 'eval', 'yield*']

View File

@ -2260,9 +2260,12 @@ IS_REGEX = /^\//
# Helper for ensuring that utility functions are assigned at the top level.
utility = (name) ->
ref = "__#{name}"
Scope.root.assign ref, UTILITIES[name]()
ref
if name of Scope.root.utilities
Scope.root.utilities[name]
else
ref = Scope.root.freeVariable "_#{name}"
Scope.root.assign ref, UTILITIES[name]()
Scope.root.utilities[name] = ref
multident = (code, tab) ->
code = code.replace /\n/g, '$&' + tab

View File

@ -24,7 +24,9 @@ and therefore should be avoided when generating variables.
constructor: (@parent, @expressions, @method, @referencedVars) ->
@variables = [{name: 'arguments', type: 'arguments'}]
@positions = {}
Scope.root = this unless @parent
unless @parent
@utilities = {}
Scope.root = this
Adds a new variable or overrides an existing one.

View File

@ -437,3 +437,23 @@ test "#1500: Assignment to variables similar to generated variables", ->
eq 1, scope.a
doesNotThrow -> CoffeeScript.compile '(@_slice...) ->'
test "Assignment to variables similar to helper functions", ->
f = (__slice...) -> __slice
arrayEq [1, 2, 3], f 1, 2, 3
eq 'undefined', typeof __slice1
class A
class B extends A
__extends = 3
__hasProp = 4
value: 5
method: (__bind, __bind1) => [__bind, __bind1, __extends, __hasProp, @value]
{method} = new B
arrayEq [1, 2, 3, 4, 5], method 1, 2
__modulo = -1 %% 3
eq 2, __modulo
__indexOf = [1, 2, 3]
ok 2 in __indexOf