coffee-lex
Advanced tools
Comparing version 8.1.2 to 9.0.0
@@ -12,2 +12,12 @@ "use strict"; | ||
var calculateTripleQuotedStringPadding_1 = require("./utils/calculateTripleQuotedStringPadding"); | ||
var ContextType; | ||
(function (ContextType) { | ||
ContextType["STRING"] = "STRING"; | ||
ContextType["INTERPOLATION"] = "INTERPOLATION"; | ||
ContextType["CSX_OPEN_TAG"] = "CSX_OPEN_TAG"; | ||
ContextType["CSX_CLOSE_TAG"] = "CSX_CLOSE_TAG"; | ||
ContextType["CSX_BODY"] = "CSX_BODY"; | ||
ContextType["BRACE"] = "BRACE"; | ||
ContextType["PAREN"] = "PAREN"; | ||
})(ContextType || (ContextType = {})); | ||
/** | ||
@@ -113,2 +123,4 @@ * Generate a list of tokens from CoffeeScript source code. | ||
var IDENTIFIER_PATTERN = /^(?!\d)((?:(?!\s)[$\w\x7f-\uffff])+)/; | ||
// Like identifier, but includes '-' and '.'. | ||
var CSX_IDENTIFIER_PATTERN = /^(?!\d)((?:(?!\s)[\.\-$\w\x7f-\uffff])+)/; | ||
var NUMBER_PATTERN = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; | ||
@@ -183,8 +195,12 @@ var SPACE_PATTERN = /^[^\n\r\S]+/; | ||
var location = new SourceLocation_1.default(SourceType_1.default.NORMAL, index); | ||
var interpolationStack = []; | ||
var braceStack = []; | ||
var parenStack = []; | ||
var stringStack = []; | ||
var contextStack = []; | ||
var start = index; | ||
var locations = []; | ||
function currentContext() { | ||
return contextStack[contextStack.length - 1] || null; | ||
} | ||
function currentContextType() { | ||
var context = currentContext(); | ||
return context ? context.type : null; | ||
} | ||
return function step() { | ||
@@ -262,2 +278,4 @@ var lastLocation = location; | ||
case SourceType_1.default.DEFAULT: | ||
case SourceType_1.default.CSX_OPEN_TAG_START: | ||
case SourceType_1.default.CSX_CLOSE_TAG_START: | ||
case SourceType_1.default.CONTINUATION: | ||
@@ -280,3 +298,4 @@ if (consume(SPACE_PATTERN)) { | ||
else if (consume('"""')) { | ||
stringStack.push({ | ||
contextStack.push({ | ||
type: ContextType.STRING, | ||
allowInterpolations: true, | ||
@@ -289,3 +308,4 @@ endingDelimiter: '"""', | ||
else if (consume('"')) { | ||
stringStack.push({ | ||
contextStack.push({ | ||
type: ContextType.STRING, | ||
allowInterpolations: true, | ||
@@ -298,3 +318,4 @@ endingDelimiter: '"', | ||
else if (consume("'''")) { | ||
stringStack.push({ | ||
contextStack.push({ | ||
type: ContextType.STRING, | ||
allowInterpolations: false, | ||
@@ -307,3 +328,4 @@ endingDelimiter: "'''", | ||
else if (consume("'")) { | ||
stringStack.push({ | ||
contextStack.push({ | ||
type: ContextType.STRING, | ||
allowInterpolations: false, | ||
@@ -322,3 +344,4 @@ endingDelimiter: "'", | ||
else if (consume('///')) { | ||
stringStack.push({ | ||
contextStack.push({ | ||
type: ContextType.STRING, | ||
allowInterpolations: true, | ||
@@ -332,7 +355,7 @@ endingDelimiter: '///', | ||
if (CALLABLE.indexOf(location.type) >= 0) { | ||
parenStack.push(SourceType_1.default.CALL_START); | ||
contextStack.push({ type: ContextType.PAREN, sourceType: SourceType_1.default.CALL_START }); | ||
setType(SourceType_1.default.CALL_START); | ||
} | ||
else { | ||
parenStack.push(SourceType_1.default.LPAREN); | ||
contextStack.push({ type: ContextType.PAREN, sourceType: SourceType_1.default.LPAREN }); | ||
setType(SourceType_1.default.LPAREN); | ||
@@ -342,17 +365,16 @@ } | ||
else if (consume(')')) { | ||
if (parenStack.length === 0) { | ||
var context_1 = contextStack.pop(); | ||
if (!context_1 || context_1.type !== ContextType.PAREN) { | ||
throw new Error("unexpected ')' at " + start); | ||
} | ||
else { | ||
var lparen = parenStack.pop(); | ||
switch (lparen) { | ||
case SourceType_1.default.LPAREN: | ||
setType(SourceType_1.default.RPAREN); | ||
break; | ||
case SourceType_1.default.CALL_START: | ||
setType(SourceType_1.default.CALL_END); | ||
break; | ||
default: | ||
throw new Error("unexpected token type for '(' matching ')' at " + start + ": " + (lparen ? lparen.toString() : '??')); | ||
} | ||
var sourceType = context_1.sourceType; | ||
switch (sourceType) { | ||
case SourceType_1.default.LPAREN: | ||
setType(SourceType_1.default.RPAREN); | ||
break; | ||
case SourceType_1.default.CALL_START: | ||
setType(SourceType_1.default.CALL_END); | ||
break; | ||
default: | ||
throw new Error("unexpected token type for '(' matching ')' at " + start + ": " + (sourceType ? sourceType.toString() : '??')); | ||
} | ||
@@ -367,14 +389,33 @@ } | ||
else if (consume('{')) { | ||
braceStack.push(start); | ||
contextStack.push({ type: ContextType.BRACE }); | ||
setType(SourceType_1.default.LBRACE); | ||
} | ||
else if (consume('}')) { | ||
if (braceStack.length === 0) { | ||
if (currentContextType() === ContextType.INTERPOLATION) { | ||
popInterpolation(); | ||
} | ||
else { | ||
braceStack.pop(); | ||
else if (currentContextType() === ContextType.BRACE) { | ||
contextStack.pop(); | ||
setType(SourceType_1.default.RBRACE); | ||
} | ||
else { | ||
throw new Error("Unexpected context type: " + currentContextType()); | ||
} | ||
} | ||
else if (consumeCSXOpenTagStart()) { | ||
contextStack.push({ type: ContextType.CSX_OPEN_TAG }); | ||
setType(SourceType_1.default.CSX_OPEN_TAG_START); | ||
} | ||
else if (currentContextType() === ContextType.CSX_OPEN_TAG && consume('>')) { | ||
contextStack.pop(); | ||
setType(SourceType_1.default.CSX_OPEN_TAG_END); | ||
} | ||
else if (currentContextType() === ContextType.CSX_OPEN_TAG && consume('/>')) { | ||
contextStack.pop(); | ||
setType(SourceType_1.default.CSX_SELF_CLOSING_TAG_END); | ||
} | ||
else if (currentContextType() === ContextType.CSX_CLOSE_TAG && consume('>')) { | ||
contextStack.pop(); | ||
setType(SourceType_1.default.CSX_CLOSE_TAG_END); | ||
} | ||
else if (consumeAny(['->', '=>'])) { | ||
@@ -424,2 +465,5 @@ setType(SourceType_1.default.FUNCTION); | ||
} | ||
else if (currentContextType() === ContextType.CSX_OPEN_TAG && consume(CSX_IDENTIFIER_PATTERN)) { | ||
setType(SourceType_1.default.IDENTIFIER); | ||
} | ||
else if (consume(IDENTIFIER_PATTERN)) { | ||
@@ -567,14 +611,15 @@ var prevLocationIndex = locations.length - 1; | ||
case SourceType_1.default.STRING_CONTENT: { | ||
var stringOptions = stringStack[stringStack.length - 1]; | ||
if (!stringOptions) { | ||
var context_2 = currentContext(); | ||
if (!context_2 || context_2.type !== ContextType.STRING) { | ||
throw new Error('Unexpected STRING_CONTENT without anything on the string stack.'); | ||
} | ||
var allowInterpolations = context_2.allowInterpolations, endingDelimiter = context_2.endingDelimiter, endSourceType = context_2.endSourceType; | ||
if (consume('\\')) { | ||
index++; | ||
} | ||
else if (consume(stringOptions.endingDelimiter)) { | ||
stringStack.pop(); | ||
setType(stringOptions.endSourceType); | ||
else if (consume(endingDelimiter)) { | ||
contextStack.pop(); | ||
setType(endSourceType); | ||
} | ||
else if (stringOptions.allowInterpolations && consume('#{')) { | ||
else if (allowInterpolations && consume('#{')) { | ||
pushInterpolation(); | ||
@@ -603,11 +648,10 @@ } | ||
break; | ||
case SourceType_1.default.INTERPOLATION_END: | ||
var lastInterpolation = interpolationStack.pop(); | ||
if (!lastInterpolation) { | ||
case SourceType_1.default.INTERPOLATION_END: { | ||
var context_3 = contextStack.pop(); | ||
if (!context_3 || context_3.type !== ContextType.INTERPOLATION) { | ||
throw new Error("found interpolation end without any interpolation start"); | ||
} | ||
var type = lastInterpolation.type, braces = lastInterpolation.braces; | ||
setType(type); | ||
braceStack = braces; | ||
setType(context_3.interpolationType); | ||
break; | ||
} | ||
case SourceType_1.default.HEREGEXP_END: | ||
@@ -641,10 +685,39 @@ while (consumeAny(REGEXP_FLAGS)) { | ||
break; | ||
case SourceType_1.default.EOF: | ||
if (braceStack.length !== 0) { | ||
throw new Error("unexpected EOF while looking for '}' to match '{' " + ("at " + braceStack[braceStack.length - 1])); | ||
case SourceType_1.default.CSX_OPEN_TAG_END: | ||
setType(SourceType_1.default.CSX_BODY); | ||
contextStack.push({ type: ContextType.CSX_BODY }); | ||
break; | ||
case SourceType_1.default.CSX_BODY: { | ||
if (consume('</')) { | ||
contextStack.pop(); | ||
setType(SourceType_1.default.CSX_CLOSE_TAG_START); | ||
contextStack.push({ type: ContextType.CSX_CLOSE_TAG }); | ||
} | ||
if (stringStack.length !== 0) { | ||
throw new Error('unexpected EOF while parsing a string'); | ||
else if (consumeCSXOpenTagStart()) { | ||
setType(SourceType_1.default.CSX_OPEN_TAG_START); | ||
contextStack.push({ type: ContextType.CSX_OPEN_TAG }); | ||
} | ||
else if (consume('{')) { | ||
pushInterpolation(); | ||
} | ||
else { | ||
index++; | ||
} | ||
break; | ||
} | ||
case SourceType_1.default.CSX_SELF_CLOSING_TAG_END: | ||
case SourceType_1.default.CSX_CLOSE_TAG_END: | ||
if (currentContextType() === ContextType.CSX_BODY) { | ||
setType(SourceType_1.default.CSX_BODY); | ||
} | ||
else { | ||
setType(SourceType_1.default.NORMAL); | ||
} | ||
break; | ||
case SourceType_1.default.EOF: | ||
var context_4 = currentContext(); | ||
if (context_4 !== null) { | ||
throw new Error("unexpected EOF while in context " + context_4.type); | ||
} | ||
break; | ||
case SourceType_1.default.UNKNOWN: | ||
@@ -710,2 +783,26 @@ // Jump to the end. | ||
} | ||
/** | ||
* CSX starts are identified by a less-than sign followed by a CSX identifier | ||
* or `<>` token (no space allowed after the less-than). | ||
* | ||
* We also bail in cases like `a<b`: if we're not already in a CSX context, | ||
* the less-than needs to be preceded by a space or a token other than identifier, | ||
* close-paren, close-bracket, or number. | ||
*/ | ||
function consumeCSXOpenTagStart() { | ||
if (!match('<')) { | ||
return false; | ||
} | ||
if (source[index + 1] !== '>' && !source.slice(index + 1).match(CSX_IDENTIFIER_PATTERN)) { | ||
return false; | ||
} | ||
var contextType = currentContextType(); | ||
if (contextType !== ContextType.CSX_BODY && | ||
contextType !== ContextType.CSX_OPEN_TAG && | ||
[SourceType_1.default.IDENTIFIER, SourceType_1.default.RPAREN, SourceType_1.default.RBRACE, SourceType_1.default.NUMBER].includes(location.type)) { | ||
return false; | ||
} | ||
consume('<'); | ||
return true; | ||
} | ||
function consumed() { | ||
@@ -727,8 +824,7 @@ return source.slice(start, index); | ||
function pushInterpolation() { | ||
interpolationStack.push({ type: location.type, braces: braceStack }); | ||
contextStack.push({ type: ContextType.INTERPOLATION, interpolationType: location.type }); | ||
setType(SourceType_1.default.INTERPOLATION_START); | ||
braceStack = []; | ||
} | ||
function popInterpolation() { | ||
if (interpolationStack.length === 0) { | ||
if (currentContextType() !== ContextType.INTERPOLATION) { | ||
throw new Error("unexpected '}' found in string at " + index + ": " + JSON.stringify(source)); | ||
@@ -735,0 +831,0 @@ } |
@@ -17,2 +17,8 @@ /** | ||
CONTINUE = "CONTINUE", | ||
CSX_BODY = "CSX_BODY", | ||
CSX_CLOSE_TAG_START = "CSX_CLOSE_TAG_START", | ||
CSX_CLOSE_TAG_END = "CSX_CLOSE_TAG_END", | ||
CSX_OPEN_TAG_START = "CSX_OPEN_TAG_START", | ||
CSX_OPEN_TAG_END = "CSX_OPEN_TAG_END", | ||
CSX_SELF_CLOSING_TAG_END = "CSX_SELF_CLOSING_TAG_END", | ||
DECREMENT = "DECREMENT", | ||
@@ -19,0 +25,0 @@ DEFAULT = "DEFAULT", |
@@ -20,2 +20,8 @@ "use strict"; | ||
SourceType["CONTINUE"] = "CONTINUE"; | ||
SourceType["CSX_BODY"] = "CSX_BODY"; | ||
SourceType["CSX_CLOSE_TAG_START"] = "CSX_CLOSE_TAG_START"; | ||
SourceType["CSX_CLOSE_TAG_END"] = "CSX_CLOSE_TAG_END"; | ||
SourceType["CSX_OPEN_TAG_START"] = "CSX_OPEN_TAG_START"; | ||
SourceType["CSX_OPEN_TAG_END"] = "CSX_OPEN_TAG_END"; | ||
SourceType["CSX_SELF_CLOSING_TAG_END"] = "CSX_SELF_CLOSING_TAG_END"; | ||
SourceType["DECREMENT"] = "DECREMENT"; | ||
@@ -22,0 +28,0 @@ SourceType["DEFAULT"] = "DEFAULT"; |
@@ -37,12 +37,11 @@ { | ||
"devDependencies": { | ||
"@types/mocha": "^2.2.46", | ||
"@types/node": "^9.3.0", | ||
"@types/mocha": "^2.2.48", | ||
"@types/node": "^9.4.7", | ||
"decaffeinate-coffeescript": "1.12.7-patch.2", | ||
"mocha": "^5.0.0", | ||
"prettier": "1.11.0", | ||
"mocha": "^5.0.4", | ||
"prettier": "1.11.1", | ||
"prettier-check": "2.0.0", | ||
"semantic-release": "^6.3.5", | ||
"ts-node": "^5.0.0", | ||
"tslint": "^5.8.0", | ||
"typescript": "^2.6.2" | ||
"ts-node": "^5.0.1", | ||
"tslint": "^5.9.1", | ||
"typescript": "^2.7.2" | ||
}, | ||
@@ -52,3 +51,3 @@ "publishConfig": { | ||
}, | ||
"version": "8.1.2" | ||
} | ||
"version": "9.0.0" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
173081
9
4153