-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Static methods unnecessarily copied to subclass constructor #3177
Comments
@rictic This is only true for browsers that support Copying the static methods is not a perfect transpilation method, but is better than none. |
The actual code uses $jscomp.inherits instead of Object.setPrototypeOf. $jscomp.inherits = function(a, b) {
a.prototype = $jscomp.objectCreate(b.prototype);
a.prototype.constructor = a;
if ($jscomp.setPrototypeOf) {
var c = $jscomp.setPrototypeOf;
c(a, b);
} else {
for (c in b) {
if ("prototype" != c) {
if (Object.defineProperties) {
var d = Object.getOwnPropertyDescriptor(b, c);
d && Object.defineProperty(a, c, d);
} else {
a[c] = b[c];
}
}
}
}
a.superClass_ = b.prototype;
}; The else block looks like it already loops through the properties of Super and copies them onto Sub. As a result, the The specific case that this came up in was a project that does not support IE <11, so they can depend on |
There's code that copies those methods outside of the I understand the extra code for projects that don't depend on <IE11, but this was the best compromise we could achieve. |
Internal issue created b/122077271 |
This is working as intended. As @ChadKillingsworth said, this was the best compromise we could reach to make sure code that depends on inheritance of static methods would work on both old and new browsers. |
We're miscommunicating. I agree that the implementation of
The explicit set of |
I think that's here: https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/Es6ToEs3ClassSideInheritance.java#L41-L42 And it sounds like this entire pass can be removed now that transpilation is after type checking. |
@rictic thanks for the clarification. We may have to just try it and see what breaks. |
We tried removing this pass a few months ago, but it caused CollapseProperties to break class-side inheritance after transpilation. The pass didn't realize that It should be possible to merge the pass's logic into property collapsing, though, instead of running it as part of transpilation.
|
It looks like that pass is being kept for optimization now under the name ConcretizeStaticInheritanceForInlining. Could the step that copies statics be removed though? https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/ConcretizeStaticInheritanceForInlining.java#L162 |
I think the problem that @lauraharker mentioned above still exists, so no. @justinfagnani what brought this to your attention? Do you have a specific use-case where changing this would make a big difference? |
@brad4d we still hit problems where code that works externally breaks in google3 in sometimes vary hard to debug ways, resulting in fixes like lit/lit#4257 where we have to access a static property only via computed property access to work around the bug. In this latest case I'm worries that the workaround has a performance cost since computed property declarations are slower, at least in V8. |
A minimal repro of the issue we're seeing now: class Foo {
/**
* Using export to avoid needing reflect.objectProperty below.
* @export
* @nocollapse
*/
static foo: string = 'Foo base value';
/** @nocollapse */
static finalize() {
if (!this.hasOwnProperty('foo')) {
this.foo = 'a subclass of Foo';
}
}
}
class Bar extends Foo {}
function assertEqual(actual: string, expected: string, name: string) {
if (actual === expected) {
return;
}
throw new Error(`Expected ${name} to be ${expected} but was ${actual}`);
}
Foo.finalize();
Bar.finalize();
assertEqual(Foo.foo, 'Foo base value', 'Foo.foo');
assertEqual(Bar.foo, 'a subclass of Foo', 'Bar.foo'); When targeting ES5 with advanced optimizations, this throws The Closure Compiler Playground version times out when compiling with advanced optimizations: |
Thanks for pinging this issue. We're working on moving transpilation passes to occur after normalization. I expect that doing that will allow us to fix this problem along with a lot of other ones. |
This code:
Is lowered to ES5 that is essentially:
The
Sub.method = Super.method;
line is unnecessary, becauseObject.setPrototypeOf(Sub, Super);
has already ensured thatSub.method
would work correctly, and it also causesSub.method
to be an ownproperty ofSub
, which diverges from the original code's semantics.The text was updated successfully, but these errors were encountered: