gkz / grasp

JavaScript structural search, replace, and refactor
http://graspjs.com
MIT License
1.28k stars 33 forks source link

Adding a method to a class via replace filter? #108

Open kristianmandrup opened 7 years ago

kristianmandrup commented 7 years ago

How do I use replace filters to add a method to a class named this.className The class body is an array, where elements/nodes typically are MethodDefinition. Do I use push or after or am I going in the wrong direction? Would be wonderful if there were examples in the docs beyond simple numbers in an Array but something more "real life" Cheers!

"body": [
        {
            "type": "ClassDeclaration",
            "id": {
                "type": "Identifier",
                "name": "Hello"
            },
            "superClass": null,
            "body": {
                "type": "ClassBody",
                "body": [
                    {
                        "type": "MethodDefinition",
                        "key": {
                            "type": "Identifier",
                            "name": "x"
                        },
                        "computed": false,
                        "value": {
                            "type": "FunctionExpression",
                            "id": null,
                            "params": [],
                            "body": {
                                "type": "BlockStatement",
                                "body": []
                            },
                            "generator": false,
                            "expression": false
                        },
                        "kind": "method",
                        "static": false
                    }
                ]
            }
        }
    ],

The "problem" is that .body includes the scope brackets { } when inserted. I always seem to get this error when I try...

    operator: undefined
    expected: undefined
    actual: undefined
    at: visitPre (node_modules/grasp-squery/lib/common.js:37:46)

Looking at append doesn't give me much of a clue :(

    if replacement?
      try
        replaced = replace replacement, clean-input, sliced-results, query-engine

...

orig-results = [node]

| 'append' =>
          for arg in args then results.push type: 'Raw', raw: "#arg"

my attempts:

class Hello {{.body hello() { } }}

var find = `class-dec[id=#Hello] body[type=#ClassBody]! `

var replace = `class Hello {{.body | append hello() {
} }}`

or do I append a String?

var replace = `class Hello {{.body | append "hello() {
}" }}`

grasp.replace('squery', find, replace)
this.code = replacer(this.code)

Can't make it work...