BlackVegetable
BlackVegetable

Reputation: 13054

All possible ways to declare Javascript variables

To create an IDE that would autocomplete all variables the user declares but would be oblivious to other variables such as Math.PI or even the module Math, the IDE would need to be able to identify all identifiers relating to variables declared by the user. What mechanism could be used to capture all such variables, assuming you already have access to the AST (Abstract Symbol Table) for the program?

I am using reflect.js (https://github.com/zaach/reflect.js) to generate the AST.

Upvotes: 7

Views: 965

Answers (2)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276306

I think it's pretty much impossible

Here is why I think it's pretty much impossible without executing it:

Let us go through the unexplored parts, from easy to hard.

Easy to catch:

Function scope is missed here:

(function(x){
    //x is now an object with an a property equal to 3
    // for the scope of that IIFE.
    x;
})({a:3});

Here is some fun dirty tricks for you all.:

Introducing... drum roll... Block Scoping!!

with({x:3}){
    x;//x is now declared in the scope of that with and is equal to 3.
}


try{ throw 5}catch(x){ 
    x // x is now declared in the scope of the try block and is equal to 5;
}

(people reading: I beg you to please not use these last two for actual scoping in code :))

Not easy:

Bracket notation:

var n = "lo";
a["h"+"e"+"l"+n] = "world"; // need to understand that a.hello is a property.
                        // not a part of the ast!

The really hard parts:

Let us not forget invoking the compiler These would not show up in the AST:

eval("var x=5"); // declares x as 5, just a string literal and a function call
new Function("window.x = 5")();// or global in node 

In node.js this can also be done with the vm module. In the browser using document.write or script tag injection.

What else? Of course they can obfuscate all they want:

new Function(["w","i","n","dow.x"," = ","5"].join(""))(); // Good luck finding this!
new Function('new Function(["w","i","n","dow.x"," = ","5"].join(""))()')();// Getting dizzy already?

So what can be done?

  • Execute the code, once, in a closed, timed environment when you update the symbol table (just the relevant parts)
  • See what's the generated symbol table is from the execution
  • Boom, you got yourself a symbol table.

This is not reliable but it's probably as close as you get.

The only other alternative I can think of, which is what most IDEs are doing is to simply ignore anything that is not:

object.property = ... //property definition
var a = ... //scoped
b = ... //global, or error in strict mode
function fn(){ //function declaration
object["property"] //property with a _fixed_ literal in bracket notation.

And also, function parameters.

I have seen no IDE that has been able to deal with anything but these. Since they're the most common by far, I think it's perfectly reasonable to count those.

Upvotes: 7

Braden
Braden

Reputation: 1558

By adding them onto am object that already exists....ie

window.mynewvar = 5;

function mynewfunc() {

}

Upvotes: -2

Related Questions