Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 78 additions & 1 deletion packages/@ember/-internals/deprecations/index.ts
Comment thread
NullVoxPopuli marked this conversation as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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
Expand Up @@ -123,7 +123,7 @@ export const DEPRECATIONS = {
for: 'ember-source',
id: 'deprecate-target-action-support',
since: { available: '7.3.0', enabled: '7.5.0' },
until: '8.0.0',
until: '7.9.0',
url: 'https://deprecations.emberjs.com/id/deprecate-target-action-support',
}),
DEPRECATE_EVENTED: deprecation({
Expand Down Expand Up @@ -161,6 +161,83 @@ export const DEPRECATIONS = {
until: '8.0.0',
url: 'https://deprecations.emberjs.com/id/deprecate-promise-proxy-mixin',
}),
DEPRECATE_OBSERVABLE_MIXIN: deprecation({
id: 'deprecate-observable-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '8.0.0',
url: 'https://deprecations.emberjs.com/id/deprecate-observable-mixin',
}),
DEPRECATE_ENUMERABLE_MIXIN: deprecation({
id: 'deprecate-enumerable-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '7.9.0',
url: 'https://deprecations.emberjs.com/id/deprecate-enumerable-mixin',
}),
DEPRECATE_MUTABLE_ENUMERABLE_MIXIN: deprecation({
id: 'deprecate-mutable-enumerable-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '7.9.0',
url: 'https://deprecations.emberjs.com/id/deprecate-mutable-enumerable-mixin',
}),
DEPRECATE_EMBER_ARRAY_MIXIN: deprecation({
id: 'deprecate-ember-array-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '8.0.0',
url: 'https://deprecations.emberjs.com/id/deprecate-ember-array-mixin',
}),
DEPRECATE_MUTABLE_ARRAY_MIXIN: deprecation({
id: 'deprecate-mutable-array-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '8.0.0',
url: 'https://deprecations.emberjs.com/id/deprecate-mutable-array-mixin',
}),
DEPRECATE_NATIVE_ARRAY_MIXIN: deprecation({
id: 'deprecate-native-array-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '8.0.0',
url: 'https://deprecations.emberjs.com/id/deprecate-native-array-mixin',
}),
DEPRECATE_CONTROLLER_MIXIN: deprecation({
id: 'deprecate-controller-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '7.9.0',
url: 'https://deprecations.emberjs.com/id/deprecate-controller-mixin',
}),
DEPRECATE_ACTION_HANDLER_MIXIN: deprecation({
id: 'deprecate-action-handler-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '7.9.0',
url: 'https://deprecations.emberjs.com/id/deprecate-action-handler-mixin',
}),
DEPRECATE_PROXY_MIXIN: deprecation({
id: 'deprecate-proxy-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '7.9.0',
url: 'https://deprecations.emberjs.com/id/deprecate-proxy-mixin',
}),
DEPRECATE_CONTAINER_PROXY_MIXIN: deprecation({
id: 'deprecate-container-proxy-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '7.9.0',
url: 'https://deprecations.emberjs.com/id/deprecate-container-proxy-mixin',
}),
DEPRECATE_REGISTRY_PROXY_MIXIN: deprecation({
id: 'deprecate-registry-proxy-mixin',
for: 'ember-source',
since: { available: '7.5.0' },
until: '7.9.0',
url: 'https://deprecations.emberjs.com/id/deprecate-registry-proxy-mixin',
}),
};

export function deprecateUntil(message: string, deprecation: DeprecationObject) {
Expand Down
10 changes: 6 additions & 4 deletions packages/@ember/-internals/glimmer/lib/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { get } from '@ember/-internals/metal/lib/property_get';
import { PROPERTY_DID_CHANGE } from '@ember/-internals/metal/lib/property_events';
import type { PropertyDidChange } from '@ember/-internals/metal/lib/property_events';
import { getOwner } from '@ember/-internals/owner';
import TargetActionSupport from '@ember/-internals/runtime/lib/mixins/target_action_support';
import type TargetActionSupport from '@ember/-internals/runtime/lib/mixins/target_action_support';
import InternalTargetActionSupport from '@ember/-internals/runtime/lib/mixins/target_action_support-internal';
import type ViewStates from '@ember/-internals/views/lib/views/states';
import ActionSupport from '@ember/-internals/views/lib/mixins/action_support';
import type ActionSupport from '@ember/-internals/views/lib/mixins/action_support';
import InternalActionSupport from '@ember/-internals/views/lib/mixins/action_support-internal';
import {
addChildView,
getChildViews,
Expand Down Expand Up @@ -803,8 +805,8 @@ interface Component<S = unknown>

class Component<S = unknown>
extends CoreView.extend(
TargetActionSupport,
ActionSupport,
InternalTargetActionSupport,
InternalActionSupport,
{
// These need to be overridable via extend/create but should still
// have a default. Defining them here is the best way to achieve that.
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/glimmer/lib/helpers/each-in.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@module @ember/helper
*/
import { tagForObject } from '@ember/-internals/metal/lib/tags';
import { contentFor as _contentFor } from '@ember/-internals/runtime/lib/mixins/-proxy';
import { contentFor as _contentFor } from '@ember/-internals/runtime/lib/mixins/-proxy-internal';
import { isProxy } from '@ember/-internals/utils/lib/is_proxy';
import { assert } from '@ember/debug';
import type { CapturedArguments } from '@glimmer/interfaces';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import EmberObject from '@ember/object';
import { A } from '@ember/array';
import MutableArray from '@ember/array/mutable';
import { tracked, notifyPropertyChange } from '@ember/-internals/metal';
import { InternalMutableArray as MutableArray } from '@ember/array/index-internal';
import Service, { service } from '@ember/service';
import { moduleFor, RenderingTestCase, runTask } from 'internal-test-helpers';
import { precompileTemplate } from '@ember/template-compilation';
Expand Down
123 changes: 123 additions & 0 deletions packages/@ember/-internals/runtime/lib/mixins/-proxy-internal.ts
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;
105 changes: 9 additions & 96 deletions packages/@ember/-internals/runtime/lib/mixins/-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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, {

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.

Prob want to add @deprecated to the yuidoc above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

/**
The object whose properties will be forwarded.

Expand All @@ -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);
},
});

Expand Down
Loading
Loading