Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patches #30

Merged
merged 26 commits into from Dec 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,11 @@
# changelog

## 0.10.0

* Complete rewrite, resulting in ~40x speed increase ([#30](https://github.com/Rich-Harris/magic-string/pull/30))
* Breaking – `magicString.locate` and `locateOrigin` are deprecated
* More forgiving rules about contiguous patches, and which ranges are valid with `magicString.slice(...)`

## 0.9.1

* Update deps
Expand Down
6 changes: 2 additions & 4 deletions README.md
Expand Up @@ -52,8 +52,6 @@ var s = new MagicString( 'problems = 99' );

s.overwrite( 0, 8, 'answer' );
s.toString(); // 'answer = 99'
s.locate( 9 ); // 7 - the character originally at index 9 ('=') is now at index 7
s.locateOrigin( 7 ); // 9

s.overwrite( 11, 13, '42' ); // character indices always refer to the original string
s.toString(); // 'answer = 42'
Expand Down Expand Up @@ -126,11 +124,11 @@ Inserts the specified `content` at the `index` in the original string. Returns `

### s.locate( index )

Finds the location, in the generated string, of the character at `index` in the original string. Returns `null` if the character in question has been removed or overwritten.
**DEPRECATED** since 0.10 – see [#30](https://github.com/Rich-Harris/magic-string/pull/30)

### s.locateOrigin( index )

The opposite of `s.locate()`. Returns `null` if the character in question was inserted with `s.append()`, `s.prepend()` or `s.overwrite()`.
**DEPRECATED** since 0.10 – see [#30](https://github.com/Rich-Harris/magic-string/pull/30)

### s.overwrite( start, end, content[, storeName] )

Expand Down
17 changes: 11 additions & 6 deletions package.json
Expand Up @@ -2,7 +2,7 @@
"name": "magic-string",
"description": "Modify strings, generate sourcemaps",
"author": "Rich Harris",
"version": "0.9.1",
"version": "0.10.0",
"repository": "https://github.com/rich-harris/magic-string",
"main": "dist/magic-string.cjs.js",
"jsnext:main": "dist/magic-string.es6.js",
Expand All @@ -13,6 +13,7 @@
"devDependencies": {
"babel-preset-es2015-rollup": "^1.0.0",
"codecov.io": "^0.1.6",
"console-group": "^0.1.2",
"es6-promise": "^3.0.2",
"eslint": "^1.10.3",
"istanbul": "^0.4.0",
Expand All @@ -22,7 +23,8 @@
"rollup": "^0.22.0",
"rollup-plugin-babel": "^2.2.0",
"rollup-plugin-npm": "^1.1.0",
"source-map": "^0.5.3"
"source-map": "^0.5.3",
"source-map-support": "^0.4.0"
},
"keywords": [
"string",
Expand All @@ -33,13 +35,16 @@
],
"scripts": {
"test": "mocha",
"pretest": "npm run build",
"pretest-coverage": "npm run build",
"pretest": "npm run build:cjs",
"pretest-coverage": "npm run build:cjs",
"test-coverage": "rm -rf coverage/* && istanbul cover --report json node_modules/.bin/_mocha -- -u exports -R spec test/index.js",
"posttest-coverage": "remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.json -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.lcov -t lcovonly -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped -t html -b dist",
"ci": "npm run test-coverage && codecov < coverage/coverage-remapped.lcov",
"build": "rm -rf dist && rollup -c -f cjs -o dist/magic-string.cjs.js && rollup -c -f es6 -o dist/magic-string.es6.js && export DEPS=true && rollup -c -f umd -o dist/magic-string.umd.js",
"prepublish": "npm test",
"build:cjs": "rollup -c -f cjs -o dist/magic-string.cjs.js",
"build:es6": "rollup -c -f es6 -o dist/magic-string.es6.js",
"build:umd": "export DEPS=true && rollup -c -f umd -o dist/magic-string.umd.js",
"build": " npm run build:cjs && npm run build:es6 && npm run build:umd",
"prepublish": "rm -rf dist && npm test && npm run build:es6 && npm run build:umd",
"lint": "eslint src"
},
"files": [
Expand Down
47 changes: 19 additions & 28 deletions src/Bundle.js
Expand Up @@ -6,7 +6,6 @@ import isObject from './utils/isObject.js';

export default function Bundle ( options = {} ) {
this.intro = options.intro || '';
this.outro = options.outro || '';
this.separator = options.separator !== undefined ? options.separator : '\n';

this.sources = [];
Expand Down Expand Up @@ -65,7 +64,6 @@ Bundle.prototype = {
clone () {
const bundle = new Bundle({
intro: this.intro,
outro: this.outro,
separator: this.separator
});

Expand All @@ -85,8 +83,7 @@ Bundle.prototype = {

let names = [];
this.sources.forEach( source => {
Object.keys( source.content.nameLocations ).forEach( location => {
const name = source.content.nameLocations[ location ];
Object.keys( source.content.storedNames ).forEach( name => {
if ( !~names.indexOf( name ) ) names.push( name );
});
});
Expand All @@ -106,8 +103,7 @@ Bundle.prototype = {
}

return prefix + mappings;
}).join( '' ) +
getSemis( this.outro )
}).join( '' )
);

return new SourceMap({
Expand Down Expand Up @@ -158,7 +154,8 @@ Bundle.prototype = {
indentStart//: trailingNewline || /\r?\n$/.test( separator ) //true///\r?\n/.test( separator )
});

trailingNewline = source.content.str.slice( 0, -1 ) === '\n';
// TODO this is a very slow way to determine this
trailingNewline = source.content.toString().slice( 0, -1 ) === '\n';
});

if ( this.intro ) {
Expand All @@ -167,8 +164,6 @@ Bundle.prototype = {
});
}

this.outro = this.outro.replace( /^[^\n]/gm, indentStr + '$&' );

return this;
},

Expand All @@ -185,7 +180,7 @@ Bundle.prototype = {
return str;
}).join( '' );

return this.intro + body + this.outro;
return this.intro + body;
},

trimLines () {
Expand All @@ -201,45 +196,41 @@ Bundle.prototype = {
this.intro = this.intro.replace( rx, '' );

if ( !this.intro ) {
let source; // TODO put inside loop if safe
let source;
let i = 0;

do {
source = this.sources[i];

if ( !source ) {
this.outro = this.outro.replace( rx, '' );
break;
}

source.content.trimStart();
source.content.trimStart( charType );
i += 1;
} while ( source.content.str === '' );
} while ( source.content.toString() === '' ); // TODO faster way to determine non-empty source?
}

return this;
},

trimEnd ( charType ) {
const rx = new RegExp( ( charType || '\\s' ) + '+$' );
this.outro = this.outro.replace( rx, '' );

if ( !this.outro ) {
let source;
let i = this.sources.length - 1;
let source;
let i = this.sources.length - 1;

do {
source = this.sources[i];
do {
source = this.sources[i];

if ( !source ) {
this.intro = this.intro.replace( rx, '' );
break;
}
if ( !source ) {
this.intro = this.intro.replace( rx, '' );
break;
}

source.content.trimEnd(charType);
i -= 1;
} while ( source.content.str === '' );
}
source.content.trimEnd( charType );
i -= 1;
} while ( source.content.toString() === '' ); // TODO faster way to determine non-empty source?

return this;
}
Expand Down