UNPKG

6.63 kBPlain TextView Raw
1// tslint:disable ban-types no-bitwise
2import AST, { SourceFile, Symbol, ts, Identifier } from 'ts-simple-ast';
3
4import path from 'path';
5
6export interface Globals {
7 readonly Array: Symbol;
8 readonly Buffer: Symbol;
9 readonly process: Symbol;
10 readonly AccountBase: Symbol;
11 readonly AssetBase: Symbol;
12 readonly AttributeBase: Symbol;
13 readonly BlockBase: Symbol;
14 readonly ContractBase: Symbol;
15 readonly HeaderBase: Symbol;
16 readonly InputBase: Symbol;
17 readonly OutputBase: Symbol;
18 readonly TransactionBase: Symbol;
19 readonly ValidatorBase: Symbol;
20 readonly StorageContextBase: Symbol;
21 readonly StorageIteratorBase: Symbol;
22 readonly syscall: Symbol;
23}
24
25const findInterfaceFile = (ast: AST, name: string): SourceFile | undefined => {
26 const files = ast.getSourceFiles();
27 return files.find((file) => {
28 if (!file.isDeclarationFile()) {
29 return false;
30 }
31
32 let bufferInterface = file.getInterface(name);
33 const globalNamespace = file.getNamespace('global');
34 let isGlobalAugmentation = false;
35 if (bufferInterface == null && globalNamespace != null) {
36 bufferInterface = globalNamespace.getInterface(name);
37 isGlobalAugmentation = true;
38 }
39
40 if (bufferInterface == null) {
41 return false;
42 }
43
44 return (
45 isGlobalAugmentation ||
46 (bufferInterface.compilerNode.flags & ts.NodeFlags.GlobalAugmentation) !==
47 0
48 );
49 });
50};
51
52export const getGlobals = (ast: AST): Globals => {
53 let bufferFile = findInterfaceFile(ast, 'Buffer');
54 if (bufferFile == null) {
55 bufferFile = ast.addExistingSourceFileIfExists(
56 require.resolve('@types/node/index.d.ts'),
57 );
58 }
59 if (bufferFile == null) {
60 throw new Error('Could not find Buffer');
61 }
62 const buffer = bufferFile.getInterfaceOrThrow('Buffer');
63
64 const typeChecker = ast.getTypeChecker().compilerObject as any;
65 // @ts-ignore
66 const array = new Symbol(
67 // @ts-ignore
68 ast.global,
69 typeChecker.createArrayType(typeChecker.getAnyType()).symbol as ts.Symbol,
70 ).getDeclaredType();
71
72 let neoFile = findInterfaceFile(ast, 'AccountBase');
73 if (neoFile == null) {
74 ast.addExistingSourceFiles(
75 path.join(
76 path.dirname(require.resolve('@neo-one/smart-contract')),
77 '**',
78 '*.ts',
79 ),
80 );
81 }
82
83 neoFile = findInterfaceFile(ast, 'AccountBase');
84 if (neoFile == null) {
85 throw new Error('Could not find NEO type definition file');
86 }
87
88 const neoGlobal = neoFile.getNamespaceOrThrow('global');
89
90 return {
91 Array: array.getSymbolOrThrow(),
92 Buffer: buffer.getSymbolOrThrow(),
93 process: bufferFile
94 .getVariableDeclarationOrThrow('process')
95 .getSymbolOrThrow(),
96 AccountBase: neoGlobal
97 .getInterfaceOrThrow('AccountBase')
98 .getSymbolOrThrow(),
99 AssetBase: neoGlobal.getInterfaceOrThrow('AssetBase').getSymbolOrThrow(),
100 AttributeBase: neoGlobal
101 .getInterfaceOrThrow('AttributeBase')
102 .getSymbolOrThrow(),
103 BlockBase: neoGlobal.getInterfaceOrThrow('BlockBase').getSymbolOrThrow(),
104 ContractBase: neoGlobal
105 .getInterfaceOrThrow('ContractBase')
106 .getSymbolOrThrow(),
107 HeaderBase: neoGlobal.getInterfaceOrThrow('HeaderBase').getSymbolOrThrow(),
108 InputBase: neoGlobal.getInterfaceOrThrow('InputBase').getSymbolOrThrow(),
109 OutputBase: neoGlobal.getInterfaceOrThrow('OutputBase').getSymbolOrThrow(),
110 TransactionBase: neoGlobal
111 .getInterfaceOrThrow('TransactionBase')
112 .getSymbolOrThrow(),
113 ValidatorBase: neoGlobal
114 .getInterfaceOrThrow('ValidatorBase')
115 .getSymbolOrThrow(),
116 StorageContextBase: neoGlobal
117 .getInterfaceOrThrow('StorageContextBase')
118 .getSymbolOrThrow(),
119 StorageIteratorBase: neoGlobal
120 .getInterfaceOrThrow('StorageIteratorBase')
121 .getSymbolOrThrow(),
122 syscall: neoGlobal.getFunctionOrThrow('syscall').getSymbolOrThrow(),
123 };
124};
125
126export interface Libs {
127 readonly SmartContract: Symbol;
128 readonly MapStorage: Symbol;
129 readonly SetStorage: Symbol;
130 readonly Fixed: Symbol;
131 readonly constant: Symbol;
132 readonly verify: Symbol;
133}
134
135const findLibFile = (ast: AST): SourceFile | undefined => {
136 const files = ast.getSourceFiles();
137 return files.find((file) => file.getClass('MapStorage') != null);
138};
139
140export const getLibs = (ast: AST): Libs => {
141 let libFileIn = findLibFile(ast);
142 if (libFileIn == null) {
143 ast.addExistingSourceFiles(
144 path.join(
145 path.dirname(require.resolve('@neo-one/smart-contract')),
146 '**',
147 '*.ts',
148 ),
149 );
150 }
151
152 libFileIn = findLibFile(ast);
153 if (libFileIn == null) {
154 throw new Error('Could not find NEO lib file');
155 }
156
157 const libFile = libFileIn;
158
159 return {
160 get SmartContract(): Symbol {
161 return libFile.getClassOrThrow('SmartContract').getSymbolOrThrow();
162 },
163 get MapStorage(): Symbol {
164 return libFile.getClassOrThrow('MapStorage').getSymbolOrThrow();
165 },
166 get SetStorage(): Symbol {
167 return libFile.getClassOrThrow('SetStorage').getSymbolOrThrow();
168 },
169 get Fixed(): Symbol {
170 return libFile.getTypeAliasOrThrow('Fixed').getSymbolOrThrow();
171 },
172 get constant(): Symbol {
173 return libFile.getFunctionOrThrow('constant').getSymbolOrThrow();
174 },
175 get verify(): Symbol {
176 return libFile.getFunctionOrThrow('verify').getSymbolOrThrow();
177 },
178 };
179};
180
181export interface LibAliases {
182 readonly Address: Set<Identifier>;
183 readonly Hash256: Set<Identifier>;
184 readonly Signature: Set<Identifier>;
185 readonly PublicKey: Set<Identifier>;
186}
187
188export const getLibAliases = (ast: AST): LibAliases => {
189 let libFileIn = findLibFile(ast);
190 if (libFileIn == null) {
191 ast.addExistingSourceFiles(
192 path.join(
193 path.dirname(require.resolve('@neo-one/smart-contract')),
194 '**',
195 '*.ts',
196 ),
197 );
198 }
199
200 libFileIn = findLibFile(ast);
201 if (libFileIn == null) {
202 throw new Error('Could not find NEO lib file');
203 }
204
205 const libFile = libFileIn;
206
207 return {
208 get Address(): Set<Identifier> {
209 return new Set(libFile
210 .getTypeAliasOrThrow('Address')
211 .getReferencingNodes() as Identifier[]);
212 },
213 get Hash256(): Set<Identifier> {
214 return new Set(libFile
215 .getTypeAliasOrThrow('Hash256')
216 .getReferencingNodes() as Identifier[]);
217 },
218 get Signature(): Set<Identifier> {
219 return new Set(libFile
220 .getTypeAliasOrThrow('Signature')
221 .getReferencingNodes() as Identifier[]);
222 },
223 get PublicKey(): Set<Identifier> {
224 return new Set(libFile
225 .getTypeAliasOrThrow('PublicKey')
226 .getReferencingNodes() as Identifier[]);
227 },
228 };
229};