Skip to content

Commit 2460d84

Browse files
committed
Add support for user defined type values
1 parent 1de119f commit 2460d84

File tree

9 files changed

+1639
-1433
lines changed

9 files changed

+1639
-1433
lines changed

antlr

src/ASTBuilder.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,18 @@ export class ASTBuilder
730730
return this._addMeta(node, ctx)
731731
}
732732

733+
public visitTypeDefinition(
734+
ctx: SP.TypeDefinitionContext
735+
): AST.TypeDefinition & WithMeta {
736+
const node: AST.TypeDefinition = {
737+
type: 'TypeDefinition',
738+
name: this._toText(ctx.identifier()),
739+
definition: this.visitElementaryTypeName(ctx.elementaryTypeName())
740+
}
741+
742+
return this._addMeta(node, ctx)
743+
}
744+
733745
public visitRevertStatement(
734746
ctx: SP.RevertStatementContext
735747
): AST.RevertStatement & WithMeta {

src/antlr/Solidity.interp

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

src/antlr/SolidityListener.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { ContractPartContext } from "./SolidityParser";
1919
import { StateVariableDeclarationContext } from "./SolidityParser";
2020
import { FileLevelConstantContext } from "./SolidityParser";
2121
import { CustomErrorDefinitionContext } from "./SolidityParser";
22+
import { TypeDefinitionContext } from "./SolidityParser";
2223
import { UsingForDeclarationContext } from "./SolidityParser";
2324
import { StructDefinitionContext } from "./SolidityParser";
2425
import { ModifierDefinitionContext } from "./SolidityParser";
@@ -282,6 +283,17 @@ export interface SolidityListener extends ParseTreeListener {
282283
*/
283284
exitCustomErrorDefinition?: (ctx: CustomErrorDefinitionContext) => void;
284285

286+
/**
287+
* Enter a parse tree produced by `SolidityParser.typeDefinition`.
288+
* @param ctx the parse tree
289+
*/
290+
enterTypeDefinition?: (ctx: TypeDefinitionContext) => void;
291+
/**
292+
* Exit a parse tree produced by `SolidityParser.typeDefinition`.
293+
* @param ctx the parse tree
294+
*/
295+
exitTypeDefinition?: (ctx: TypeDefinitionContext) => void;
296+
285297
/**
286298
* Enter a parse tree produced by `SolidityParser.usingForDeclaration`.
287299
* @param ctx the parse tree

src/antlr/SolidityParser.ts

Lines changed: 1534 additions & 1431 deletions
Large diffs are not rendered by default.

src/antlr/SolidityVisitor.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { ContractPartContext } from "./SolidityParser";
1919
import { StateVariableDeclarationContext } from "./SolidityParser";
2020
import { FileLevelConstantContext } from "./SolidityParser";
2121
import { CustomErrorDefinitionContext } from "./SolidityParser";
22+
import { TypeDefinitionContext } from "./SolidityParser";
2223
import { UsingForDeclarationContext } from "./SolidityParser";
2324
import { StructDefinitionContext } from "./SolidityParser";
2425
import { ModifierDefinitionContext } from "./SolidityParser";
@@ -221,6 +222,13 @@ export interface SolidityVisitor<Result> extends ParseTreeVisitor<Result> {
221222
*/
222223
visitCustomErrorDefinition?: (ctx: CustomErrorDefinitionContext) => Result;
223224

225+
/**
226+
* Visit a parse tree produced by `SolidityParser.typeDefinition`.
227+
* @param ctx the parse tree
228+
* @return the visitor result
229+
*/
230+
visitTypeDefinition?: (ctx: TypeDefinitionContext) => Result;
231+
224232
/**
225233
* Visit a parse tree produced by `SolidityParser.usingForDeclaration`.
226234
* @param ctx the parse tree

src/ast-types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export const astNodeTypes = [
119119
'CatchClause',
120120
'FileLevelConstant',
121121
'AssemblyMemberAccess',
122+
'TypeDefinition'
122123
] as const
123124

124125
export type ASTNodeTypeString = typeof astNodeTypes[number]
@@ -188,11 +189,19 @@ export interface FunctionDefinition extends BaseASTNode {
188189
isFallback: boolean
189190
isVirtual: boolean
190191
}
192+
191193
export interface CustomErrorDefinition extends BaseASTNode {
192194
type: 'CustomErrorDefinition'
193195
name: string
194196
parameters: VariableDeclaration[]
195197
}
198+
199+
export interface TypeDefinition extends BaseASTNode {
200+
type: 'TypeDefinition'
201+
name: string
202+
definition: ElementaryTypeName
203+
}
204+
196205
export interface RevertStatement extends BaseASTNode {
197206
type: 'RevertStatement'
198207
revertCall: FunctionCall
@@ -614,6 +623,7 @@ export type ASTNode =
614623
| AssemblyMemberAccess
615624
| CatchClause
616625
| FileLevelConstant
626+
| TypeDefinition
617627

618628
export type AssemblyItem =
619629
| Identifier

test/ast.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3463,4 +3463,32 @@ describe('AST', () => {
34633463
},
34643464
})
34653465
})
3466+
3467+
it('should support top-level user defined value types', function () {
3468+
const ast = parseNode('type Price is uint128;')
3469+
3470+
assert.deepEqual(ast, {
3471+
type: 'TypeDefinition',
3472+
name: 'Price',
3473+
definition: {
3474+
type: 'ElementaryTypeName',
3475+
name: 'uint128',
3476+
stateMutability: null
3477+
}
3478+
})
3479+
});
3480+
3481+
it('should support contract-level user defined value types', function () {
3482+
const ast = parseContract('contract Foo { type Price is uint128; }')
3483+
3484+
assert.deepEqual(ast.subNodes[0], {
3485+
type: 'TypeDefinition',
3486+
name: 'Price',
3487+
definition: {
3488+
type: 'ElementaryTypeName',
3489+
name: 'uint128',
3490+
stateMutability: null
3491+
}
3492+
})
3493+
});
34663494
})

test/test.sol

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,3 +749,35 @@ contract CustomErrors {
749749
revert ContractCustomError();
750750
}
751751
}
752+
753+
// User defined value types
754+
type Price is uint128;
755+
type Quantity is uint128;
756+
757+
contract Foo {
758+
type Id is uint8;
759+
760+
Id public id;
761+
}
762+
763+
type UFixed is uint256;
764+
765+
library FixedMath {
766+
uint constant multiplier = 10**18;
767+
768+
function add(UFixed a, UFixed b) internal pure returns (UFixed) {
769+
return UFixed.wrap(UFixed.unwrap(a) + UFixed.unwrap(b));
770+
}
771+
772+
function mul(UFixed a, uint256 b) internal pure returns (UFixed) {
773+
return UFixed.wrap(UFixed.unwrap(a) * b);
774+
}
775+
776+
function floor(UFixed a) internal pure returns (uint256) {
777+
return UFixed.unwrap(a) / multiplier;
778+
}
779+
780+
function toUFixed(uint256 a) internal pure returns (UFixed) {
781+
return UFixed.wrap(a * multiplier);
782+
}
783+
}

0 commit comments

Comments
 (0)