0

I'm looking for a way to get a function declaration body by name from a string of js code. I'm in Nodejs environment. Let's say I have some spaghetti.js file. I can read it into a string

const allJs = fs.readFileSync('spaghetti.js');

Now I need a function that receives that string and function name and returns a string with everything between { }.

Something like this

allJs = 'let a=1; const b=[2, 3]; function cook(items){return items}; cook(b)';
parseFunction(allJs, 'cook');//'return items'

The complexity of input js is not limited.

I tried to find an npm module for that, but no luck.

artemean
  • 805
  • 1
  • 10
  • 24
  • 1
    What is the second parameter ("cook") of your `parseFunction` for? – Jamiec Apr 19 '17 at 10:50
  • If the complexity of your input js is not limited, you should specify which function bodies you want. All, just the first, a special one, even nested ones, class methods, etc ...? – dsuckau Apr 19 '17 at 10:52
  • @Jamiec that's a function name to look for in the input code – artemean Apr 19 '17 at 10:52
  • right, but your string input already includes a call to `cook`. POssibly you meant for that to be `return cook(b);` no? – Jamiec Apr 19 '17 at 10:53
  • @dsuckau, let's say I only want top level function declarations. No classes, methods etc. – artemean Apr 19 '17 at 10:53
  • See [JavaScript parser in JavaScript](http://stackoverflow.com/questions/2554519/javascript-parser-in-javascript) – Wiktor Stribiżew Apr 19 '17 at 10:54
  • @Jamiec, no, my function should return a string with a function declaration body. That's it. Invocations should be ignored. – artemean Apr 19 '17 at 10:55
  • Ok, not sure I understand what you're trying to achieve so i'll be off now :) – Jamiec Apr 19 '17 at 10:57

2 Answers2

2

You should have a look at an AST parser for Javascript:

http://esprima.org/

https://github.com/ternjs/acorn

That should be more safe than using RegExp or something.

dsuckau
  • 592
  • 3
  • 15
0

A String can be evaluated locally with the native eval() method. But remember, eval is a form of evil!

If the parseFunction() above is relying on something like this then the global Function constructor is being used and the 'new' function is bound to the return value of that operation (and thus that return value itself needs to be called).

A simple way to achieve this might be to do something like this...

var funcString = 'var a = 1, b = 3;';
funcString += 'function summit(){return a + b;}';
funcString += 'return summit();';

function makeNewFunc(str) {
    return new Function(str);
}

var newFunc = makeNewFunc( funcString );

console.log('newFunc:',newFunc);
//-> newFunc: function anonymous()

console.log('newFunc():',newFunc());
//-> newFunc(): 4

This demonstrates how functions can be created and invoked from String snippets. (EDIT: Turning something like that into a Node module is a simple matter);

Hope that helped. :)

Community
  • 1
  • 1
Brian Peacock
  • 1,801
  • 16
  • 24
  • It seems you haven't understood my problem. I don't want to invoke anything. I just want to get a STRING representing a particular function's body. A simple text. You can think of it as some form of static code analysis. – artemean Apr 19 '17 at 15:16
  • @Andrey - I took your question, it's title, and the proposed `parseFunction` function to mean you were looking to, you know, parse a function from a string. If you want to extract a string representation of a function's body then you're after "function decompilation" - see this SO answer: http://stackoverflow.com/a/3179967/4746328 – Brian Peacock Apr 19 '17 at 17:07