Commit 85ab44ec by kzc Committed by Marijn Haverbeke

fix corruption of whitespace in string literals in class methods (#159)

parent fa979b88
Pipeline #5379721 passed with stage
in 3 minutes 0 seconds
......@@ -18,13 +18,13 @@ export default function Program ( source, ast, transforms, options ) {
wrap( this.body = ast, this );
this.body.__proto__ = BlockStatement.prototype;
this.templateElements = [];
this.indentExclusionElements = [];
this.body.initialise( transforms );
this.indentExclusions = {};
for ( const node of this.templateElements ) {
this.indentExclusions = Object.create( null );
for ( const node of this.indentExclusionElements ) {
for ( let i = node.start; i < node.end; i += 1 ) {
this.indentExclusions[ node.start + i ] = true;
this.indentExclusions[ i ] = true;
}
}
......
......@@ -3,6 +3,12 @@ import CompileError from '../../utils/CompileError.js';
import rewritePattern from 'regexpu-core';
export default class Literal extends Node {
initialise () {
if ( typeof this.value === 'string' ) {
this.program.indentExclusionElements.push( this );
}
}
transpile ( code, transforms ) {
if ( transforms.numericLiteral ) {
const leading = this.raw.slice( 0, 2 );
......
......@@ -2,6 +2,6 @@ import Node from '../Node.js';
export default class TemplateElement extends Node {
initialise () {
this.program.templateElements.push( this );
this.program.indentExclusionElements.push( this );
}
}
......@@ -7,15 +7,22 @@ export default function deindent ( node, code ) {
const end = node.end;
const indentStr = code.getIndentString();
const pattern = new RegExp( indentStr + '\\S', 'g' );
const indentStrLen = indentStr.length;
const indentStart = start - indentStrLen;
if ( code.original.slice( start - indentStr.length, start ) === indentStr ) {
code.remove( start - indentStr.length, start );
if ( !node.program.indentExclusions[ indentStart ]
&& code.original.slice( indentStart, start ) === indentStr ) {
code.remove( indentStart, start );
}
const pattern = new RegExp( indentStr + '\\S', 'g' );
const slice = code.original.slice( start, end );
let match;
while ( match = pattern.exec( slice ) ) {
if ( !node.program.indentExclusions[ match.index ] ) code.remove( start + match.index, start + match.index + indentStr.length );
const removeStart = start + match.index;
if ( !node.program.indentExclusions[ removeStart ] ) {
code.remove( removeStart, removeStart + indentStrLen );
}
}
}
......@@ -597,6 +597,33 @@ module.exports = [
},
{
description: 'verify deindent() does not corrupt string literals in class methods (#159)',
input: `
class Foo {
bar() {
var s = "0\t1\t\t2\t\t\t3\t\t\t\t4\t\t\t\t\t5";
return s + '\t';
}
baz() {
return \`\t\`;
}
}
`,
output: `
var Foo = function Foo () {};
Foo.prototype.bar = function bar () {
var s = "0\t1\t\t2\t\t\t3\t\t\t\t4\t\t\t\t\t5";
return s + '\t';
};
Foo.prototype.baz = function baz () {
return "\\t";
};
`
},
{
description: 'deindents a function body with destructuring (#22)',
input: `
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment