@neo-one/smart-contract-compiler
Version:
NEO•ONE TypeScript smart contract compiler.
89 lines (87 loc) • 15.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const ts_utils_1 = require("@neo-one/ts-utils");
const utils_1 = require("@neo-one/utils");
const typescript_1 = tslib_1.__importDefault(require("typescript"));
const createContext_1 = require("./createContext");
const errors_1 = require("./errors");
exports.scanContext = (context) => {
const smartContract = ts_utils_1.tsUtils.symbol.getDeclarations(context.builtins.getValueSymbol('SmartContract'))[0];
if (!typescript_1.default.isClassDeclaration(smartContract)) {
throw new Error('Something went wrong!');
}
const { contracts, dependencies } = ts_utils_1.tsUtils.class_
.getExtendors(context.program, context.languageService, smartContract)
.reduce((acc, derived) => {
if (!ts_utils_1.tsUtils.modifier.isAbstract(derived) &&
!ts_utils_1.tsUtils.file.isDeclarationFile(ts_utils_1.tsUtils.node.getSourceFile(derived))) {
const filePath = ts_utils_1.tsUtils.file.getFilePath(ts_utils_1.tsUtils.node.getSourceFile(derived));
const name = ts_utils_1.tsUtils.node.getNameOrThrow(derived);
const existing = acc.contracts[filePath];
if (existing !== undefined) {
throw new errors_1.MultipleContractsInFileError(filePath);
}
const references = [
...new Set(ts_utils_1.tsUtils.reference
.findReferencesAsNodes(context.program, context.languageService, derived)
.map((reference) => ts_utils_1.tsUtils.file.getFilePath(ts_utils_1.tsUtils.node.getSourceFile(reference)))),
];
const dependency = { filePath, name };
const dependenciesOut = references.reduce((innerAcc, reference) => {
let filePathDependencies = innerAcc[reference];
if (filePathDependencies === undefined) {
filePathDependencies = [];
}
return Object.assign({}, innerAcc, { [reference]: [...filePathDependencies, dependency] });
}, acc.dependencies);
return {
contracts: Object.assign({}, acc.contracts, { [filePath]: {
filePath,
name,
dependencies: [],
} }),
dependencies: dependenciesOut,
};
}
return acc;
}, { contracts: {}, dependencies: {} });
const unsortedContracts = Object.values(contracts).map((contract) => {
const filePathDependencies = dependencies[contract.filePath];
return Object.assign({}, contract, { dependencies: filePathDependencies === undefined ? [] : filePathDependencies });
});
return topographicalSort(unsortedContracts);
};
const topographicalSort = (contracts) => {
const contractToDependencies = contracts.reduce((acc, contract) => (Object.assign({}, acc, { [contract.filePath]: new Set(contract.dependencies.map((dep) => dep.filePath)) })), {});
const mutableOut = [];
const satisfied = contracts.filter((contract) => contract.dependencies.length === 0);
let remaining = contracts.filter((contract) => contract.dependencies.length !== 0);
while (satisfied.length > 0) {
const node = satisfied.shift();
if (node === undefined) {
break;
}
mutableOut.push(node);
remaining = remaining
.map((contract) => {
const deps = contractToDependencies[contract.filePath];
deps.delete(node.filePath);
if (deps.size === 0) {
satisfied.push(contract);
return undefined;
}
return contract;
})
.filter(utils_1.utils.notNull);
}
if (mutableOut.length !== contracts.length) {
throw new errors_1.CircularLinkedDependencyError(contracts.map((contract) => contract.name));
}
return mutableOut;
};
exports.scan = async (dir, host) => {
const context = await createContext_1.createContextForDir(dir, host);
return exports.scanContext(context);
};
//# sourceMappingURL=data:application/json;charset=utf8;base64,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LENBQUM7SUFFckQsT0FBTyxtQkFBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzlCLENBQUMsQ0FBQyIsImZpbGUiOiJuZW8tb25lLXNtYXJ0LWNvbnRyYWN0LWNvbXBpbGVyL3NyYy9zY2FuLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdHNVdGlscyB9IGZyb20gJ0BuZW8tb25lL3RzLXV0aWxzJztcbmltcG9ydCB7IHV0aWxzIH0gZnJvbSAnQG5lby1vbmUvdXRpbHMnO1xuaW1wb3J0IHRzIGZyb20gJ3R5cGVzY3JpcHQnO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4vQ29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVDb250ZXh0Rm9yRGlyIH0gZnJvbSAnLi9jcmVhdGVDb250ZXh0JztcbmltcG9ydCB7IENpcmN1bGFyTGlua2VkRGVwZW5kZW5jeUVycm9yLCBNdWx0aXBsZUNvbnRyYWN0c0luRmlsZUVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgQ29tcGlsZXJIb3N0IH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udHJhY3REZXBlbmRlbmN5IHtcbiAgcmVhZG9ubHkgZmlsZVBhdGg6IHN0cmluZztcbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xufVxuZXhwb3J0IGludGVyZmFjZSBDb250cmFjdCB7XG4gIHJlYWRvbmx5IGZpbGVQYXRoOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgZGVwZW5kZW5jaWVzOiBSZWFkb25seUFycmF5PENvbnRyYWN0RGVwZW5kZW5jeT47XG59XG5leHBvcnQgdHlwZSBDb250cmFjdHMgPSBSZWFkb25seUFycmF5PENvbnRyYWN0PjtcblxuaW50ZXJmYWNlIEZpbGVQYXRoVG9Db250cmFjdCB7XG4gIHJlYWRvbmx5IFtmaWxlUGF0aDogc3RyaW5nXTogQ29udHJhY3Q7XG59XG5pbnRlcmZhY2UgRmlsZVBhdGhUb0RlcGVuZGVuY2llcyB7XG4gIHJlYWRvbmx5IFtmaWxlUGF0aDogc3RyaW5nXTogUmVhZG9ubHlBcnJheTxDb250cmFjdERlcGVuZGVuY3k+O1xufVxuXG5leHBvcnQgY29uc3Qgc2NhbkNvbnRleHQgPSAoY29udGV4dDogQ29udGV4dCk6IENvbnRyYWN0cyA9PiB7XG4gIGNvbnN0IHNtYXJ0Q29udHJhY3QgPSB0c1V0aWxzLnN5bWJvbC5nZXREZWNsYXJhdGlvbnMoY29udGV4dC5idWlsdGlucy5nZXRWYWx1ZVN5bWJvbCgnU21hcnRDb250cmFjdCcpKVswXTtcbiAgaWYgKCF0cy5pc0NsYXNzRGVjbGFyYXRpb24oc21hcnRDb250cmFjdCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvbWV0aGluZyB3ZW50IHdyb25nIScpO1xuICB9XG5cbiAgY29uc3QgeyBjb250cmFjdHMsIGRlcGVuZGVuY2llcyB9ID0gdHNVdGlscy5jbGFzc19cbiAgICAuZ2V0RXh0ZW5kb3JzKGNvbnRleHQucHJvZ3JhbSwgY29udGV4dC5sYW5ndWFnZVNlcnZpY2UsIHNtYXJ0Q29udHJhY3QpXG4gICAgLnJlZHVjZTx7IGNvbnRyYWN0czogRmlsZVBhdGhUb0NvbnRyYWN0OyBkZXBlbmRlbmNpZXM6IEZpbGVQYXRoVG9EZXBlbmRlbmNpZXMgfT4oXG4gICAgICAoYWNjLCBkZXJpdmVkKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhdHNVdGlscy5tb2RpZmllci5pc0Fic3RyYWN0KGRlcml2ZWQpICYmXG4gICAgICAgICAgIXRzVXRpbHMuZmlsZS5pc0RlY2xhcmF0aW9uRmlsZSh0c1V0aWxzLm5vZGUuZ2V0U291cmNlRmlsZShkZXJpdmVkKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgZmlsZVBhdGggPSB0c1V0aWxzLmZpbGUuZ2V0RmlsZVBhdGgodHNVdGlscy5ub2RlLmdldFNvdXJjZUZpbGUoZGVyaXZlZCkpO1xuICAgICAgICAgIGNvbnN0IG5hbWUgPSB0c1V0aWxzLm5vZGUuZ2V0TmFtZU9yVGhyb3coZGVyaXZlZCk7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhY2MuY29udHJhY3RzW2ZpbGVQYXRoXSBhcyBDb250cmFjdCB8IHVuZGVmaW5lZDtcbiAgICAgICAgICBpZiAoZXhpc3RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IE11bHRpcGxlQ29udHJhY3RzSW5GaWxlRXJyb3IoZmlsZVBhdGgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHJlZmVyZW5jZXMgPSBbXG4gICAgICAgICAgICAuLi5uZXcgU2V0KFxuICAgICAgICAgICAgICB0c1V0aWxzLnJlZmVyZW5jZVxuICAgICAgICAgICAgICAgIC5maW5kUmVmZXJlbmNlc0FzTm9kZXMoY29udGV4dC5wcm9ncmFtLCBjb250ZXh0Lmxhbmd1YWdlU2VydmljZSwgZGVyaXZlZClcbiAgICAgICAgICAgICAgICAubWFwKChyZWZlcmVuY2UpID0+IHRzVXRpbHMuZmlsZS5nZXRGaWxlUGF0aCh0c1V0aWxzLm5vZGUuZ2V0U291cmNlRmlsZShyZWZlcmVuY2UpKSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCBkZXBlbmRlbmN5ID0geyBmaWxlUGF0aCwgbmFtZSB9O1xuICAgICAgICAgIGNvbnN0IGRlcGVuZGVuY2llc091dCA9IHJlZmVyZW5jZXMucmVkdWNlKChpbm5lckFjYywgcmVmZXJlbmNlKSA9PiB7XG4gICAgICAgICAgICBsZXQgZmlsZVBhdGhEZXBlbmRlbmNpZXMgPSBpbm5lckFjY1tyZWZlcmVuY2VdIGFzIFJlYWRvbmx5QXJyYXk8Q29udHJhY3REZXBlbmRlbmN5PiB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChmaWxlUGF0aERlcGVuZGVuY2llcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGZpbGVQYXRoRGVwZW5kZW5jaWVzID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIC4uLmlubmVyQWNjLFxuICAgICAgICAgICAgICBbcmVmZXJlbmNlXTogWy4uLmZpbGVQYXRoRGVwZW5kZW5jaWVzLCBkZXBlbmRlbmN5XSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSwgYWNjLmRlcGVuZGVuY2llcyk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udHJhY3RzOiB7XG4gICAgICAgICAgICAgIC4uLmFjYy5jb250cmFjdHMsXG4gICAgICAgICAgICAgIFtmaWxlUGF0aF06IHtcbiAgICAgICAgICAgICAgICBmaWxlUGF0aCxcbiAgICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGVwZW5kZW5jaWVzOiBkZXBlbmRlbmNpZXNPdXQsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAgeyBjb250cmFjdHM6IHt9LCBkZXBlbmRlbmNpZXM6IHt9IH0sXG4gICAgKTtcblxuICBjb25zdCB1bnNvcnRlZENvbnRyYWN0cyA9IE9iamVjdC52YWx1ZXMoY29udHJhY3RzKS5tYXAoKGNvbnRyYWN0KSA9PiB7XG4gICAgY29uc3QgZmlsZVBhdGhEZXBlbmRlbmNpZXMgPSBkZXBlbmRlbmNpZXNbY29udHJhY3QuZmlsZVBhdGhdIGFzIFJlYWRvbmx5QXJyYXk8Q29udHJhY3REZXBlbmRlbmN5PiB8IHVuZGVmaW5lZDtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5jb250cmFjdCxcbiAgICAgIGRlcGVuZGVuY2llczogZmlsZVBhdGhEZXBlbmRlbmNpZXMgPT09IHVuZGVmaW5lZCA/IFtdIDogZmlsZVBhdGhEZXBlbmRlbmNpZXMsXG4gICAgfTtcbiAgfSk7XG5cbiAgcmV0dXJuIHRvcG9ncmFwaGljYWxTb3J0KHVuc29ydGVkQ29udHJhY3RzKTtcbn07XG5cbmNvbnN0IHRvcG9ncmFwaGljYWxTb3J0ID0gKGNvbnRyYWN0czogQ29udHJhY3RzKTogQ29udHJhY3RzID0+IHtcbiAgY29uc3QgY29udHJhY3RUb0RlcGVuZGVuY2llcyA9IGNvbnRyYWN0cy5yZWR1Y2U8eyBbZmlsZVBhdGg6IHN0cmluZ106IFNldDxzdHJpbmc+IH0+KFxuICAgIChhY2MsIGNvbnRyYWN0KSA9PiAoe1xuICAgICAgLi4uYWNjLFxuICAgICAgW2NvbnRyYWN0LmZpbGVQYXRoXTogbmV3IFNldChjb250cmFjdC5kZXBlbmRlbmNpZXMubWFwKChkZXApID0+IGRlcC5maWxlUGF0aCkpLFxuICAgIH0pLFxuICAgIHt9LFxuICApO1xuICBjb25zdCBtdXRhYmxlT3V0OiBDb250cmFjdFtdID0gW107XG4gIGNvbnN0IHNhdGlzZmllZCA9IGNvbnRyYWN0cy5maWx0ZXIoKGNvbnRyYWN0KSA9PiBjb250cmFjdC5kZXBlbmRlbmNpZXMubGVuZ3RoID09PSAwKTtcbiAgbGV0IHJlbWFpbmluZyA9IGNvbnRyYWN0cy5maWx0ZXIoKGNvbnRyYWN0KSA9PiBjb250cmFjdC5kZXBlbmRlbmNpZXMubGVuZ3RoICE9PSAwKTtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3Atc3RhdGVtZW50XG4gIHdoaWxlIChzYXRpc2ZpZWQubGVuZ3RoID4gMCkge1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1hcnJheS1tdXRhdGlvblxuICAgIGNvbnN0IG5vZGUgPSBzYXRpc2ZpZWQuc2hpZnQoKTtcbiAgICBpZiAobm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgbXV0YWJsZU91dC5wdXNoKG5vZGUpO1xuICAgIHJlbWFpbmluZyA9IHJlbWFpbmluZ1xuICAgICAgLm1hcCgoY29udHJhY3QpID0+IHtcbiAgICAgICAgY29uc3QgZGVwcyA9IGNvbnRyYWN0VG9EZXBlbmRlbmNpZXNbY29udHJhY3QuZmlsZVBhdGhdO1xuICAgICAgICBkZXBzLmRlbGV0ZShub2RlLmZpbGVQYXRoKTtcbiAgICAgICAgaWYgKGRlcHMuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1hcnJheS1tdXRhdGlvblxuICAgICAgICAgIHNhdGlzZmllZC5wdXNoKGNvbnRyYWN0KTtcblxuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29udHJhY3Q7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcih1dGlscy5ub3ROdWxsKTtcbiAgfVxuXG4gIGlmIChtdXRhYmxlT3V0Lmxlbmd0aCAhPT0gY29udHJhY3RzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBDaXJjdWxhckxpbmtlZERlcGVuZGVuY3lFcnJvcihjb250cmFjdHMubWFwKChjb250cmFjdCkgPT4gY29udHJhY3QubmFtZSkpO1xuICB9XG5cbiAgcmV0dXJuIG11dGFibGVPdXQ7XG59O1xuXG5leHBvcnQgY29uc3Qgc2NhbiA9IGFzeW5jIChkaXI6IHN0cmluZywgaG9zdDogQ29tcGlsZXJIb3N0KTogUHJvbWlzZTxDb250cmFjdHM+ID0+IHtcbiAgY29uc3QgY29udGV4dCA9IGF3YWl0IGNyZWF0ZUNvbnRleHRGb3JEaXIoZGlyLCBob3N0KTtcblxuICByZXR1cm4gc2NhbkNvbnRleHQoY29udGV4dCk7XG59O1xuIl19