-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Deprecate PromiseProxyMixin, Enumerable, and Observable (mixins, RFC#… #21588
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated to 7.5 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| /** | ||
| @module ember | ||
| */ | ||
|
|
||
| import { meta } from '@ember/-internals/meta/lib/meta'; | ||
| import { InternalMixin } from '@ember/object/mixin-internal'; | ||
| import { get } from '@ember/-internals/metal/lib/property_get'; | ||
| import { set } from '@ember/-internals/metal/lib/property_set'; | ||
| import { defineProperty } from '@ember/-internals/metal/lib/properties'; | ||
| import { tagForObject, tagForProperty } from '@ember/-internals/metal/lib/tags'; | ||
| import computed from '@ember/-internals/metal/lib/computed'; | ||
| import { setProxy, isProxy } from '@ember/-internals/utils/lib/is_proxy'; | ||
| import { setupMandatorySetter } from '@ember/-internals/utils/lib/mandatory-setter'; | ||
| import { isObject } from '@ember/-internals/utils/lib/spec'; | ||
| import { assert } from '@ember/debug'; | ||
| import { DEBUG } from '@glimmer/env'; | ||
| import { setCustomTagFor } from '@glimmer/manager/lib/util/args-proxy'; | ||
| import type { UpdatableTag, Tag } from '@glimmer/interfaces'; | ||
| import { combine, UPDATE_TAG as updateTag } from '@glimmer/validator/lib/validators'; | ||
| import { tagFor, tagMetaFor } from '@glimmer/validator/lib/meta'; | ||
|
|
||
| export function contentFor<T>(proxy: { content: T | null }): T | null { | ||
| let content = get(proxy, 'content'); | ||
| // SAFETY: Ideally we'd assert instead of casting, but @glimmer/validator doesn't give us | ||
| // sufficient public types for this. Previously this code was .js and worked correctly so | ||
| // hopefully this is sufficiently reliable. | ||
| updateTag(tagForObject(proxy) as UpdatableTag, tagForObject(content)); | ||
| return content; | ||
| } | ||
|
|
||
| function customTagForProxy(proxy: object, key: string, addMandatorySetter?: boolean): Tag { | ||
| assert('Expected a proxy', isProxy(proxy)); | ||
|
|
||
| let meta = tagMetaFor(proxy); | ||
| let tag = tagFor(proxy, key, meta); | ||
|
|
||
| if (DEBUG) { | ||
| // TODO: Replace this with something more first class for tracking tags in DEBUG | ||
| // SAFETY: This is not an officially supported property but setting shouldn't cause issues. | ||
| (tag as any)._propertyKey = key; | ||
| } | ||
|
|
||
| if (key in proxy) { | ||
| if (DEBUG && addMandatorySetter) { | ||
| assert('[BUG] setupMandatorySetter should be set when debugging', setupMandatorySetter); | ||
| setupMandatorySetter(tag, proxy, key); | ||
| } | ||
|
|
||
| return tag; | ||
| } else { | ||
| let tags: Tag[] = [tag, tagFor(proxy, 'content', meta)]; | ||
|
|
||
| let content = contentFor(proxy); | ||
|
|
||
| if (isObject(content)) { | ||
| tags.push(tagForProperty(content, key, addMandatorySetter)); | ||
| } | ||
|
|
||
| return combine(tags); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| The internal counterpart to the public `ProxyMixin`. Ember's own internals | ||
| apply this so that they do not trigger the deprecation that the public | ||
| mixin emits. The public API documentation lives on the public copy. | ||
|
|
||
| @internal | ||
| */ | ||
| const InternalProxyMixin = /*@__PURE__*/ InternalMixin.create({ | ||
| /** | ||
| The object whose properties will be forwarded. | ||
|
|
||
| @property content | ||
| @type {unknown} | ||
| @default null | ||
| */ | ||
| content: null, | ||
|
|
||
| init() { | ||
| this._super(...arguments); | ||
| setProxy(this); | ||
| tagForObject(this); | ||
| setCustomTagFor(this, customTagForProxy); | ||
| }, | ||
|
|
||
| willDestroy() { | ||
| this.set('content', null); | ||
| this._super(...arguments); | ||
| }, | ||
|
|
||
| isTruthy: computed('content', function () { | ||
| return Boolean(get(this, 'content')); | ||
| }), | ||
|
|
||
| unknownProperty(key: string) { | ||
| let content = contentFor(this); | ||
| return content ? get(content, key) : undefined; | ||
| }, | ||
|
|
||
| setUnknownProperty(key: string, value: unknown) { | ||
| let m = meta(this); | ||
|
|
||
| if (m.isInitializing() || m.isPrototypeMeta(this)) { | ||
| // if marked as prototype or object is initializing then just | ||
| // defineProperty rather than delegate | ||
| defineProperty(this, key, null, value); | ||
| return value; | ||
| } | ||
|
|
||
| let content = contentFor(this); | ||
|
|
||
| assert( | ||
| `Cannot delegate set('${key}', ${value}) to the 'content' property of object proxy ${this}: its 'content' is undefined.`, | ||
| content | ||
| ); | ||
|
|
||
| // SAFETY: We don't actually guarantee that this is an object, so this isn't necessarily safe :( | ||
| return set(content as object, key, value); | ||
| }, | ||
| }); | ||
|
|
||
| export default InternalProxyMixin; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,69 +2,17 @@ | |
| @module ember | ||
| */ | ||
|
|
||
| import { meta } from '@ember/-internals/meta/lib/meta'; | ||
| import Mixin from '@ember/object/mixin'; | ||
| import { INTERNAL_MIXIN_CREATE } from '@ember/-internals/utils/lib/internal-mixin-create'; | ||
| import { get } from '@ember/-internals/metal/lib/property_get'; | ||
| import { set } from '@ember/-internals/metal/lib/property_set'; | ||
| import { defineProperty } from '@ember/-internals/metal/lib/properties'; | ||
| import { tagForObject, tagForProperty } from '@ember/-internals/metal/lib/tags'; | ||
| import computed from '@ember/-internals/metal/lib/computed'; | ||
| import { setProxy, isProxy } from '@ember/-internals/utils/lib/is_proxy'; | ||
| import { setupMandatorySetter } from '@ember/-internals/utils/lib/mandatory-setter'; | ||
| import { isObject } from '@ember/-internals/utils/lib/spec'; | ||
| import { assert } from '@ember/debug'; | ||
| import { DEBUG } from '@glimmer/env'; | ||
| import { setCustomTagFor } from '@glimmer/manager/lib/util/args-proxy'; | ||
| import type { UpdatableTag, Tag } from '@glimmer/interfaces'; | ||
| import { combine, UPDATE_TAG as updateTag } from '@glimmer/validator/lib/validators'; | ||
| import { tagFor, tagMetaFor } from '@glimmer/validator/lib/meta'; | ||
| import { DeprecatedMixin } from '@ember/object/mixin-internal'; | ||
| import { deprecateUntil, DEPRECATIONS } from '@ember/-internals/deprecations'; | ||
| import InternalProxyMixin from '@ember/-internals/runtime/lib/mixins/-proxy-internal'; | ||
|
|
||
| export function contentFor<T>(proxy: ProxyMixin<T>): T | null { | ||
| let content = get(proxy, 'content'); | ||
| // SAFETY: Ideally we'd assert instead of casting, but @glimmer/validator doesn't give us | ||
| // sufficient public types for this. Previously this code was .js and worked correctly so | ||
| // hopefully this is sufficiently reliable. | ||
| updateTag(tagForObject(proxy) as UpdatableTag, tagForObject(content)); | ||
| return content; | ||
| } | ||
|
|
||
| function customTagForProxy(proxy: object, key: string, addMandatorySetter?: boolean): Tag { | ||
| assert('Expected a proxy', isProxy(proxy)); | ||
|
|
||
| let meta = tagMetaFor(proxy); | ||
| let tag = tagFor(proxy, key, meta); | ||
|
|
||
| if (DEBUG) { | ||
| // TODO: Replace this with something more first class for tracking tags in DEBUG | ||
| // SAFETY: This is not an officially supported property but setting shouldn't cause issues. | ||
| (tag as any)._propertyKey = key; | ||
| } | ||
|
|
||
| if (key in proxy) { | ||
| if (DEBUG && addMandatorySetter) { | ||
| assert('[BUG] setupMandatorySetter should be set when debugging', setupMandatorySetter); | ||
| setupMandatorySetter(tag, proxy, key); | ||
| } | ||
|
|
||
| return tag; | ||
| } else { | ||
| let tags: Tag[] = [tag, tagFor(proxy, 'content', meta)]; | ||
|
|
||
| let content = contentFor(proxy); | ||
|
|
||
| if (isObject(content)) { | ||
| tags.push(tagForProperty(content, key, addMandatorySetter)); | ||
| } | ||
|
|
||
| return combine(tags); | ||
| } | ||
| } | ||
| export { contentFor } from '@ember/-internals/runtime/lib/mixins/-proxy-internal'; | ||
|
|
||
| /** | ||
| `ProxyMixin` forwards all properties not defined by the proxy itself | ||
| to a proxied `content` object. See ObjectProxy for more details. | ||
|
|
||
| @deprecated | ||
| @class ProxyMixin | ||
| @namespace Ember | ||
| @private | ||
|
|
@@ -91,7 +39,7 @@ interface ProxyMixin<T = unknown> { | |
| setUnknownProperty<V>(key: string, value: V): V; | ||
| } | ||
|
|
||
| const ProxyMixin = /*@__PURE__*/ Mixin[INTERNAL_MIXIN_CREATE]({ | ||
| const ProxyMixin = /*@__PURE__*/ DeprecatedMixin.create(InternalProxyMixin, { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prob want to add
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| /** | ||
| The object whose properties will be forwarded. | ||
|
|
||
|
|
@@ -100,48 +48,13 @@ const ProxyMixin = /*@__PURE__*/ Mixin[INTERNAL_MIXIN_CREATE]({ | |
| @default null | ||
| @public | ||
| */ | ||
| content: null, | ||
|
|
||
| init() { | ||
| this._super(...arguments); | ||
| setProxy(this); | ||
| tagForObject(this); | ||
| setCustomTagFor(this, customTagForProxy); | ||
| }, | ||
|
|
||
| willDestroy() { | ||
| this.set('content', null); | ||
| this._super(...arguments); | ||
| }, | ||
|
|
||
| isTruthy: computed('content', function () { | ||
| return Boolean(get(this, 'content')); | ||
| }), | ||
|
|
||
| unknownProperty(key: string) { | ||
| let content = contentFor(this); | ||
| return content ? get(content, key) : undefined; | ||
| }, | ||
|
|
||
| setUnknownProperty(key: string, value: unknown) { | ||
| let m = meta(this); | ||
|
|
||
| if (m.isInitializing() || m.isPrototypeMeta(this)) { | ||
| // if marked as prototype or object is initializing then just | ||
| // defineProperty rather than delegate | ||
| defineProperty(this, key, null, value); | ||
| return value; | ||
| } | ||
|
|
||
| let content = contentFor(this); | ||
|
|
||
| assert( | ||
| `Cannot delegate set('${key}', ${value}) to the 'content' property of object proxy ${this}: its 'content' is undefined.`, | ||
| content | ||
| deprecateUntil( | ||
| 'The `ProxyMixin` mixin is deprecated. Access the underlying object directly instead.', | ||
| DEPRECATIONS.DEPRECATE_PROXY_MIXIN | ||
| ); | ||
|
|
||
| // SAFETY: We don't actually guarantee that this is an object, so this isn't necessarily safe :( | ||
| return set(content as object, key, value); | ||
| }, | ||
| }); | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.