dop251 / goja

ECMAScript/JavaScript engine in pure Go
MIT License
5.63k stars 378 forks source link

Request for Assistance: Obtaining Abstract Syntax Tree (AST) with Goja #568

Closed chushuai closed 6 months ago

chushuai commented 7 months ago

I'm currently exploring the capabilities of Goja and I'm interested in replicating the functionality provided by the Python library pyjsparser. Specifically, I aim to parse JavaScript code and obtain its abstract syntax tree (AST) using Goja.

import pyjsparser

js_code = """
function exampleFunction() {
    var number = 42;
    var text = 'Hello, World!';
    var obj = { key: 'value' };
    var arr = [1, 2, 3];
    return [number, text, obj, arr];
}
"""
parsed = pyjsparser.parse(js_code)
print(json.dumps(parsed))

output

{
    "type": "Program",
    "body": [
        {
            "type": "FunctionDeclaration",
            "id": {
                "type": "Identifier",
                "name": "exampleFunction"
            },
            "params": [],
            "defaults": [],
            "body": {
                "type": "BlockStatement",
                "body": [
                    {
                        "type": "VariableDeclaration",
                        "declarations": [
                            {
                                "type": "VariableDeclarator",
                                "id": {
                                    "type": "Identifier",
                                    "name": "number"
                                },
                                "init": {
                                    "type": "Literal",
                                    "value": 42.0,
                                    "raw": "42"
                                }
                            }
                        ],
                        "kind": "var"
                    },
                    {
                        "type": "VariableDeclaration",
                        "declarations": [
                            {
                                "type": "VariableDeclarator",
                                "id": {
                                    "type": "Identifier",
                                    "name": "text"
                                },
                                "init": {
                                    "type": "Literal",
                                    "value": "Hello, World!",
                                    "raw": "'Hello, World!'"
                                }
                            }
                        ],
                        "kind": "var"
                    },
                    {
                        "type": "VariableDeclaration",
                        "declarations": [
                            {
                                "type": "VariableDeclarator",
                                "id": {
                                    "type": "Identifier",
                                    "name": "obj"
                                },
                                "init": {
                                    "type": "ObjectExpression",
                                    "properties": [
                                        {
                                            "type": "Property",
                                            "key": {
                                                "type": "Identifier",
                                                "name": "key"
                                            },
                                            "computed": false,
                                            "value": {
                                                "type": "Literal",
                                                "value": "value",
                                                "raw": "'value'"
                                            },
                                            "kind": "init",
                                            "method": false,
                                            "shorthand": false
                                        }
                                    ]
                                }
                            }
                        ],
                        "kind": "var"
                    },
                    {
                        "type": "VariableDeclaration",
                        "declarations": [
                            {
                                "type": "VariableDeclarator",
                                "id": {
                                    "type": "Identifier",
                                    "name": "arr"
                                },
                                "init": {
                                    "type": "ArrayExpression",
                                    "elements": [
                                        {
                                            "type": "Literal",
                                            "value": 1.0,
                                            "raw": "1"
                                        },
                                        {
                                            "type": "Literal",
                                            "value": 2.0,
                                            "raw": "2"
                                        },
                                        {
                                            "type": "Literal",
                                            "value": 3.0,
                                            "raw": "3"
                                        }
                                    ]
                                }
                            }
                        ],
                        "kind": "var"
                    },
                    {
                        "type": "ReturnStatement",
                        "argument": {
                            "type": "ArrayExpression",
                            "elements": [
                                {
                                    "type": "Identifier",
                                    "name": "number"
                                },
                                {
                                    "type": "Identifier",
                                    "name": "text"
                                },
                                {
                                    "type": "Identifier",
                                    "name": "obj"
                                },
                                {
                                    "type": "Identifier",
                                    "name": "arr"
                                }
                            ]
                        }
                    }
                ]
            },
            "generator": false,
            "expression": false
        },
        {
            "type": "EmptyStatement"
        }
    ]
}
chushuai commented 7 months ago

I found a solution implemented using Goja. I'm wondering if there's a better implementation method? https://github.com/yaklang/yaklang/blob/main/common/javascript/astwalker.go#L26