Skip to content

Commit 540a821

Browse files
committed
Add support for custom storage layout
1 parent 6ec9754 commit 540a821

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

src/ASTBuilder.ts

+11
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ export class ASTBuilder
5454

5555
this._currentContract = name
5656

57+
const customLayoutStorageList = ctx.customStorageLayout_list()
58+
if (customLayoutStorageList.length > 1) {
59+
throw new Error('Only one custom storage layout is allowed per contract')
60+
}
61+
5762
const node: AST.ContractDefinition = {
5863
type: 'ContractDefinition',
5964
name,
@@ -64,6 +69,12 @@ export class ASTBuilder
6469
kind,
6570
}
6671

72+
if (customLayoutStorageList.length === 1) {
73+
node.storageLayout = this.visitExpression(
74+
customLayoutStorageList[0].expression()
75+
)
76+
}
77+
6778
return this._addMeta(node, ctx)
6879
}
6980

src/ast-types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface ContractDefinition extends BaseASTNode {
3838
baseContracts: InheritanceSpecifier[]
3939
kind: string
4040
subNodes: BaseASTNode[]
41+
storageLayout?: Expression
4142
}
4243

4344
export interface InheritanceSpecifier extends BaseASTNode {

test/ast.ts

+72
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,78 @@ describe('AST', () => {
440440
subNodes: [],
441441
kind: 'interface',
442442
})
443+
444+
// custom layout storage, no inheritance
445+
ast = parseContract('contract test layout at 1 {}')
446+
assert.deepEqual(ast, {
447+
type: 'ContractDefinition',
448+
name: 'test',
449+
baseContracts: [],
450+
subNodes: [],
451+
kind: 'contract',
452+
storageLayout: {
453+
number: '1',
454+
subdenomination: null,
455+
type: 'NumberLiteral',
456+
},
457+
})
458+
459+
// custom layout storage after inheritance specifier
460+
ast = parseContract('contract test is foo layout at 1+2 {}')
461+
assert.deepEqual(ast, {
462+
type: 'ContractDefinition',
463+
name: 'test',
464+
baseContracts: [
465+
{
466+
type: 'InheritanceSpecifier',
467+
baseName: {
468+
type: 'UserDefinedTypeName',
469+
namePath: 'foo',
470+
},
471+
arguments: [],
472+
},
473+
],
474+
subNodes: [],
475+
kind: 'contract',
476+
storageLayout: {
477+
type: 'BinaryOperation',
478+
operator: '+',
479+
left: {
480+
type: 'NumberLiteral',
481+
number: '1',
482+
subdenomination: null,
483+
},
484+
right: {
485+
type: 'NumberLiteral',
486+
number: '2',
487+
subdenomination: null,
488+
},
489+
},
490+
})
491+
492+
// custom layout storage before inheritance specifier
493+
ast = parseContract('contract test layout at 10 is foo {}')
494+
assert.deepEqual(ast, {
495+
type: 'ContractDefinition',
496+
name: 'test',
497+
baseContracts: [
498+
{
499+
type: 'InheritanceSpecifier',
500+
baseName: {
501+
type: 'UserDefinedTypeName',
502+
namePath: 'foo',
503+
},
504+
arguments: [],
505+
},
506+
],
507+
subNodes: [],
508+
kind: 'contract',
509+
storageLayout: {
510+
type: 'NumberLiteral',
511+
number: '10',
512+
subdenomination: null,
513+
},
514+
})
443515
})
444516

445517
it('FunctionDefinition constructor case', () => {

0 commit comments

Comments
 (0)