Open byakuren-hijiri opened 6 months ago
Save types to AST or improve an access API to type information.
This would be insanely useful in tools like language server and such!
In general, I agree with all those points, but implementation of some may just require us to make our own lexer→parser→semantic analysis pipeline, suitable for compiler AND external tooling depending on various steps in it. I'd say this depends on #286, but I may be wrong and we could pull off such feat without compromising the Ohm's toolkit.
I would also suggest creating named union types for AST entries used in fields. For example:
export type ASTContract = {
kind: 'def_contract';
origin: TypeOrigin;
id: number;
name: string;
traits: ASTString[];
attributes: ASTContractAttribute[];
declarations: (ASTField | ASTFunction | ASTInitFunction | ASTReceive | ASTConstant)[];
ref: ASTRef;
};
Could be rewritten as:
export type ASTContractDeclaration = (ASTField | ASTFunction | ASTInitFunction | ASTReceive | ASTConstant);
export type ASTContract = {
kind: 'def_contract';
origin: TypeOrigin;
id: number;
name: string;
traits: ASTString[];
attributes: ASTContractAttribute[];
declarations: ASTContractDeclaration[];
ref: ASTRef;
};
This will simplify the life of tooling developers by enabling them to reuse these type definitions from the compiler. Otherwise, I find myself copy-pasting these entries in my projects. Here is an example of a function with such a signature implemented in the static analyzer internals:
function getMethodInfo(
decl: ASTField | ASTFunction | ASTInitFunction | ASTReceive | ASTConstant,
): [string | undefined, FunctionKind | undefined] {
Added three more points:
Add more context to every internal Error to be thrown in compiler internals. This is crucial for debugging third-party tools. Add AST iterators that perform functional map and fold over nested nodes of the AST. This will enable API users to inspect the AST in a more convenient way, for example, sorting nodes of a certain type. Add an API that provides equivalence checks between AST nodes of the same type. This is needed, for example, in https://github.com/tact-lang/tact/pull/335 to implement unit tests.
Added while working on tests for https://github.com/tact-lang/tact/pull/559:
- [ ] Refactoring: Extract methods from the
build
function (src/pipeline/build.ts
) to make it more modular. We need to separate the build functionality from CLI parsing and use different methods to create context, compile, and precompile. This is important to implement in order to enable third-party tools to hook into the compilation pipeline in the most flexible way. Perhaps, the best way to achieve this functionality is to create theBuilder
class with public methods defining the pipeline.
There are a few possible ways to improve the Tact frontend API that would be helpful for tooling:
{Node,Virtual}FileSystem
API. These functions should have improved documentation, e.g. noting that they do not support relative paths. Additionally, we might consider encapsulating them making them private to make users of the Tact API only interact with absolute paths when working with compiler internals.precompile
function is quite convoluted. All the arguments of the functions used beforeprecompile
should be documented, we should extract small methods when possible, and document them, to make that API more useful for third-parties.Error
to bethrow
n in compiler internals. This is crucial for debugging third-party tools.map
andfold
over nested nodes of the AST. This will enable API users to inspect the AST in a more convenient way, for example, sorting nodes of a certain type. (Done in PR #368)ASTStore
to be public. Currently, it should be copy-pasted each time a tool is going to parse AST, sincegetRawAST
returns that type.CompilerContext
. Some tools might generate AST without parsing, so we won't need to pass mocks inopenContext
.build
function (src/pipeline/build.ts
) to make it more modular. We need to separate the build functionality from CLI parsing and use different methods to create context, compile, and precompile. This is important to implement in order to enable third-party tools to hook into the compilation pipeline in the most flexible way. Perhaps, the best way to achieve this functionality is to create theBuilder
class with public methods defining the pipeline.These are my points after working with the Tact API for a while. Feel free to discuss and extend them and create separate issues from each checkbox when working on these.