@atomist/automation-client
Version:
Atomist API for software low-level client
113 lines • 4.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tree_path_1 = require("@atomist/tree-path");
const logger_1 = require("../../util/logger");
/**
* Replacement option to zap trailing whitespace
* @type {{replaceAfter: {after: RegExp; replacement: string}}}
*/
exports.ZapTrailingWhitespace = {
replaceAfter: { after: /\s*/, replacement: "" },
};
/**
* Represents a file and the hits against it
*/
class FileHit {
/**
* Represents the hits within a file within a project
* @param project
* @param {File} file file within the project
* @param {TreeNode} fileNode node structure including AST, so
* that if we want to dig into it or run further path expressions
* we don't need to reparse the file.
* @param {TreeNode[]} nodes
*/
constructor(project, file, fileNode, nodes) {
this.project = project;
this.file = file;
this.fileNode = fileNode;
this.nodes = nodes;
const updates = [];
function doReplace() {
return file.getContent()
.then(content => {
// Replace in reverse order so that offsets work
let newContent = content;
const sorted = updates.sort((a, b) => b.offset - a.offset);
for (const u of sorted) {
if (u.offset === undefined) {
throw new Error(`Cannot update as offset is not set: ${JSON.stringify(u)}`);
}
logger_1.logger.debug("Applying update %j", u);
if (!!u.replaceAfter) {
newContent = newContent.substr(0, u.offset) +
newContent.substr(u.offset).replace(u.initialValue, u.currentValue);
newContent = newContent.substr(0, u.offset + u.currentValue.length) +
newContent.substr(u.offset + u.currentValue.length).replace(u.replaceAfter.after, u.replaceAfter.replacement);
}
else {
newContent = newContent.substr(0, u.offset) +
newContent.substr(u.offset).replace(u.initialValue, u.currentValue);
}
}
return file.setContent(newContent);
});
}
this.matches = nodes;
makeUpdatable(this.matches, updates);
project.recordAction(doReplace);
}
}
exports.FileHit = FileHit;
function requireOffset(m) {
if (m.$offset === undefined) {
throw new Error("Sorry, you can't update this because I don't know its offset. " + m.$name + "=" + m.$value);
}
}
function makeUpdatable(matches, updates) {
matches.forEach(m => {
const initialValue = m.$value;
let currentValue = m.$value;
try {
Object.defineProperty(m, "$value", {
get() {
return currentValue;
},
set(v2) {
logger_1.logger.debug("Updating value from '%s' to '%s' on '%s'", currentValue, v2, m.$name);
// TODO allow only one
currentValue = v2;
requireOffset(m);
updates.push({ initialValue, currentValue, offset: m.$offset });
},
});
}
catch (_a) {
// Ok
}
m.append = (content) => {
requireOffset(m);
updates.push({ initialValue: "", currentValue: content, offset: m.$offset + currentValue.length });
};
m.prepend = (content) => {
requireOffset(m);
updates.push({ initialValue: "", currentValue: content, offset: m.$offset });
};
m.replace = (s, opts) => {
requireOffset(m);
updates.push(Object.assign(Object.assign({}, opts), { initialValue, currentValue: s, offset: m.$offset }));
};
m.zap = (opts) => {
requireOffset(m);
updates.push(Object.assign(Object.assign({}, opts), { initialValue, currentValue: "", offset: m.$offset }));
};
m.evaluateExpression = (pex) => {
const r = tree_path_1.evaluateExpression(m, pex);
if (tree_path_1.isSuccessResult(r)) {
makeUpdatable(r, updates);
}
return r;
};
});
}
//# sourceMappingURL=FileHits.js.map