@openzeppelin/upgrades-core 1.34.4 → 1.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/utils/make-namespaced.d.ts +2 -1
- package/dist/utils/make-namespaced.d.ts.map +1 -1
- package/dist/utils/make-namespaced.js +65 -3
- package/dist/utils/make-namespaced.js.map +1 -1
- package/dist/utils/make-namespaced.test.js +7 -2
- package/dist/utils/make-namespaced.test.js.map +1 -1
- package/dist/utils/slang/trivia.d.ts +9 -0
- package/dist/utils/slang/trivia.d.ts.map +1 -0
- package/dist/utils/slang/trivia.js +23 -0
- package/dist/utils/slang/trivia.js.map +1 -0
- package/package.json +2 -1
- package/src/utils/make-namespaced.test.ts +12 -1
- package/src/utils/make-namespaced.test.ts.md +277 -14
- package/src/utils/make-namespaced.test.ts.snap +0 -0
- package/src/utils/make-namespaced.ts +75 -3
- package/src/utils/slang/trivia.ts +23 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.35.0 (2024-07-31)
|
|
4
|
+
|
|
5
|
+
- Fix Hardhat compile error when public variables are used to implement interface functions. ([#1055](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1055))
|
|
6
|
+
- Remove non-struct NatSpec from Hardhat compilation step for namespaced storage layout validations. ([#1051](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1051))
|
|
7
|
+
|
|
3
8
|
## 1.34.4 (2024-07-22)
|
|
4
9
|
|
|
5
10
|
- Fix Hardhat compile error when return parameter names are documented as param. ([#1050](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1050))
|
|
@@ -13,7 +13,8 @@ import { SolcInput, SolcOutput } from '../solc-api';
|
|
|
13
13
|
*
|
|
14
14
|
* @param input The original solc input.
|
|
15
15
|
* @param output The original solc output.
|
|
16
|
+
* @param solcVersion The version of the solc compiler that was originally used to compile the input.
|
|
16
17
|
* @returns The modified solc input with storage layout that includes namespaced type information.
|
|
17
18
|
*/
|
|
18
|
-
export declare function makeNamespacedInput(input: SolcInput, output: SolcOutput): SolcInput;
|
|
19
|
+
export declare function makeNamespacedInput(input: SolcInput, output: SolcOutput, solcVersion?: string): SolcInput;
|
|
19
20
|
//# sourceMappingURL=make-namespaced.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"make-namespaced.d.ts","sourceRoot":"","sources":["../../src/utils/make-namespaced.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAYpD
|
|
1
|
+
{"version":3,"file":"make-namespaced.d.ts","sourceRoot":"","sources":["../../src/utils/make-namespaced.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAYpD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAgIzG"}
|
|
@@ -24,9 +24,10 @@ const OUTPUT_SELECTION = {
|
|
|
24
24
|
*
|
|
25
25
|
* @param input The original solc input.
|
|
26
26
|
* @param output The original solc output.
|
|
27
|
+
* @param solcVersion The version of the solc compiler that was originally used to compile the input.
|
|
27
28
|
* @returns The modified solc input with storage layout that includes namespaced type information.
|
|
28
29
|
*/
|
|
29
|
-
function makeNamespacedInput(input, output) {
|
|
30
|
+
function makeNamespacedInput(input, output, solcVersion) {
|
|
30
31
|
const modifiedSources = {};
|
|
31
32
|
for (const [sourcePath] of Object.entries(input.sources)) {
|
|
32
33
|
const source = input.sources[sourcePath];
|
|
@@ -40,6 +41,11 @@ function makeNamespacedInput(input, output) {
|
|
|
40
41
|
switch (node.nodeType) {
|
|
41
42
|
case 'ContractDefinition': {
|
|
42
43
|
const contractDef = node;
|
|
44
|
+
// Mark contracts as abstract, since state variables are converted to dummy enums
|
|
45
|
+
// which would not generate public getters for inherited interface functions
|
|
46
|
+
if (contractDef.contractKind === 'contract' && !contractDef.abstract) {
|
|
47
|
+
modifications.push(makeInsertBefore(contractDef, 'abstract '));
|
|
48
|
+
}
|
|
43
49
|
// Remove any calls to parent constructors from the inheritance list
|
|
44
50
|
const inherits = contractDef.baseContracts;
|
|
45
51
|
for (const inherit of inherits) {
|
|
@@ -131,10 +137,59 @@ function makeNamespacedInput(input, output) {
|
|
|
131
137
|
}
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
|
-
|
|
140
|
+
const modifiedSource = tryRemoveNonStructNatSpec(getModifiedSource(orig, modifications), solcVersion);
|
|
141
|
+
modifiedSources[sourcePath] = { ...source, content: modifiedSource };
|
|
135
142
|
}
|
|
136
143
|
return { ...input, sources: modifiedSources, settings: { ...input.settings, outputSelection: OUTPUT_SELECTION } };
|
|
137
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* If Slang is supported for the current platform and we have the compiler version available,
|
|
147
|
+
* use Slang to parse and remove all NatSpec comments that do not precede a struct definition and return the modified content.
|
|
148
|
+
*
|
|
149
|
+
* Otherwise, return the original content.
|
|
150
|
+
*/
|
|
151
|
+
function tryRemoveNonStructNatSpec(origContent, solcVersion) {
|
|
152
|
+
const natSpecRemovals = [];
|
|
153
|
+
if (solcVersion !== undefined && tryRequire('@nomicfoundation/slang')) {
|
|
154
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
155
|
+
const { Language } = require('@nomicfoundation/slang/language');
|
|
156
|
+
const { NonterminalKind, TerminalKind } = require('@nomicfoundation/slang/kinds');
|
|
157
|
+
const { TerminalNode } = require('@nomicfoundation/slang/cst');
|
|
158
|
+
const { isTrivia } = require('./slang/trivia');
|
|
159
|
+
/* eslint-enable @typescript-eslint/no-var-requires */
|
|
160
|
+
const language = new Language(solcVersion);
|
|
161
|
+
const parseOutput = language.parse(NonterminalKind.SourceUnit, origContent);
|
|
162
|
+
const cursor = parseOutput.createTreeCursor();
|
|
163
|
+
while (cursor.goToNextTerminalWithKinds([TerminalKind.MultiLineNatSpecComment, TerminalKind.SingleLineNatSpecComment])) {
|
|
164
|
+
// Lookahead to determine if the next non-trivia node is the struct keyword.
|
|
165
|
+
// If so, this NatSpec is part of the struct definition and should not be removed.
|
|
166
|
+
const lookaheadCursor = cursor.clone();
|
|
167
|
+
while (lookaheadCursor.goToNextTerminal() && isTrivia(lookaheadCursor.node())) {
|
|
168
|
+
// skip over trivia nodes
|
|
169
|
+
}
|
|
170
|
+
if (lookaheadCursor.node().kind === TerminalKind.StructKeyword) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const triviaNode = cursor.node();
|
|
174
|
+
(0, assert_1.assert)(triviaNode instanceof TerminalNode);
|
|
175
|
+
natSpecRemovals.push(makeDeleteRange(cursor.textRange.start.utf8, cursor.textRange.end.utf8));
|
|
176
|
+
}
|
|
177
|
+
return getModifiedSource(Buffer.from(origContent, 'utf8'), natSpecRemovals);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
return origContent;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function tryRequire(id) {
|
|
184
|
+
try {
|
|
185
|
+
require(id);
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
// do nothing
|
|
190
|
+
}
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
138
193
|
function toDummyEnumWithName(name) {
|
|
139
194
|
return `enum ${name} { dummy }`;
|
|
140
195
|
}
|
|
@@ -177,6 +232,10 @@ function makeReplace(node, orig, text) {
|
|
|
177
232
|
const { start, end } = makeDelete(node, orig);
|
|
178
233
|
return { start, end, text };
|
|
179
234
|
}
|
|
235
|
+
function makeInsertBefore(node, text) {
|
|
236
|
+
const { start } = getPositions(node);
|
|
237
|
+
return { start: start, end: start, text };
|
|
238
|
+
}
|
|
180
239
|
function makeInsertAfter(node, text) {
|
|
181
240
|
const { end } = getPositions(node);
|
|
182
241
|
return { start: end, end, text };
|
|
@@ -193,7 +252,10 @@ function makeDelete(node, orig) {
|
|
|
193
252
|
end += 1;
|
|
194
253
|
}
|
|
195
254
|
}
|
|
196
|
-
return
|
|
255
|
+
return makeDeleteRange(positions.start, end);
|
|
256
|
+
}
|
|
257
|
+
function makeDeleteRange(start, end) {
|
|
258
|
+
return { start, end };
|
|
197
259
|
}
|
|
198
260
|
function getModifiedSource(orig, modifications) {
|
|
199
261
|
let result = '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"make-namespaced.js","sourceRoot":"","sources":["../../src/utils/make-namespaced.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"make-namespaced.js","sourceRoot":"","sources":["../../src/utils/make-namespaced.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,18 +11,22 @@ const make_namespaced_1 = require("./make-namespaced");
|
|
|
11
11
|
const origBuildInfo = await hardhat_1.artifacts.getBuildInfo('contracts/test/NamespacedToModifyImported.sol:Example');
|
|
12
12
|
await testMakeNamespaced(origBuildInfo, t, '0.8.20');
|
|
13
13
|
});
|
|
14
|
+
(0, ava_1.default)('make namespaced input - keep all natspec', async (t) => {
|
|
15
|
+
const origBuildInfo = await hardhat_1.artifacts.getBuildInfo('contracts/test/NamespacedToModifyImported.sol:Example');
|
|
16
|
+
await testMakeNamespaced(origBuildInfo, t, '0.8.20', true);
|
|
17
|
+
});
|
|
14
18
|
(0, ava_1.default)('make namespaced input - solc 0.7', async (t) => {
|
|
15
19
|
// The nameNamespacedInput function must work for different solc versions, since it is called before we check whether namespaces are used with solc >= 0.8.20
|
|
16
20
|
const origBuildInfo = await hardhat_1.artifacts.getBuildInfo('contracts/test/NamespacedToModify07.sol:HasFunction');
|
|
17
21
|
await testMakeNamespaced(origBuildInfo, t, '0.7.6');
|
|
18
22
|
});
|
|
19
|
-
async function testMakeNamespaced(origBuildInfo, t, solcVersion) {
|
|
23
|
+
async function testMakeNamespaced(origBuildInfo, t, solcVersion, keepAllNatSpec = false) {
|
|
20
24
|
if (origBuildInfo === undefined) {
|
|
21
25
|
throw new Error('Build info not found');
|
|
22
26
|
}
|
|
23
27
|
// Inefficient, but we want to test that we don't actually modify the original input object
|
|
24
28
|
const origInput = JSON.parse(JSON.stringify(origBuildInfo.input));
|
|
25
|
-
const modifiedInput = (0, make_namespaced_1.makeNamespacedInput)(origBuildInfo.input, origBuildInfo.output);
|
|
29
|
+
const modifiedInput = (0, make_namespaced_1.makeNamespacedInput)(origBuildInfo.input, origBuildInfo.output, keepAllNatSpec ? undefined : origBuildInfo.solcVersion);
|
|
26
30
|
// Run hardhat compile on the modified input and make sure it has no errors
|
|
27
31
|
const modifiedOutput = await hardhatCompile(modifiedInput, solcVersion);
|
|
28
32
|
t.is(modifiedOutput.errors, undefined, JSON.stringify(modifiedInput.sources, null, 2));
|
|
@@ -37,6 +41,7 @@ function normalizeIdentifiers(input) {
|
|
|
37
41
|
source.content = source.content
|
|
38
42
|
.replace(/\$MainStorage_\d{1,6}/g, '$MainStorage_random')
|
|
39
43
|
.replace(/\$SecondaryStorage_\d{1,6}/g, '$SecondaryStorage_random')
|
|
44
|
+
.replace(/\$StorageWithComment_\d{1,6}/g, '$StorageWithComment_random')
|
|
40
45
|
.replace(/\$astId_\d+_\d{1,6}/g, '$astId_id_random');
|
|
41
46
|
}
|
|
42
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"make-namespaced.test.js","sourceRoot":"","sources":["../../src/utils/make-namespaced.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAA6C;AAC7C,qCAAyC;AACzC,iEAI0C;AAE1C,uDAAwD;AAKxD,IAAA,aAAI,EAAC,uBAAuB,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IACtC,MAAM,aAAa,GAAG,MAAM,mBAAS,CAAC,YAAY,CAAC,uDAAuD,CAAC,CAAC;IAC5G,MAAM,kBAAkB,CAAC,aAAa,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,kCAAkC,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IACjD,6JAA6J;IAC7J,MAAM,aAAa,GAAG,MAAM,mBAAS,CAAC,YAAY,CAAC,qDAAqD,CAAC,CAAC;IAC1G,MAAM,kBAAkB,CAAC,aAAa,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,kBAAkB,CAC/B,aAAoC,EACpC,CAA4B,EAC5B,WAAmB;
|
|
1
|
+
{"version":3,"file":"make-namespaced.test.js","sourceRoot":"","sources":["../../src/utils/make-namespaced.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Node } from '@nomicfoundation/slang/cst';
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if the node is a trivia terminal (whitespace or comment or NatSpec)
|
|
4
|
+
*
|
|
5
|
+
* CAUTION: This must be imported dynamically.
|
|
6
|
+
* Only import this file if Slang is supported on the current platform, otherwise an error will be thrown on import.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isTrivia(node: Node): boolean;
|
|
9
|
+
//# sourceMappingURL=trivia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trivia.d.ts","sourceRoot":"","sources":["../../../src/utils/slang/trivia.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAgB,MAAM,4BAA4B,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,WAElC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isTrivia = isTrivia;
|
|
4
|
+
const kinds_1 = require("@nomicfoundation/slang/kinds");
|
|
5
|
+
const cst_1 = require("@nomicfoundation/slang/cst");
|
|
6
|
+
/**
|
|
7
|
+
* Returns true if the node is a trivia terminal (whitespace or comment or NatSpec)
|
|
8
|
+
*
|
|
9
|
+
* CAUTION: This must be imported dynamically.
|
|
10
|
+
* Only import this file if Slang is supported on the current platform, otherwise an error will be thrown on import.
|
|
11
|
+
*/
|
|
12
|
+
function isTrivia(node) {
|
|
13
|
+
return node instanceof cst_1.TerminalNode && isTriviaKind(node.kind);
|
|
14
|
+
}
|
|
15
|
+
function isTriviaKind(kind) {
|
|
16
|
+
return (kind === kinds_1.TerminalKind.EndOfLine ||
|
|
17
|
+
kind === kinds_1.TerminalKind.MultiLineComment ||
|
|
18
|
+
kind === kinds_1.TerminalKind.MultiLineNatSpecComment ||
|
|
19
|
+
kind === kinds_1.TerminalKind.SingleLineComment ||
|
|
20
|
+
kind === kinds_1.TerminalKind.SingleLineNatSpecComment ||
|
|
21
|
+
kind === kinds_1.TerminalKind.Whitespace);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=trivia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trivia.js","sourceRoot":"","sources":["../../../src/utils/slang/trivia.ts"],"names":[],"mappings":";;AASA,4BAEC;AAXD,wDAA4D;AAC5D,oDAAgE;AAEhE;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,IAAU;IACjC,OAAO,IAAI,YAAY,kBAAY,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,YAAY,CAAC,IAAkB;IACtC,OAAO,CACL,IAAI,KAAK,oBAAY,CAAC,SAAS;QAC/B,IAAI,KAAK,oBAAY,CAAC,gBAAgB;QACtC,IAAI,KAAK,oBAAY,CAAC,uBAAuB;QAC7C,IAAI,KAAK,oBAAY,CAAC,iBAAiB;QACvC,IAAI,KAAK,oBAAY,CAAC,wBAAwB;QAC9C,IAAI,KAAK,oBAAY,CAAC,UAAU,CACjC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openzeppelin/upgrades-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.35.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades/tree/master/packages/core",
|
|
6
6
|
"license": "MIT",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"typescript": "^5.0.0"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
+
"@nomicfoundation/slang": "^0.15.1",
|
|
64
65
|
"cbor": "^9.0.0",
|
|
65
66
|
"chalk": "^4.1.0",
|
|
66
67
|
"compare-versions": "^6.0.0",
|
|
@@ -16,6 +16,11 @@ test('make namespaced input', async t => {
|
|
|
16
16
|
await testMakeNamespaced(origBuildInfo, t, '0.8.20');
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
test('make namespaced input - keep all natspec', async t => {
|
|
20
|
+
const origBuildInfo = await artifacts.getBuildInfo('contracts/test/NamespacedToModifyImported.sol:Example');
|
|
21
|
+
await testMakeNamespaced(origBuildInfo, t, '0.8.20', true);
|
|
22
|
+
});
|
|
23
|
+
|
|
19
24
|
test('make namespaced input - solc 0.7', async t => {
|
|
20
25
|
// The nameNamespacedInput function must work for different solc versions, since it is called before we check whether namespaces are used with solc >= 0.8.20
|
|
21
26
|
const origBuildInfo = await artifacts.getBuildInfo('contracts/test/NamespacedToModify07.sol:HasFunction');
|
|
@@ -26,6 +31,7 @@ async function testMakeNamespaced(
|
|
|
26
31
|
origBuildInfo: BuildInfo | undefined,
|
|
27
32
|
t: ExecutionContext<unknown>,
|
|
28
33
|
solcVersion: string,
|
|
34
|
+
keepAllNatSpec = false,
|
|
29
35
|
) {
|
|
30
36
|
if (origBuildInfo === undefined) {
|
|
31
37
|
throw new Error('Build info not found');
|
|
@@ -34,7 +40,11 @@ async function testMakeNamespaced(
|
|
|
34
40
|
// Inefficient, but we want to test that we don't actually modify the original input object
|
|
35
41
|
const origInput = JSON.parse(JSON.stringify(origBuildInfo.input));
|
|
36
42
|
|
|
37
|
-
const modifiedInput = makeNamespacedInput(
|
|
43
|
+
const modifiedInput = makeNamespacedInput(
|
|
44
|
+
origBuildInfo.input,
|
|
45
|
+
origBuildInfo.output,
|
|
46
|
+
keepAllNatSpec ? undefined : origBuildInfo.solcVersion,
|
|
47
|
+
);
|
|
38
48
|
|
|
39
49
|
// Run hardhat compile on the modified input and make sure it has no errors
|
|
40
50
|
const modifiedOutput = await hardhatCompile(modifiedInput, solcVersion);
|
|
@@ -53,6 +63,7 @@ function normalizeIdentifiers(input: SolcInput): void {
|
|
|
53
63
|
source.content = source.content
|
|
54
64
|
.replace(/\$MainStorage_\d{1,6}/g, '$MainStorage_random')
|
|
55
65
|
.replace(/\$SecondaryStorage_\d{1,6}/g, '$SecondaryStorage_random')
|
|
66
|
+
.replace(/\$StorageWithComment_\d{1,6}/g, '$StorageWithComment_random')
|
|
56
67
|
.replace(/\$astId_\d+_\d{1,6}/g, '$astId_id_random');
|
|
57
68
|
}
|
|
58
69
|
}
|
|
@@ -32,7 +32,7 @@ Generated by [AVA](https://avajs.dev).
|
|
|
32
32
|
content: `// SPDX-License-Identifier: MIT␊
|
|
33
33
|
pragma solidity ^0.8.20;␊
|
|
34
34
|
␊
|
|
35
|
-
contract Example {␊
|
|
35
|
+
abstract contract Example {␊
|
|
36
36
|
/// @custom:storage-location erc7201:example.main␊
|
|
37
37
|
struct MainStorage {␊
|
|
38
38
|
uint256 x;␊
|
|
@@ -44,6 +44,251 @@ Generated by [AVA](https://avajs.dev).
|
|
|
44
44
|
uint256 a;␊
|
|
45
45
|
uint256 b;␊
|
|
46
46
|
} SecondaryStorage $SecondaryStorage_random;␊
|
|
47
|
+
␊
|
|
48
|
+
/// @custom:storage-location erc7201:example.with.following.comment␊
|
|
49
|
+
// some comment␊
|
|
50
|
+
struct StorageWithComment {␊
|
|
51
|
+
uint256 a;␊
|
|
52
|
+
uint256 b;␊
|
|
53
|
+
} StorageWithComment $StorageWithComment_random;␊
|
|
54
|
+
␊
|
|
55
|
+
␊
|
|
56
|
+
function foo() public {}␊
|
|
57
|
+
␊
|
|
58
|
+
␊
|
|
59
|
+
function foo1(uint a) public {}␊
|
|
60
|
+
␊
|
|
61
|
+
␊
|
|
62
|
+
function foo2(uint a) internal {}␊
|
|
63
|
+
struct MyStruct { uint b; }␊
|
|
64
|
+
␊
|
|
65
|
+
// keccak256(abi.encode(uint256(keccak256("example.main")) - 1)) & ~bytes32(uint256(0xff));␊
|
|
66
|
+
bytes32 private constant MAIN_STORAGE_LOCATION =␊
|
|
67
|
+
0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500;␊
|
|
68
|
+
␊
|
|
69
|
+
function _getMainStorage() private pure returns (bool $) {}␊
|
|
70
|
+
␊
|
|
71
|
+
function _getXTimesY() internal view returns (bool) {}␊
|
|
72
|
+
␊
|
|
73
|
+
␊
|
|
74
|
+
␊
|
|
75
|
+
␊
|
|
76
|
+
enum $astId_id_random { dummy }␊
|
|
77
|
+
␊
|
|
78
|
+
// standalone doc␊
|
|
79
|
+
␊
|
|
80
|
+
␊
|
|
81
|
+
␊
|
|
82
|
+
␊
|
|
83
|
+
function foo3() public {}␊
|
|
84
|
+
␊
|
|
85
|
+
␊
|
|
86
|
+
function foo4() public {}␊
|
|
87
|
+
␊
|
|
88
|
+
␊
|
|
89
|
+
enum $astId_id_random { dummy }␊
|
|
90
|
+
␊
|
|
91
|
+
enum $astId_id_random { dummy }␊
|
|
92
|
+
enum $astId_id_random { dummy }␊
|
|
93
|
+
enum $astId_id_random { dummy }␊
|
|
94
|
+
enum $astId_id_random { dummy }␊
|
|
95
|
+
enum $astId_id_random { dummy }␊
|
|
96
|
+
}␊
|
|
97
|
+
␊
|
|
98
|
+
abstract contract HasFunction {␊
|
|
99
|
+
␊
|
|
100
|
+
function foo() pure public returns (bool) {}␊
|
|
101
|
+
}␊
|
|
102
|
+
␊
|
|
103
|
+
abstract contract UsingFunction is HasFunction {␊
|
|
104
|
+
enum $astId_id_random { dummy }␊
|
|
105
|
+
}␊
|
|
106
|
+
␊
|
|
107
|
+
function FreeFunctionUsingSelector() pure returns (bool) {}␊
|
|
108
|
+
␊
|
|
109
|
+
bytes4 constant CONSTANT_USING_SELECTOR = HasFunction.foo.selector;␊
|
|
110
|
+
␊
|
|
111
|
+
library Lib {␊
|
|
112
|
+
function usingSelector() pure public returns (bool) {}␊
|
|
113
|
+
␊
|
|
114
|
+
function plusOne(uint x) pure public returns (bool) {}␊
|
|
115
|
+
}␊
|
|
116
|
+
␊
|
|
117
|
+
abstract contract Consumer {␊
|
|
118
|
+
enum $astId_id_random { dummy }␊
|
|
119
|
+
␊
|
|
120
|
+
function usingFreeFunction() pure public returns (bool) {}␊
|
|
121
|
+
␊
|
|
122
|
+
function usingConstant() pure public returns (bool) {}␊
|
|
123
|
+
␊
|
|
124
|
+
function usingLibraryFunction() pure public returns (bool) {}␊
|
|
125
|
+
}␊
|
|
126
|
+
␊
|
|
127
|
+
abstract contract HasConstantWithSelector {␊
|
|
128
|
+
bytes4 constant CONTRACT_CONSTANT_USING_SELECTOR = HasFunction.foo.selector;␊
|
|
129
|
+
}␊
|
|
130
|
+
␊
|
|
131
|
+
function plusTwo(uint x) pure returns (bool) {}␊
|
|
132
|
+
␊
|
|
133
|
+
␊
|
|
134
|
+
␊
|
|
135
|
+
␊
|
|
136
|
+
function plusThree(uint x) pure returns (bool) {}␊
|
|
137
|
+
␊
|
|
138
|
+
␊
|
|
139
|
+
␊
|
|
140
|
+
␊
|
|
141
|
+
function plusThree(uint x, uint y) pure returns (bool) {}␊
|
|
142
|
+
␊
|
|
143
|
+
function originallyNoDocumentation() pure {}␊
|
|
144
|
+
␊
|
|
145
|
+
␊
|
|
146
|
+
enum $astId_id_random { dummy }␊
|
|
147
|
+
␊
|
|
148
|
+
abstract contract UsingForDirectives {␊
|
|
149
|
+
enum $astId_id_random { dummy }␊
|
|
150
|
+
␊
|
|
151
|
+
function usingFor(uint x) pure public returns (bool) {}␊
|
|
152
|
+
}␊
|
|
153
|
+
␊
|
|
154
|
+
␊
|
|
155
|
+
enum FreeEnum { MyEnum }␊
|
|
156
|
+
␊
|
|
157
|
+
␊
|
|
158
|
+
enum CustomErrorOutsideContract { dummy }␊
|
|
159
|
+
␊
|
|
160
|
+
int8 constant MAX_SIZE_C = 2;␊
|
|
161
|
+
␊
|
|
162
|
+
abstract contract StructArrayUsesConstant {␊
|
|
163
|
+
uint16 private constant MAX_SIZE = 10;␊
|
|
164
|
+
␊
|
|
165
|
+
struct NotNamespaced {␊
|
|
166
|
+
uint16 a;␊
|
|
167
|
+
uint256[MAX_SIZE] b;␊
|
|
168
|
+
uint256[MAX_SIZE_C] c;␊
|
|
169
|
+
}␊
|
|
170
|
+
␊
|
|
171
|
+
/// @custom:storage-location erc7201:uses.constant␊
|
|
172
|
+
struct MainStorage {␊
|
|
173
|
+
uint256 x;␊
|
|
174
|
+
uint256[MAX_SIZE] y;␊
|
|
175
|
+
uint256[MAX_SIZE_C] c;␊
|
|
176
|
+
} MainStorage $MainStorage_random;␊
|
|
177
|
+
}␊
|
|
178
|
+
␊
|
|
179
|
+
address constant MY_ADDRESS = address(0);␊
|
|
180
|
+
uint constant CONVERTED_ADDRESS = uint160(MY_ADDRESS);␊
|
|
181
|
+
␊
|
|
182
|
+
interface IDummy {␊
|
|
183
|
+
}␊
|
|
184
|
+
␊
|
|
185
|
+
abstract contract UsesAddress {␊
|
|
186
|
+
IDummy public constant MY_CONTRACT = IDummy(MY_ADDRESS);␊
|
|
187
|
+
}␊
|
|
188
|
+
␊
|
|
189
|
+
abstract contract HasFunctionWithRequiredReturn {␊
|
|
190
|
+
struct S { uint x; }␊
|
|
191
|
+
function foo(S calldata s) internal pure returns (bool) {}␊
|
|
192
|
+
}␊
|
|
193
|
+
␊
|
|
194
|
+
␊
|
|
195
|
+
function hasMultipleReturns() pure returns (bool, bool) {}␊
|
|
196
|
+
␊
|
|
197
|
+
␊
|
|
198
|
+
function hasMultipleNamedReturns() pure returns (bool a, bool b) {}␊
|
|
199
|
+
␊
|
|
200
|
+
␊
|
|
201
|
+
function hasReturnsDocumentedAsParams() pure returns (bool a, bool b) {}␊
|
|
202
|
+
␊
|
|
203
|
+
abstract contract HasNatSpecWithMultipleReturns {␊
|
|
204
|
+
␊
|
|
205
|
+
function hasMultipleReturnsInContract() public pure returns (bool, bool) {}␊
|
|
206
|
+
␊
|
|
207
|
+
␊
|
|
208
|
+
function hasMultipleNamedReturnsInContract() public pure returns (bool a, bool b) {}␊
|
|
209
|
+
␊
|
|
210
|
+
␊
|
|
211
|
+
function hasReturnsDocumentedAsParamsInContract() public pure returns (bool a, bool b) {}␊
|
|
212
|
+
}␊
|
|
213
|
+
␊
|
|
214
|
+
interface IHasExternalViewFunction {␊
|
|
215
|
+
function foo() external view returns (bool);␊
|
|
216
|
+
}␊
|
|
217
|
+
␊
|
|
218
|
+
abstract contract HasExternalViewFunction is IHasExternalViewFunction {␊
|
|
219
|
+
// This generates a getter function that conforms to the interface␊
|
|
220
|
+
enum $astId_id_random { dummy }␊
|
|
221
|
+
␊
|
|
222
|
+
// References a selector in an interface␊
|
|
223
|
+
bytes4 constant USING_INTERFACE_FUNCTION_SELECTOR = IHasExternalViewFunction.foo.selector;␊
|
|
224
|
+
␊
|
|
225
|
+
// References a getter generated for a public variable␊
|
|
226
|
+
enum $astId_id_random { dummy }␊
|
|
227
|
+
}␊
|
|
228
|
+
␊
|
|
229
|
+
abstract contract DeploysContractToImmutable {␊
|
|
230
|
+
enum $astId_id_random { dummy }␊
|
|
231
|
+
}`,
|
|
232
|
+
},
|
|
233
|
+
'contracts/test/NamespacedToModifyImported.sol': {
|
|
234
|
+
content: `// SPDX-License-Identifier: MIT␊
|
|
235
|
+
pragma solidity ^0.8.20;␊
|
|
236
|
+
␊
|
|
237
|
+
import {CONSTANT_USING_SELECTOR, plusTwo, plusThree, CustomErrorOutsideContract} from "./NamespacedToModify.sol";␊
|
|
238
|
+
␊
|
|
239
|
+
abstract contract Example {}␊
|
|
240
|
+
`,
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
## make namespaced input - keep all natspec
|
|
246
|
+
|
|
247
|
+
> Snapshot 1
|
|
248
|
+
|
|
249
|
+
{
|
|
250
|
+
language: 'Solidity',
|
|
251
|
+
settings: {
|
|
252
|
+
evmVersion: 'paris',
|
|
253
|
+
optimizer: {
|
|
254
|
+
enabled: true,
|
|
255
|
+
runs: 200,
|
|
256
|
+
},
|
|
257
|
+
outputSelection: {
|
|
258
|
+
'*': {
|
|
259
|
+
'': [
|
|
260
|
+
'ast',
|
|
261
|
+
],
|
|
262
|
+
'*': [
|
|
263
|
+
'storageLayout',
|
|
264
|
+
],
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
sources: {
|
|
269
|
+
'contracts/test/NamespacedToModify.sol': {
|
|
270
|
+
content: `// SPDX-License-Identifier: MIT␊
|
|
271
|
+
pragma solidity ^0.8.20;␊
|
|
272
|
+
␊
|
|
273
|
+
abstract contract Example {␊
|
|
274
|
+
/// @custom:storage-location erc7201:example.main␊
|
|
275
|
+
struct MainStorage {␊
|
|
276
|
+
uint256 x;␊
|
|
277
|
+
uint256 y;␊
|
|
278
|
+
} MainStorage $MainStorage_random;␊
|
|
279
|
+
␊
|
|
280
|
+
/// @custom:storage-location erc7201:example.secondary␊
|
|
281
|
+
struct SecondaryStorage {␊
|
|
282
|
+
uint256 a;␊
|
|
283
|
+
uint256 b;␊
|
|
284
|
+
} SecondaryStorage $SecondaryStorage_random;␊
|
|
285
|
+
␊
|
|
286
|
+
/// @custom:storage-location erc7201:example.with.following.comment␊
|
|
287
|
+
// some comment␊
|
|
288
|
+
struct StorageWithComment {␊
|
|
289
|
+
uint256 a;␊
|
|
290
|
+
uint256 b;␊
|
|
291
|
+
} StorageWithComment $StorageWithComment_random;␊
|
|
47
292
|
␊
|
|
48
293
|
/// @notice some natspec␊
|
|
49
294
|
function foo() public {}␊
|
|
@@ -98,12 +343,12 @@ Generated by [AVA](https://avajs.dev).
|
|
|
98
343
|
enum $astId_id_random { dummy }␊
|
|
99
344
|
}␊
|
|
100
345
|
␊
|
|
101
|
-
contract HasFunction {␊
|
|
346
|
+
abstract contract HasFunction {␊
|
|
102
347
|
␊
|
|
103
348
|
function foo() pure public returns (bool) {}␊
|
|
104
349
|
}␊
|
|
105
350
|
␊
|
|
106
|
-
contract UsingFunction is HasFunction {␊
|
|
351
|
+
abstract contract UsingFunction is HasFunction {␊
|
|
107
352
|
enum $astId_id_random { dummy }␊
|
|
108
353
|
}␊
|
|
109
354
|
␊
|
|
@@ -117,7 +362,7 @@ Generated by [AVA](https://avajs.dev).
|
|
|
117
362
|
function plusOne(uint x) pure public returns (bool) {}␊
|
|
118
363
|
}␊
|
|
119
364
|
␊
|
|
120
|
-
contract Consumer {␊
|
|
365
|
+
abstract contract Consumer {␊
|
|
121
366
|
enum $astId_id_random { dummy }␊
|
|
122
367
|
␊
|
|
123
368
|
function usingFreeFunction() pure public returns (bool) {}␊
|
|
@@ -127,7 +372,7 @@ Generated by [AVA](https://avajs.dev).
|
|
|
127
372
|
function usingLibraryFunction() pure public returns (bool) {}␊
|
|
128
373
|
}␊
|
|
129
374
|
␊
|
|
130
|
-
contract HasConstantWithSelector {␊
|
|
375
|
+
abstract contract HasConstantWithSelector {␊
|
|
131
376
|
bytes4 constant CONTRACT_CONSTANT_USING_SELECTOR = HasFunction.foo.selector;␊
|
|
132
377
|
}␊
|
|
133
378
|
␊
|
|
@@ -159,7 +404,7 @@ Generated by [AVA](https://avajs.dev).
|
|
|
159
404
|
*/␊
|
|
160
405
|
enum $astId_id_random { dummy }␊
|
|
161
406
|
␊
|
|
162
|
-
contract UsingForDirectives {␊
|
|
407
|
+
abstract contract UsingForDirectives {␊
|
|
163
408
|
enum $astId_id_random { dummy }␊
|
|
164
409
|
␊
|
|
165
410
|
function usingFor(uint x) pure public returns (bool) {}␊
|
|
@@ -185,7 +430,7 @@ Generated by [AVA](https://avajs.dev).
|
|
|
185
430
|
␊
|
|
186
431
|
int8 constant MAX_SIZE_C = 2;␊
|
|
187
432
|
␊
|
|
188
|
-
contract StructArrayUsesConstant {␊
|
|
433
|
+
abstract contract StructArrayUsesConstant {␊
|
|
189
434
|
uint16 private constant MAX_SIZE = 10;␊
|
|
190
435
|
␊
|
|
191
436
|
struct NotNamespaced {␊
|
|
@@ -208,11 +453,11 @@ Generated by [AVA](https://avajs.dev).
|
|
|
208
453
|
interface IDummy {␊
|
|
209
454
|
}␊
|
|
210
455
|
␊
|
|
211
|
-
contract UsesAddress {␊
|
|
456
|
+
abstract contract UsesAddress {␊
|
|
212
457
|
IDummy public constant MY_CONTRACT = IDummy(MY_ADDRESS);␊
|
|
213
458
|
}␊
|
|
214
459
|
␊
|
|
215
|
-
contract HasFunctionWithRequiredReturn {␊
|
|
460
|
+
abstract contract HasFunctionWithRequiredReturn {␊
|
|
216
461
|
struct S { uint x; }␊
|
|
217
462
|
function foo(S calldata s) internal pure returns (bool) {}␊
|
|
218
463
|
}␊
|
|
@@ -235,7 +480,7 @@ Generated by [AVA](https://avajs.dev).
|
|
|
235
480
|
*/␊
|
|
236
481
|
function hasReturnsDocumentedAsParams() pure returns (bool a, bool b) {}␊
|
|
237
482
|
␊
|
|
238
|
-
contract HasNatSpecWithMultipleReturns {␊
|
|
483
|
+
abstract contract HasNatSpecWithMultipleReturns {␊
|
|
239
484
|
/**␊
|
|
240
485
|
* @return uint 1␊
|
|
241
486
|
* @return uint 2␊
|
|
@@ -254,7 +499,25 @@ Generated by [AVA](https://avajs.dev).
|
|
|
254
499
|
*/␊
|
|
255
500
|
function hasReturnsDocumentedAsParamsInContract() public pure returns (bool a, bool b) {}␊
|
|
256
501
|
}␊
|
|
257
|
-
|
|
502
|
+
␊
|
|
503
|
+
interface IHasExternalViewFunction {␊
|
|
504
|
+
function foo() external view returns (bool);␊
|
|
505
|
+
}␊
|
|
506
|
+
␊
|
|
507
|
+
abstract contract HasExternalViewFunction is IHasExternalViewFunction {␊
|
|
508
|
+
// This generates a getter function that conforms to the interface␊
|
|
509
|
+
enum $astId_id_random { dummy }␊
|
|
510
|
+
␊
|
|
511
|
+
// References a selector in an interface␊
|
|
512
|
+
bytes4 constant USING_INTERFACE_FUNCTION_SELECTOR = IHasExternalViewFunction.foo.selector;␊
|
|
513
|
+
␊
|
|
514
|
+
// References a getter generated for a public variable␊
|
|
515
|
+
enum $astId_id_random { dummy }␊
|
|
516
|
+
}␊
|
|
517
|
+
␊
|
|
518
|
+
abstract contract DeploysContractToImmutable {␊
|
|
519
|
+
enum $astId_id_random { dummy }␊
|
|
520
|
+
}`,
|
|
258
521
|
},
|
|
259
522
|
'contracts/test/NamespacedToModifyImported.sol': {
|
|
260
523
|
content: `// SPDX-License-Identifier: MIT␊
|
|
@@ -262,7 +525,7 @@ Generated by [AVA](https://avajs.dev).
|
|
|
262
525
|
␊
|
|
263
526
|
import {CONSTANT_USING_SELECTOR, plusTwo, plusThree, CustomErrorOutsideContract} from "./NamespacedToModify.sol";␊
|
|
264
527
|
␊
|
|
265
|
-
contract Example {}␊
|
|
528
|
+
abstract contract Example {}␊
|
|
266
529
|
`,
|
|
267
530
|
},
|
|
268
531
|
},
|
|
@@ -295,12 +558,12 @@ Generated by [AVA](https://avajs.dev).
|
|
|
295
558
|
content: `// SPDX-License-Identifier: MIT␊
|
|
296
559
|
pragma solidity 0.7.6;␊
|
|
297
560
|
␊
|
|
298
|
-
contract HasFunction {␊
|
|
561
|
+
abstract contract HasFunction {␊
|
|
299
562
|
␊
|
|
300
563
|
function foo() pure public returns (bool) {}␊
|
|
301
564
|
}␊
|
|
302
565
|
␊
|
|
303
|
-
contract UsingFunction is HasFunction {␊
|
|
566
|
+
abstract contract UsingFunction is HasFunction {␊
|
|
304
567
|
enum $astId_id_random { dummy }␊
|
|
305
568
|
}␊
|
|
306
569
|
`,
|
|
Binary file
|
|
@@ -26,9 +26,10 @@ const OUTPUT_SELECTION = {
|
|
|
26
26
|
*
|
|
27
27
|
* @param input The original solc input.
|
|
28
28
|
* @param output The original solc output.
|
|
29
|
+
* @param solcVersion The version of the solc compiler that was originally used to compile the input.
|
|
29
30
|
* @returns The modified solc input with storage layout that includes namespaced type information.
|
|
30
31
|
*/
|
|
31
|
-
export function makeNamespacedInput(input: SolcInput, output: SolcOutput): SolcInput {
|
|
32
|
+
export function makeNamespacedInput(input: SolcInput, output: SolcOutput, solcVersion?: string): SolcInput {
|
|
32
33
|
const modifiedSources: Record<string, { content?: string }> = {};
|
|
33
34
|
|
|
34
35
|
for (const [sourcePath] of Object.entries(input.sources)) {
|
|
@@ -48,6 +49,12 @@ export function makeNamespacedInput(input: SolcInput, output: SolcOutput): SolcI
|
|
|
48
49
|
case 'ContractDefinition': {
|
|
49
50
|
const contractDef = node;
|
|
50
51
|
|
|
52
|
+
// Mark contracts as abstract, since state variables are converted to dummy enums
|
|
53
|
+
// which would not generate public getters for inherited interface functions
|
|
54
|
+
if (contractDef.contractKind === 'contract' && !contractDef.abstract) {
|
|
55
|
+
modifications.push(makeInsertBefore(contractDef, 'abstract '));
|
|
56
|
+
}
|
|
57
|
+
|
|
51
58
|
// Remove any calls to parent constructors from the inheritance list
|
|
52
59
|
const inherits = contractDef.baseContracts;
|
|
53
60
|
for (const inherit of inherits) {
|
|
@@ -144,12 +151,68 @@ export function makeNamespacedInput(input: SolcInput, output: SolcOutput): SolcI
|
|
|
144
151
|
}
|
|
145
152
|
}
|
|
146
153
|
|
|
147
|
-
|
|
154
|
+
const modifiedSource = tryRemoveNonStructNatSpec(getModifiedSource(orig, modifications), solcVersion);
|
|
155
|
+
|
|
156
|
+
modifiedSources[sourcePath] = { ...source, content: modifiedSource };
|
|
148
157
|
}
|
|
149
158
|
|
|
150
159
|
return { ...input, sources: modifiedSources, settings: { ...input.settings, outputSelection: OUTPUT_SELECTION } };
|
|
151
160
|
}
|
|
152
161
|
|
|
162
|
+
/**
|
|
163
|
+
* If Slang is supported for the current platform and we have the compiler version available,
|
|
164
|
+
* use Slang to parse and remove all NatSpec comments that do not precede a struct definition and return the modified content.
|
|
165
|
+
*
|
|
166
|
+
* Otherwise, return the original content.
|
|
167
|
+
*/
|
|
168
|
+
function tryRemoveNonStructNatSpec(origContent: string, solcVersion: string | undefined): string {
|
|
169
|
+
const natSpecRemovals: Modification[] = [];
|
|
170
|
+
|
|
171
|
+
if (solcVersion !== undefined && tryRequire('@nomicfoundation/slang')) {
|
|
172
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
173
|
+
const { Language } = require('@nomicfoundation/slang/language');
|
|
174
|
+
const { NonterminalKind, TerminalKind } = require('@nomicfoundation/slang/kinds');
|
|
175
|
+
const { TerminalNode } = require('@nomicfoundation/slang/cst');
|
|
176
|
+
const { isTrivia } = require('./slang/trivia');
|
|
177
|
+
/* eslint-enable @typescript-eslint/no-var-requires */
|
|
178
|
+
|
|
179
|
+
const language = new Language(solcVersion);
|
|
180
|
+
const parseOutput = language.parse(NonterminalKind.SourceUnit, origContent);
|
|
181
|
+
const cursor = parseOutput.createTreeCursor();
|
|
182
|
+
|
|
183
|
+
while (
|
|
184
|
+
cursor.goToNextTerminalWithKinds([TerminalKind.MultiLineNatSpecComment, TerminalKind.SingleLineNatSpecComment])
|
|
185
|
+
) {
|
|
186
|
+
// Lookahead to determine if the next non-trivia node is the struct keyword.
|
|
187
|
+
// If so, this NatSpec is part of the struct definition and should not be removed.
|
|
188
|
+
const lookaheadCursor = cursor.clone();
|
|
189
|
+
while (lookaheadCursor.goToNextTerminal() && isTrivia(lookaheadCursor.node())) {
|
|
190
|
+
// skip over trivia nodes
|
|
191
|
+
}
|
|
192
|
+
if (lookaheadCursor.node().kind === TerminalKind.StructKeyword) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const triviaNode = cursor.node();
|
|
197
|
+
assert(triviaNode instanceof TerminalNode);
|
|
198
|
+
natSpecRemovals.push(makeDeleteRange(cursor.textRange.start.utf8, cursor.textRange.end.utf8));
|
|
199
|
+
}
|
|
200
|
+
return getModifiedSource(Buffer.from(origContent, 'utf8'), natSpecRemovals);
|
|
201
|
+
} else {
|
|
202
|
+
return origContent;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function tryRequire(id: string) {
|
|
207
|
+
try {
|
|
208
|
+
require(id);
|
|
209
|
+
return true;
|
|
210
|
+
} catch (e: any) {
|
|
211
|
+
// do nothing
|
|
212
|
+
}
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
|
|
153
216
|
interface Modification {
|
|
154
217
|
start: number;
|
|
155
218
|
end: number;
|
|
@@ -210,6 +273,11 @@ function makeReplace(node: Node, orig: Buffer, text: string): Modification {
|
|
|
210
273
|
return { start, end, text };
|
|
211
274
|
}
|
|
212
275
|
|
|
276
|
+
function makeInsertBefore(node: Node, text: string): Modification {
|
|
277
|
+
const { start } = getPositions(node);
|
|
278
|
+
return { start: start, end: start, text };
|
|
279
|
+
}
|
|
280
|
+
|
|
213
281
|
function makeInsertAfter(node: Node, text: string): Modification {
|
|
214
282
|
const { end } = getPositions(node);
|
|
215
283
|
return { start: end, end, text };
|
|
@@ -227,7 +295,11 @@ function makeDelete(node: Node, orig: Buffer): Modification {
|
|
|
227
295
|
end += 1;
|
|
228
296
|
}
|
|
229
297
|
}
|
|
230
|
-
return
|
|
298
|
+
return makeDeleteRange(positions.start, end);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function makeDeleteRange(start: number, end: number): Modification {
|
|
302
|
+
return { start, end };
|
|
231
303
|
}
|
|
232
304
|
|
|
233
305
|
function getModifiedSource(orig: Buffer, modifications: Modification[]): string {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TerminalKind } from '@nomicfoundation/slang/kinds';
|
|
2
|
+
import { Node, TerminalNode } from '@nomicfoundation/slang/cst';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns true if the node is a trivia terminal (whitespace or comment or NatSpec)
|
|
6
|
+
*
|
|
7
|
+
* CAUTION: This must be imported dynamically.
|
|
8
|
+
* Only import this file if Slang is supported on the current platform, otherwise an error will be thrown on import.
|
|
9
|
+
*/
|
|
10
|
+
export function isTrivia(node: Node) {
|
|
11
|
+
return node instanceof TerminalNode && isTriviaKind(node.kind);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isTriviaKind(kind: TerminalKind) {
|
|
15
|
+
return (
|
|
16
|
+
kind === TerminalKind.EndOfLine ||
|
|
17
|
+
kind === TerminalKind.MultiLineComment ||
|
|
18
|
+
kind === TerminalKind.MultiLineNatSpecComment ||
|
|
19
|
+
kind === TerminalKind.SingleLineComment ||
|
|
20
|
+
kind === TerminalKind.SingleLineNatSpecComment ||
|
|
21
|
+
kind === TerminalKind.Whitespace
|
|
22
|
+
);
|
|
23
|
+
}
|