Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tact frontend API: Improvements for tooling #314

Open
7 of 17 tasks
byakuren-hijiri opened this issue May 1, 2024 · 4 comments
Open
7 of 17 tasks

Tact frontend API: Improvements for tooling #314

byakuren-hijiri opened this issue May 1, 2024 · 4 comments
Labels
api Tact's TypeScript API for third-party tools ast discussion Ideas that are not fully formed and require discussion refactoring tooling tracking-issue

Comments

@byakuren-hijiri
Copy link
Contributor

byakuren-hijiri commented May 1, 2024

There are a few possible ways to improve the Tact frontend API that would be helpful for tooling:

  • Improve workflow with {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.
  • Support attributes for identifiers #639
  • Save comments to AST or create a separate CST structure. This is crucial for developing a formatter (Tact source code formatter #162), and might be useful for other tools to e.g. suppress warnings or add user-defined invariants.
  • Save types to AST or improve an access API to type information (ASTs should support annotations #289).
  • Document and refactor the frontend pipeline. Currently, the way the compiler prepares to calling the precompile function is quite convoluted. All the arguments of the functions used before precompile should be documented, we should extract small methods when possible, and document them, to make that API more useful for third-parties.
  • Optionally, we should consider introducing mappings from ASTNode ID to ASTNode. This approach makes sense only if necessary, for example, when refining the typechecker. It's a common approach; for instance, rustc internals are implemented this way. For tooling it might be useful to access a node by its ID when navigating the AST structure from other IR entries.
  • 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. (Done in PR feat(api): Introduce fold/map functions for AST traversal #368)
  • AST Comparison API #686
  • Make all the definitions needed to access the AST public. We should make at least ASTStore to be public. Currently, it should be copy-pasted each time a tool is going to parse AST, since getRawAST returns that type.
  • Separate the process of parsing from creating the CompilerContext. Some tools might generate AST without parsing, so we won't need to pass mocks in openContext.
  • Create named union types for fields of AST nodes (see: Tact frontend API: Improvements for tooling #314 (comment))
  • 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 the Builder class with public methods defining the pipeline.
  • Throw TactCompilationError instead Error when possible #645
  • Refactor build to Separate Feature Enabling Function #646
  • ILogger interface #648
  • Finalize index.ts and export it in package.json #776

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.

@byakuren-hijiri byakuren-hijiri added discussion Ideas that are not fully formed and require discussion refactoring tooling api Tact's TypeScript API for third-party tools labels May 1, 2024
@byakuren-hijiri byakuren-hijiri changed the title Tact AST API: Improvements for tooling Tact frontend API: Improvements for tooling May 1, 2024
@novusnota
Copy link
Member

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.

@byakuren-hijiri
Copy link
Contributor Author

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] {

byakuren-hijiri added a commit to byakuren-hijiri/tact that referenced this issue May 6, 2024
byakuren-hijiri added a commit to byakuren-hijiri/tact that referenced this issue May 6, 2024
anton-trunov pushed a commit that referenced this issue May 7, 2024
…326)

Refers to #314

* feat(store): Remove `openMockContext`

API users can simply create an `ASTProgram` containing the desired
top-level entries and use `createContext` instead.

* feat(store): Change the default behavior of `openContext`
@byakuren-hijiri
Copy link
Contributor Author

byakuren-hijiri commented May 23, 2024

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 #335 to implement unit tests.

byakuren-hijiri added a commit to nowarp/misti that referenced this issue May 29, 2024
This should be introduced in the compiler's API: tact-lang/tact#314
byakuren-hijiri added a commit to byakuren-hijiri/tact that referenced this issue May 30, 2024
This improves compiler's API providing an interface to traverse the AST.
It should be a part of the compiler, since it is be useful for devtools
using the API and might be useful internally.

Refers to tact-lang#314
anton-trunov pushed a commit that referenced this issue Jun 3, 2024
This improves compiler's API providing an interface to traverse the AST.
It should be a part of the compiler, since it is useful for devtools
using the API and might be useful internally.

Refers to #314
@anton-trunov anton-trunov pinned this issue Jun 4, 2024
@byakuren-hijiri
Copy link
Contributor Author

byakuren-hijiri commented Jul 18, 2024

Added while working on tests for #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 the Builder class with public methods defining the pipeline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api Tact's TypeScript API for third-party tools ast discussion Ideas that are not fully formed and require discussion refactoring tooling tracking-issue
Projects
None yet
Development

No branches or pull requests

3 participants