647: fixed quote/newline escaping in here documents

This commit is contained in:
satyr
2010-10-03 07:45:23 +09:00
parent 769870b493
commit ae55c70ac5
3 changed files with 44 additions and 25 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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 '\\`', `
"\\\`" "\\\`"
` `