Skip to content

Do not reimplement AST#34

Closed
fredefox wants to merge 2 commits intotsearch-io:masterfrom
fredefox:fredefox/do-not-reimplement-ast
Closed

Do not reimplement AST#34
fredefox wants to merge 2 commits intotsearch-io:masterfrom
fredefox:fredefox/do-not-reimplement-ast

Conversation

@fredefox
Copy link
Collaborator

This isn't really in a usable state, but my thought was that it should
not be necessary to try and re-implement the AST of TypeScript types.
In stead we should be able to pull out the representation as defined
by the typescript/lib module (which ts-morph wraps). Now,
unfortunately ts-morph is infected with OOP and so the structures
are circular and cannot directly be serialized. So a little logic
is required to flatten the data.[see footnote 1] This is what I've tried to do.

My implementation uses unsafe coercions in two places. I'm not very
happy with this.

Below is an example of how the exported representation will differ
with this patch. Note that this will break your Haskell package
which is not expecting this structure.

One things that would need a bit of extra work is to convert the
returnType field into something more structured. Really it's a
Type node and does have a well-defined structure - but for some
reason when it's converted to JSON only a string representation is
output.

Before:

> node bin/ts-earch . | jq '.[0:1]'
[
  {
    "name": "findFunctions",
    "text": "\nexport default function findFunctions(directory: string, options: ts.ProjectOptions): FunctionRecord[];",
    "docs": "",
    "signature": {
      "parameters": [
        {
          "name": "directory",
          "type": {
            "__tag": "StringT"
          }
        },
        {
          "name": "options",
          "type": {
            "__tag": "Other",
            "values": "import(\"/home/fredefox/git/tsearch-io/indexer/node_modules/ts-morph/lib/ts-morph\").ProjectOptions"
          }
        }
      ],
      "returnType": {
        "__tag": "Other",
        "values": "import(\"/home/fredefox/git/tsearch-io/indexer/build/types\").FunctionRecord[]"
      }
    },
    "module": "indexer",
    "location": {
      "path": "build/index.d.ts",
      "lines": {
        "from": 3,
        "to": 3
      }
    }
  }
]

After:

> node bin/ts-earch . | jq '.[0:1]'
[
  {
    "name": "findFunctions",
    "type": {
      "parameters": [
        {
          "name": "directory",
          "type": "string",
          "isReadonly": false,
          "decorators": [],
          "hasQuestionToken": false,
          "kind": 28,
          "isRestParameter": false
        },
        {
          "name": "options",
          "type": "ts.ProjectOptions",
          "isReadonly": false,
          "decorators": [],
          "hasQuestionToken": false,
          "kind": 28,
          "isRestParameter": false
        }
      ],
      "returnType": "{\n    name: string;\n    type: ts.Structure;\n}[]",
      "typeParameters": []
    }
  }
]

[1]: Alternatively some function that I have yet to find allows for exporting the structure whole-sale.

@fredefox fredefox marked this pull request as draft June 14, 2020 10:34
@fredefox
Copy link
Collaborator Author

My implementation uses unsafe coercions in two places. I'm not very
happy with this.

TypeScript I wouldn't worry too much unless this becomes the norm

Note that this will break your Haskell package which is not expecting this structure.

That shouldn't be a problem at all. There's nothing set in stone yet, I'm just experiment around to be honest.

I guess is only a matter of finding the spec or some doces (there should be) around the TS AST to use it on the Haskell side.

The initial reasoning behind having our own representation was to have control on how it looked and only include what was needed. Thing is, eventually most of the AST will be used so I see now that it makes sense to just use that, if it turns to be inefficient it can be changed.

As with the other PR, do you mind opening it on https://github.com/tsearch-io/tsearch ?

In terms of efficiency. It might make sense to zip the generated JSON (easy) or use some other JSON-compatible binary format.

@gillchristian
Copy link
Member

I meant efficiency in terms of consuming the AST on the Haskell side.

My plan for the initial iterations (until results are meaningful at least) is to us a small subset of libraries (probably the FP ecosystem https://gcanti.github.io/fp-ts/ecosystem/). So the output wouldn't be that big, but yes eventually some binary format would be better.

@fredefox
Copy link
Collaborator Author

#37

@fredefox fredefox closed this Jun 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants