Fixing Issue #744 -- you can now use reserved words as static properties of a class.

This commit is contained in:
Jeremy Ashkenas 2010-10-06 20:07:19 -04:00
parent af2e866947
commit 69b901a5b6
5 changed files with 26 additions and 25 deletions

View File

@ -29,7 +29,7 @@
return (new Rewriter).rewrite(this.tokens); return (new Rewriter).rewrite(this.tokens);
}; };
Lexer.prototype.identifierToken = function() { Lexer.prototype.identifierToken = function() {
var closeIndex, forcedIdentifier, id, match, tag; var forcedIdentifier, id, match, tag;
if (!(match = IDENTIFIER.exec(this.chunk))) { if (!(match = IDENTIFIER.exec(this.chunk))) {
return false; return false;
} }
@ -64,15 +64,9 @@
} }
if (include(JS_FORBIDDEN, id)) { if (include(JS_FORBIDDEN, id)) {
if (forcedIdentifier) { if (forcedIdentifier) {
tag = 'STRING'; tag = 'IDENTIFIER';
id = ("\"" + id + "\""); id = new String(id);
if (forcedIdentifier === 'accessor') { id.reserved = true;
closeIndex = true;
if (this.tag() !== '@') {
this.tokens.pop();
}
this.token('INDEX_START', '[');
}
} else if (include(RESERVED, id)) { } else if (include(RESERVED, id)) {
this.identifierError(id); this.identifierError(id);
} }
@ -88,9 +82,6 @@
} }
} }
this.token(tag, id); this.token(tag, id);
if (closeIndex) {
this.token(']', ']');
}
return true; return true;
}; };
Lexer.prototype.numberToken = function() { Lexer.prototype.numberToken = function() {
@ -335,7 +326,8 @@
this.i += value.length; this.i += value.length;
tag = value; tag = value;
if (value === '=') { if (value === '=') {
if (include(JS_FORBIDDEN, pval = this.value())) { pval = this.value();
if (!pval.reserved && include(JS_FORBIDDEN, pval)) {
this.assignmentError(); this.assignmentError();
} }
if (('or' === pval || 'and' === pval)) { if (('or' === pval || 'and' === pval)) {

View File

@ -263,11 +263,15 @@
}; };
LiteralNode.prototype.isPureStatement = LiteralNode.prototype.isStatement; LiteralNode.prototype.isPureStatement = LiteralNode.prototype.isStatement;
LiteralNode.prototype.isComplex = NO; LiteralNode.prototype.isComplex = NO;
LiteralNode.prototype.isReserved = function() {
return !!this.value.reserved;
};
LiteralNode.prototype.compileNode = function(o) { LiteralNode.prototype.compileNode = function(o) {
var end, idt; var end, idt, val;
idt = this.isStatement(o) ? this.idt() : ''; idt = this.isStatement(o) ? this.idt() : '';
end = this.isStatement(o) ? ';' : ''; end = this.isStatement(o) ? ';' : '';
return idt + this.value + end; val = this.isReserved() ? ("\"" + (this.value) + "\"") : this.value;
return idt + val + end;
}; };
LiteralNode.prototype.toString = function() { LiteralNode.prototype.toString = function() {
return ' "' + this.value + '"'; return ' "' + this.value + '"';

View File

@ -100,12 +100,9 @@ exports.Lexer = class Lexer
id = '!' + id id = '!' + id
if include JS_FORBIDDEN, id if include JS_FORBIDDEN, id
if forcedIdentifier if forcedIdentifier
tag = 'STRING' tag = 'IDENTIFIER'
id = "\"#{id}\"" id = new String id
if forcedIdentifier is 'accessor' id.reserved = yes
closeIndex = on
@tokens.pop() if @tag() isnt '@'
@token 'INDEX_START', '['
else if include(RESERVED, id) else if include(RESERVED, id)
@identifierError id @identifierError id
unless forcedIdentifier unless forcedIdentifier
@ -115,7 +112,6 @@ exports.Lexer = class Lexer
else if include LOGIC, id else if include LOGIC, id
tag = 'LOGIC' tag = 'LOGIC'
@token tag, id @token tag, id
@token ']', ']' if closeIndex
true true
# Matches numbers, including decimals, hex, and exponential notation. # Matches numbers, including decimals, hex, and exponential notation.
@ -312,7 +308,8 @@ exports.Lexer = class Lexer
@i += value.length @i += value.length
tag = value tag = value
if value is '=' if value is '='
@assignmentError() if include JS_FORBIDDEN, pval = @value() pval = @value()
@assignmentError() if not pval.reserved and include JS_FORBIDDEN, pval
if pval in ['or', 'and'] if pval in ['or', 'and']
prev = last @tokens prev = last @tokens
prev[0] = 'COMPOUND_ASSIGN' prev[0] = 'COMPOUND_ASSIGN'

View File

@ -248,10 +248,14 @@ exports.LiteralNode = class LiteralNode extends BaseNode
isComplex: NO isComplex: NO
isReserved: ->
!!@value.reserved
compileNode: (o) -> compileNode: (o) ->
idt = if @isStatement(o) then @idt() else '' idt = if @isStatement(o) then @idt() else ''
end = if @isStatement(o) then ';' else '' end = if @isStatement(o) then ';' else ''
idt + @value + end val = if @isReserved() then "\"#{@value}\"" else @value
idt + val + end
toString: -> ' "' + @value + '"' toString: -> ' "' + @value + '"'

View File

@ -51,6 +51,8 @@ ok (new SubClass).prop is 'top-super-sub'
class OneClass class OneClass
@new: 'new'
function: 'function'
constructor: (name) -> @name = name constructor: (name) -> @name = name
class TwoClass extends OneClass class TwoClass extends OneClass
@ -58,6 +60,8 @@ class TwoClass extends OneClass
Function.prototype.new = -> new this arguments... Function.prototype.new = -> new this arguments...
ok (TwoClass.new('three')).name is 'three' ok (TwoClass.new('three')).name is 'three'
ok (new OneClass).function is 'function'
ok OneClass.new is 'new'
delete Function.prototype.new delete Function.prototype.new