| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- var Source = require("./Source");
- var SourceNode = require("source-map").SourceNode;
- var SourceListMap = require("source-list-map").SourceListMap;
- var fromStringWithSourceMap = require("source-list-map").fromStringWithSourceMap;
- var SourceMapConsumer = require("source-map").SourceMapConsumer;
- function ReplaceSource(source, name) {
- Source.call(this);
- this._source = source;
- this._name = name;
- this.replacements = [];
- }
- module.exports = ReplaceSource;
- ReplaceSource.prototype = Object.create(Source.prototype);
- ReplaceSource.prototype.constructor = ReplaceSource;
- ReplaceSource.prototype.replace = function(start, end, newValue) {
- this.replacements.push([start, end, newValue]);
- };
- ReplaceSource.prototype.insert = function(pos, newValue) {
- this.replacements.push([pos, pos-1, newValue]);
- };
- ReplaceSource.prototype.source = function(options) {
- return this._replaceString(this._source.source());
- };
- ReplaceSource.prototype._sortReplacements = function() {
- this.replacements.forEach(function(item, idx) {
- item[3] = idx;
- });
- this.replacements.sort(function(a, b) {
- var diff = b[1] - a[1];
- if(diff !== 0)
- return diff;
- return b[3] - a[3];
- });
- };
- ReplaceSource.prototype._replaceString = function(str) {
- this._sortReplacements();
- var result = [str];
- this.replacements.forEach(function(repl) {
- var remSource = result.pop();
- var splitted1 = this._splitString(remSource, Math.floor(repl[1]+1));
- var splitted2 = this._splitString(splitted1[0], Math.floor(repl[0]));
- result.push(splitted1[1], repl[2], splitted2[0]);
- }, this);
- result = result.reverse();
- return result.join("");
- };
- require("./SourceAndMapMixin")(ReplaceSource.prototype);
- ReplaceSource.prototype.node = function(options) {
- this._sortReplacements();
- var result = [this._source.node(options)];
- this.replacements.forEach(function(repl) {
- var remSource = result.pop();
- var splitted1 = this._splitSourceNode(remSource, Math.floor(repl[1]+1));
- if(Array.isArray(splitted1)) {
- var splitted2 = this._splitSourceNode(splitted1[0], Math.floor(repl[0]));
- if(Array.isArray(splitted2)) {
- result.push(splitted1[1], this._replacementToSourceNode(splitted2[1], repl[2]), splitted2[0]);
- } else {
- result.push(splitted1[1], this._replacementToSourceNode(splitted1[1], repl[2]), splitted1[0]);
- }
- } else {
- var splitted2 = this._splitSourceNode(remSource, Math.floor(repl[0]));
- if(Array.isArray(splitted2)) {
- result.push(this._replacementToSourceNode(splitted2[1], repl[2]), splitted2[0]);
- } else {
- result.push(repl[2], remSource);
- }
- }
- }, this);
- result = result.reverse();
- return new SourceNode(null, null, null, result);
- };
- ReplaceSource.prototype.listMap = function(options) {
- var map = this._source.listMap(options);
- if(map.children.length !== 1) {
- var code = map.toString();
- code = this._replaceString(code).split("\n");
- var currentIndex = 0;
- map.mapGeneratedCode(function(str) {
- var idx = -1;
- var count = -1;
- do {
- count++;
- idx = str.indexOf("\n", idx + 1);
- } while(idx >= 0);
- if(!count) return "";
- var result = code.slice(currentIndex, currentIndex + count).join("\n") + "\n";
- currentIndex += count;
- return result;
- });
- map.add(code.slice(currentIndex).join("\n"));
- } else {
- map.mapGeneratedCode(this._replaceString.bind(this));
- }
- return map;
- };
- ReplaceSource.prototype._replacementToSourceNode = function(oldNode, newString) {
- var map = oldNode.toStringWithSourceMap({ file: "?" }).map;
- var original = new SourceMapConsumer(map.toJSON()).originalPositionFor({ line: 1, column: 0 });
- if(original) {
- return new SourceNode(original.line, original.column, original.source, newString);
- } else {
- return newString;
- }
- };
- ReplaceSource.prototype._splitSourceNode = function(node, position) {
- if(typeof node === "string") {
- if(node.length <= position) return position - node.length;
- return [node.substr(0, position), node.substr(position)];
- } else {
- for(var i = 0; i < node.children.length; i++) {
- position = this._splitSourceNode(node.children[i], position);
- if(Array.isArray(position)) {
- var leftNode = new SourceNode(
- node.line,
- node.column,
- node.source,
- node.children.slice(0, i).concat([position[0]]),
- node.name
- );
- var rightNode = new SourceNode(
- node.line,
- node.column,
- node.source,
- [position[1]].concat(node.children.slice(i+1)),
- node.name
- );
- leftNode.sourceContents = node.sourceContents;
- return [leftNode, rightNode];
- }
- }
- return position;
- }
- };
- ReplaceSource.prototype._splitString = function(str, position) {
- return [str.substr(0, position), str.substr(position)];
- };
|