swc-project / swc

Rust-based platform for the Web
https://swc.rs
Apache License 2.0
31.26k stars 1.23k forks source link

helper `set` is incorrectly renamed when it needs protection #9663

Closed unbyte closed 1 month ago

unbyte commented 1 month ago

Describe the bug

The set function reassigns itself internally. When eval exists within the scope, the set function's name should be protected, but it's incorrectly renamed to set1, causing the helpers to fail to execute properly.

It was introduced by #9546

Input code

class A {
    world = false
}

eval("hello")

class B extends A {
    constructor() {
        super()
    }

    set hello(v) {
        super.world = v
    }

    get hello() {
        return super.world
    }
}

Config

No response

Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.7.37-nightly-20241021.1&code=H4sIAAAAAAAAA03NPQ6DMAwF4Dk%2BhcUUlt6Aob1JFFwYrKSynYBUcffyUxCbZX%2FvOXJQxSd%2BwU1ZuMcO34GVYAGgGtg3IzHnpgWIO30hzUap%2F4diTmpSomXx7bZwWj60zuDWBqdkuBf4ers%2Bzlf1UMOlDiRkRRLe7OaWH0dO9hOsAAAA&config=H4sIAAAAAAAAA12PSw6DMAxE95wCed1tNz1BNz2ElRoU5HxkBwmEuHsDJLRll3ljjydL07YwqIFHu%2BRnFhFFSU6dic4%2B4ZQJkHGoRmxMcKvuoJvVISvtaD0cSIJeuyAuu35krhilp7SH6b2kAIegVFMKoymReOQncSTRi%2Bust93829Kh7%2FkSkrEJLgqp%2FndsSk9w4T3uW%2BX3aY6b2tZc8IPCOWn1VWfPC98aR%2Fb6AXANGa1PAQAA

SWC Info output

No response

Expected behavior

keep name set

Actual behavior

set is renamed to set1 while usages are still set

function set1(target, property, value, receiver) {
    if (typeof Reflect !== "undefined" && Reflect.set) {
        set1 = Reflect.set;
    } else {
        set1 = function set1(target, property, value, receiver) {
            var base = _super_prop_base(target, property);
            var desc;
            if (base) {
                desc = Object.getOwnPropertyDescriptor(base, property);
                if (desc.set) {
                    desc.set.call(receiver, value);
                    return true;
                } else if (!desc.writable) {
                    return false;
                }
            }
            desc = Object.getOwnPropertyDescriptor(receiver, property);
            if (desc) {
                if (!desc.writable) {
                    return false;
                }
                desc.value = value;
                Object.defineProperty(receiver, property, desc);
            } else {
                _define_property(receiver, property, value);
            }
            return true;
        };
    }
    return set1(target, property, value, receiver);
}
function _set(target, property, value, receiver, isStrict) {
    var s = set(target, property, value, receiver || target);
    if (!s && isStrict) {
        throw new Error("failed to set property");
    }
    return value;
}

Version

1.7.36

Additional context

No response