Skip to content
Draft
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
4 changes: 4 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
EmberENV['_ALL_DEPRECATIONS_ENABLED'] = true;
}

if (QUnit.urlParams.NO_EMBER_OBJECT) {
EmberENV['_NO_EMBER_OBJECT'] = true;
}

if (QUnit.urlParams.OVERRIDE_DEPRECATION_VERSION) {
EmberENV['_OVERRIDE_DEPRECATION_VERSION'] = QUnit.urlParams.OVERRIDE_DEPRECATION_VERSION;
}
Expand Down
34 changes: 34 additions & 0 deletions packages/@ember/-internals/deprecations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ export const DEPRECATIONS = {
until: '8.0.0',
url: 'https://deprecations.emberjs.com/id/deprecate-ember-utils',
}),
DEPRECATE_EMBER_OBJECT: deprecation({
id: 'deprecate-ember-object',
for: 'ember-source',
since: { available: '7.5.0' },
until: '9.0.0',
url: 'https://deprecations.emberjs.com/id/deprecate-ember-object',
}),
};

export function deprecateUntil(message: string, deprecation: DeprecationObject) {
Expand All @@ -183,3 +190,30 @@ export function deprecateUntil(message: string, deprecation: DeprecationObject)
}
deprecate(message, deprecation.test, options);
}

declare global {
interface ImportMetaEnv {
EMBER_DROP_CLASSIC_FEATURES?: boolean | string;
}
}

/**
Reports the use of an API that RFC 1234 removes with `EmberObject`.

The `EMBER_DROP_CLASSIC_FEATURES` build flag is a preview of the removal:
when it is set, the API throws.

@private
*/
export function deprecateEmberObject(api: string) {
if (import.meta.env?.EMBER_DROP_CLASSIC_FEATURES) {
throw new Error(
`${api} is not available, because the \`EMBER_DROP_CLASSIC_FEATURES\` build flag is set. Please see ${DEPRECATIONS.DEPRECATE_EMBER_OBJECT.options.url} for more details.`
);
}

deprecateUntil(
`${api} is deprecated. Use native classes with tracked properties instead.`,
DEPRECATIONS.DEPRECATE_EMBER_OBJECT
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
setOwner,
} from '@ember/-internals/owner';
import { guidFor } from '@ember/-internals/utils/lib/guid';
import setProperties from '@ember/-internals/metal/lib/set_properties';
import {
addChildView,
setElementView,
Expand Down Expand Up @@ -454,7 +455,7 @@ export default class CurlyComponentManager
bucket.argsRevision = valueForTag(argsTag);

component[IS_DISPATCHING_ATTRS] = true;
component.setProperties(props);
setProperties(component, props);
component[IS_DISPATCHING_ATTRS] = false;

sendCoreViewEvent(component, 'didUpdateAttrs');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { InternalOwner } from '@ember/-internals/owner';
import { generateControllerFactory } from '@ember/routing/lib/generate_controller';
import { assert } from '@ember/debug';
import { set } from '@ember/-internals/metal/lib/property_set';
import type EngineInstance from '@ember/engine/instance';
import { associateDestroyableChild } from '@glimmer/destroyable';
import type {
Expand Down Expand Up @@ -161,7 +162,7 @@ class MountManager
let { controller, modelRef } = bucket;

if (modelRef !== undefined) {
controller.set('model', valueForRef(modelRef));
set(controller, 'model', valueForRef(modelRef));
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion packages/@ember/-internals/glimmer/lib/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
getComponentCapturedArgs,
} from './component-managers/curly';
import hasDOM from '@ember/-internals/browser-environment/lib/has-dom';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

// Keep track of which component classes have already been processed for lazy event setup.
let lazyEventsProcessed = new WeakMap<EventDispatcher, WeakSet<object>>();
Expand Down Expand Up @@ -1051,7 +1052,7 @@ class Component<S = unknown>

getAttr(key: string) {
// TODO Intimate API should be deprecated
return this.get(key);
return get(this, key);
}

/**
Expand Down Expand Up @@ -1693,4 +1694,6 @@ Component.reopenClass({

setInternalComponentManager(CURLY_COMPONENT_MANAGER, Component);

setFrameworkClass(Component);

export default Component;
3 changes: 3 additions & 0 deletions packages/@ember/-internals/glimmer/lib/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type { DirtyableTag } from '@glimmer/interfaces';
import { consumeTag } from '@glimmer/validator/lib/tracking';
import { createTag, DIRTY_TAG as dirtyTag } from '@glimmer/validator/lib/validators';
import { IS_CLASSIC_HELPER } from './helper-brand';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

export { isClassicHelper } from './helper-brand';

Expand Down Expand Up @@ -408,3 +409,5 @@ export function helper(
// `helper()` invocation in favor of using plain functions.
return new Wrapper(helperFn) as unknown as FunctionBasedHelper<any>;
}

setFrameworkClass(Helper);
2 changes: 1 addition & 1 deletion packages/@ember/-internals/runtime/lib/mixins/-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const ProxyMixin = /*@__PURE__*/ Mixin[INTERNAL_MIXIN_CREATE]({
},

willDestroy() {
this.set('content', null);
set(this, 'content', null);
this._super(...arguments);
},

Expand Down
31 changes: 31 additions & 0 deletions packages/@ember/-internals/utils/lib/internal-framework-class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
Marks the classes that Ember itself builds on `EmberObject`, such as
`Route`, `Controller` and `Service`.

The `EmberObject` deprecation applies to classes that extend `EmberObject`
directly. A class that has this mark, and each subclass of it, stays
usable.

This is a Symbol so that application code cannot set the mark by name.

@private
*/
const FRAMEWORK_CLASS = Symbol('__internal__framework__class__');

export function setFrameworkClass(Class: object): void {
(Class as Record<symbol, unknown>)[FRAMEWORK_CLASS] = true;
}

/**
True for a marked class and for each subclass of it.
*/
export function isFrameworkClass(Class: object): boolean {
return (Class as Record<symbol, unknown>)[FRAMEWORK_CLASS] === true;
}

/**
True only for the class that Ember marked, not for its subclasses.
*/
export function isOwnFrameworkClass(Class: object): boolean {
return Object.prototype.hasOwnProperty.call(Class, FRAMEWORK_CLASS);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import EmberObject from '@ember/object';
import { getElementView } from './utils';
import type { BootEnvironment } from '@ember/engine/instance';
import type Component from '@ember/-internals/glimmer/lib/component';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

/**
@module ember
Expand Down Expand Up @@ -316,3 +317,5 @@ export default class EventDispatcher extends EmberObject {
return '(EventDispatcher)';
}
}

setFrameworkClass(EventDispatcher);
3 changes: 3 additions & 0 deletions packages/@ember/-internals/views/lib/views/core_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Evented from '@ember/object/evented';
import { FrameworkObject } from '@ember/object/-internals';
import type { ViewState } from './states';
import states from './states';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

/**
`CoreView` is an abstract class that exists to give view-like behavior
Expand Down Expand Up @@ -135,4 +136,6 @@ class CoreView extends FrameworkObject.extend(ActionHandler) {
// Declare on the prototype to have a single shared value.
CoreView.prototype._states = states;

setFrameworkClass(CoreView);

export default CoreView;
3 changes: 3 additions & 0 deletions packages/@ember/application/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { setupApplicationRegistry } from '@ember/-internals/glimmer/lib/setup-re
import RouterService from '@ember/routing/router-service';
import type { EngineInstanceOptions } from '@ember/engine/instance';
import type { SimpleDocument, SimpleElement } from '@simple-dom/interface';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

/**
* @deprecated Use `import { getOwner } from '@ember/owner';` instead.
Expand Down Expand Up @@ -1133,4 +1134,6 @@ function commonSetupRegistry(registry: Registry) {
registry.register('service:router', RouterService);
}

setFrameworkClass(Application);

export { Application as default };
3 changes: 3 additions & 0 deletions packages/@ember/application/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Router from '@ember/routing/router';
import EventDispatcher from '@ember/-internals/views/lib/system/event_dispatcher';
import type Registry from '@ember/-internals/container/lib/registry';
import type { SimpleElement } from '@simple-dom/interface';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

/**
The `ApplicationInstance` encapsulates all of the stateful aspects of a
Expand Down Expand Up @@ -503,4 +504,6 @@ class _BootOptions {
}
}

setFrameworkClass(ApplicationInstance);

export default ApplicationInstance;
3 changes: 3 additions & 0 deletions packages/@ember/application/namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { getName, setName } from '@ember/-internals/utils/lib/name';
import { guidFor } from '@ember/-internals/utils/lib/guid';
import { assert } from '@ember/debug';
import EmberObject from '@ember/object';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

/**
A Namespace is an object usually used to contain other objects or methods
Expand Down Expand Up @@ -78,4 +79,6 @@ class Namespace extends EmberObject {
// Declare on the prototype to have a single shared value.
Namespace.prototype.isNamespace = true;

setFrameworkClass(Namespace);

export default Namespace;
5 changes: 4 additions & 1 deletion packages/@ember/array/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
import { consumeTag } from '@glimmer/validator/lib/tracking';
import { tagFor } from '@glimmer/validator/lib/meta';
import type { Tag } from '@glimmer/interfaces';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

function isMutable<T>(obj: T[] | EmberArray<T>): obj is T[] | MutableArray<T> {
return Array.isArray(obj) || typeof (obj as MutableArray<T>).replace === 'function';
Expand Down Expand Up @@ -387,7 +388,7 @@ class ArrayProxy<T> extends EmberObject implements PropertyDidChange {
this._arrangedContentTag === null ||
!validateTag(this._arrangedContentTag, this._arrangedContentRevision!)
) {
let arrangedContent = this.get('arrangedContent');
let arrangedContent = get(this, 'arrangedContent');

if (this._arrangedContentTag === null) {
// This is the first time the proxy has been setup, only add the observer
Expand Down Expand Up @@ -416,4 +417,6 @@ ArrayProxy.reopen(MutableArray, {
arrangedContent: alias('content'),
});

setFrameworkClass(ArrayProxy);

export default ArrayProxy;
3 changes: 3 additions & 0 deletions packages/@ember/controller/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { INTERNAL_MIXIN_CREATE } from '@ember/-internals/utils/lib/internal-mixi
import type { RouteArgs } from '@ember/routing/-internals';
import ActionHandler from '@ember/-internals/runtime/lib/mixins/action_handler';
import type { Transition } from 'router_js';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

export type ControllerQueryParamType = 'boolean' | 'number' | 'array' | 'string';
export type ControllerQueryParam =
Expand Down Expand Up @@ -375,6 +376,8 @@ export function inject(
return metalInject('controller', ...args);
}

setFrameworkClass(Controller);

export { Controller as default, ControllerMixin };

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/@ember/debug/container-debug-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type Owner from '@ember/owner';
import { getOwner } from '@ember/-internals/owner';
import type { Resolver } from '@ember/-internals/owner';
import Namespace from '@ember/application/namespace';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

/**
@module @ember/debug/container-debug-adapter
Expand Down Expand Up @@ -107,3 +108,5 @@ export default class ContainerDebugAdapter extends EmberObject {
return types;
}
}

setFrameworkClass(ContainerDebugAdapter);
3 changes: 3 additions & 0 deletions packages/@ember/debug/data-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { consumeTag, createCache, getValue, untrack } from '@glimmer/validator/l
import { tagFor } from '@glimmer/validator/lib/meta';
import type ContainerDebugAdapter from '@ember/debug/container-debug-adapter';
import { assert } from '.';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

/**
@module @ember/debug/data-adapter
Expand Down Expand Up @@ -685,3 +686,5 @@ export default class DataAdapter<T> extends EmberObject {
return null;
}
}

setFrameworkClass(DataAdapter);
3 changes: 3 additions & 0 deletions packages/@ember/engine/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { RoutingService } from '@ember/routing/-internals';
import { setupEngineRegistry } from '@ember/-internals/glimmer/lib/setup-registry';
import RegistryProxyMixin from '@ember/-internals/runtime/lib/mixins/registry_proxy';
import { StrictResolver } from './lib/strict-resolver';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

function props(obj: object) {
let properties = [];
Expand Down Expand Up @@ -532,4 +533,6 @@ function commonSetupRegistry(registry: Registry) {
registry.register('container-debug-adapter:main', ContainerDebugAdapter);
}

setFrameworkClass(Engine);

export default Engine;
3 changes: 3 additions & 0 deletions packages/@ember/engine/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { type FullName, isFactory } from '@ember/-internals/owner';
import type Engine from '@ember/engine';
import type Application from '@ember/application';
import type { SimpleElement } from '@simple-dom/interface';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

export interface BootOptions {
isBrowser?: boolean;
Expand Down Expand Up @@ -265,4 +266,6 @@ class EngineInstance extends EmberObject.extend(RegistryProxyMixin, ContainerPro
}
}

setFrameworkClass(EngineInstance);

export default EngineInstance;
3 changes: 3 additions & 0 deletions packages/@ember/object/-internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { addListener } from '@ember/-internals/metal/lib/events';
import { assert } from '@ember/debug';
import { DEBUG } from '@glimmer/env';
import EmberObject from '.';
import { setFrameworkClass } from '@ember/-internals/utils/lib/internal-framework-class';

// Here we have runtime shenanigans to add debug-only errors to the class in dev
// builds. Those runtime shenanigans produce the need for type-level shenanigans
Expand Down Expand Up @@ -47,4 +48,6 @@ if (DEBUG) {
addListener(FrameworkObject.prototype, 'init', null, ASSERT_INIT_WAS_CALLED);
}

setFrameworkClass(FrameworkObject);

export { FrameworkObject };
Loading
Loading