5.4. Using AST Types#
So far we've been using the CST of a Solidity file or fragment. However, the CST is too verbose, and not always convenient to use for extracting information of the program. In the following example, we are going to show how to obtain the parameters and attributes of a function using the AST, an abstract representation of the program tree.
We start as usual by parsing the input, and then we can use the ParseOutput
root to create the CST type. Since it is a node of kind FunctionDefinition
, we are using the AST type of the same name to analyze it.
The FunctionDefinition
type has named fields to access all its children. For example, we can check the name of the function, list its parameters, or attributes:
using-ast-types.mts
import assert from "node:assert";
import { Parser } from "@nomicfoundation/slang/parser";
import { NonterminalKind } from "@nomicfoundation/slang/cst";
import { FunctionDefinition } from "@nomicfoundation/slang/ast";
test("using the ast", async () => {
const source = `
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
`;
const parser = Parser.create("0.8.28");
const parseOutput = parser.parseNonterminal(NonterminalKind.FunctionDefinition, source);
assert(parseOutput.isValid());
const func = new FunctionDefinition(parseOutput.tree);
assert.strictEqual(func.name.variant.unparse(), "add");
const parameters = func.parameters.parameters.items.map((parameter) => parameter.cst.unparse().trim());
assert.deepEqual(parameters, ["uint256 a", "uint256 b"]);
const attributes = func.attributes.items.map((attribute) => attribute.cst.unparse().trim());
assert.deepEqual(attributes, ["public", "pure"]);
});