Skip to content

Commit

Permalink
perf: avoid create uncessary overrides for replace
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 3, 2024
1 parent 6f6cd52 commit a1b857c
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -193,7 +193,7 @@ The differences from [`String.replace`]((https://developer.mozilla.org/en-US/doc
### s.replaceAll( regexpOrString, substitution )

Same as `s.replace`, but replace all matched strings instead of just one.
If `substitution` is a regex, then it must have the global (`g`) flag set, or a `TypeError` is thrown. Matches the behavior of the bultin [`String.property.replaceAll`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll).
If `substitution` is a regex, then it must have the global (`g`) flag set, or a `TypeError` is thrown. Matches the behavior of the builtin [`String.property.replaceAll`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll).

### s.remove( start, end )

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -33,6 +33,7 @@
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"format": "prettier --single-quote --print-width 100 --use-tabs --write src/*.js src/**/*.js",
"lint": "eslint src test && publint",
"lint:fix": "eslint src test --fix",
"prepare": "npm run build",
"prepublishOnly": "npm run lint && rm -rf dist && npm test",
"release": "bumpp -x \"npm run changelog\" --all --commit --tag --push && npm publish",
Expand Down
34 changes: 22 additions & 12 deletions src/MagicString.js
Expand Up @@ -797,21 +797,29 @@ export default class MagicString {
if (searchValue.global) {
const matches = matchAll(searchValue, this.original);
matches.forEach((match) => {
if (match.index != null)
if (match.index != null) {
const replacement = getReplacement(match, this.original);
if (replacement !== match[0]) {
this.overwrite(
match.index,
match.index + match[0].length,
replacement
);
}
}
});
} else {
const match = this.original.match(searchValue);
if (match && match.index != null) {
const replacement = getReplacement(match, this.original);
if (replacement !== match[0]) {
this.overwrite(
match.index,
match.index + match[0].length,
getReplacement(match, this.original),
replacement
);
});
} else {
const match = this.original.match(searchValue);
if (match && match.index != null)
this.overwrite(
match.index,
match.index + match[0].length,
getReplacement(match, this.original),
);
}
}
}
return this;
}
Expand Down Expand Up @@ -843,7 +851,9 @@ export default class MagicString {
index !== -1;
index = original.indexOf(string, index + stringLength)
) {
this.overwrite(index, index + stringLength, replacement);
const previous = original.slice(index, index + stringLength);
if (previous !== replacement)
this.overwrite(index, index + stringLength, replacement);
}

return this;
Expand Down
19 changes: 19 additions & 0 deletions test/MagicString.js
Expand Up @@ -1758,6 +1758,25 @@ describe('MagicString', () => {
new MagicString(code).replace(regex, replacer).toString()
);
});

it('should ignore non-changed replacements', () => {
const code = 'a12bc345#$*%';
const matched = [];

const s = new MagicString(code);

assert.strictEqual(s.firstChunk, s.lastChunk);

s.replace(/(\d)/g, (match, $1) => {
matched.push($1);
return match;
});

assert.strictEqual(s.toString(), code);
assert.deepStrictEqual(matched, ['1', '2', '3', '4', '5']);

assert.strictEqual(s.firstChunk, s.lastChunk);
});
});

describe('replaceAll', () => {
Expand Down

0 comments on commit a1b857c

Please sign in to comment.