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

Implement pretty print for Cadence #209

Open
MaxStalker opened this issue Jul 4, 2020 · 11 comments
Open

Implement pretty print for Cadence #209

MaxStalker opened this issue Jul 4, 2020 · 11 comments
Assignees

Comments

@MaxStalker
Copy link
Contributor

MaxStalker commented Jul 4, 2020

Issue To Be Solved

At the moment there is no pretty print solution for Cadence, which leads to simple mistakes - single quotes for String literals, for example - and waste of time, when you would reformat your code to make it more readable.

(Optional): Suggest A Solution

Prettier is a de-facto goto solution for pretty print in web development. And it have support for plugins. Main repository also have multiple implementations - Swift, for example - which can serve as inspiration and guidance to build one for Cadence.

@turbolent
Copy link
Member

A formatter / pretty printer is something we've been wanting for quite a while, but have not gotten around too.

There are two things we need before we can pretty print:

  1. Generate JSON from the AST where all position info (start and end) is fully calculated.
    Currently it is sometimes calculated from child nodes (for performance reasons: less work if not needed)

  2. Add support for keeping "trivia" in the AST (that’s e.g. what it is called in Swift’s AST), i.e. leading and trailing whitespace and comments

Both aren’t hard, just a bit of work.

Once we add support for trivia, we can then also use it for other purposes, e.g. generate nice API documentation, use it as doc strings in the completion items in the VS Code extension.

I think if Prettier provides us some infrastructure which would save us some work, we should use it.
As far as I understand it provides a pretty print document AST, and the task of a plugin is to translate its AST to Prettier's AST.

As an aside: The other day I played with Go’s WebAssembly target, and successfully compiled the new parser to WebAssembly in the browser. The code can be found in an unmerged branch: https://github.com/onflow/cadence/compare/bastian/astexplorer. I think we could use it to maybe avoid having to shell out to the parser (and have users build the Go parser)

@turbolent
Copy link
Member

I opened #210 for the JSON serialization improvements for the AST

@turbolent
Copy link
Member

I opened a first PR for #210 to demonstrate what needs to be done: #211

@turbolent
Copy link
Member

Created #308 for retaining comments in the AST

@turbolent
Copy link
Member

After all 5 PRs are merged, #210 should be done, and the AST is ready to be consumed!

For development, the cmd/parse tool can be used with the json flag to get the output.

Given a file program.cdc:

struct X {}

The JSON representation can be obtained with:

$ go run ./cmd/parse -json program.cdc
[
  {
    "path": "program.cdc",
    "Program": {
      "Declarations": [
        {
          "Type": "CompositeDeclaration",
          "Access": "AccessNotSpecified",
          "CompositeKind": "CompositeKindStructure",
          "Identifier": {
            "Identifier": "X",
            "StartPos": {
              "Offset": 7,
              "Line": 1,
              "Column": 7
            },
            "EndPos": {
              "Offset": 7,
              "Line": 1,
              "Column": 7
            }
          },
          "Conformances": null,
          "Members": {
            "Declarations": null
          },
          "DocString": "",
          "StartPos": {
            "Offset": 0,
            "Line": 1,
            "Column": 0
          },
          "EndPos": {
            "Offset": 10,
            "Line": 1,
            "Column": 10
          }
        }
      ]
    }
  }
]

Note that the result is an array because the tool supports parsing multiple files.

@turbolent
Copy link
Member

turbolent commented Sep 7, 2020

List of AST elements that need to be printed:

Expressions:

  • BoolExpression
  • NilExpression
  • StringExpression
  • IntegerExpression
  • FixedPointExpression
  • ArrayExpression
  • DictionaryExpression
  • IdentifierExpression
  • InvocationExpression
    • Argument
  • MemberExpression
  • IndexExpression
  • ConditionalExpression
  • UnaryExpression
  • BinaryExpression
  • FunctionExpression
  • CastingExpression
  • CreateExpression
  • DestroyExpression
  • ReferenceExpression
  • ForceExpression
  • PathExpression

Declarations:

  • VariableDeclaration
  • FunctionDeclaration
  • SpecialFunctionDeclaration
  • ImportDeclaration
  • InterfaceDeclaration
  • TransactionDeclaration
  • PragmaDeclaration
  • CompositeDeclaration
  • FieldDeclaration

Function-related:

  • Parameter
  • ParameterList
  • Condition
  • FunctionBlock

Statements:

  • ReturnStatement
  • BreakStatement
  • ContinueStatement
  • IfStatement
  • WhileStatement
  • ForStatement
  • EmitStatement
  • AssignmentStatement
  • SwapStatement
  • ExpressionStatement

Types:

  • TypeAnnotation
  • NominalType
  • OptionalType
  • VariableSizedType
  • ConstantSizedType
  • DictionaryType
  • FunctionType
  • ReferenceType
  • RestrictedType
  • InstantiationType

Locations:

  • IdentifierLocation
  • StringLocation
  • AddressLocation

Transfer-related:

  • Transfer
  • TransferOperation

Kinds:

  • ConditionKind
  • VariableKind
  • DeclarationKind
  • CompositeKind

Other:

  • Members
  • Operation
  • Program
  • Access
  • Block

@turbolent turbolent removed their assignment Sep 7, 2020
@turbolent turbolent added the Good First Issue Good for newcomers label Sep 7, 2020
@MaxStalker MaxStalker self-assigned this Mar 8, 2021
@turbolent turbolent assigned turbolent and unassigned MaxStalker Jun 20, 2021
@turbolent
Copy link
Member

I've started again on this, this time by implementing a pretty-printing library in Go, https://github.com/turbolent/prettier, and then started implementing functions for the AST elements above that return a prettier.Doc.

@turbolent
Copy link
Member

turbolent commented Mar 21, 2022

With #1520, pretty printing of all AST elements is now complete.

Last remaining actionable is printing comments, which depends on them being available in the AST, i.e. #308.

Optional / follow-up work:

  • We could refactor ast.Element.String() implementations to rely on their respective Doc() implementations
  • We could add settings/options to control certain aspects of pretty printing
  • We could add more "breaks" (indentation), e.g. for CastingExpression

@bjartek
Copy link
Contributor

bjartek commented Apr 28, 2023

What is the status of this issue?

@sideninja
Copy link
Contributor

@turbolent should we make this part of a grant?

@turbolent
Copy link
Member

turbolent commented May 4, 2023

@bjartek There has been no further progress. The last remaining item is still to retain comments in the formatted output.

@sideninja yes, we're currently working on a grant proposal for this (https://www.notion.so/dapperlabs/Implement-pretty-print-for-Cadence-32e7652c14454f668549d069cc0b5680?pvs=4)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants