gkz / grasp

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

question: what are the use-cases for grasp? #2

Open roryokane opened 10 years ago

roryokane commented 10 years ago

Why would one ever practically need structural search or search-and-replace of JavaScript? When would textual search (with grep, etc.) for something you actually need in your work be insufficiently powerful or harder than using grasp?

I can think of two use-cases for grasp, but they don’t seem very compelling, so I must be missing some.

The three toy examples on the home page show the syntax and capabilities, but don’t sound like things anyone would want to actually do.

I think the answer to this should be in the FAQ, or maybe even on the home page.

gkz commented 10 years ago

Good question! I plan on writing a couple of blog posts going through several use cases with grasp. The first one will be on how to easily refactor code using grasp - that's what replace excels at.

Why do we search code in general? We want to find piece of our code. It's quite hard to do anything complex with grep at all. Say you are trying to remember where to find a function that resides as a property in an object literal, that calls the function isEven somewhere in the body. For example this code lies somewhere in your big codebase:

var obj = {
  toEven: function(x) {
    if (isEven(x)) {
      return x;
    } else {
      return x + 1;
    }
  }
};

You could simply search for isEven in grep, but that finds all use cases of it, not what we want. And grep won't even limit it self to finding identifiers named isEven, it will find the text isEven in strings or comments or whatever.

So you use grasp:

grasp 'obj.props func! #isEven' d.js

and you get

2-8:(multiline):
  toEven: function(x) {
    if (isEven(x)) {
      return x;
    } else {
      return x + 1;
    }
  }

(imagine the function definition is bold - GH markdown won't let me format in that way)

grasp allows you to search in ways you didn't even think were possible.

gkz commented 10 years ago

I added an initial section to the FAQ, and added a link to it from the home page. http://graspjs.com/faq/#what_are_some_use_cases

edit: github does not deal with daylight savings time very well! the comments are out of order

justinbaker999 commented 10 years ago

Perhaps macros(at least the functionality) can be created with grasp?

gkz commented 10 years ago

Yes that's another good example - we can't create new syntax, but we can change any current syntax to something completely different. For instance, you could change a call to map to a for loop.

feross commented 10 years ago

Could this be used to add/remove semicolons from a source file, for people who want to convert between coding styles?

gkz commented 10 years ago

Here's the first blog post I wanted to write, with some examples of using Grasp to refactor:

http://graspjs.com/blog/2014/01/07/refactoring-javascript-with-grasp/

PEM-- commented 10 years ago

AOP would be a nice use case.

For instance, I would like to write only one version of my source in dev, but have one version with specificities for mobile and another one version with other specificities for website.

Ex: I call some Cordova stuff for handling a splashscreen mobile but I don't need it in my website.

mquandalle commented 10 years ago

I agree with @PEM-- about AOP

For instance if you want specific code for mobile you can use a constant in your code:

if (App.isMobile) {
  console.log("I'm a mobile");
}

And then use grasp to replace App.isMobile by false if your target is not a mobile. Uglifyjs will automatically remove the unnecessary code. I've used this strategy for a Meteor App (in Meteor you can write both server and client code in the same file), you can see the package here: meteor-minifiers

vendethiel commented 10 years ago

That seems like a very cool idea !

ainthek commented 10 years ago

We are using (trying to) use grasp to write code review and analytic (sort of) tools: We are programming using dojo, but same principles can be applied to any other library to check for suspicious constructions, coding rules violations etc...

//find all usages of dojo has (see http://ainthek.blogspot.sk/2014/03/dojo-and-usage-of-has.html) grasp 'call[callee=#has].args' -r . -o --no-filename --line-number=false --color=false

//find potentially unsecure code (innerHtml without encoding) grasp -s "call[callee=(obj, [obj=#html][prop=#set])].args:nth(1):not(call[callee=(obj, [obj=(#encHtml, #enc)])])"

// partial with one parameter (strange construction) grasp -e ".partial()"

// another sample, dynamic node.js require calls (requiring something other than static string) grasp "call[callee=#require].args:not([value=type(String)])" ./proxy.js

etc. etc... However, we are still struggling with syntax and missing more real life samples

ainthek commented 10 years ago

// another sample, dynamic node require calls (requiring something other than static string) grasp "call[callee=#require].args:not([value=type(String)])" ./proxy.js

ainthek commented 8 years ago

See github.com/gratex/grasp-samples for more usecases