1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const ts_utils_1 = require("@neo-one/ts-utils");
|
5 | const utils_1 = require("@neo-one/utils");
|
6 | const typescript_1 = tslib_1.__importDefault(require("typescript"));
|
7 | const constants_1 = require("../constants");
|
8 | const contract_1 = require("../contract");
|
9 | const DiagnosticCode_1 = require("../DiagnosticCode");
|
10 | const DiagnosticMessage_1 = require("../DiagnosticMessage");
|
11 | const builtins_1 = require("./builtins");
|
12 | const PARAMETERS = ['String', 'Array'];
|
13 | const RETURN_TYPE = 'Buffer';
|
14 | const getSmartContract = (context, sourceFile) => {
|
15 | const classDecls = ts_utils_1.tsUtils.statement
|
16 | .getStatements(sourceFile)
|
17 | .filter(typescript_1.default.isClassDeclaration)
|
18 | .filter((decl) => ts_utils_1.tsUtils.modifier.isNamedExport(decl))
|
19 | .filter((decl) => context.analysis.isSmartContract(decl));
|
20 | if (classDecls.length === 0) {
|
21 | return undefined;
|
22 | }
|
23 | if (classDecls.length === 1) {
|
24 | return classDecls[0];
|
25 | }
|
26 | context.reportError(classDecls[1], DiagnosticCode_1.DiagnosticCode.InvalidContract, DiagnosticMessage_1.DiagnosticMessage.InvalidContractMultipleInFile);
|
27 | return classDecls[0];
|
28 | };
|
29 | const addOverrideSymbol = (context, contractInfo, overrideSymbol) => {
|
30 | const superSymbol = context.analysis.getSymbol(contractInfo.smartContract);
|
31 | if (superSymbol === undefined) {
|
32 | return;
|
33 | }
|
34 | if (overrideSymbol !== undefined) {
|
35 | context.builtins.addOverride(superSymbol, overrideSymbol);
|
36 | }
|
37 | const superSmartContract = contractInfo.superSmartContract;
|
38 | if (superSmartContract !== undefined) {
|
39 | addOverrideSymbol(context, superSmartContract, superSymbol);
|
40 | }
|
41 | };
|
42 | const addContractInfo = (context, contractInfo) => {
|
43 | const propertyNameToOverride = new Map();
|
44 | contract_1.getAllPropInfos(contractInfo).forEach((propInfo) => {
|
45 | const symbol = context.analysis.getSymbol(propInfo.classDecl);
|
46 | if (symbol !== undefined &&
|
47 | propInfo.type !== 'deploy' &&
|
48 | propInfo.type !== 'refundAssets' &&
|
49 | propInfo.type !== 'upgrade' &&
|
50 | propInfo.type !== 'completeSend') {
|
51 | const memberSymbol = propInfo.symbol;
|
52 | switch (propInfo.type) {
|
53 | case 'function':
|
54 | if (typescript_1.default.isPropertyDeclaration(propInfo.decl)) {
|
55 | context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberCallableProperty(propInfo.decl));
|
56 | }
|
57 | else {
|
58 | context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberMethod(propInfo.decl));
|
59 | }
|
60 | break;
|
61 | case 'accessor':
|
62 | context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberAccessor(propInfo.getter === undefined ? undefined : propInfo.getter.decl, propInfo.setter === undefined ? undefined : propInfo.setter.decl));
|
63 | break;
|
64 | case 'property':
|
65 | if (propInfo.structuredStorageType === undefined) {
|
66 | context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberStorageProperty(propInfo.name));
|
67 | }
|
68 | else {
|
69 | context.builtins.addMember(symbol, memberSymbol, new builtins_1.BuiltinInstanceMemberStructuredStorageProperty(propInfo.structuredStorageType, propInfo.name));
|
70 | }
|
71 | break;
|
72 | default:
|
73 | utils_1.utils.assertNever(propInfo);
|
74 | throw new Error('For TS');
|
75 | }
|
76 | const memberName = ts_utils_1.tsUtils.symbol.getName(memberSymbol);
|
77 | const overrideSymbol = propertyNameToOverride.get(memberName);
|
78 | if (overrideSymbol === undefined) {
|
79 | propertyNameToOverride.set(memberName, memberSymbol);
|
80 | }
|
81 | else {
|
82 | context.builtins.addOverride(memberSymbol, overrideSymbol);
|
83 | }
|
84 | }
|
85 | });
|
86 | addOverrideSymbol(context, contractInfo);
|
87 | };
|
88 | exports.getSmartContractInfo = (context, sourceFile) => {
|
89 | const smartContract = getSmartContract(context, sourceFile);
|
90 | const contractInfo = smartContract === undefined ? undefined : contract_1.getContractInfo(context, smartContract);
|
91 | const properties = smartContract === undefined ? constants_1.DEFAULT_CONTRACT_PROPERTIES : contract_1.getContractProperties(context, smartContract);
|
92 | const payable = contractInfo === undefined
|
93 | ? true
|
94 | : contractInfo.propInfos.some((propInfo) => propInfo.type === 'function' && propInfo.receive);
|
95 | if (contractInfo !== undefined) {
|
96 | addContractInfo(context, contractInfo);
|
97 | return {
|
98 | contractInfo,
|
99 | abi: contract_1.getABI(context, contractInfo),
|
100 | contract: Object.assign(Object.assign({ parameters: PARAMETERS, returnType: RETURN_TYPE }, properties), { storage: true, dynamicInvoke: true, payable }),
|
101 | };
|
102 | }
|
103 | return {
|
104 | contractInfo,
|
105 | abi: {
|
106 | functions: [],
|
107 | events: [],
|
108 | },
|
109 | contract: Object.assign(Object.assign({ parameters: PARAMETERS, returnType: RETURN_TYPE }, properties), { storage: true, dynamicInvoke: true, payable }),
|
110 | };
|
111 | };
|
112 |
|
113 |
|