Skip to content

Fix super set semantic#5774

Closed
hax wants to merge 12 commits intobabel:masterfrom
hax:master
Closed

Fix super set semantic#5774
hax wants to merge 12 commits intobabel:masterfrom
hax:master

Conversation

@hax
Copy link
Copy Markdown

@hax hax commented May 25, 2017

Q A
Patch: Bug Fix? Yes
Major: Breaking Change? No
Minor: New Feature? No
Deprecations? No
Spec Compliancy? Yes
Tests Added/Pass? Yes
Fixed Tickets Fixes #5769
License MIT
Doc PR No
Dependency Changes No

This PR fixes #5769 .

This PR also revise an unrelated testcase which embed _set code, I add external-helpers to its conf to remove _set/_get implementation details from it.

@mention-bot
Copy link
Copy Markdown

@hax, thanks for your PR! By analyzing the history of the files in this pull request, we identified @spicyj, @Nooks and @ksjun to be potential reviewers.

@codecov
Copy link
Copy Markdown

codecov bot commented May 25, 2017

Codecov Report

Merging #5774 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #5774   +/-   ##
=======================================
  Coverage   84.79%   84.79%           
=======================================
  Files         204      204           
  Lines        9607     9607           
  Branches     2701     2701           
=======================================
  Hits         8146     8146           
  Misses        977      977           
  Partials      484      484
Impacted Files Coverage Δ
packages/babel-helpers/src/helpers.js 100% <ø> (ø) ⬆️
packages/babel-traverse/src/path/context.js 85.34% <0%> (-0.87%) ⬇️
...bel-plugin-transform-es2015-classes/src/vanilla.js 90.59% <0%> (+0.42%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5b26184...bdc5ad7. Read the comment docs.

@jridgewell jridgewell added the PR: Spec Compliance 👓 A type of pull request used for our changelog categories label May 25, 2017
Copy link
Copy Markdown
Member

@jridgewell jridgewell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add the code from #5769 as a new exec.js test case.

@hax
Copy link
Copy Markdown
Author

hax commented May 26, 2017

@jridgewell test case added.

if (parent !== null) {
set(parent, property, value, receiver);
} else {
receiver[property] = value;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://tc39.github.io/ecma262/#sec-ordinaryset

This combines steps 3.c.i (overwriting desc with a new descriptor) and the steps under 4. Looks fine.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... looks like this is not fine.

receiver[property] = value will execute setters defined in the receiver's prototype, even though they should not be executed (the setter from super should be executed instead).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading spec is hard. So I just add another test case for accessors. This test case pass in V8, WebKit and Firefox so I assume it's correct.

receiver[property] = value;
}
} else if ("value" in desc && desc.writable) {
desc.value = value;
Copy link
Copy Markdown
Member

@Jessidhia Jessidhia May 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused about this, though, but hopefully this is not broken as it is here. Step 4.d.iv does a [[DefineOwnProperty]] call, but this just directly updates the .value in the descriptor without calling Object.defineProperty.

var o = { foo: 'bar' }; Object.getOwnPropertyDescriptor(o, 'foo').value = 'baz'

is not sufficient to change the value of o.foo.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The helper also just silently does nothing if not writable (needs to throw in strict mode), but solving that is a harder problem.

Copy link
Copy Markdown
Member

@Jessidhia Jessidhia May 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the right way to solve it is also to replace it with basically receiver[property] = value. This will also execute the OrdinarySet algorithm. However, there needs to be a check for 'value' in Object.getOwnPropertyDescriptor(receiver, property) (if there is a pre-existing descriptor). It needs to fail if the receiver[property] is a setter.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the silent fail in sloopy mode or throw in strict mode for writeable: false and no setter is a hard problem, that's why I do not want to deal with it in this PR. Let's just do one thing in one time.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO DefineOwnProperty is not the same with receiver[property] = value.
Think this example.

class A {
}

class B extends A {
    constructor() {
        super()
        super.x = 3
        console.log(this.x)
        console.log(super.x)
    }

    set x(v) {
        console.log('i am invoked!') // will not invoked
        this._x = v
    }
    get x() {
        return this._x
    }
}
new B()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

if (parent !== null) {
set(parent, property, value, receiver);
} else {
Object.defineProperty(receiver, property, {value: value});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs writable: true, enumerable: true, configurable: true?

@danez
Copy link
Copy Markdown
Member

danez commented Mar 12, 2018

This is part of #7553 . Closing

@danez danez closed this Mar 12, 2018
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 5, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Spec Compliance 👓 A type of pull request used for our changelog categories

Projects

None yet

Development

Successfully merging this pull request may close these issues.

class inheritance: uses super to access the properties of the parent class

7 participants