HaxeFoundation / HaxeFoundation/haxe
[JS] Use of js.Syntax.code may result in variables being redeclared during use scope
- Dominant language
- Haxe
- Stars
- 6.9k
- Forks
- 715
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 11
Description
Version: 4.2.0-rc.1+45809b90c
I felt like stitching a loop via js.Syntax.code as per [last year's recommendation](https://github.com/HaxeFoundation/haxe/issues/8069#issuecomment-478325996) was inevitably going to backfire and so it did.
Haxe:
```haxe
import haxe.DynamicAccess;
class Test {
/** https://github.com/HaxeFoundation/haxe/issues/8069#issuecomment-478325996 */
public static inline function forField(q:Dynamic, fn:String->Void):Void {
var fd:String = null;
var has:js.lib.Function = untyped js.lib.Object.prototype.hasOwnProperty;
js.Syntax.code("for ({0} in {1}) {", fd, q);
if (has.call(q, fd)) fn(fd);
js.Syntax.code("}");
}
static inline function add(comp:Comp) {
trace(comp, comp); // just forcing the variable to be preserved
}
static function trouble(kind:DynamicAccess, comp:Array) {
var results:Array<{name:String}> = [];
forField(kind, function(field:String) {
var matches = comp.filter((c) -> c.name == field);
add(matches[0]);
});
return results;
}
public static inline function main() {
trouble(
{ test: "hi", test2: "hello", test3: "oh no" },
[{name: "test"}, {name: "etc."}]
);
}
}
typedef Comp = { name:String };
```
Output of interest:
```js
Test.trouble = function(kind,comp) {
var results = [];
var q = kind;
var fd = null;
var has = Object.prototype.hasOwnProperty;
for (fd in q) {
if(has.call(q,fd)) {
var _g = [];
var _g1 = 0;
var _g2 = comp;
while(_g1 < _g2.length) {
var v = _g2[_g1];
++_g1;
if(v.name == fd) {
_g.push(v);
}
}
var matches = _g;
var comp = matches[0]; // <-- (!)
haxe_Log.trace(comp,{ fileName : "src/Test.hx", lineNumber : 14, className : "Test", methodName : "add", customParams : [comp]});
}
}
return results;
};
```
Note that the compiler shadows `comp` because, as far as it's concerned, the comp-argument will no longer be needed (but it is, since we're in a loop).
I do not have any particular suggestions as to how this should be cleanly detected - ultimately I still feel like there's need for a mechanism to inject blocks of code.
Contributor guide
Assessment
This issue has not been assessed yet.