mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-19 03:44:23 -05:00
647: fixed quote/newline escaping in here documents
This commit is contained in:
21
lib/lexer.js
21
lib/lexer.js
@@ -124,9 +124,13 @@
|
|||||||
quote: quote,
|
quote: quote,
|
||||||
indent: null
|
indent: null
|
||||||
});
|
});
|
||||||
this.interpolateString(quote + doc + quote, {
|
if (quote === '"') {
|
||||||
heredoc: true
|
this.interpolateString(quote + doc + quote, {
|
||||||
});
|
heredoc: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.token('STRING', quote + doc + quote);
|
||||||
|
}
|
||||||
this.line += count(heredoc, '\n');
|
this.line += count(heredoc, '\n');
|
||||||
this.i += heredoc.length;
|
this.i += heredoc.length;
|
||||||
return true;
|
return true;
|
||||||
@@ -362,7 +366,7 @@
|
|||||||
return accessor ? 'accessor' : false;
|
return accessor ? 'accessor' : false;
|
||||||
};
|
};
|
||||||
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
|
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
|
||||||
var _ref2, attempt, herecomment, indent, match;
|
var _ref2, attempt, herecomment, indent, match, quote;
|
||||||
_ref2 = options, indent = _ref2.indent, herecomment = _ref2.herecomment;
|
_ref2 = options, indent = _ref2.indent, herecomment = _ref2.herecomment;
|
||||||
if (herecomment && !include(doc, '\n')) {
|
if (herecomment && !include(doc, '\n')) {
|
||||||
return doc;
|
return doc;
|
||||||
@@ -381,8 +385,13 @@
|
|||||||
if (herecomment) {
|
if (herecomment) {
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
doc = doc.replace(/^\n/, '').replace(RegExp("" + (options.quote), "g"), '\\$&');
|
quote = options.quote;
|
||||||
if (options.quote === "'") {
|
doc = doc.replace(/^\n/, '');
|
||||||
|
doc = doc.replace(/\\([\s\S])/g, function(m, c) {
|
||||||
|
return ('\n' === c || quote === c) ? c : m;
|
||||||
|
});
|
||||||
|
doc = doc.replace(RegExp("" + (quote), "g"), '\\$&');
|
||||||
|
if (quote === "'") {
|
||||||
doc = this.escapeLines(doc, true);
|
doc = this.escapeLines(doc, true);
|
||||||
}
|
}
|
||||||
return doc;
|
return doc;
|
||||||
|
|||||||
@@ -139,7 +139,10 @@ exports.Lexer = class Lexer
|
|||||||
heredoc = match[0]
|
heredoc = match[0]
|
||||||
quote = heredoc.charAt 0
|
quote = heredoc.charAt 0
|
||||||
doc = @sanitizeHeredoc match[2], {quote, indent: null}
|
doc = @sanitizeHeredoc match[2], {quote, indent: null}
|
||||||
@interpolateString quote + doc + quote, heredoc: yes
|
if quote is '"'
|
||||||
|
@interpolateString quote + doc + quote, heredoc: yes
|
||||||
|
else
|
||||||
|
@token 'STRING', quote + doc + quote
|
||||||
@line += count heredoc, '\n'
|
@line += count heredoc, '\n'
|
||||||
@i += heredoc.length
|
@i += heredoc.length
|
||||||
true
|
true
|
||||||
@@ -340,8 +343,11 @@ exports.Lexer = class Lexer
|
|||||||
indent = attempt if indent is null or 0 < attempt.length < indent.length
|
indent = attempt if indent is null or 0 < attempt.length < indent.length
|
||||||
doc = doc.replace /\n#{ indent }/g, '\n' if indent
|
doc = doc.replace /\n#{ indent }/g, '\n' if indent
|
||||||
return doc if herecomment
|
return doc if herecomment
|
||||||
doc = doc.replace(/^\n/, '').replace(/#{ options.quote }/g, '\\$&')
|
{quote} = options
|
||||||
doc = @escapeLines doc, yes if options.quote is "'"
|
doc = doc.replace /^\n/, ''
|
||||||
|
doc = doc.replace /\\([\s\S])/g, (m, c) -> if c in ['\n', quote] then c else m
|
||||||
|
doc = doc.replace /#{quote}/g, '\\$&'
|
||||||
|
doc = @escapeLines doc, yes if quote is "'"
|
||||||
doc
|
doc
|
||||||
|
|
||||||
# A source of ambiguity in our grammar used to be parameter lists in function
|
# A source of ambiguity in our grammar used to be parameter lists in function
|
||||||
|
|||||||
@@ -34,11 +34,27 @@ func = ->
|
|||||||
|
|
||||||
ok func() is null
|
ok func() is null
|
||||||
|
|
||||||
|
eq /\\/.source, "\\\\"
|
||||||
|
eq '(((dollars)))', '\(\(\(dollars\)\)\)'
|
||||||
|
eq 'one two three', "one
|
||||||
|
two
|
||||||
|
three"
|
||||||
|
eq "four five", 'four
|
||||||
|
|
||||||
str = "\\"
|
five'
|
||||||
reg = /\\/
|
|
||||||
|
#647
|
||||||
|
eq "''Hello, World\\''", '''
|
||||||
|
'\'Hello, World\\\''
|
||||||
|
'''
|
||||||
|
eq '""Hello, World\\""', """
|
||||||
|
"\"Hello, World\\\""
|
||||||
|
"""
|
||||||
|
eq 'Hello, World\n', '''
|
||||||
|
Hello, World\
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
ok reg(str) and str is '\\'
|
|
||||||
|
|
||||||
trailingComma = [1, 2, 3,]
|
trailingComma = [1, 2, 3,]
|
||||||
ok (trailingComma[0] is 1) and (trailingComma[2] is 3) and (trailingComma.length is 3)
|
ok (trailingComma[0] is 1) and (trailingComma[2] is 3) and (trailingComma.length is 3)
|
||||||
@@ -54,18 +70,6 @@ trailingComma = {k1: "v1", k2: 4, k3: (-> true),}
|
|||||||
ok trailingComma.k3() and (trailingComma.k2 is 4) and (trailingComma.k1 is "v1")
|
ok trailingComma.k3() and (trailingComma.k2 is 4) and (trailingComma.k1 is "v1")
|
||||||
|
|
||||||
|
|
||||||
money$ = '(((dollars)))'
|
|
||||||
|
|
||||||
ok money$ is '\(\(\(dollars\)\)\)'
|
|
||||||
|
|
||||||
|
|
||||||
multiline = "one
|
|
||||||
two
|
|
||||||
three"
|
|
||||||
|
|
||||||
ok multiline is 'one two three'
|
|
||||||
|
|
||||||
|
|
||||||
ok {a: (num) -> num is 10 }.a 10
|
ok {a: (num) -> num is 10 }.a 10
|
||||||
|
|
||||||
|
|
||||||
@@ -242,6 +246,6 @@ ok b is 100
|
|||||||
|
|
||||||
|
|
||||||
# Inline JS
|
# Inline JS
|
||||||
ok '\\`' is `
|
eq '\\`', `
|
||||||
"\\\`"
|
"\\\`"
|
||||||
`
|
`
|
||||||
|
|||||||
Reference in New Issue
Block a user