Peter van der Zee
ecma at qfox.nl
Mon Sep 12 11:17:20 PDT 2011
> or static analysis (hmm, is there a central wiki or bibliography where
> we could record and collect such JS-related references? should I post
> here what I've found so far?).
For as far as you haven't already, I'd love to see more of them.
>>> That said, I think the "I want to refactor automatically" use-case is
>>> sort of over-played.
> That depends. Automatic "refactoring", in the strict sense of changing
> code structure without changing code behaviour, is nearly impossible
> you count reflection).
The "Extract method" is ok, if you don't count context or eval.
(Selecting a snippet of code which will be created as a function,
adding boiler plate code to make sure new/changed variables are
reflected in the original code position. You would have to make sure
that the calling context is correct, as that's pretty much impossible
to infer. Of course safe "eval" cases are out as well.) Granted,
that's still not absolute.
There are more transformations but they are more on a smaller scale.
Like those in uglifyjs and google closure compiler.
>> Indeed. The type-system related features I use most often in Eclipse are:
>> - *Safely* renaming a method or function. I do this frequently to keep the
>> vocabulary used in methods etc. fresh. All JS IDEs that I have tried are
>> much fun in this regard.
> Surprisingly difficult, see reference above. I believe jetbrains have some
Obviously, renaming variables is very safe and relatively easy to do
outside the with or eval context. The with case becomes dreadfully
more difficult, but there are some options there. Eval is completely
> It used to track object properties better (which was used for navigation
> and completion), but apparently that got broken a while ago. This is the
> part that would improve completion and navigation to methods or
> module exports.
>> - Find all invocations of a method/function. Often, I just change the
>> name of a method (e.g. by appending an "x") and go through all the
>> errors that that produces.
> though approximations will be useful.
What I do in Zeon is I have a "scope centric" tracking object for each
variable. And a "tracking object centric" tracking object for
properties of a variable. Dito for properties on a property. This of
course stops at dynamic access (although numbers and other literals
can be worked around with and you could also work around it with
annotations). But when you take this central tracking object and store
every reference you encounter for it in it, including marking the
point of declaration(s), you end up with a very easy navigation
structure. If you infer that tracking object to be a function, you
have your declaration, usage and invocations.
More generic, I've come up with a kind of xpath for js (jspath?) where
you can refer to specific elements in the code. (It might actually not
be new, I haven't done an exhaustive search. I'd be surprised if it
were.) Since you work with scopes and each variable in a scope is
unique, you can create reference points to variables in scopes. You
can also create reference points to specific literals like functions,
objects and arrays. If foo is a global function, /foo/bar would refer
to the variable `bar` in the function `foo`. More complex patterns are
possible of course with absolute and relative paths, this is just an
example. I'll publish an article on this soon. Anyways, you can use
this system to have a central tracking method for typing, annotation
and for navigation.
What I'm trying to say is that while there is definitely room for
improvement, it's not entirely hopeless. Although for a lot of cases
it is, as you say, not very "absolute". I've found the worst cases for
js (with respect to static analysis) to be context and dynamic
property access. I'm not counting eval because I don't think eval is
relevant in static analysis (as in, if eval, warn for the worst).
Maybe some kind of annotation could fix the eval black hole... But I'd
love some more tools to help here.
More information about the es-discuss