Skip to content

Commit

Permalink
fix #1 :: Supporting jison reference location, token and index variab…
Browse files Browse the repository at this point in the history
…les fails for negative indexes
  • Loading branch information
GerHobbelt committed Nov 10, 2017
1 parent 1d639f3 commit 2547b43
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 58 deletions.
75 changes: 49 additions & 26 deletions dist/esprima.js
Original file line number Diff line number Diff line change
Expand Up @@ -4665,14 +4665,8 @@ var Scanner = /** @class */ (function () {
return character_1.Character.fromCodePoint(code);
};
Scanner.prototype.getIdentifier = function () {
var start = this.index++;
var ch1 = this.source.charCodeAt(this.index - 1);
var ch2 = this.source.charCodeAt(this.index);
if ((ch1 === 0x23 || ch1 === 0x40) &&
(ch2 === 0x23 || ch2 === 0x40)) {
// ## and @@ at start of identifier name (JISON action variables contain these, e.g. `@@1` or `##INDEX`)
++this.index;
}
var start = this.index;
this.index++;
while (!this.eof()) {
var ch = this.source.charCodeAt(this.index);
if (ch === 0x5C) {
Expand Down Expand Up @@ -4778,11 +4772,14 @@ var Scanner = /** @class */ (function () {
};
};
// https://tc39.github.io/ecma262/#sec-names-and-keywords
Scanner.prototype.scanIdentifier = function () {
Scanner.prototype.scanIdentifier = function (start) {
var type;
var start = this.index;
var partStart = this.index;
// Backslash (U+005C) starts an escaped character.
var id = (this.source.charCodeAt(start) === 0x5C) ? this.getComplexIdentifier() : this.getIdentifier();
var id = ((this.source.charCodeAt(partStart) === 0x5C) ? this.getComplexIdentifier() : this.getIdentifier());
if (partStart > start) {
id = this.source.slice(start, partStart) + id;
}
// There is no keyword or literal with only one character.
// Thus, it must be an identifier.
if (id.length === 1) {
Expand Down Expand Up @@ -5448,27 +5445,53 @@ var Scanner = /** @class */ (function () {
};
}
var cp = this.source.charCodeAt(this.index);
var cpNext = this.source.charCodeAt(this.index + 1);
if (character_1.Character.isIdentifierStart(cp) ||
if (character_1.Character.isIdentifierStart(cp)) {
return this.scanIdentifier(this.index);
}
else if (cp === 0x23 || cp === 0x40) {
//
// # and @ (JISON action variables contain these, e.g. `@1` or `#LABEL#`)
//
// Note that these characters may only occur at the START or END of an identifier
// AND these cannot occur on their own but must be a prefix or postfix of a
// larger identifier, e.g. `@1`, `@label1`, `#3`, `#loc`, `#id#`
//
((cp === 0x23 || cp === 0x40) &&
(character_1.Character.isIdentifierPart(cpNext) ||
//
// ## and @@ (JISON action variables contain these, e.g. `@@1` or `##INDEX`)
//
// Note that these characters may only occur at the START of an identifier
// AND these cannot occur on their own but must be a prefix of a
// larger identifier, e.g. `@@1`, `@@label1`, `##3`, `##loc`, `##id`
//
((cpNext === 0x23 || cpNext === 0x40) &&
character_1.Character.isIdentifierPart(this.source.charCodeAt(this.index + 2)))))) {
return this.scanIdentifier();
var start = this.index;
var cpNext = this.source.charCodeAt(this.index + 1);
if (character_1.Character.isIdentifierPart(cpNext)) {
this.index += 1;
return this.scanIdentifier(start);
}
else if (cpNext === 0x23 || cpNext === 0x40) {
//
// ## and @@ (JISON action variables contain these, e.g. `@@1` or `##INDEX`)
//
// Note that these characters may only occur at the START of an identifier
// AND these cannot occur on their own but must be a prefix of a
// larger identifier, e.g. `@@1`, `@@label1`, `##3`, `##loc`, `##id`
//
var cpNextNext = this.source.charCodeAt(this.index + 2);
if (character_1.Character.isIdentifierPart(cpNextNext)) {
this.index += 2;
return this.scanIdentifier(start);
}
else if (cpNextNext === 0x2D) {
// negative reference index variable, e.g. `@@-1`:
var cpN3 = this.source.charCodeAt(this.index + 3);
if (character_1.Character.isDecimalDigit(cpN3)) {
this.index += 3;
return this.scanIdentifier(start);
}
}
}
else if (cpNext === 0x2D) {
// negative reference index variable, e.g. `@-1`:
var cpN2 = this.source.charCodeAt(this.index + 2);
if (character_1.Character.isDecimalDigit(cpN2)) {
this.index += 2;
return this.scanIdentifier(start);
}
}
}
// Very common: ( and ) and ;
if (cp === 0x28 || cp === 0x29 || cp === 0x3B) {
Expand Down Expand Up @@ -5497,7 +5520,7 @@ var Scanner = /** @class */ (function () {
// Possible identifier start in a surrogate pair.
if (cp >= 0xD800 && cp < 0xDFFF) {
if (character_1.Character.isIdentifierStart(this.codePointAt(this.index))) {
return this.scanIdentifier();
return this.scanIdentifier(this.index);
}
}
return this.scanPunctuator();
Expand Down
77 changes: 45 additions & 32 deletions src/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,16 +421,8 @@ export class Scanner {
}

private getIdentifier(): string {
const start = this.index++;
const ch1 = this.source.charCodeAt(this.index - 1);
const ch2 = this.source.charCodeAt(this.index);
if ((ch1 === 0x23 || ch1 === 0x40) &&
(ch2 === 0x23 || ch2 === 0x40)
) {
// ## and @@ at start of identifier name (JISON action variables contain these, e.g. `@@1` or `##INDEX`)
++this.index;
}

const start = this.index;
this.index++;
while (!this.eof()) {
const ch = this.source.charCodeAt(this.index);
if (ch === 0x5C) {
Expand Down Expand Up @@ -545,12 +537,15 @@ export class Scanner {

// https://tc39.github.io/ecma262/#sec-names-and-keywords

private scanIdentifier(): RawToken {
private scanIdentifier(start: number): RawToken {
let type: Token;
const start = this.index;
const partStart = this.index;

// Backslash (U+005C) starts an escaped character.
const id = (this.source.charCodeAt(start) === 0x5C) ? this.getComplexIdentifier() : this.getIdentifier();
let id = ((this.source.charCodeAt(partStart) === 0x5C) ? this.getComplexIdentifier() : this.getIdentifier());
if (partStart > start) {
id = this.source.slice(start, partStart) + id;
}

// There is no keyword or literal with only one character.
// Thus, it must be an identifier.
Expand Down Expand Up @@ -1275,32 +1270,50 @@ export class Scanner {
}

const cp = this.source.charCodeAt(this.index);
const cpNext = this.source.charCodeAt(this.index + 1);

if (Character.isIdentifierStart(cp) ||
if (Character.isIdentifierStart(cp)) {
return this.scanIdentifier(this.index);
} else if (cp === 0x23 || cp === 0x40) {
//
// # and @ (JISON action variables contain these, e.g. `@1` or `#LABEL#`)
//
// Note that these characters may only occur at the START or END of an identifier
// AND these cannot occur on their own but must be a prefix or postfix of a
// larger identifier, e.g. `@1`, `@label1`, `#3`, `#loc`, `#id#`
//
((cp === 0x23 || cp === 0x40) &&
(Character.isIdentifierPart(cpNext) ||
//
// ## and @@ (JISON action variables contain these, e.g. `@@1` or `##INDEX`)
//
// Note that these characters may only occur at the START of an identifier
// AND these cannot occur on their own but must be a prefix of a
// larger identifier, e.g. `@@1`, `@@label1`, `##3`, `##loc`, `##id`
//
((cpNext === 0x23 || cpNext === 0x40) &&
Character.isIdentifierPart(this.source.charCodeAt(this.index + 2))
)
)
)
) {
return this.scanIdentifier();
const start = this.index;
const cpNext = this.source.charCodeAt(this.index + 1);
if (Character.isIdentifierPart(cpNext)) {
this.index += 1;
return this.scanIdentifier(start);
} else if (cpNext === 0x23 || cpNext === 0x40) {
//
// ## and @@ (JISON action variables contain these, e.g. `@@1` or `##INDEX`)
//
// Note that these characters may only occur at the START of an identifier
// AND these cannot occur on their own but must be a prefix of a
// larger identifier, e.g. `@@1`, `@@label1`, `##3`, `##loc`, `##id`
//
const cpNextNext = this.source.charCodeAt(this.index + 2);
if (Character.isIdentifierPart(cpNextNext)) {
this.index += 2;
return this.scanIdentifier(start);
} else if (cpNextNext === 0x2D) {
// negative reference index variable, e.g. `@@-1`:
const cpN3 = this.source.charCodeAt(this.index + 3);
if (Character.isDecimalDigit(cpN3)) {
this.index += 3;
return this.scanIdentifier(start);
}
}
} else if (cpNext === 0x2D) {
// negative reference index variable, e.g. `@-1`:
const cpN2 = this.source.charCodeAt(this.index + 2);
if (Character.isDecimalDigit(cpN2)) {
this.index += 2;
return this.scanIdentifier(start);
}
}
}

// Very common: ( and ) and ;
Expand Down Expand Up @@ -1335,7 +1348,7 @@ export class Scanner {
// Possible identifier start in a surrogate pair.
if (cp >= 0xD800 && cp < 0xDFFF) {
if (Character.isIdentifierStart(this.codePointAt(this.index))) {
return this.scanIdentifier();
return this.scanIdentifier(this.index);
}
}

Expand Down

0 comments on commit 2547b43

Please sign in to comment.