-
Notifications
You must be signed in to change notification settings - Fork 2k
Temporary variables should not be accessible from user code #1500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Potential issue with this: are there valid use cases for meta-programming wizardry that need to use or redefine these variables inside of CoffeeScript code? |
@breckinloggins: these variables are implementation details that aren't (supposed to be) exposed to the coffeescript user, so no |
I like the strategy of checking for a special prefix. I assume it would be faster than another pass.
|
@breckinloggins: That would make the output JS considerably less readable in my opinion. It's an option of course, but one I'd like to avoid. |
Another option: collecting all identifiers in lexer or parser. Yet anothor option is an optimistic way: just generate codes as before. When the compiler detect a name crush, record the crushed name, throw a exception, and retry generating the codes from beginning. |
@taku0 Your second option has architecture and memory advantages since we're not having the lexer or parser keep track of extra information just for the sake of this somewhat pathological case. I assume when you say "checking name crushes", you're just referring to any mention of a name that's been declared in Let's say someone declares The other thing that would be nice is to fix:
Here the code is assuming that anything that starts with a Also, the way the compiler handes utility functions is different from variables. It treats them as reserved words and doesn't let you use them in code. I suppose we could do it this way for temp vars except it would be much less friendly because you couldn't predict in advance what would be reserved and what would not be reserved. |
I meant to scan declared names up to the root of scope chain, not just from that scope chain one level up (I have confused "clash" with "crush". "name clashing" is the correct words). On the other hand, I noticed now that it is enough to regenerate from one level up if we declare the variable in the inner scope. In the example below, inserting
Declareing the variable in the inner scope would be safe since the temporary variables are used only in the declared scope but not inner scopes, with respect to the current compiler. |
…rs uniquely Any variables generated by CoffeeScript are now made sure to be named to something not present in the source code being compiled. This way you can no longer interfere with them, either on purpose or by mistake. (jashkenas#1500, jashkenas#1574) For example, `({a}, _arg) ->` now compiles correctly. (jashkenas#1574) As opposed to the somewhat complex implementations discussed in jashkenas#1500, this commit takes a very simple approach by saving all used variables names using a single pass over the token stream. Any generated variables are then made sure not to exist in that list. `(@A) -> a` used to be equivalent to `(@A) -> @a`, but now throws a runtime `ReferenceError` instead (unless `a` exists in an upper scope of course). (jashkenas#3318) `(@A) ->` used to compile to `(function(a) { this.a = a; })`. Now it compiles to `(function(_at_a) { this.a = _at_a; })`. (But you cannot access `_at_a` either, of course.) Because of the above, `(@A, a) ->` is now valid; `@a` and `a` are not duplicate parameters. Duplicate this-parameters with a reserved word, such as `(@case, @case) ->`, used to compile but now throws, just like regular duplicate parameters.
Running the following code result in a TypeError "Cannot call method 'push' of null" since the compiler-generated temporary variable "_results" is overriden.
The compiler should generate a fresh variable that is never accessed from user code.
To accomplish this, we might use 2-pass strategy: one for scan all variables used in the code, and one for generating JavaScript code.
Another storategy is reserving all words starting with special prefix (e.g. '__coffee_script_compiler_generated') and prohibiting users from using them as variable names.
The text was updated successfully, but these errors were encountered: