merged in stricter noncallables
This commit is contained in:
commit
351c875576
|
@ -1,6 +1,6 @@
|
|||
// Generated by CoffeeScript 1.6.3
|
||||
(function() {
|
||||
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, CodeFragment, Comment, Existence, Extends, For, HEXNUM, IDENTIFIER, IDENTIFIER_STR, 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, last, locationDataToString, merge, multident, parseNum, some, starts, throwSyntaxError, unfoldSoak, utility, _ref, _ref1, _ref2, _ref3,
|
||||
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, CodeFragment, Comment, Existence, 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, last, locationDataToString, merge, multident, parseNum, some, starts, throwSyntaxError, unfoldSoak, utility, _ref, _ref1, _ref2, _ref3,
|
||||
__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; },
|
||||
__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; },
|
||||
|
@ -678,8 +678,16 @@
|
|||
return !!this.properties.length;
|
||||
};
|
||||
|
||||
Value.prototype.bareLiteral = function(type) {
|
||||
return !this.properties.length && this.base instanceof type;
|
||||
};
|
||||
|
||||
Value.prototype.isArray = function() {
|
||||
return !this.properties.length && this.base instanceof Arr;
|
||||
return this.bareLiteral(Arr);
|
||||
};
|
||||
|
||||
Value.prototype.isRange = function() {
|
||||
return this.bareLiteral(Range);
|
||||
};
|
||||
|
||||
Value.prototype.isComplex = function() {
|
||||
|
@ -691,11 +699,15 @@
|
|||
};
|
||||
|
||||
Value.prototype.isSimpleNumber = function() {
|
||||
return this.base instanceof Literal && SIMPLENUM.test(this.base.value);
|
||||
return this.bareLiteral(Literal) && SIMPLENUM.test(this.base.value);
|
||||
};
|
||||
|
||||
Value.prototype.isString = function() {
|
||||
return this.base instanceof Literal && IS_STRING.test(this.base.value);
|
||||
return this.bareLiteral(Literal) && IS_STRING.test(this.base.value);
|
||||
};
|
||||
|
||||
Value.prototype.isRegex = function() {
|
||||
return this.bareLiteral(Literal) && IS_REGEX.test(this.base.value);
|
||||
};
|
||||
|
||||
Value.prototype.isAtomic = function() {
|
||||
|
@ -710,6 +722,10 @@
|
|||
return true;
|
||||
};
|
||||
|
||||
Value.prototype.isNotCallable = function() {
|
||||
return this.isSimpleNumber() || this.isString() || this.isRegex() || this.isArray() || this.isRange() || this.isSplice() || this.isObject();
|
||||
};
|
||||
|
||||
Value.prototype.isStatement = function(o) {
|
||||
return !this.properties.length && this.base.isStatement(o);
|
||||
};
|
||||
|
@ -847,6 +863,9 @@
|
|||
this.isNew = false;
|
||||
this.isSuper = variable === 'super';
|
||||
this.variable = this.isSuper ? null : variable;
|
||||
if (variable instanceof Value && variable.isNotCallable()) {
|
||||
variable.error("literal is not a function");
|
||||
}
|
||||
}
|
||||
|
||||
Call.prototype.children = ['variable', 'args'];
|
||||
|
@ -1742,7 +1761,7 @@
|
|||
fromDecl = fromRef = '0';
|
||||
}
|
||||
if (to) {
|
||||
if ((from != null ? from.isSimpleNumber() : void 0) && to.isSimpleNumber()) {
|
||||
if (from && from instanceof Value && (from != null ? from.isSimpleNumber() : void 0) && to instanceof Value && to.isSimpleNumber()) {
|
||||
to = +to.compile(o) - +fromRef;
|
||||
if (!exclusive) {
|
||||
to += 1;
|
||||
|
@ -3057,6 +3076,8 @@
|
|||
|
||||
IS_STRING = /^['"]/;
|
||||
|
||||
IS_REGEX = /^\//;
|
||||
|
||||
utility = function(name) {
|
||||
var ref;
|
||||
ref = "__" + name;
|
||||
|
|
|
@ -469,17 +469,25 @@ exports.Value = class Value extends Base
|
|||
hasProperties: ->
|
||||
!!@properties.length
|
||||
|
||||
bareLiteral: (type) ->
|
||||
not @properties.length and @base instanceof type
|
||||
|
||||
# Some boolean checks for the benefit of other nodes.
|
||||
isArray : -> not @properties.length and @base instanceof Arr
|
||||
isArray : -> @bareLiteral(Arr)
|
||||
isRange : -> @bareLiteral(Range)
|
||||
isComplex : -> @hasProperties() or @base.isComplex()
|
||||
isAssignable : -> @hasProperties() or @base.isAssignable()
|
||||
isSimpleNumber : -> @base instanceof Literal and SIMPLENUM.test @base.value
|
||||
isString : -> @base instanceof Literal and IS_STRING.test @base.value
|
||||
isSimpleNumber : -> @bareLiteral(Literal) and SIMPLENUM.test @base.value
|
||||
isString : -> @bareLiteral(Literal) and IS_STRING.test @base.value
|
||||
isRegex : -> @bareLiteral(Literal) and IS_REGEX.test @base.value
|
||||
isAtomic : ->
|
||||
for node in @properties.concat @base
|
||||
return no if node.soak or node instanceof Call
|
||||
yes
|
||||
|
||||
isNotCallable : -> @isSimpleNumber() or @isString() or @isRegex() or
|
||||
@isArray() or @isRange() or @isSplice() or @isObject()
|
||||
|
||||
isStatement : (o) -> not @properties.length and @base.isStatement o
|
||||
assigns : (name) -> not @properties.length and @base.assigns name
|
||||
jumps : (o) -> not @properties.length and @base.jumps o
|
||||
|
@ -570,6 +578,8 @@ exports.Call = class Call extends Base
|
|||
@isNew = false
|
||||
@isSuper = variable is 'super'
|
||||
@variable = if @isSuper then null else variable
|
||||
if variable instanceof Value and variable.isNotCallable()
|
||||
variable.error "literal is not a function"
|
||||
|
||||
children: ['variable', 'args']
|
||||
|
||||
|
@ -1257,7 +1267,8 @@ exports.Assign = class Assign extends Base
|
|||
else
|
||||
fromDecl = fromRef = '0'
|
||||
if to
|
||||
if from?.isSimpleNumber() and to.isSimpleNumber()
|
||||
if from and from instanceof Value and from?.isSimpleNumber() and
|
||||
to instanceof Value and to.isSimpleNumber()
|
||||
to = +to.compile(o) - +fromRef
|
||||
to += 1 unless exclusive
|
||||
else
|
||||
|
@ -2182,8 +2193,9 @@ METHOD_DEF = ///
|
|||
$
|
||||
///
|
||||
|
||||
# Is a literal value a string?
|
||||
# Is a literal value a string/regex?
|
||||
IS_STRING = /^['"]/
|
||||
IS_REGEX = /^\//
|
||||
|
||||
# Utility Functions
|
||||
# -----------------
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
# shared identity function
|
||||
id = (_) -> if arguments.length is 1 then _ else [arguments...]
|
||||
|
||||
# helper to assert that a string should fail compilation
|
||||
cantCompile = (code) ->
|
||||
throws -> CoffeeScript.compile code
|
||||
|
||||
test "basic argument passing", ->
|
||||
|
||||
|
@ -649,3 +652,25 @@ test "Loose tokens inside of explicit call lists", ->
|
|||
bar = first( first
|
||||
one: 1)
|
||||
eq bar.one, 1
|
||||
|
||||
test "Non-callable literals shouldn't compile", ->
|
||||
cantCompile '1(2)'
|
||||
cantCompile '1 2'
|
||||
cantCompile '/t/(2)'
|
||||
cantCompile '/t/ 2'
|
||||
cantCompile '///t///(2)'
|
||||
cantCompile '///t/// 2'
|
||||
cantCompile "''(2)"
|
||||
cantCompile "'' 2"
|
||||
cantCompile '""(2)'
|
||||
cantCompile '"" 2'
|
||||
cantCompile '""""""(2)'
|
||||
cantCompile '"""""" 2'
|
||||
cantCompile '{}(2)'
|
||||
cantCompile '{} 2'
|
||||
cantCompile '[](2)'
|
||||
cantCompile '[] 2'
|
||||
cantCompile '[2..9] 2'
|
||||
cantCompile '[2..9](2)'
|
||||
cantCompile '[1..10][2..9] 2'
|
||||
cantCompile '[1..10][2..9](2)'
|
||||
|
|
|
@ -144,3 +144,12 @@ test "#1723: operator precedence in unbounded splice compilation", ->
|
|||
list = [0..9]
|
||||
list[..if n then n else 0] = n
|
||||
arrayEq [n..9], list
|
||||
|
||||
test "#2953: methods on endpoints in assignment from array splice literal", ->
|
||||
list = [0..9]
|
||||
|
||||
Number.prototype.same = -> this
|
||||
list[1.same()...9.same()] = 5
|
||||
delete Number.prototype.same
|
||||
|
||||
arrayEq [0, 5, 9], list
|
||||
|
|
|
@ -130,5 +130,5 @@ test "soaked constructor invocations with caching and property access", ->
|
|||
eq 1, semaphore
|
||||
|
||||
test "soaked function invocation safe on non-functions", ->
|
||||
eq undefined, 0?(1)
|
||||
eq undefined, 0? 1, 2
|
||||
eq undefined, (0)?(1)
|
||||
eq undefined, (0)? 1, 2
|
||||
|
|
Loading…
Reference in New Issue