@neo-one/smart-contract-compiler
Version:
NEO•ONE TypeScript smart contract compiler.
122 lines (120 loc) • 5.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSmartContractInfo = void 0;
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 constants_1 = require("../constants");
const contract_1 = require("../contract");
const DiagnosticCode_1 = require("../DiagnosticCode");
const DiagnosticMessage_1 = require("../DiagnosticMessage");
const builtins_1 = require("./builtins");
const PARAMETERS = ['String', 'Array'];
const RETURN_TYPE = 'Buffer';
const getSmartContract = (context, sourceFile) => {
const classDecls = ts_utils_1.tsUtils.statement
.getStatements(sourceFile)
.filter(typescript_1.default.isClassDeclaration)
.filter((decl) => ts_utils_1.tsUtils.modifier.isNamedExport(decl))
.filter((decl) => context.analysis.isSmartContract(decl));
if (classDecls.length === 0) {
return undefined;
}
if (classDecls.length === 1) {
return classDecls[0];
}
context.reportError(classDecls[1], DiagnosticCode_1.DiagnosticCode.InvalidContract, DiagnosticMessage_1.DiagnosticMessage.InvalidContractMultipleInFile);
return classDecls[0];
};
const addOverrideSymbol = (context, contractInfo, overrideSymbol) => {
const superSymbol = context.analysis.getSymbol(contractInfo.smartContract);
if (superSymbol === undefined) {
return;
}
if (overrideSymbol !== undefined) {
context.builtins.addOverride(superSymbol, overrideSymbol);
}
const superSmartContract = contractInfo.superSmartContract;
if (superSmartContract !== undefined) {
addOverrideSymbol(context, superSmartContract, superSymbol);
}
};
const addContractInfo = (context, contractInfo) => {
const propertyNameToOverride = new Map();
contract_1.getAllPropInfos(contractInfo).forEach((propInfo) => {
const symbol = context.analysis.getSymbol(propInfo.classDecl);
if (symbol !== undefined &&
propInfo.type !== 'deploy' &&
propInfo.type !== 'refundAssets' &&
propInfo.type !== 'upgrade' &&
propInfo.type !== 'completeSend') {
const memberSymbol = propInfo.symbol;
switch (propInfo.type) {
case 'function':
if (typescript_1.default.isPropertyDeclaration(propInfo.decl)) {
context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberCallableProperty(propInfo.decl));
}
else {
context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberMethod(propInfo.decl));
}
break;
case 'accessor':
context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberAccessor(propInfo.getter === undefined ? undefined : propInfo.getter.decl, propInfo.setter === undefined ? undefined : propInfo.setter.decl));
break;
case 'property':
if (propInfo.structuredStorageType === undefined) {
context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberStorageProperty(propInfo.name));
}
else {
context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberStructuredStorageProperty(propInfo.structuredStorageType, propInfo.name));
}
break;
default:
utils_1.utils.assertNever(propInfo);
throw new Error('For TS');
}
const memberName = ts_utils_1.tsUtils.symbol.getName(memberSymbol);
const overrideSymbol = propertyNameToOverride.get(memberName);
if (overrideSymbol === undefined) {
propertyNameToOverride.set(memberName, memberSymbol);
}
else {
context.builtins.addOverride(memberSymbol, overrideSymbol);
}
}
});
addOverrideSymbol(context, contractInfo);
};
exports.getSmartContractInfo = (context, sourceFile) => {
const smartContract = getSmartContract(context, sourceFile);
const contractInfo = smartContract === undefined ? undefined : contract_1.getContractInfo(context, smartContract);
const properties = smartContract === undefined ? constants_1.DEFAULT_CONTRACT_PROPERTIES : contract_1.getContractProperties(context, smartContract);
const payable = contractInfo === undefined
? true
: contractInfo.propInfos.some((propInfo) => propInfo.type === 'function' && propInfo.receive);
if (contractInfo !== undefined) {
addContractInfo(context, contractInfo);
return {
contractInfo,
abi: contract_1.getABI(context, contractInfo),
debugInfo: contract_1.getDebugInfo(context, contractInfo),
contract: Object.assign(Object.assign({ parameters: PARAMETERS, returnType: RETURN_TYPE }, properties), { storage: true, dynamicInvoke: true, payable }),
};
}
return {
contractInfo,
abi: {
functions: [],
events: [],
},
debugInfo: {
entrypoint: '',
documents: [],
methods: [],
events: [],
},
contract: Object.assign(Object.assign({ parameters: PARAMETERS, returnType: RETURN_TYPE }, properties), { storage: true, dynamicInvoke: true, payable }),
};
};
//# sourceMappingURL=getSmartContractInfo.js.map