mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Changed multiline string literals
This commit is contained in:
parent
9e9c83f788
commit
efe8c68c75
5 changed files with 68 additions and 25 deletions
|
@ -96,8 +96,7 @@
|
||||||
return new Value($1);
|
return new Value($1);
|
||||||
}), o('ObjAssignable : Expression', function() {
|
}), o('ObjAssignable : Expression', function() {
|
||||||
return new Assign(LOC(1)(new Value($1)), $3, 'object');
|
return new Assign(LOC(1)(new Value($1)), $3, 'object');
|
||||||
}), o('ObjAssignable :\
|
}), o('ObjAssignable : INDENT Expression OUTDENT', function() {
|
||||||
INDENT Expression OUTDENT', function() {
|
|
||||||
return new Assign(LOC(1)(new Value($1)), $4, 'object');
|
return new Assign(LOC(1)(new Value($1)), $4, 'object');
|
||||||
}), o('Comment')
|
}), o('Comment')
|
||||||
],
|
],
|
||||||
|
@ -573,14 +572,11 @@
|
||||||
} else {
|
} else {
|
||||||
return new Op($2, $1, $3);
|
return new Op($2, $1, $3);
|
||||||
}
|
}
|
||||||
}), o('SimpleAssignable COMPOUND_ASSIGN\
|
}), o('SimpleAssignable COMPOUND_ASSIGN Expression', function() {
|
||||||
Expression', function() {
|
|
||||||
return new Assign($1, $3, $2);
|
return new Assign($1, $3, $2);
|
||||||
}), o('SimpleAssignable COMPOUND_ASSIGN\
|
}), o('SimpleAssignable COMPOUND_ASSIGN INDENT Expression OUTDENT', function() {
|
||||||
INDENT Expression OUTDENT', function() {
|
|
||||||
return new Assign($1, $4, $2);
|
return new Assign($1, $4, $2);
|
||||||
}), o('SimpleAssignable COMPOUND_ASSIGN TERMINATOR\
|
}), o('SimpleAssignable COMPOUND_ASSIGN TERMINATOR Expression', function() {
|
||||||
Expression', function() {
|
|
||||||
return new Assign($1, $4, $2);
|
return new Assign($1, $4, $2);
|
||||||
}), o('SimpleAssignable EXTENDS Expression', function() {
|
}), o('SimpleAssignable EXTENDS Expression', function() {
|
||||||
return new Extends($1, $3);
|
return new Extends($1, $3);
|
||||||
|
|
|
@ -173,7 +173,7 @@
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
string = match[0];
|
string = match[0];
|
||||||
this.token('STRING', string.replace(MULTILINER, '\\\n'), 0, string.length);
|
this.token('STRING', this.trimAndEscapeLines(string), 0, string.length);
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
if (!(string = this.balancedString(this.chunk, '"'))) {
|
if (!(string = this.balancedString(this.chunk, '"'))) {
|
||||||
|
@ -185,7 +185,7 @@
|
||||||
lexedLength: string.length
|
lexedLength: string.length
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.token('STRING', this.escapeLines(string), 0, string.length);
|
this.token('STRING', this.trimAndEscapeLines(string), 0, string.length);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -762,16 +762,24 @@
|
||||||
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
|
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.trimAndEscapeLines = function(str) {
|
||||||
|
return this.escapeLines(str.replace(/^(.)\s*\n\s*/, '$1').replace(/\s*\n\s*(.)$/, '$1'));
|
||||||
|
};
|
||||||
|
|
||||||
Lexer.prototype.escapeLines = function(str, heredoc) {
|
Lexer.prototype.escapeLines = function(str, heredoc) {
|
||||||
return str.replace(MULTILINER, heredoc ? '\\n' : '');
|
if (heredoc) {
|
||||||
|
return str.replace(MULTILINER, '\\n');
|
||||||
|
} else {
|
||||||
|
return str.replace(/\\\n\s*/g, '').replace(/\s*\n\s*/g, ' ');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Lexer.prototype.makeString = function(body, quote, heredoc) {
|
Lexer.prototype.makeString = function(body, quote, heredoc) {
|
||||||
if (!body) {
|
if (!body) {
|
||||||
return quote + quote;
|
return quote + quote;
|
||||||
}
|
}
|
||||||
body = body.replace(/\\([\s\S])/g, function(match, contents) {
|
body = body.replace(/\\([^])/g, function(match, contents) {
|
||||||
if (contents === '\n' || contents === quote) {
|
if (contents === quote || heredoc && contents === '\n') {
|
||||||
return contents;
|
return contents;
|
||||||
} else {
|
} else {
|
||||||
return match;
|
return match;
|
||||||
|
@ -852,7 +860,7 @@
|
||||||
|
|
||||||
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
|
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
|
||||||
|
|
||||||
SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
|
SIMPLESTR = /^'[^\\']*(?:\\[^][^\\']*)*'/;
|
||||||
|
|
||||||
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
|
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
|
||||||
|
|
||||||
|
|
|
@ -190,13 +190,13 @@ exports.Lexer = class Lexer
|
||||||
when "'"
|
when "'"
|
||||||
return 0 unless match = SIMPLESTR.exec @chunk
|
return 0 unless match = SIMPLESTR.exec @chunk
|
||||||
string = match[0]
|
string = match[0]
|
||||||
@token 'STRING', string.replace(MULTILINER, '\\\n'), 0, string.length
|
@token 'STRING', @trimAndEscapeLines(string), 0, string.length
|
||||||
when '"'
|
when '"'
|
||||||
return 0 unless string = @balancedString @chunk, '"'
|
return 0 unless string = @balancedString @chunk, '"'
|
||||||
if 0 < string.indexOf '#{', 1
|
if 0 < string.indexOf '#{', 1
|
||||||
@interpolateString string[1...-1], strOffset: 1, lexedLength: string.length
|
@interpolateString string[1...-1], strOffset: 1, lexedLength: string.length
|
||||||
else
|
else
|
||||||
@token 'STRING', @escapeLines(string), 0, string.length
|
@token 'STRING', @trimAndEscapeLines(string), 0, string.length
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
if octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test string
|
if octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test string
|
||||||
|
@ -684,15 +684,23 @@ exports.Lexer = class Lexer
|
||||||
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', '+', '-', 'SHIFT', 'RELATION'
|
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', '+', '-', 'SHIFT', 'RELATION'
|
||||||
'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
|
'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
|
||||||
|
|
||||||
|
# Remove newlines from beginning and end of string literals.
|
||||||
|
# `str` includes quotes.
|
||||||
|
trimAndEscapeLines: (str) ->
|
||||||
|
@escapeLines str.replace(/^(.)\s*\n\s*/, '$1').replace(/\s*\n\s*(.)$/, '$1')
|
||||||
|
|
||||||
# Converts newlines for string literals.
|
# Converts newlines for string literals.
|
||||||
escapeLines: (str, heredoc) ->
|
escapeLines: (str, heredoc) ->
|
||||||
str.replace MULTILINER, if heredoc then '\\n' else ''
|
if heredoc
|
||||||
|
str.replace MULTILINER, '\\n'
|
||||||
|
else
|
||||||
|
str.replace(/\\\n\s*/g, '').replace(/\s*\n\s*/g, ' ')
|
||||||
|
|
||||||
# Constructs a string token by escaping quotes and newlines.
|
# Constructs a string token by escaping quotes and newlines.
|
||||||
makeString: (body, quote, heredoc) ->
|
makeString: (body, quote, heredoc) ->
|
||||||
return quote + quote unless body
|
return quote + quote unless body
|
||||||
body = body.replace /\\([\s\S])/g, (match, contents) ->
|
body = body.replace /\\([^])/g, (match, contents) ->
|
||||||
if contents in ['\n', quote] then contents else match
|
if contents is quote or heredoc and contents is '\n' then contents else match
|
||||||
body = body.replace /// #{quote} ///g, '\\$&'
|
body = body.replace /// #{quote} ///g, '\\$&'
|
||||||
quote + @escapeLines(body, heredoc) + quote
|
quote + @escapeLines(body, heredoc) + quote
|
||||||
|
|
||||||
|
@ -787,7 +795,7 @@ CODE = /^[-=]>/
|
||||||
|
|
||||||
MULTI_DENT = /^(?:\n[^\n\S]*)+/
|
MULTI_DENT = /^(?:\n[^\n\S]*)+/
|
||||||
|
|
||||||
SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/
|
SIMPLESTR = /^'[^\\']*(?:\\[^][^\\']*)*'/
|
||||||
|
|
||||||
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/
|
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ eq "#{6 / 2}", '3'
|
||||||
eq "#{6 / 2}#{6 / 2}", '33' # parsed as division
|
eq "#{6 / 2}#{6 / 2}", '33' # parsed as division
|
||||||
eq "#{6 + /2}#{6/ + 2}", '6/2}#{6/2' # parsed as a regex
|
eq "#{6 + /2}#{6/ + 2}", '6/2}#{6/2' # parsed as a regex
|
||||||
eq "#{6/2}
|
eq "#{6/2}
|
||||||
#{6/2}", '3 3' # newline cannot be part of a regex, so it's division
|
#{6/2}", '3 3' # newline cannot be part of a regex, so it's division
|
||||||
eq "#{/// "'/'"/" ///}", '/"\'\\/\'"\\/"/' # heregex, stuffed with spicy characters
|
eq "#{/// "'/'"/" ///}", '/"\'\\/\'"\\/"/' # heregex, stuffed with spicy characters
|
||||||
eq "#{/\\'/}", "/\\\\'/"
|
eq "#{/\\'/}", "/\\\\'/"
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,38 @@ eq "four five", 'four
|
||||||
|
|
||||||
five'
|
five'
|
||||||
|
|
||||||
|
test "#3229, multine strings", ->
|
||||||
|
eq 'one
|
||||||
|
two', 'one two'
|
||||||
|
eq "one
|
||||||
|
two", 'one two'
|
||||||
|
eq 'a \
|
||||||
|
b\
|
||||||
|
c \
|
||||||
|
d', 'a bc d'
|
||||||
|
eq "a \
|
||||||
|
b\
|
||||||
|
c \
|
||||||
|
d", 'a bc d'
|
||||||
|
eq 'one
|
||||||
|
|
||||||
|
two', 'one two'
|
||||||
|
eq "one
|
||||||
|
|
||||||
|
two", 'one two'
|
||||||
|
eq '
|
||||||
|
a
|
||||||
|
b
|
||||||
|
', 'a b'
|
||||||
|
eq "
|
||||||
|
a
|
||||||
|
b
|
||||||
|
", 'a b'
|
||||||
|
eq "interpolation #{1}
|
||||||
|
follows #{2} \
|
||||||
|
too #{3}\
|
||||||
|
!", 'interpolation 1 follows 2 too 3!'
|
||||||
|
|
||||||
#647
|
#647
|
||||||
eq "''Hello, World\\''", '''
|
eq "''Hello, World\\''", '''
|
||||||
'\'Hello, World\\\''
|
'\'Hello, World\\\''
|
||||||
|
@ -91,10 +123,9 @@ ok a is "one\ntwo\n"
|
||||||
eq ''' line 0
|
eq ''' line 0
|
||||||
should not be relevant
|
should not be relevant
|
||||||
to the indent level
|
to the indent level
|
||||||
''', '
|
''', ' line 0\n\
|
||||||
line 0\n
|
should not be relevant\n \
|
||||||
should not be relevant\n
|
to the indent level
|
||||||
to the indent level
|
|
||||||
'
|
'
|
||||||
|
|
||||||
eq ''' '\\\' ''', " '\\' "
|
eq ''' '\\\' ''', " '\\' "
|
||||||
|
|
Loading…
Reference in a new issue