UNPKG

@solvprotocol/upgrade-safe-transpiler

Version:

Solidity preprocessor used to generate OpenZeppelin Contracts Upgrade Safe.

112 lines 4.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Transform = void 0; const lodash_1 = require("lodash"); const src_decoder_1 = require("./solc/src-decoder"); const layout_getter_1 = require("./solc/layout-getter"); const shifts_1 = require("./shifts"); const apply_1 = require("./transformations/apply"); const compare_1 = require("./transformations/compare"); const ast_resolver_1 = require("./ast-resolver"); class Transform { constructor(input, output, options) { var _a; this.state = {}; this.data = new WeakMap(); this.decodeSrc = (0, src_decoder_1.srcDecoder)(output); this.getLayout = (0, layout_getter_1.layoutGetter)(output); this.resolver = new ast_resolver_1.ASTResolver(output, options === null || options === void 0 ? void 0 : options.exclude); for (const source in input.sources) { if ((_a = options === null || options === void 0 ? void 0 : options.exclude) === null || _a === void 0 ? void 0 : _a.call(options, source)) { continue; } const s = input.sources[source]; if (!('content' in s)) { throw new Error(`Missing content for ${source}`); } const contentBuf = Buffer.from(s.content); this.state[source] = { ast: output.sources[source].ast, original: s.content, originalBuf: contentBuf, content: contentBuf, transformations: [], shifts: [], }; } } apply(transform) { for (const source in this.state) { const { original: originalSource, originalBuf: originalSourceBuf, ast } = this.state[source]; const { resolver, getLayout } = this; const readOriginal = this.readOriginal.bind(this); const getData = this.getData.bind(this); const tools = { originalSource, originalSourceBuf, resolver, readOriginal, getData, getLayout, }; for (const t of transform(ast, tools)) { const { content, shifts, transformations } = this.state[source]; insertSortedAndValidate(transformations, t); const { result, shift } = (0, apply_1.applyTransformation)(t, content, shifts, this); shifts.push(shift); this.state[source].content = result; } } } getData(node) { let data = this.data.get(node); if (data === undefined) { data = {}; this.data.set(node, data); } return data; } readOriginal(node, type = 'string') { const { source, start, length } = this.decodeSrc(node.src); const { originalBuf } = this.state[source]; const buf = originalBuf.slice(start, start + length); if (type === 'buffer') { return buf; } else { return buf.toString('utf8'); } } read(node) { const { source, ...bounds } = this.decodeSrc(node.src); const { shifts, transformations, content } = this.state[source]; const incompatible = (t) => { const c = (0, compare_1.compareContainment)(t, bounds); return c === 'partial overlap' || (typeof c === 'number' && c > 0); }; if (transformations.some(incompatible)) { throw new Error(`Can't read from segment that has been partially transformed`); } const sb = (0, shifts_1.shiftBounds)(shifts, bounds); return content.slice(sb.start, sb.start + sb.length).toString(); } results() { return (0, lodash_1.mapValues)(this.state, s => s.content.toString()); } asts() { return Object.values(this.state).map(s => s.ast); } } exports.Transform = Transform; function insertSortedAndValidate(transformations, t) { transformations.push(t); transformations.sort(compare_1.compareTransformations); // checks for overlaps for (let i = transformations.indexOf(t) + 1; i < transformations.length; i += 1) { const s = transformations[i]; const c = (0, compare_1.compareContainment)(t, s); if (typeof c === 'number' && c < 0) { throw new Error(`A bigger area has already been transformed (${s.kind} > ${t.kind})`); } } } //# sourceMappingURL=transform.js.map