Skip to content

Deprecate classic classes (RFC 1117) - #21673

Draft
NullVoxPopuli-ai-agent wants to merge 1 commit into
emberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/deprecate-classic-classes
Draft

NullVoxPopuli-ai-agent wants to merge 1 commit into
emberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/deprecate-classic-classes

Conversation

@NullVoxPopuli-ai-agent

Copy link
Copy Markdown
Contributor

extend, reopen and reopenClass now give the deprecate-classic-classes deprecation (RFC 1117). This PR replaces the draft #21580, which conflicts with main.

Blocked by

emberjs/ember-test-helpers#1583 must release first. @ember/test-helpers calls EmberObject.extend() at import time, so these CI jobs fail here until then:

  • "All deprecations enabled" (both variants)
  • "Deprecations as errors" (both variants)
  • "Smoke tests with Deprecations Removed"

With that fix put into node_modules by hand, the first two groups pass locally. I did not run the smoke tests locally.

The deprecation

id deprecate-classic-classes
available 7.5.0
enabled not yet, the RFC is not Ready for Release
until 8.0.0

These calls deprecate:

  • SomeClass.extend(...)
  • SomeClass.reopen(...)
  • SomeClass.reopenClass(...)
  • someInstance.reopen(...)

Internal use

Ember still applies framework mixins to its own classes, for example Observable on EmberObject and ActionHandler on Route. Those call sites use symbol-keyed methods that do not deprecate:

  • INTERNAL_EXTEND
  • INTERNAL_REOPEN
  • INTERNAL_REOPEN_CLASS

This is the pattern of INTERNAL_MIXIN_CREATE from #21577. The symbols live in @ember/-internals/utils/lib/internal-classic-class.ts.

#21580 used helper functions in a new module instead. That module needed an entry in package.json, and it made six more modules fail the tree shaking snapshot. The symbol methods need neither change.

Tests

  • Tests of the classic class system have testUnless(DEPRECATIONS.DEPRECATE_CLASSIC_CLASSES.isRemoved) and call expectClassicClassDeprecation().
  • Tests of features that stay now use native classes: router service, query params, HistoryLocation, NoneLocation, the router DSL.
  • The test harness (internal-test-helpers) uses the internal symbols, because it builds classes from property bags (routerOptions, the -top-level component).

Three additions to internal-test-helpers:

  • expectClassicClassDeprecation() expects the deprecation only while it is enabled.
  • subclass(specifier, build) on the application test case replaces a registration with a subclass of it. It replaces this.router.reopen(...).
  • expectDeprecationQuietly(message) adds no assertion on a match. expectDeprecation adds one assertion for each message, so 21 tests with assert.expect(n) had a different count when the deprecation was enabled.

Local results

All runs have the @ember/test-helpers fix in node_modules.

Run Tests Fail
default 9548 0
all deprecations enabled 9548 0
all deprecations enabled, optional features 9550 0
deprecations as errors 8693 (619 skipped) 0
deprecations as errors, optional features 8695 (619 skipped) 0
production build, optional features 9385 0

Also green: pnpm lint, pnpm type-check, pnpm test:node, pnpm test:node:vitest (tree shaking), and pnpm build leaves package.json unchanged.

Not in this PR

  • The deprecation guide for deprecations.emberjs.com.
  • smoke-tests/node-template still calls .extend() in its helpers. Those tests run without the deprecation.
  • The @classic decorator. It is in the ember-classic-decorator addon, not in this repository.

🤖 Generated with Claude Code

`extend`, `reopen` and `reopenClass` on `CoreObject` now give the
`deprecate-classic-classes` deprecation. It is available in 7.5.0 and
it is not enabled until the RFC is Ready for Release.

Ember still applies framework mixins to its own classes. Those call
sites use symbol-keyed methods (`INTERNAL_EXTEND`, `INTERNAL_REOPEN`,
`INTERNAL_REOPEN_CLASS`) that do not deprecate. This is the pattern of
`INTERNAL_MIXIN_CREATE` from the mixin deprecation.

Tests:

- Tests of the classic class system use `testUnless(isRemoved)` and
  the new `expectClassicClassDeprecation()` helper.
- Tests of features that stay (router service, query params,
  locations) now use native classes.
- `subclass()` on the application test case replaces a registration
  with a subclass of it. It replaces `this.router.reopen(...)`.
- A quiet expectation in the call tracker adds no assertion on a
  match. `assert.expect` counts then stay the same in each test run.

This continues emberjs#21580.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
id: 'deprecate-classic-classes',
for: 'ember-source',
since: { available: '7.5.0' },
until: '8.0.0',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

probably needs to move to v9, in coordination with RFC#1234

@NullVoxPopuli

Copy link
Copy Markdown
Contributor

NOTE: this impl is now optional (but would be good for deprecation guides)

due to RFC #1234

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants