Fixes Issue #525 -- String interpolation bug due to conflict with Heredoc interpolation.
This commit is contained in:
parent
ff88482034
commit
dfa50c90b3
|
@ -149,7 +149,7 @@
|
||||||
doc = this.sanitizeHeredoc(match[2] || match[4], {
|
doc = this.sanitizeHeredoc(match[2] || match[4], {
|
||||||
quote: quote
|
quote: quote
|
||||||
});
|
});
|
||||||
this.interpolateString("" + quote + doc + quote);
|
this.interpolateString(("" + quote + doc + quote), false, true);
|
||||||
this.line += count(match[1], "\n");
|
this.line += count(match[1], "\n");
|
||||||
this.i += match[1].length;
|
this.i += match[1].length;
|
||||||
return true;
|
return true;
|
||||||
|
@ -453,7 +453,7 @@
|
||||||
}
|
}
|
||||||
return !i ? false : str.substring(0, i);
|
return !i ? false : str.substring(0, i);
|
||||||
};
|
};
|
||||||
Lexer.prototype.interpolateString = function(str, escapeQuotes) {
|
Lexer.prototype.interpolateString = function(str, escapeQuotes, heredoc) {
|
||||||
var _d, _e, _f, _g, _h, _i, _j, escaped, expr, group, i, idx, inner, interp, interpolated, lexer, match, nested, pi, quote, tag, tok, token, tokens, value;
|
var _d, _e, _f, _g, _h, _i, _j, escaped, expr, group, i, idx, inner, interp, interpolated, lexer, match, nested, pi, quote, tag, tok, token, tokens, value;
|
||||||
if (str.length < 3 || !starts(str, '"')) {
|
if (str.length < 3 || !starts(str, '"')) {
|
||||||
return this.token('STRING', str);
|
return this.token('STRING', str);
|
||||||
|
@ -486,7 +486,9 @@
|
||||||
}
|
}
|
||||||
inner = expr.substring(2, expr.length - 1);
|
inner = expr.substring(2, expr.length - 1);
|
||||||
if (inner.length) {
|
if (inner.length) {
|
||||||
inner = inner.replace(new RegExp('\\\\' + quote, 'g'), quote);
|
if (heredoc) {
|
||||||
|
inner = inner.replace(new RegExp('\\\\' + quote, 'g'), quote);
|
||||||
|
}
|
||||||
nested = lexer.tokenize(("(" + inner + ")"), {
|
nested = lexer.tokenize(("(" + inner + ")"), {
|
||||||
line: this.line
|
line: this.line
|
||||||
});
|
});
|
||||||
|
|
|
@ -132,7 +132,7 @@ exports.Lexer: class Lexer
|
||||||
return false unless match: @chunk.match(HEREDOC)
|
return false unless match: @chunk.match(HEREDOC)
|
||||||
quote: match[1].substr 0, 1
|
quote: match[1].substr 0, 1
|
||||||
doc: @sanitizeHeredoc match[2] or match[4], {quote}
|
doc: @sanitizeHeredoc match[2] or match[4], {quote}
|
||||||
@interpolateString "$quote$doc$quote"
|
@interpolateString "$quote$doc$quote", no, yes
|
||||||
@line: + count match[1], "\n"
|
@line: + count match[1], "\n"
|
||||||
@i: + match[1].length
|
@i: + match[1].length
|
||||||
true
|
true
|
||||||
|
@ -389,7 +389,7 @@ exports.Lexer: class Lexer
|
||||||
# If it encounters an interpolation, this method will recursively create a
|
# If it encounters an interpolation, this method will recursively create a
|
||||||
# new Lexer, tokenize the interpolated contents, and merge them into the
|
# new Lexer, tokenize the interpolated contents, and merge them into the
|
||||||
# token stream.
|
# token stream.
|
||||||
interpolateString: (str, escapeQuotes) ->
|
interpolateString: (str, escapeQuotes, heredoc) ->
|
||||||
if str.length < 3 or not starts str, '"'
|
if str.length < 3 or not starts str, '"'
|
||||||
@token 'STRING', str
|
@token 'STRING', str
|
||||||
else
|
else
|
||||||
|
@ -411,7 +411,7 @@ exports.Lexer: class Lexer
|
||||||
tokens.push ['STRING', "$quote${ str.substring(pi, i) }$quote"] if pi < i
|
tokens.push ['STRING', "$quote${ str.substring(pi, i) }$quote"] if pi < i
|
||||||
inner: expr.substring(2, expr.length - 1)
|
inner: expr.substring(2, expr.length - 1)
|
||||||
if inner.length
|
if inner.length
|
||||||
inner: inner.replace new RegExp('\\\\' + quote, 'g'), quote
|
inner: inner.replace new RegExp('\\\\' + quote, 'g'), quote if heredoc
|
||||||
nested: lexer.tokenize "($inner)", {line: @line}
|
nested: lexer.tokenize "($inner)", {line: @line}
|
||||||
(tok[0]: ')') for tok, idx in nested when tok[0] is 'CALL_END'
|
(tok[0]: ')') for tok, idx in nested when tok[0] is 'CALL_END'
|
||||||
nested.pop()
|
nested.pop()
|
||||||
|
|
|
@ -11,6 +11,7 @@ ok "${hello}$${world}" is 'Hello$World'
|
||||||
ok "Hello ${ 1 + 2 } World" is 'Hello 3 World'
|
ok "Hello ${ 1 + 2 } World" is 'Hello 3 World'
|
||||||
ok "$hello ${ 1 + 2 } $world" is "Hello 3 World"
|
ok "$hello ${ 1 + 2 } $world" is "Hello 3 World"
|
||||||
|
|
||||||
|
|
||||||
[s, t, r, i, n, g]: ['s', 't', 'r', 'i', 'n', 'g']
|
[s, t, r, i, n, g]: ['s', 't', 'r', 'i', 'n', 'g']
|
||||||
ok "$s$t$r$i$n$g" is 'string'
|
ok "$s$t$r$i$n$g" is 'string'
|
||||||
ok "${s}${t}${r}${i}${n}${g}" is 'string'
|
ok "${s}${t}${r}${i}${n}${g}" is 'string'
|
||||||
|
@ -20,6 +21,7 @@ ok "\${s}\${t}\${r}\${i}\${n}\${g}" is '${s}${t}${r}${i}${n}${g}'
|
||||||
ok "\$string" is '$string'
|
ok "\$string" is '$string'
|
||||||
ok "\${string}" is '${string}'
|
ok "\${string}" is '${string}'
|
||||||
|
|
||||||
|
|
||||||
ok "\$Escaping first" is '$Escaping first'
|
ok "\$Escaping first" is '$Escaping first'
|
||||||
ok "\${Escaping} first" is '${Escaping} first'
|
ok "\${Escaping} first" is '${Escaping} first'
|
||||||
ok "Escaping \$in middle" is 'Escaping $in middle'
|
ok "Escaping \$in middle" is 'Escaping $in middle'
|
||||||
|
@ -27,24 +29,29 @@ ok "Escaping \${in} middle" is 'Escaping ${in} middle'
|
||||||
ok "Escaping \$last" is 'Escaping $last'
|
ok "Escaping \$last" is 'Escaping $last'
|
||||||
ok "Escaping \${last}" is 'Escaping ${last}'
|
ok "Escaping \${last}" is 'Escaping ${last}'
|
||||||
|
|
||||||
|
|
||||||
ok "$$" is '$$'
|
ok "$$" is '$$'
|
||||||
ok "${}" is ''
|
ok "${}" is ''
|
||||||
ok "${}A${} ${} ${}B${}" is 'A B'
|
ok "${}A${} ${} ${}B${}" is 'A B'
|
||||||
ok "\\\\\$$" is '\\\\\$$'
|
ok "\\\\\$$" is '\\\\\$$'
|
||||||
ok "\\\${}" is '\\${}'
|
ok "\\\${}" is '\\${}'
|
||||||
|
|
||||||
|
|
||||||
ok "I won $20 last night." is 'I won $20 last night.'
|
ok "I won $20 last night." is 'I won $20 last night.'
|
||||||
ok "I won $${20} last night." is 'I won $20 last night.'
|
ok "I won $${20} last night." is 'I won $20 last night.'
|
||||||
ok "I won $#20 last night." is 'I won $#20 last night.'
|
ok "I won $#20 last night." is 'I won $#20 last night.'
|
||||||
ok "I won $${'#20'} last night." is 'I won $#20 last night.'
|
ok "I won $${'#20'} last night." is 'I won $#20 last night.'
|
||||||
|
|
||||||
|
|
||||||
ok "${hello + world}" is 'HelloWorld'
|
ok "${hello + world}" is 'HelloWorld'
|
||||||
ok "${hello + ' ' + world + '!'}" is 'Hello World!'
|
ok "${hello + ' ' + world + '!'}" is 'Hello World!'
|
||||||
|
|
||||||
|
|
||||||
list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
ok "values: ${list.join(', ')}, length: ${list.length}." is 'values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, length: 10.'
|
ok "values: ${list.join(', ')}, length: ${list.length}." is 'values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, length: 10.'
|
||||||
ok "values: ${list.join ' '}" is 'values: 0 1 2 3 4 5 6 7 8 9'
|
ok "values: ${list.join ' '}" is 'values: 0 1 2 3 4 5 6 7 8 9'
|
||||||
|
|
||||||
|
|
||||||
obj: {
|
obj: {
|
||||||
name: 'Joe'
|
name: 'Joe'
|
||||||
hi: -> "Hello $@name."
|
hi: -> "Hello $@name."
|
||||||
|
@ -53,6 +60,7 @@ obj: {
|
||||||
ok obj.hi() is "Hello Joe."
|
ok obj.hi() is "Hello Joe."
|
||||||
ok obj.cya() is "Goodbye Joe."
|
ok obj.cya() is "Goodbye Joe."
|
||||||
|
|
||||||
|
|
||||||
ok "With ${"quotes"}" is 'With quotes'
|
ok "With ${"quotes"}" is 'With quotes'
|
||||||
ok 'With ${"quotes"}' is 'With ${"quotes"}'
|
ok 'With ${"quotes"}' is 'With ${"quotes"}'
|
||||||
|
|
||||||
|
@ -64,17 +72,24 @@ ok "Hello ${world ? "$hello"}" is 'Hello World'
|
||||||
|
|
||||||
ok "Hello ${"${"${obj["name"]}" + '!'}"}" is 'Hello Joe!'
|
ok "Hello ${"${"${obj["name"]}" + '!'}"}" is 'Hello Joe!'
|
||||||
|
|
||||||
|
|
||||||
a: """
|
a: """
|
||||||
Hello ${ "Joe" }
|
Hello ${ "Joe" }
|
||||||
"""
|
"""
|
||||||
ok a is "Hello Joe"
|
ok a is "Hello Joe"
|
||||||
|
|
||||||
|
|
||||||
a: 1
|
a: 1
|
||||||
b: 2
|
b: 2
|
||||||
c: 3
|
c: 3
|
||||||
ok "$a$b$c" is '123'
|
ok "$a$b$c" is '123'
|
||||||
|
|
||||||
|
|
||||||
result: null
|
result: null
|
||||||
stash: (str) -> result: str
|
stash: (str) -> result: str
|
||||||
stash "a ${ ('aa').replace /a/g, 'b' } c"
|
stash "a ${ ('aa').replace /a/g, 'b' } c"
|
||||||
ok result is 'a bb c'
|
ok result is 'a bb c'
|
||||||
|
|
||||||
|
|
||||||
|
foo: "hello"
|
||||||
|
ok "${foo.replace("\"", "")}" is 'hello'
|
Loading…
Reference in New Issue