diff --git a/package.json b/package.json index 4462bf87b1e..8ccc6fe529f 100644 --- a/package.json +++ b/package.json @@ -74,15 +74,15 @@ }, "devDependencies": { "@babel/preset-env": "^7.9.5", - "@glimmer/compiler": "^0.56.1", + "@glimmer/compiler": "^0.57.2", "@glimmer/env": "^0.1.7", - "@glimmer/interfaces": "^0.56.1", - "@glimmer/node": "^0.56.1", - "@glimmer/opcode-compiler": "^0.56.1", - "@glimmer/program": "^0.56.1", - "@glimmer/reference": "^0.56.1", - "@glimmer/runtime": "^0.56.1", - "@glimmer/validator": "^0.56.1", + "@glimmer/interfaces": "^0.57.2", + "@glimmer/node": "^0.57.2", + "@glimmer/opcode-compiler": "^0.57.2", + "@glimmer/program": "^0.57.2", + "@glimmer/reference": "^0.57.2", + "@glimmer/runtime": "^0.57.2", + "@glimmer/validator": "^0.57.2", "@simple-dom/document": "^1.4.0", "@types/qunit": "^2.9.1", "@types/rsvp": "^4.0.3", diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/abstract.ts b/packages/@ember/-internals/glimmer/lib/component-managers/abstract.ts index 6ccabd6838c..e10deaca827 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/abstract.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/abstract.ts @@ -9,8 +9,7 @@ import { PreparedArguments, VMArguments, } from '@glimmer/interfaces'; -import { VersionedPathReference } from '@glimmer/reference'; -import { Tag } from '@glimmer/validator'; +import { PathReference } from '@glimmer/reference'; import { SimpleElement } from '@simple-dom/interface'; import { EmberVMEnvironment } from '../environment'; @@ -23,16 +22,18 @@ export default abstract class AbstractManager implements ComponentManager< return null; } + abstract getDebugName(state: U): string; + abstract create( env: EmberVMEnvironment, definition: U, args: VMArguments, dynamicScope: DynamicScope, - caller: VersionedPathReference, + caller: PathReference, hasDefaultBlock: boolean ): T; - abstract getSelf(component: T): VersionedPathReference; + abstract getSelf(component: T): PathReference; abstract getCapabilities(state: U): ComponentCapabilities; didCreateElement(_component: T, _element: SimpleElement, _operations: ElementOperations): void { @@ -47,8 +48,6 @@ export default abstract class AbstractManager implements ComponentManager< // noop } - abstract getTag(_bucket: T): Tag; - update(_bucket: T, _dynamicScope: DynamicScope): void { // noop } diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/curly.ts b/packages/@ember/-internals/glimmer/lib/component-managers/curly.ts index 02834779a79..ea19befad9a 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/curly.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/curly.ts @@ -21,10 +21,18 @@ import { WithJitDynamicLayout, WithJitStaticLayout, } from '@glimmer/interfaces'; -import { RootReference, VersionedPathReference } from '@glimmer/reference'; +import { PathReference, RootReference } from '@glimmer/reference'; import { PrimitiveReference, registerDestructor } from '@glimmer/runtime'; import { EMPTY_ARRAY, unwrapTemplate } from '@glimmer/util'; -import { combine, Tag, validateTag, valueForTag } from '@glimmer/validator'; +import { + beginTrackFrame, + beginUntrackFrame, + consumeTag, + endTrackFrame, + endUntrackFrame, + validateTag, + valueForTag, +} from '@glimmer/validator'; import { SimpleElement } from '@simple-dom/interface'; import { BOUNDS, DIRTY_TAG, HAS_BLOCK, IS_DISPATCHING_ATTRS } from '../component'; import { EmberVMEnvironment } from '../environment'; @@ -62,8 +70,7 @@ function applyAttributeBindings( attributeBindings: Array, component: Component, rootRef: RootReference, - operations: ElementOperations, - environment: EmberVMEnvironment + operations: ElementOperations ) { let seen: string[] = []; let i = attributeBindings.length - 1; @@ -75,7 +82,7 @@ function applyAttributeBindings( if (seen.indexOf(attribute) === -1) { seen.push(attribute); - AttributeBinding.install(component, rootRef, parsed, operations, environment); + AttributeBinding.install(component, rootRef, parsed, operations); } i--; @@ -91,12 +98,12 @@ function applyAttributeBindings( installIsVisibleBinding !== undefined && seen.indexOf('style') === -1 ) { - installIsVisibleBinding(rootRef, operations, environment); + installIsVisibleBinding(rootRef, operations); } } const DEFAULT_LAYOUT = P`template:components/-default`; -const EMPTY_POSITIONAL_ARGS: VersionedPathReference[] = []; +const EMPTY_POSITIONAL_ARGS: PathReference[] = []; debugFreeze(EMPTY_POSITIONAL_ARGS); @@ -167,7 +174,7 @@ export default class CurlyComponentManager positional: EMPTY_POSITIONAL_ARGS, named: { ...rest, - ...(__ARGS__.value() as { [key: string]: VersionedPathReference }), + ...(__ARGS__.value() as { [key: string]: PathReference }), }, }; @@ -227,7 +234,7 @@ export default class CurlyComponentManager state: DefinitionState, args: VMArguments, dynamicScope: DynamicScope, - callerSelfRef: VersionedPathReference, + callerSelfRef: PathReference, hasBlock: boolean ): ComponentStateBucket { // Get the nearest concrete component instance from the scope. "Virtual" @@ -240,7 +247,10 @@ export default class CurlyComponentManager // Capture the arguments, which tells Glimmer to give us our own, stable // copy of the Arguments object that is safe to hold on to between renders. let capturedArgs = args.named.capture(); + + beginTrackFrame(); let props = processComponentArgs(capturedArgs); + let argsTag = endTrackFrame(); // Alias `id` argument to `elementId` property on the component instance. aliasIdToElementId(args, props); @@ -271,6 +281,7 @@ export default class CurlyComponentManager // Now that we've built up all of the properties to set on the component instance, // actually create it. + beginUntrackFrame(); let component = factory.create(props); let finalizer = _instrumentStart('render.component', initialRenderInstrumentDetails, component); @@ -308,6 +319,7 @@ export default class CurlyComponentManager environment, component, capturedArgs, + argsTag, finalizer, hasWrappedElement ); @@ -324,6 +336,8 @@ export default class CurlyComponentManager component.trigger('willRender'); } + endUntrackFrame(); + if (ENV._DEBUG_RENDER_TREE) { environment.extra.debugRenderTree.create(bucket, { type: 'component', @@ -338,10 +352,18 @@ export default class CurlyComponentManager }); } + // consume every argument so we always run again + consumeTag(bucket.argsTag); + consumeTag(component[DIRTY_TAG]); + return bucket; } - getSelf({ rootRef }: ComponentStateBucket): VersionedPathReference { + getDebugName({ name }: DefinitionState) { + return name; + } + + getSelf({ rootRef }: ComponentStateBucket): PathReference { return rootRef; } @@ -356,12 +378,12 @@ export default class CurlyComponentManager let { attributeBindings, classNames, classNameBindings } = component; if (attributeBindings && attributeBindings.length) { - applyAttributeBindings(attributeBindings, component, rootRef, operations, environment); + applyAttributeBindings(attributeBindings, component, rootRef, operations); } else { let id = component.elementId ? component.elementId : guidFor(component); operations.setAttribute('id', PrimitiveReference.create(id), false, null); if (EMBER_COMPONENT_IS_VISIBLE) { - installIsVisibleBinding!(rootRef, operations, environment); + installIsVisibleBinding!(rootRef, operations); } } @@ -403,10 +425,6 @@ export default class CurlyComponentManager } } - getTag({ args, component }: ComponentStateBucket): Tag { - return args ? combine([args.tag, component[DIRTY_TAG]]) : component[DIRTY_TAG]; - } - didCreate({ component, environment }: ComponentStateBucket): void { if (environment.isInteractive) { component._transitionTo('inDOM'); @@ -416,7 +434,7 @@ export default class CurlyComponentManager } update(bucket: ComponentStateBucket): void { - let { component, args, argsRevision, environment } = bucket; + let { component, args, argsTag, argsRevision, environment } = bucket; if (ENV._DEBUG_RENDER_TREE) { environment.extra.debugRenderTree.update(bucket); @@ -424,10 +442,14 @@ export default class CurlyComponentManager bucket.finalizer = _instrumentStart('render.component', rerenderInstrumentDetails, component); - if (args && !validateTag(args.tag, argsRevision)) { + beginUntrackFrame(); + + if (args !== null && !validateTag(argsTag, argsRevision)) { + beginTrackFrame(); let props = processComponentArgs(args!); + argsTag = bucket.argsTag = endTrackFrame(); - bucket.argsRevision = valueForTag(args!.tag); + bucket.argsRevision = valueForTag(argsTag); component[IS_DISPATCHING_ATTRS] = true; component.setProperties(props); @@ -441,6 +463,11 @@ export default class CurlyComponentManager component.trigger('willUpdate'); component.trigger('willRender'); } + + endUntrackFrame(); + + consumeTag(argsTag); + consumeTag(component[DIRTY_TAG]); } didUpdateLayout(bucket: ComponentStateBucket, bounds: Bounds): void { diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/custom.ts b/packages/@ember/-internals/glimmer/lib/component-managers/custom.ts index a865ef2813f..c1bd4933eab 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/custom.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/custom.ts @@ -19,7 +19,7 @@ import { import { ComponentRootReference, PathReference } from '@glimmer/reference'; import { registerDestructor } from '@glimmer/runtime'; import { unwrapTemplate } from '@glimmer/util'; -import { consumeTag, createTag, isConstTagged, Tag } from '@glimmer/validator'; +import { track } from '@glimmer/validator'; import { EmberVMEnvironment } from '../environment'; import RuntimeResolver from '../resolver'; import { OwnedTemplate } from '../template'; @@ -194,17 +194,14 @@ export default class CustomComponentManager if (EMBER_CUSTOM_COMPONENT_ARG_PROXY) { let getTag = (key: string) => { - return namedArgs.get(key).tag; + return track(() => namedArgs.get(key).value()); }; if (HAS_NATIVE_PROXY) { let handler: ProxyHandler<{}> = { get(_target, prop) { if (namedArgs.has(prop as string)) { - let ref = namedArgs.get(prop as string); - consumeTag(ref.tag); - - return ref.value(); + return namedArgs.get(prop as string).value(); } else if (prop === CUSTOM_TAG_FOR) { return getTag; } @@ -256,10 +253,7 @@ export default class CustomComponentManager enumerable: true, configurable: true, get() { - let ref = namedArgs.get(name); - consumeTag(ref.tag); - - return ref.value(); + return namedArgs.get(name).value(); }, }); }); @@ -294,6 +288,10 @@ export default class CustomComponentManager return bucket; } + getDebugName({ name }: CustomComponentDefinitionState) { + return name; + } + update(bucket: CustomComponentState) { if (ENV._DEBUG_RENDER_TREE) { bucket.env.extra.debugRenderTree.update(bucket); @@ -353,15 +351,6 @@ export default class CustomComponentManager }); } - getTag({ args }: CustomComponentState): Tag { - if (isConstTagged(args)) { - // returning a const tag skips the update hook (VM BUG?) - return createTag(); - } else { - return args.tag; - } - } - didRenderLayout(bucket: CustomComponentState, bounds: Bounds) { if (ENV._DEBUG_RENDER_TREE) { bucket.env.extra.debugRenderTree.didRender(bucket, bounds); diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/input.ts b/packages/@ember/-internals/glimmer/lib/component-managers/input.ts index 71f7a381b34..ca932be23db 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/input.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/input.ts @@ -11,9 +11,8 @@ import { PreparedArguments, VMArguments, } from '@glimmer/interfaces'; -import { ComponentRootReference, ConstReference, VersionedPathReference } from '@glimmer/reference'; +import { ComponentRootReference, ConstReference, PathReference } from '@glimmer/reference'; import { registerDestructor } from '@glimmer/runtime'; -import { CONSTANT_TAG, createTag, isConstTagged } from '@glimmer/validator'; import { EmberVMEnvironment } from '../environment'; import InternalComponentManager, { InternalDefinitionState } from './internal'; @@ -34,11 +33,11 @@ const CAPABILITIES: ComponentCapabilities = { export interface InputComponentState { env: EmberVMEnvironment; - type: VersionedPathReference; + type: PathReference; instance: Destroyable; } -const EMPTY_POSITIONAL_ARGS: VersionedPathReference[] = []; +const EMPTY_POSITIONAL_ARGS: PathReference[] = []; debugFreeze(EMPTY_POSITIONAL_ARGS); @@ -53,7 +52,7 @@ export default class InputComponentManager extends InternalComponentManager = args.named.capture().map; + let __ARGS__: Dict = args.named.capture().map; return { positional: EMPTY_POSITIONAL_ARGS, @@ -69,9 +68,9 @@ export default class InputComponentManager extends InternalComponentManager; environment: EmberVMEnvironment; - modelRef?: VersionedPathReference; + modelRef?: PathReference; } interface EngineDefinitionState { @@ -128,22 +127,12 @@ class MountManager extends AbstractManager return bucket; } - getSelf({ self }: EngineState): VersionedPathReference { - return self; + getDebugName({ name }: EngineDefinitionState) { + return name; } - getTag(state: EngineState): Tag { - let tag: Tag = CONSTANT_TAG; - - if (state.modelRef) { - tag = state.modelRef.tag; - } - - if (ENV._DEBUG_RENDER_TREE && isConstTag(tag)) { - tag = createTag(); - } - - return tag; + getSelf({ self }: EngineState): PathReference { + return self; } getDestroyable(bucket: EngineState): Option { diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts b/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts index 9fed9fde112..85a87787196 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts @@ -15,10 +15,9 @@ import { WithDynamicTagName, WithJitStaticLayout, } from '@glimmer/interfaces'; -import { ComponentRootReference, VersionedPathReference } from '@glimmer/reference'; +import { ComponentRootReference, PathReference } from '@glimmer/reference'; import { EMPTY_ARGS, registerDestructor } from '@glimmer/runtime'; import { unwrapTemplate } from '@glimmer/util'; -import { CONSTANT_TAG, createTag, Tag } from '@glimmer/validator'; import { SimpleElement } from '@simple-dom/interface'; import { EmberVMEnvironment } from '../environment'; @@ -34,7 +33,7 @@ function instrumentationPayload(def: OutletDefinitionState) { } interface OutletInstanceState { - self: VersionedPathReference; + self: PathReference; environment: EmberVMEnvironment; outlet?: { name: string }; engine?: { mountPoint: string }; @@ -42,7 +41,7 @@ interface OutletInstanceState { } export interface OutletDefinitionState { - ref: VersionedPathReference; + ref: PathReference; name: string; outlet: string; template: OwnedTemplate; @@ -140,6 +139,14 @@ class OutletComponentManager extends AbstractManager, }; } - - getTag({ component }: ComponentStateBucket) { - return component[DIRTY_TAG]; - } } diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/template-only.ts b/packages/@ember/-internals/glimmer/lib/component-managers/template-only.ts index c73f6d7b2ae..ab818f9a9bb 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/template-only.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/template-only.ts @@ -9,7 +9,6 @@ import { } from '@glimmer/interfaces'; import { NULL_REFERENCE, registerDestructor } from '@glimmer/runtime'; import { unwrapTemplate } from '@glimmer/util'; -import { CONSTANT_TAG, createTag } from '@glimmer/validator'; import { EmberVMEnvironment } from '../environment'; import RuntimeResolver from '../resolver'; import { OwnedTemplate } from '../template'; @@ -76,18 +75,12 @@ export default class TemplateOnlyComponentManager } } - getSelf() { - return NULL_REFERENCE; + getDebugName({ name }: TemplateOnlyComponentDefinitionState) { + return name; } - getTag() { - if (ENV._DEBUG_RENDER_TREE) { - // returning a const tag skips the update hook (VM BUG?) - return createTag(); - } else { - // an outlet has no hooks - return CONSTANT_TAG; - } + getSelf() { + return NULL_REFERENCE; } getDestroyable(bucket: Option) { diff --git a/packages/@ember/-internals/glimmer/lib/environment.ts b/packages/@ember/-internals/glimmer/lib/environment.ts index d5de72884e3..249f110fb81 100644 --- a/packages/@ember/-internals/glimmer/lib/environment.ts +++ b/packages/@ember/-internals/glimmer/lib/environment.ts @@ -7,11 +7,6 @@ import { assert, deprecate, warn } from '@ember/debug'; import { backburner, schedule } from '@ember/runloop'; import { DEBUG } from '@glimmer/env'; import { ElementBuilder, Environment, Option } from '@glimmer/interfaces'; -import { - IterationItemReference, - PropertyReference, - VersionedPathReference, -} from '@glimmer/reference'; import { DynamicAttribute, dynamicAttribute, @@ -20,11 +15,11 @@ import { setScheduleDestroyed, SimpleDynamicAttribute, } from '@glimmer/runtime'; -import { setAutotrackingTransactionEnv, setPropertyDidChange } from '@glimmer/validator'; +import { setPropertyDidChange, setTrackingTransactionEnv } from '@glimmer/validator'; import { AttrNamespace as SimpleAttrNamespace, SimpleElement } from '@simple-dom/interface'; import installPlatformSpecificProtocolForURL from './protocol-for-url'; import { OwnedTemplate } from './template'; -import DebugRenderTree, { PathNodeType } from './utils/debug-render-tree'; +import DebugRenderTree from './utils/debug-render-tree'; import toIterator from './utils/iterator'; import { isHTMLSafe } from './utils/string'; import toBool from './utils/to-bool'; @@ -38,7 +33,7 @@ import toBool from './utils/to-bool'; setPropertyDidChange(() => backburner.ensureInstance()); if (DEBUG) { - setAutotrackingTransactionEnv!({ + setTrackingTransactionEnv!({ assert(message) { assert(message, false); }, @@ -143,28 +138,6 @@ export class EmberEnvironmentDelegate implements EnvironmentDelegate - ) { - let type: PathNodeType = 'root'; - - if (pathRef instanceof IterationItemReference) { - type = 'iterator'; - } else if (pathRef instanceof PropertyReference) { - type = 'property'; - } - - this.extra.debugRenderTree.createPath(pathRef, desc, type, parentRef); - } - onTransactionBegin() { this.extra.begin(); } diff --git a/packages/@ember/-internals/glimmer/lib/helpers/-assert-implicit-component-helper-argument.ts b/packages/@ember/-internals/glimmer/lib/helpers/-assert-implicit-component-helper-argument.ts index a827e52bc27..b9266bcea80 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/-assert-implicit-component-helper-argument.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/-assert-implicit-component-helper-argument.ts @@ -1,17 +1,16 @@ import { assert } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import { Helper, VMArguments } from '@glimmer/interfaces'; -import { VersionedPathReference } from '@glimmer/reference'; -import { Tag } from '@glimmer/validator'; +import { PathReference } from '@glimmer/reference'; let helper: Helper; if (DEBUG) { - class ComponentAssertionReference implements VersionedPathReference { - public tag: Tag; + class ComponentAssertionReference implements PathReference { + constructor(private component: PathReference, private message: string) {} - constructor(private component: VersionedPathReference, private message: string) { - this.tag = component.tag; + isConst() { + return this.component.isConst(); } value(): unknown { @@ -22,7 +21,7 @@ if (DEBUG) { return value; } - get(property: string): VersionedPathReference { + get(property: string): PathReference { return this.component.get(property); } } diff --git a/packages/@ember/-internals/glimmer/lib/helpers/-in-element-null-check.ts b/packages/@ember/-internals/glimmer/lib/helpers/-in-element-null-check.ts index 26b5340443e..e2ff86c76e1 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/-in-element-null-check.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/-in-element-null-check.ts @@ -1,17 +1,16 @@ import { assert } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import { Helper, VMArguments } from '@glimmer/interfaces'; -import { VersionedPathReference } from '@glimmer/reference'; -import { Tag } from '@glimmer/validator'; +import { PathReference } from '@glimmer/reference'; let helper: Helper; if (DEBUG) { - class InElementNullCheckReference implements VersionedPathReference { - public tag: Tag; + class InElementNullCheckReference implements PathReference { + constructor(private inner: PathReference) {} - constructor(private inner: VersionedPathReference) { - this.tag = inner.tag; + isConst() { + return this.inner.isConst(); } value(): unknown { @@ -25,7 +24,7 @@ if (DEBUG) { return value; } - get(key: string): VersionedPathReference { + get(key: string): PathReference { return this.inner.get(key); } } diff --git a/packages/@ember/-internals/glimmer/lib/helpers/-track-array.ts b/packages/@ember/-internals/glimmer/lib/helpers/-track-array.ts index 7ddb1338b5d..049d3d807f3 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/-track-array.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/-track-array.ts @@ -4,33 +4,32 @@ import { tagForProperty } from '@ember/-internals/metal'; import { isObject } from '@ember/-internals/utils'; import { VMArguments } from '@glimmer/interfaces'; -import { VersionedPathReference } from '@glimmer/reference'; -import { combine, CONSTANT_TAG, createUpdatableTag, Tag, updateTag } from '@glimmer/validator'; +import { PathReference } from '@glimmer/reference'; +import { consumeTag } from '@glimmer/validator'; /** This reference is used to get the `[]` tag of iterables, so we can trigger updates to `{{each}}` when it changes. It is put into place by a template transform at build time, similar to the (-each-in) helper */ -class TrackArrayReference implements VersionedPathReference { - public tag: Tag; - private valueTag = createUpdatableTag(); +class TrackArrayReference implements PathReference { + constructor(private inner: PathReference) {} - constructor(private inner: VersionedPathReference) { - this.tag = combine([inner.tag, this.valueTag]); + isConst() { + return this.inner.isConst(); } value(): unknown { let iterable = this.inner.value(); - let tag = isObject(iterable) ? tagForProperty(iterable, '[]') : CONSTANT_TAG; - - updateTag(this.valueTag, tag); + if (isObject(iterable)) { + consumeTag(tagForProperty(iterable, '[]')); + } return iterable; } - get(key: string): VersionedPathReference { + get(key: string): PathReference { return this.inner.get(key); } } diff --git a/packages/@ember/-internals/glimmer/lib/helpers/action.ts b/packages/@ember/-internals/glimmer/lib/helpers/action.ts index 603bf6a1834..705dbe82e71 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/action.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/action.ts @@ -8,8 +8,7 @@ import { flaggedInstrument } from '@ember/instrumentation'; import { join } from '@ember/runloop'; import { DEBUG } from '@glimmer/env'; import { VM, VMArguments } from '@glimmer/interfaces'; -import { VersionedPathReference } from '@glimmer/reference'; -import { isConstTagged } from '@glimmer/validator'; +import { PathReference } from '@glimmer/reference'; import { UnboundRootReference } from '../utils/references'; import { INVOKE } from './mut'; @@ -299,8 +298,6 @@ export default function(args: VMArguments, vm: VM): UnboundRootReference | false, - actionArgsRef: Array> + valuePathRef: PathReference | false, + actionArgsRef: Array> ) { let mergeArgs: any; diff --git a/packages/@ember/-internals/glimmer/lib/helpers/each-in.ts b/packages/@ember/-internals/glimmer/lib/helpers/each-in.ts index 9af103f4f62..46457caeac6 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/each-in.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/each-in.ts @@ -5,8 +5,8 @@ import { tagForObject } from '@ember/-internals/metal'; import { _contentFor } from '@ember/-internals/runtime'; import { isProxy } from '@ember/-internals/utils'; import { VMArguments } from '@glimmer/interfaces'; -import { VersionedPathReference } from '@glimmer/reference'; -import { combine, createUpdatableTag, Tag, updateTag } from '@glimmer/validator'; +import { PathReference } from '@glimmer/reference'; +import { consumeTag } from '@glimmer/validator'; /** The `{{#each}}` helper loops over elements in a collection. It is an extension @@ -154,18 +154,17 @@ import { combine, createUpdatableTag, Tag, updateTag } from '@glimmer/validator' @public @since 2.1.0 */ -class EachInReference implements VersionedPathReference { - public tag: Tag; - private valueTag = createUpdatableTag(); +class EachInReference implements PathReference { + constructor(private inner: PathReference) {} - constructor(private inner: VersionedPathReference) { - this.tag = combine([inner.tag, this.valueTag]); + isConst() { + return this.inner.isConst(); } value(): unknown { let iterable = this.inner.value(); - let tag = tagForObject(iterable); + consumeTag(tagForObject(iterable)); if (isProxy(iterable)) { // this is because the each-in doesn't actually get(proxy, 'key') but bypasses it @@ -173,12 +172,10 @@ class EachInReference implements VersionedPathReference { iterable = _contentFor(iterable); } - updateTag(this.valueTag, tag); - return new EachInWrapper(iterable); } - get(key: string): VersionedPathReference { + get(key: string): PathReference { return this.inner.get(key); } } diff --git a/packages/@ember/-internals/glimmer/lib/helpers/fn.ts b/packages/@ember/-internals/glimmer/lib/helpers/fn.ts index a7789945e2f..5b9ec823e5a 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/fn.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/fn.ts @@ -1,6 +1,6 @@ import { assert } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; -import { CapturedArguments, Environment, VM, VMArguments } from '@glimmer/interfaces'; +import { CapturedArguments, VM, VMArguments } from '@glimmer/interfaces'; import { HelperRootReference } from '@glimmer/reference'; import buildUntouchableThis from '../utils/untouchable-this'; import { INVOKE } from './mut'; @@ -79,7 +79,7 @@ const context = buildUntouchableThis('`fn` helper'); @since 3.11.0 */ -function fn({ positional }: CapturedArguments, env?: Environment) { +function fn({ positional }: CapturedArguments) { let callbackRef = positional.at(0); assert( @@ -93,7 +93,7 @@ function fn({ positional }: CapturedArguments, env?: Environment) { assert( `You must pass a function as the \`fn\` helpers first argument, you passed ${ callback === null ? 'null' : typeof callback - }. ${env!.getTemplatePathDebugContext(callbackRef)}`, + }. While rendering:\n\n${callbackRef.debugLabel}`, typeof callback === 'function' ); } @@ -112,12 +112,5 @@ function fn({ positional }: CapturedArguments, env?: Environment) { } export default function(args: VMArguments, vm: VM) { - let callback = fn; - if (DEBUG) { - callback = (args: CapturedArguments) => { - return fn(args, vm.env); - }; - } - - return new HelperRootReference(callback, args.capture(), vm.env); + return new HelperRootReference(fn, args.capture(), vm.env); } diff --git a/packages/@ember/-internals/glimmer/lib/helpers/get.ts b/packages/@ember/-internals/glimmer/lib/helpers/get.ts index 1da33f32c32..5b5dd4f16f0 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/get.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/get.ts @@ -1,13 +1,8 @@ import { get as emberGet, set as emberSet } from '@ember/-internals/metal'; import { isObject } from '@ember/-internals/utils'; import { CapturedArguments, Environment, VM, VMArguments } from '@glimmer/interfaces'; -import { - HelperRootReference, - UPDATE_REFERENCED_VALUE, - VersionedPathReference, -} from '@glimmer/reference'; +import { HelperRootReference, PathReference, UPDATE_REFERENCED_VALUE } from '@glimmer/reference'; import { NULL_REFERENCE } from '@glimmer/runtime'; -import { isConstTagged } from '@glimmer/validator'; import { referenceFromParts } from '../utils/references'; /** @@ -98,11 +93,12 @@ export default function(args: VMArguments, vm: VM) { let sourceReference = args.positional.at(0); let pathReference = args.positional.at(1); - if (isConstTagged(pathReference)) { + let path = pathReference.value(); + + if (pathReference.isConst()) { // Since the path is constant, we can create a normal chain of property // references. The source reference will update like normal, and all of the // child references will update accordingly. - let path = pathReference.value(); if (path === undefined || path === null || path === '') { return NULL_REFERENCE; @@ -127,8 +123,8 @@ function get({ positional }: CapturedArguments) { } class GetHelperRootReference extends HelperRootReference { - private sourceReference: VersionedPathReference; - private pathReference: VersionedPathReference; + private sourceReference: PathReference; + private pathReference: PathReference; constructor(args: CapturedArguments, env: Environment) { super(get, args, env); diff --git a/packages/@ember/-internals/glimmer/lib/helpers/mut.ts b/packages/@ember/-internals/glimmer/lib/helpers/mut.ts index 7a75461cd05..ae0c36eb70b 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/mut.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/mut.ts @@ -3,9 +3,8 @@ */ import { symbol } from '@ember/-internals/utils'; import { assert } from '@ember/debug'; -import { Environment, VM, VMArguments } from '@glimmer/interfaces'; -import { RootReference, UPDATE_REFERENCED_VALUE, VersionedPathReference } from '@glimmer/reference'; -import { Tag } from '@glimmer/validator'; +import { VMArguments } from '@glimmer/interfaces'; +import { PathReference, UPDATE_REFERENCED_VALUE } from '@glimmer/reference'; /** The `mut` helper lets you __clearly specify__ that a child `Component` can update the @@ -83,21 +82,22 @@ import { Tag } from '@glimmer/validator'; export const INVOKE: unique symbol = symbol('INVOKE') as any; const SOURCE: unique symbol = symbol('SOURCE') as any; -class MutReference extends RootReference { - public tag: Tag; - public [SOURCE]: VersionedPathReference; +class MutReference implements PathReference { + public [SOURCE]: PathReference; - constructor(protected inner: VersionedPathReference, env: Environment) { - super(env); - this.tag = inner.tag; + constructor(protected inner: PathReference) { this[SOURCE] = inner; } - value(): unknown { + value() { return this.inner.value(); } - get(key: string): VersionedPathReference { + isConst() { + return this.inner.isConst(); + } + + get(key: string): PathReference { return this.inner.get(key); } @@ -110,11 +110,11 @@ class MutReference extends RootReference { } } -export function unMut(ref: VersionedPathReference) { +export function unMut(ref: PathReference) { return ref[SOURCE] || ref; } -export default function(args: VMArguments, vm: VM) { +export default function(args: VMArguments) { let rawRef = args.positional.at(0); if (typeof rawRef[INVOKE] === 'function') { @@ -135,5 +135,5 @@ export default function(args: VMArguments, vm: VM) { // confusing for the second case. assert('You can only pass a path to mut', rawRef[UPDATE_REFERENCED_VALUE] !== undefined); - return new MutReference(rawRef, vm.env); + return new MutReference(rawRef); } diff --git a/packages/@ember/-internals/glimmer/lib/helpers/readonly.ts b/packages/@ember/-internals/glimmer/lib/helpers/readonly.ts index d04214ca715..55080aff795 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/readonly.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/readonly.ts @@ -1,9 +1,8 @@ /** @module ember */ -import { Environment, VM, VMArguments } from '@glimmer/interfaces'; -import { RootReference, VersionedPathReference } from '@glimmer/reference'; -import { Tag } from '@glimmer/validator'; +import { VMArguments } from '@glimmer/interfaces'; +import { PathReference } from '@glimmer/reference'; import { INVOKE, unMut } from './mut'; /** @@ -121,29 +120,28 @@ import { INVOKE, unMut } from './mut'; @for Ember.Templates.helpers @private */ -class ReadonlyReference extends RootReference { - public tag: Tag; - - constructor(protected inner: VersionedPathReference, env: Environment) { - super(env); - this.tag = inner.tag; - } +class ReadonlyReference implements PathReference { + constructor(protected inner: PathReference) {} get [INVOKE](): Function | undefined { return this.inner[INVOKE]; } + isConst() { + return this.inner.isConst(); + } + value(): unknown { return this.inner.value(); } - get(key: string): VersionedPathReference { + get(key: string): PathReference { return this.inner.get(key); } } -export default function(args: VMArguments, vm: VM) { +export default function(args: VMArguments) { let ref = unMut(args.positional.at(0)); - return new ReadonlyReference(ref, vm.env); + return new ReadonlyReference(ref); } diff --git a/packages/@ember/-internals/glimmer/lib/modifiers/action.ts b/packages/@ember/-internals/glimmer/lib/modifiers/action.ts index b9001a590d1..795bae958aa 100644 --- a/packages/@ember/-internals/glimmer/lib/modifiers/action.ts +++ b/packages/@ember/-internals/glimmer/lib/modifiers/action.ts @@ -11,7 +11,7 @@ import { VMArguments, } from '@glimmer/interfaces'; import { registerDestructor } from '@glimmer/runtime'; -import { Tag } from '@glimmer/validator'; +import { createUpdatableTag } from '@glimmer/validator'; import { SimpleElement } from '@simple-dom/interface'; import { INVOKE } from '../helpers/mut'; @@ -70,29 +70,23 @@ export class ActionState { public implicitTarget: any; public dom: any; public eventName: any; - public tag: Tag; + public tag = createUpdatableTag(); constructor( element: SimpleElement, actionId: number, - actionName: any, actionArgs: any[], namedArgs: CapturedNamedArguments, positionalArgs: CapturedPositionalArguments, - implicitTarget: any, - dom: any, - tag: Tag + dom: any ) { this.element = element; this.actionId = actionId; - this.actionName = actionName; this.actionArgs = actionArgs; this.namedArgs = namedArgs; this.positional = positionalArgs; - this.implicitTarget = implicitTarget; this.dom = dom; this.eventName = this.getEventName(); - this.tag = tag; registerDestructor(this, () => ActionHelper.unregisterAction(this)); } @@ -192,33 +186,7 @@ export default class ActionModifierManager implements ModifierManager 1) { - implicitTarget = positional.at(0); - actionNameRef = positional.at(1); - - if (actionNameRef[INVOKE]) { - actionName = actionNameRef; - } else { - let actionLabel = actionNameRef.propertyKey; - actionName = actionNameRef.value(); - - assert( - 'You specified a quoteless path, `' + - actionLabel + - '`, to the ' + - '{{action}} helper which did not resolve to an action name (a ' + - 'string). Perhaps you meant to use a quoted actionName? (e.g. ' + - '{{action "' + - actionLabel + - '"}}).', - typeof actionName === 'string' || typeof actionName === 'function' - ); - } - } + let { named, positional } = args.capture(); let actionArgs: any[] = []; // The first two arguments are (1) `this` and (2) the action name. @@ -228,17 +196,7 @@ export default class ActionModifierManager implements ModifierManager 1) { + implicitTarget = positional.at(0); + actionNameRef = positional.at(1); + + if (actionNameRef[INVOKE]) { + actionName = actionNameRef; + } else { + let actionLabel = actionNameRef.propertyKey; + actionName = actionNameRef.value(); + + assert( + 'You specified a quoteless path, `' + + actionLabel + + '`, to the ' + + '{{action}} helper which did not resolve to an action name (a ' + + 'string). Perhaps you meant to use a quoted actionName? (e.g. ' + + '{{action "' + + actionLabel + + '"}}).', + typeof actionName === 'string' || typeof actionName === 'function' + ); + } + } + + actionState.actionName = actionName; + actionState.implicitTarget = implicitTarget; ActionHelper.registerAction(actionState); diff --git a/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts b/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts index 15fd849c6f2..f14076aabb1 100644 --- a/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts +++ b/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts @@ -1,20 +1,10 @@ import { Factory } from '@ember/-internals/owner'; -import { getDebugName } from '@ember/-internals/utils'; import { assert } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import { CapturedArguments, Dict, ModifierManager, VMArguments } from '@glimmer/interfaces'; import { registerDestructor } from '@glimmer/runtime'; -import { - combine, - CONSTANT_TAG, - createUpdatableTag, - Tag, - track, - untrack, - updateTag, -} from '@glimmer/validator'; +import { createUpdatableTag, untrack } from '@glimmer/validator'; import { SimpleElement } from '@simple-dom/interface'; -import debugRenderMessage from '../utils/debug-render-message'; export interface CustomModifierDefinitionState { ModifierClass: Factory; @@ -65,6 +55,7 @@ export class CustomModifierDefinition { export class CustomModifierState { public tag = createUpdatableTag(); + debugName?: string; constructor( public element: SimpleElement, @@ -129,16 +120,25 @@ class InteractiveCustomModifierManager const capturedArgs = args.capture(); let instance = definition.delegate.createModifier(ModifierClass, capturedArgs.value()); + let state = new CustomModifierState(element, delegate, instance, capturedArgs); - return new CustomModifierState(element, delegate, instance, capturedArgs); + if (DEBUG) { + state.debugName = definition.name; + } + + return state; + } + + getDebugName({ debugName }: CustomModifierState) { + return debugName!; } - getTag({ args, tag }: CustomModifierState): Tag { - return combine([tag, args.tag]); + getTag({ tag }: CustomModifierState) { + return tag; } install(state: CustomModifierState) { - let { element, args, delegate, modifier, tag } = state; + let { element, args, delegate, modifier } = state; assert( 'Custom modifier managers must define their capabilities using the capabilities() helper function', @@ -146,31 +146,24 @@ class InteractiveCustomModifierManager ); let { capabilities } = delegate; + let argsValue = args.value(); if (capabilities.disableAutoTracking === true) { - untrack(() => delegate.installModifier(modifier, element, args.value())); + untrack(() => delegate.installModifier(modifier, element, argsValue)); } else { - let combinedTrackingTag = track( - () => delegate.installModifier(modifier, element, args.value()), - DEBUG && debugRenderMessage!(`(instance of a \`${getDebugName!(modifier)}\` modifier)`) - ); - - updateTag(tag, combinedTrackingTag); + delegate.installModifier(modifier, element, argsValue); } } update(state: CustomModifierState) { - let { args, delegate, modifier, tag } = state; + let { args, delegate, modifier } = state; let { capabilities } = delegate; + let argsValue = args.value(); if (capabilities.disableAutoTracking === true) { - untrack(() => delegate.updateModifier(modifier, args.value())); + untrack(() => delegate.updateModifier(modifier, argsValue)); } else { - let combinedTrackingTag = track( - () => delegate.updateModifier(modifier, args.value()), - DEBUG && debugRenderMessage!(`(instance of a \`${getDebugName!(modifier)}\` modifier)`) - ); - updateTag(tag, combinedTrackingTag); + delegate.updateModifier(modifier, argsValue); } } @@ -185,8 +178,12 @@ class NonInteractiveCustomModifierManager return null; } - getTag(): Tag { - return CONSTANT_TAG; + getDebugName() { + return ''; + } + + getTag() { + return null; } install() {} diff --git a/packages/@ember/-internals/glimmer/lib/modifiers/on.ts b/packages/@ember/-internals/glimmer/lib/modifiers/on.ts index 56db7bf1b63..5ebb682b49a 100644 --- a/packages/@ember/-internals/glimmer/lib/modifiers/on.ts +++ b/packages/@ember/-internals/glimmer/lib/modifiers/on.ts @@ -3,10 +3,8 @@ import { assert } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import { CapturedArguments, ModifierManager, VMArguments } from '@glimmer/interfaces'; import { registerDestructor } from '@glimmer/runtime'; -import { expect } from '@glimmer/util'; -import { CONSTANT_TAG, Tag } from '@glimmer/validator'; +import { createUpdatableTag, UpdatableTag } from '@glimmer/validator'; import { SimpleElement } from '@simple-dom/interface'; -import { Renderer } from '../renderer'; import buildUntouchableThis from '../utils/untouchable-this'; const untouchableContext = buildUntouchableThis('`on` modifier'); @@ -51,7 +49,7 @@ const SUPPORTS_EVENT_OPTIONS = (() => { })(); export class OnModifierState { - public tag: Tag; + public tag = createUpdatableTag(); public owner: Owner; public element: Element; public args: CapturedArguments; @@ -68,7 +66,6 @@ export class OnModifierState { this.owner = owner; this.element = element; this.args = args; - this.tag = args.tag; } updateFromArgs() { @@ -115,18 +112,11 @@ export class OnModifierState { args.positional.at(1) !== undefined ); - // hardcoding `renderer:-dom` here because we guard for `this.isInteractive` before instantiating OnModifierState, it can never be created when the renderer is `renderer:-inert` - let renderer = expect( - this.owner.lookup('renderer:-dom'), - `BUG: owner is missing renderer:-dom` - ); - let stack = renderer.debugRenderTree.logRenderStackForPath(userProvidedCallbackReference); - let value = userProvidedCallbackReference.value(); assert( `You must pass a function as the second argument to the \`on\` modifier, you passed ${ value === null ? 'null' : typeof value - }. While rendering:\n\n${stack}`, + }. While rendering:\n\n${userProvidedCallbackReference.debugLabel}`, typeof value === 'function' ); } @@ -330,6 +320,10 @@ export default class OnModifierManager implements ModifierManagerelement, capturedArgs); } - getTag(state: OnModifierState | null): Tag { + getTag(state: OnModifierState | null): UpdatableTag | null { if (state === null) { - return CONSTANT_TAG; + return null; } return state.tag; diff --git a/packages/@ember/-internals/glimmer/lib/renderer.ts b/packages/@ember/-internals/glimmer/lib/renderer.ts index 72f1601ce78..45d5dc524c7 100644 --- a/packages/@ember/-internals/glimmer/lib/renderer.ts +++ b/packages/@ember/-internals/glimmer/lib/renderer.ts @@ -3,7 +3,6 @@ import { getOwner, Owner } from '@ember/-internals/owner'; import { getViewElement, getViewId, OwnedTemplateMeta } from '@ember/-internals/views'; import { assert } from '@ember/debug'; import { backburner, getCurrentRunLoop } from '@ember/runloop'; -import { DEBUG } from '@glimmer/env'; import { Bounds, Cursor, @@ -16,7 +15,7 @@ import { SyntaxCompilationContext, } from '@glimmer/interfaces'; import { JitContext } from '@glimmer/opcode-compiler'; -import { VersionedPathReference } from '@glimmer/reference'; +import { PathReference } from '@glimmer/reference'; import { clientBuilder, CurriedComponentDefinition, @@ -25,19 +24,13 @@ import { DOMChanges, DOMTreeConstruction, inTransaction, - IteratorResult, JitRuntime, JitSyntaxCompilationContext, renderJitMain, UNDEFINED_REFERENCE, } from '@glimmer/runtime'; import { unwrapHandle, unwrapTemplate } from '@glimmer/util'; -import { - CURRENT_TAG, - runInAutotrackingTransaction, - validateTag, - valueForTag, -} from '@glimmer/validator'; +import { CURRENT_TAG, validateTag, valueForTag } from '@glimmer/validator'; import { SimpleDocument, SimpleElement, SimpleNode } from '@simple-dom/interface'; import RSVP from 'rsvp'; import CompileTimeResolver from './compile-time-lookup'; @@ -59,14 +52,14 @@ export type IBuilder = (env: Environment, cursor: Cursor) => ElementBuilder; export class DynamicScope implements GlimmerDynamicScope { constructor( public view: Component | {} | null, - public outletState: VersionedPathReference + public outletState: PathReference ) {} child() { return new DynamicScope(this.view, this.outletState); } - get(key: 'outletState'): VersionedPathReference { + get(key: 'outletState'): PathReference { // tslint:disable-next-line:max-line-length assert( `Using \`-get-dynamic-scope\` is only supported for \`outletState\` (you used \`${key}\`).`, @@ -75,7 +68,7 @@ export class DynamicScope implements GlimmerDynamicScope { return this.outletState; } - set(key: 'outletState', value: VersionedPathReference) { + set(key: 'outletState', value: PathReference) { // tslint:disable-next-line:max-line-length assert( `Using \`-with-dynamic-scope\` is only supported for \`outletState\` (you used \`${key}\`).`, @@ -97,7 +90,7 @@ class RootState { public runtime: JitRuntimeContext, context: SyntaxCompilationContext, template: OwnedTemplate, - self: VersionedPathReference, + self: PathReference, parentElement: SimpleElement, dynamicScope: DynamicScope, builder: IBuilder @@ -120,12 +113,8 @@ class RootState { unwrapHandle(handle), dynamicScope ); - let iteratorResult: IteratorResult; - do { - iteratorResult = iterator.next(); - } while (!iteratorResult.done); - let result = (this.result = iteratorResult.value); + let result = (this.result = iterator.sync()); // override .render function after initial render this.render = () => result.rerender({ alwaysRevalidate: false }); @@ -457,14 +446,7 @@ export abstract class Renderer { continue; } - if (DEBUG) { - // run in an autotracking transaction to prevent backflow errors. - // we use `bind` here to avoid creating a closure (and requiring a - // hoisted variable). - runInAutotrackingTransaction!(root.render.bind(root)); - } else { - root.render(); - } + root.render(); } this._lastRevision = valueForTag(CURRENT_TAG); diff --git a/packages/@ember/-internals/glimmer/lib/syntax/mount.ts b/packages/@ember/-internals/glimmer/lib/syntax/mount.ts index 5f8b790c5cc..361ba06af40 100644 --- a/packages/@ember/-internals/glimmer/lib/syntax/mount.ts +++ b/packages/@ember/-internals/glimmer/lib/syntax/mount.ts @@ -4,21 +4,20 @@ import { assert } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import { CapturedArguments, Option, VM, VMArguments } from '@glimmer/interfaces'; -import { VersionedPathReference } from '@glimmer/reference'; +import { PathReference } from '@glimmer/reference'; import { CurriedComponentDefinition, curry, EMPTY_ARGS, UNDEFINED_REFERENCE, } from '@glimmer/runtime'; -import { Tag } from '@glimmer/validator'; import { MODEL_ARG_NAME, MountDefinition } from '../component-managers/mount'; import { EmberVMEnvironment } from '../environment'; export function mountHelper( args: VMArguments, vm: VM -): VersionedPathReference { +): PathReference { let env = vm.env as EmberVMEnvironment; let nameRef = args.positional.at(0); let captured: Option = null; @@ -47,7 +46,6 @@ export function mountHelper( assert('[BUG] this should already be checked by the macro', args.named.length === 1); let named = args.named.capture(); - let { tag } = named; // TODO delete me after EMBER_ROUTING_MODEL_ARG has shipped if (DEBUG && MODEL_ARG_NAME !== 'model') { @@ -56,7 +54,6 @@ export function mountHelper( } captured = { - tag, positional: EMPTY_ARGS.positional, named, length: 1, @@ -113,17 +110,18 @@ export function mountHelper( @public */ -class DynamicEngineReference implements VersionedPathReference> { - public tag: Tag; +class DynamicEngineReference implements PathReference> { private _lastName: Option = null; private _lastDef: Option = null; constructor( - public nameRef: VersionedPathReference, + public nameRef: PathReference, public env: EmberVMEnvironment, public args: Option - ) { - this.tag = nameRef.tag; + ) {} + + isConst() { + return false; } value(): Option { diff --git a/packages/@ember/-internals/glimmer/lib/syntax/outlet.ts b/packages/@ember/-internals/glimmer/lib/syntax/outlet.ts index 4ac1afa9af1..0e8c138846c 100644 --- a/packages/@ember/-internals/glimmer/lib/syntax/outlet.ts +++ b/packages/@ember/-internals/glimmer/lib/syntax/outlet.ts @@ -1,12 +1,7 @@ import { EMBER_ROUTING_MODEL_ARG } from '@ember/canary-features'; import { DEBUG } from '@glimmer/env'; import { CapturedArguments, Dict, Option, unsafe, VM, VMArguments } from '@glimmer/interfaces'; -import { - ConstReference, - Reference, - RootReference, - VersionedPathReference, -} from '@glimmer/reference'; +import { ConstReference, PathReference, Reference, RootReference } from '@glimmer/reference'; import { CurriedComponentDefinition, curry, @@ -14,7 +9,6 @@ import { UNDEFINED_REFERENCE, } from '@glimmer/runtime'; import { dict } from '@glimmer/util'; -import { Tag } from '@glimmer/validator'; import { OutletComponentDefinition, OutletDefinitionState } from '../component-managers/outlet'; import { EmberVMEnvironment } from '../environment'; import { DynamicScope } from '../renderer'; @@ -75,7 +69,7 @@ export function outletHelper(args: VMArguments, vm: VM) { if (args.positional.length === 0) { nameRef = new ConstReference('main'); } else { - nameRef = args.positional.at>(0); + nameRef = args.positional.at>(0); } return new OutletComponentReference( @@ -85,17 +79,19 @@ export function outletHelper(args: VMArguments, vm: VM) { } class OutletModelReference extends RootReference { - public tag: Tag; - - constructor( - private parent: VersionedPathReference, - env: EmberVMEnvironment - ) { + constructor(private parent: PathReference, env: EmberVMEnvironment) { super(env); - this.tag = parent.tag; + + if (DEBUG) { + this.debugLabel = '@model'; + } } - value(): unknown { + isConst() { + return false; + } + + compute(): unknown { let state = this.parent.value(); if (state === undefined) { @@ -112,22 +108,17 @@ class OutletModelReference extends RootReference { } } -if (DEBUG) { - OutletModelReference.prototype['debugLogName'] = '@model'; -} - -class OutletComponentReference - implements VersionedPathReference { - public tag: Tag; +class OutletComponentReference implements PathReference { private definition: Option = null; private lastState: Option = null; constructor( - private outletRef: VersionedPathReference, + private outletRef: PathReference, private env: EmberVMEnvironment - ) { - // The router always dirties the root state. - this.tag = outletRef.tag; + ) {} + + isConst() { + return false; } value(): CurriedComponentDefinition | null { @@ -154,22 +145,22 @@ class OutletComponentReference } function makeArgs( - outletRef: VersionedPathReference, + outletRef: PathReference, env: EmberVMEnvironment ): CapturedArguments { - let tag = outletRef.tag; let modelRef = new OutletModelReference(outletRef, env); - let map = dict(); + let map = dict(); map.model = modelRef; // TODO: the functionailty to create a proper CapturedArgument should be // exported by glimmer, or that it should provide an overload for `curry` // that takes `PreparedArguments` return { - tag, positional: EMPTY_ARGS.positional, named: { - tag, + isConst() { + return false; + }, map, names: ['model'], references: [modelRef], @@ -177,7 +168,7 @@ function makeArgs( has(key: string): boolean { return key === 'model'; }, - get(key: string): T { + get(key: string): T { return (key === 'model' ? modelRef : UNDEFINED_REFERENCE) as unsafe; }, value(): Dict { @@ -195,9 +186,7 @@ function makeArgs( }; } -function stateFor( - ref: VersionedPathReference -): OutletDefinitionState | null { +function stateFor(ref: PathReference): OutletDefinitionState | null { let outlet = ref.value(); if (outlet === undefined) return null; let render = outlet.render; diff --git a/packages/@ember/-internals/glimmer/lib/utils/bindings.ts b/packages/@ember/-internals/glimmer/lib/utils/bindings.ts index caffdbd5407..2822d31bece 100644 --- a/packages/@ember/-internals/glimmer/lib/utils/bindings.ts +++ b/packages/@ember/-internals/glimmer/lib/utils/bindings.ts @@ -4,16 +4,10 @@ import { EMBER_COMPONENT_IS_VISIBLE } from '@ember/deprecated-features'; import { dasherize } from '@ember/string'; import { DEBUG } from '@glimmer/env'; import { ElementOperations, Option } from '@glimmer/interfaces'; -import { - Reference, - RootReference, - VersionedPathReference, - VersionedReference, -} from '@glimmer/reference'; +import { CachedReference, PathReference, Reference, RootReference } from '@glimmer/reference'; import { PrimitiveReference, UNDEFINED_REFERENCE } from '@glimmer/runtime'; -import { combine, Tag } from '@glimmer/validator'; +import { logTrackingStack } from '@glimmer/validator'; import { SimpleElement } from '@simple-dom/interface'; -import { EmberVMEnvironment } from '../environment'; import { Component } from './curly-component-state-bucket'; import { referenceFromParts } from './references'; import { htmlSafe, isHTMLSafe, SafeString } from './string'; @@ -64,8 +58,7 @@ export const AttributeBinding = { component: Component, rootRef: RootReference, parsed: [string, string, boolean], - operations: ElementOperations, - env: EmberVMEnvironment + operations: ElementOperations ) { let [prop, attribute, isSimple] = parsed; @@ -98,8 +91,7 @@ export const AttributeBinding = { reference = new StyleBindingReference( rootRef, reference, - referenceForKey(rootRef, 'isVisible'), - env + referenceForKey(rootRef, 'isVisible') ); } @@ -115,46 +107,39 @@ let StyleBindingReference: | undefined | { new ( - parent: VersionedPathReference, + parent: PathReference, inner: Reference, - isVisible: Reference, - env: EmberVMEnvironment - ): VersionedReference; + isVisible: Reference + ): Reference; }; export let installIsVisibleBinding: | undefined - | (( - rootRef: RootReference, - operations: ElementOperations, - environment: EmberVMEnvironment - ) => void); + | ((rootRef: RootReference, operations: ElementOperations) => void); if (EMBER_COMPONENT_IS_VISIBLE) { - StyleBindingReference = class implements VersionedPathReference { - public tag: Tag; + StyleBindingReference = class extends CachedReference { + debugLabel?: string; + constructor( - parent: VersionedPathReference, + parent: PathReference, private inner: Reference, - private isVisible: Reference, - private env: EmberVMEnvironment + private isVisible: Reference ) { - this.tag = combine([inner.tag, isVisible.tag]); + super(); if (DEBUG) { - env.setTemplatePathDebugContext(this, 'style', parent); + this.debugLabel = `${parent.debugLabel}.style`; } } - value(): string | SafeString { + compute(): string | SafeString { let value = this.inner.value(); let isVisible = this.isVisible.value(); - if (isVisible !== undefined) { + if (DEBUG && isVisible !== undefined) { deprecate( - `The \`isVisible\` property on classic component classes is deprecated. Was accessed ${this.env - .getTemplatePathDebugContext(this) - .replace(/^W/, 'w')}`, + `The \`isVisible\` property on classic component classes is deprecated. Was accessed:\n\n${logTrackingStack!()}`, false, { id: 'ember-component.is-visible', @@ -179,19 +164,10 @@ if (EMBER_COMPONENT_IS_VISIBLE) { } }; - installIsVisibleBinding = ( - rootRef: RootReference, - operations: ElementOperations, - environment: EmberVMEnvironment - ) => { + installIsVisibleBinding = (rootRef: RootReference, operations: ElementOperations) => { operations.setAttribute( 'style', - new StyleBindingReference!( - rootRef, - UNDEFINED_REFERENCE, - rootRef.get('isVisible'), - environment - ), + new StyleBindingReference!(rootRef, UNDEFINED_REFERENCE, rootRef.get('isVisible')), false, null ); @@ -227,13 +203,13 @@ export const ClassNameBinding = { }, }; -export class SimpleClassNameBindingReference implements VersionedReference> { - public tag: Tag; - private dasherizedPath: Option; +export class SimpleClassNameBindingReference implements Reference> { + private dasherizedPath: Option = null; - constructor(private inner: Reference, private path: string) { - this.tag = inner.tag; - this.dasherizedPath = null; + constructor(private inner: Reference, private path: string) {} + + isConst() { + return this.inner.isConst(); } value(): Option { @@ -250,15 +226,15 @@ export class SimpleClassNameBindingReference implements VersionedReference> { - public tag: Tag; - +class ColonClassNameBindingReference implements Reference> { constructor( private inner: Reference, private truthy: Option = null, private falsy: Option = null - ) { - this.tag = inner.tag; + ) {} + + isConst() { + return this.inner.isConst(); } value(): Option { diff --git a/packages/@ember/-internals/glimmer/lib/utils/curly-component-state-bucket.ts b/packages/@ember/-internals/glimmer/lib/utils/curly-component-state-bucket.ts index 7e28b47db32..f58b051bbc0 100644 --- a/packages/@ember/-internals/glimmer/lib/utils/curly-component-state-bucket.ts +++ b/packages/@ember/-internals/glimmer/lib/utils/curly-component-state-bucket.ts @@ -1,8 +1,8 @@ import { clearElementView, clearViewElement, getViewElement } from '@ember/-internals/views'; import { CapturedNamedArguments } from '@glimmer/interfaces'; -import { ComponentRootReference, VersionedReference } from '@glimmer/reference'; +import { ComponentRootReference, Reference } from '@glimmer/reference'; import { registerDestructor } from '@glimmer/runtime'; -import { Revision, valueForTag } from '@glimmer/validator'; +import { Revision, Tag, valueForTag } from '@glimmer/validator'; import { EmberVMEnvironment } from '../environment'; import { Renderer } from '../renderer'; import { Factory as TemplateFactory, OwnedTemplate } from '../template'; @@ -40,7 +40,7 @@ function NOOP() {} @private */ export default class ComponentStateBucket { - public classRef: VersionedReference | null = null; + public classRef: Reference | null = null; public rootRef: ComponentRootReference; public argsRevision: Revision; @@ -48,11 +48,12 @@ export default class ComponentStateBucket { public environment: EmberVMEnvironment, public component: Component, public args: CapturedNamedArguments | null, + public argsTag: Tag, public finalizer: Finalizer, public hasWrappedElement: boolean ) { this.classRef = null; - this.argsRevision = args === null ? 0 : valueForTag(args.tag); + this.argsRevision = args === null ? 0 : valueForTag(argsTag); this.rootRef = new ComponentRootReference(component, environment); registerDestructor(this, () => this.willDestroy(), true); diff --git a/packages/@ember/-internals/glimmer/lib/utils/debug-render-tree.ts b/packages/@ember/-internals/glimmer/lib/utils/debug-render-tree.ts index 56aae9ebb9e..990529df378 100644 --- a/packages/@ember/-internals/glimmer/lib/utils/debug-render-tree.ts +++ b/packages/@ember/-internals/glimmer/lib/utils/debug-render-tree.ts @@ -1,14 +1,11 @@ import { assert } from '@ember/debug'; import { Bounds, CapturedArguments, Option } from '@glimmer/interfaces'; -import { VersionedPathReference } from '@glimmer/reference'; import { expect, Stack, unwrapTemplate } from '@glimmer/util'; import { SimpleElement, SimpleNode } from '@simple-dom/interface'; import { OwnedTemplate } from '../template'; export type RenderNodeType = 'outlet' | 'engine' | 'route-template' | 'component'; -export type PathNodeType = 'root' | 'argument' | 'property' | 'iterator'; - export interface RenderNode { type: RenderNodeType; name: string; @@ -20,17 +17,9 @@ export interface RenderNode { interface InternalRenderNode extends RenderNode { bounds: Option; refs: Set>; - paths: Set>; parent?: InternalRenderNode; } -interface InternalPathNode { - name: string; - type: PathNodeType; - parent: InternalPathNode | InternalRenderNode; - paths: Set>; -} - export interface CapturedRenderNode { id: string; type: RenderNodeType; @@ -48,17 +37,6 @@ export interface CapturedRenderNode { let GUID = 0; -function isPathNode( - node: RenderNode | InternalPathNode -): node is InternalPathNode { - return ( - node.type === 'root' || - node.type === 'argument' || - node.type === 'property' || - node.type === 'iterator' - ); -} - export class Ref { readonly id: number = GUID++; private value: Option; @@ -91,23 +69,12 @@ export class Ref { } } -const _repeat = - String.prototype.repeat || - function(this: string, count: number) { - return new Array(count + 1).join(this); - }; - -function repeatString(str: string, count: number) { - return _repeat.call(str, count); -} - export default class DebugRenderTree { private stack = new Stack(); private refs = new WeakMap>(); private roots = new Set>(); private nodes = new WeakMap>(); - private pathNodes = new WeakMap>(); begin(): void { this.reset(); @@ -118,7 +85,6 @@ export default class DebugRenderTree { ...node, bounds: null, refs: new Set(), - paths: new Set(), }; this.nodes.set(state, internalNode); this.appendChild(internalNode, state); @@ -152,109 +118,6 @@ export default class DebugRenderTree { return this.captureRefs(this.roots); } - createPath( - pathRef: VersionedPathReference, - name: string, - type: PathNodeType, - parentRef: Option - ) { - assert( - 'BUG: Attempted to register a path that had already been registered', - !this.pathNodes.has(pathRef) - ); - - let { current } = this.stack; - - if (current === null) { - // Not currently in a rendering context, don't register the node - return; - } - - let currentNode = expect( - this.nodes.get(current), - 'BUG: Attempted to create a path, but there is no current render node' - ); - - let parent: InternalPathNode | InternalRenderNode; - - if (parentRef === null) { - parent = currentNode; - } else { - let { named } = currentNode.args; - let refIndex = named.references.indexOf(parentRef); - - if (refIndex !== -1) { - parent = { - parent: currentNode, - type: 'argument', - name: `@${named.names[refIndex]}`, - paths: new Set(), - }; - } else if (this.pathNodes.has(parentRef)) { - parent = this.pathNodes.get(parentRef)!; - } else { - // Some RootReferences get created before a component context has been - // setup (root, curly). This is mainly because the debugRenderTree is - // tied to the manager hooks, and not built into the VM directly. In - // these cases, we setup the path lazily when the first property is - // accessed. - - this.createPath(parentRef, 'this', 'root', null); - - parent = this.pathNodes.get(parentRef)!; - } - } - - let pathNode: InternalPathNode = { - name, - type, - parent, - paths: new Set(), - }; - - parent.paths.add(pathNode); - - this.pathNodes.set(pathRef, pathNode); - } - - logRenderStackForPath(pathRef: VersionedPathReference): string { - let node: InternalRenderNode | InternalPathNode | undefined = expect( - this.pathNodes.get(pathRef), - 'BUG: Attempted to create a log for a path reference, but no node exist for that reference' - ); - - let pathParts = []; - - while (node !== undefined && isPathNode(node)) { - if (node.type === 'iterator') { - // Iterator items are a combination of their own name (the key of the item) and - // their parent, the iterable itself. - let part = `${node.parent.name}[${node.name}]`; - pathParts.push(part); - - node = node.parent; - } else { - pathParts.unshift(node.name); - } - - node = node.parent; - } - - let messageParts = [pathParts.join('.')]; - - while (node !== undefined) { - if (node.type === 'outlet' || node.name === '-top-level') { - node = node.parent; - continue; - } - - messageParts.unshift(node.name); - node = node.parent; - } - - return messageParts.map((part, index) => `${repeatString(' ', index * 2)}${part}`).join('\n'); - } - private reset(): void { if (this.stack.size !== 0) { // We probably encountered an error during the rendering loop. This will diff --git a/packages/@ember/-internals/glimmer/lib/utils/outlet.ts b/packages/@ember/-internals/glimmer/lib/utils/outlet.ts index 7f705129da8..2d875581011 100644 --- a/packages/@ember/-internals/glimmer/lib/utils/outlet.ts +++ b/packages/@ember/-internals/glimmer/lib/utils/outlet.ts @@ -1,6 +1,6 @@ import { Owner } from '@ember/-internals/owner'; -import { Reference, VersionedPathReference } from '@glimmer/reference'; -import { combine, createTag, dirtyTag, Tag } from '@glimmer/validator'; +import { PathReference, Reference } from '@glimmer/reference'; +import { consumeTag, createTag, dirtyTag } from '@glimmer/validator'; import { Factory as TemplateFactory, OwnedTemplate } from '../template'; export interface RenderState { @@ -67,16 +67,21 @@ export interface OutletState { /** * Represents the root outlet. */ -export class RootOutletReference implements VersionedPathReference { - tag = createTag(); +export class RootOutletReference implements PathReference { + private tag = createTag(); constructor(public outletState: OutletState) {} - get(key: string): VersionedPathReference { - return new PathReference(this, key); + get(key: string): PathReference { + return new OutletPathReference(this, key); + } + + isConst() { + return false; } value(): OutletState { + consumeTag(this.tag); return this.outletState; } @@ -89,14 +94,14 @@ export class RootOutletReference implements VersionedPathReference /** * Represents the connected outlet. */ -export class OutletReference implements VersionedPathReference { - tag: Tag; - +export class OutletReference implements PathReference { constructor( - public parentStateRef: VersionedPathReference, + public parentStateRef: PathReference, public outletNameRef: Reference - ) { - this.tag = combine([parentStateRef.tag, outletNameRef.tag]); + ) {} + + isConst() { + return false; } value(): OutletState | undefined { @@ -105,8 +110,8 @@ export class OutletReference implements VersionedPathReference { - return new PathReference(this, key); + get(key: string): PathReference { + return new OutletPathReference(this, key); } } @@ -114,19 +119,21 @@ export class OutletReference implements VersionedPathReference { - public parent: VersionedPathReference; +class OutletPathReference implements PathReference { + public parent: PathReference; public key: string; - public tag: Tag; - constructor(parent: VersionedPathReference, key: string) { + constructor(parent: PathReference, key: string) { this.parent = parent; this.key = key; - this.tag = parent.tag; } - get(key: string): VersionedPathReference { - return new PathReference(this, key); + isConst() { + return false; + } + + get(key: string): PathReference { + return new OutletPathReference(this, key); } value(): unknown { diff --git a/packages/@ember/-internals/glimmer/lib/utils/references.ts b/packages/@ember/-internals/glimmer/lib/utils/references.ts index 42f69ce91b4..2cc5bb53651 100644 --- a/packages/@ember/-internals/glimmer/lib/utils/references.ts +++ b/packages/@ember/-internals/glimmer/lib/utils/references.ts @@ -2,9 +2,9 @@ import { getDebugName, isObject } from '@ember/-internals/utils'; import { debugFreeze } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import { CapturedArguments, Environment } from '@glimmer/interfaces'; -import { HelperRootReference, RootReference, VersionedPathReference } from '@glimmer/reference'; +import { HelperRootReference, PathReference, RootReference } from '@glimmer/reference'; import { PrimitiveReference } from '@glimmer/runtime'; -import { consumeTag, deprecateMutationsInAutotrackingTransaction } from '@glimmer/validator'; +import { consumeTag, deprecateMutationsInTrackingTransaction } from '@glimmer/validator'; import { HelperInstance, isClassHelper, RECOMPUTE_TAG, SimpleHelper } from '../helper'; export class EmberHelperRootReference extends HelperRootReference { @@ -25,7 +25,7 @@ export class EmberHelperRootReference extends HelperRootReference { + deprecateMutationsInTrackingTransaction!(() => { ret = helper.compute(positionalValue, namedValue); }); } else { @@ -50,24 +50,27 @@ export class EmberHelperRootReference extends HelperRootReference extends RootReference { - constructor( - private inner: T, - protected env: Environment, - parent?: VersionedPathReference, - key?: string - ) { + constructor(private inner: T, protected env: Environment, parent?: PathReference, key?: string) { super(env); if (DEBUG) { - env.setTemplatePathDebugContext(this, key || 'this', parent || null); + this.debugLabel = parent ? `${parent.debugLabel}.${key}` : `this`; } } + isConst() { + return true; + } + value() { return this.inner; } - get(key: string): VersionedPathReference { + compute() { + return this.inner; + } + + get(key: string): PathReference { let value = this.value(); if (isObject(value)) { @@ -82,9 +85,9 @@ export class UnboundRootReference extends RootReference { export class UnboundPropertyReference extends UnboundRootReference {} export function referenceFromParts( - root: VersionedPathReference, + root: PathReference, parts: string[] -): VersionedPathReference { +): PathReference { let reference = root; for (let i = 0; i < parts.length; i++) { diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js index 473284052c9..90bb9229520 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js @@ -3068,7 +3068,7 @@ moduleFor( this.render(`{{foo-bar id="foo-bar" isVisible=visible}}`, { visible: false, }); - }, /The `isVisible` property on classic component classes is deprecated. Was accessed while rendering:\n\nfoo-bar/); + }, /The `isVisible` property on classic component classes is deprecated. Was accessed:\n\n- While rendering:\n {2}foo-bar/); assertStyle('display: none;'); @@ -3078,7 +3078,7 @@ moduleFor( runTask(() => { set(this.context, 'visible', true); }); - }, /The `isVisible` property on classic component classes is deprecated. Was accessed while rendering:\n\nfoo-bar/); + }, /The `isVisible` property on classic component classes is deprecated. Was accessed:\n\n- While rendering:\n {2}foo-bar/); assertStyle(''); @@ -3086,7 +3086,7 @@ moduleFor( runTask(() => { set(this.context, 'visible', false); }); - }, /The `isVisible` property on classic component classes is deprecated. Was accessed while rendering:\n\nfoo-bar/); + }, /The `isVisible` property on classic component classes is deprecated. Was accessed:\n\n- While rendering:\n {2}foo-bar/); assertStyle('display: none;'); } @@ -3105,7 +3105,7 @@ moduleFor( this.render(`{{foo-bar id="foo-bar" isVisible=visible}}`, { visible: false, }); - }, /The `isVisible` property on classic component classes is deprecated. Was accessed while rendering:\n\nfoo-bar/); + }, /The `isVisible` property on classic component classes is deprecated. Was accessed:\n\n- While rendering:\n {2}foo-bar/); this.assertComponentElement(this.firstChild, { tagName: 'div', @@ -3118,7 +3118,7 @@ moduleFor( runTask(() => { set(this.context, 'visible', true); }); - }, /The `isVisible` property on classic component classes is deprecated. Was accessed while rendering:\n\nfoo-bar/); + }, /The `isVisible` property on classic component classes is deprecated. Was accessed:\n\n- While rendering:\n {2}foo-bar/); this.assertComponentElement(this.firstChild, { tagName: 'div', @@ -3129,7 +3129,7 @@ moduleFor( runTask(() => { set(this.context, 'visible', false); }); - }, /The `isVisible` property on classic component classes is deprecated. Was accessed while rendering:\n\nfoo-bar/); + }, /The `isVisible` property on classic component classes is deprecated. Was accessed:\n\n- While rendering:\n {2}foo-bar/); this.assertComponentElement(this.firstChild, { tagName: 'div', @@ -3165,7 +3165,7 @@ moduleFor( visible: false, foo: 'baz', }); - }, /The `isVisible` property on classic component classes is deprecated. Was accessed while rendering:\n\nfoo-bar/); + }, /The `isVisible` property on classic component classes is deprecated. Was accessed:\n\n- While rendering:\n {2}foo-bar/); assertStyle('display: none;'); @@ -3175,7 +3175,7 @@ moduleFor( runTask(() => { set(this.context, 'visible', true); }); - }, /The `isVisible` property on classic component classes is deprecated. Was accessed while rendering:\n\nfoo-bar/); + }, /The `isVisible` property on classic component classes is deprecated. Was accessed:\n\n- While rendering:\n {2}foo-bar/); assertStyle(''); @@ -3184,7 +3184,7 @@ moduleFor( set(this.context, 'visible', false); set(this.context, 'foo', 'woo'); }); - }, /The `isVisible` property on classic component classes is deprecated. Was accessed while rendering:\n\nfoo-bar/); + }, /The `isVisible` property on classic component classes is deprecated. Was accessed:\n\n- While rendering:\n {2}foo-bar/); assertStyle('display: none;'); assert.equal(this.firstChild.getAttribute('foo'), 'woo'); diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/template-only-components-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/template-only-components-test.js index 0c08240dbd7..ea01c6391de 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/template-only-components-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/template-only-components-test.js @@ -150,7 +150,7 @@ if (ENV._TEMPLATE_ONLY_GLIMMER_COMPONENTS) { this.registerTemplateOnlyComponent('x-inner-template-only', '{{@value}}'); let expectedBacktrackingMessage = backtrackingMessageFor('content', '<.+?>', { - renderTree: ['x-outer', 'this.wrapper.content'], + renderTree: ['x-outer', 'x-inner-template-only', 'this.wrapper.content'], }); expectAssertion(() => { diff --git a/packages/@ember/-internals/glimmer/tests/integration/content-test.js b/packages/@ember/-internals/glimmer/tests/integration/content-test.js index c494df787fd..25ad36ceb6c 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/content-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/content-test.js @@ -707,18 +707,29 @@ class DynamicContentTestGenerator { [`${tag} rendering ${label}`]() { this.renderPath('value', { value }); + // NaN is unstable, not worth optimizing for in the VM + let wasNaN = typeof value === 'number' && isNaN(value); + this.assertContent(expected); - this.assertStableRerender(); + if (!wasNaN) { + this.assertStableRerender(); + } runTask(() => set(this.context, 'value', 'hello')); this.assertContent('hello'); - this.assertInvariants(); + + if (!wasNaN) { + this.assertInvariants(); + } runTask(() => set(this.context, 'value', value)); this.assertContent(expected); - this.assertInvariants(); + + if (!wasNaN) { + this.assertInvariants(); + } }, }; } diff --git a/packages/@ember/-internals/glimmer/tests/integration/custom-modifier-manager-test.js b/packages/@ember/-internals/glimmer/tests/integration/custom-modifier-manager-test.js index caedda7718b..503878e65d6 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/custom-modifier-manager-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/custom-modifier-manager-test.js @@ -286,7 +286,7 @@ moduleFor( ); let expectedMessage = backtrackingMessageFor('name', 'Person', { - renderTree: ['\\(instance of a `MyModifier` modifier\\)'], + renderTree: ['\\(instance of a `foo-bar` modifier\\)'], }); expectAssertion(() => { diff --git a/packages/@ember/-internals/glimmer/tests/integration/mount-test.js b/packages/@ember/-internals/glimmer/tests/integration/mount-test.js index 7ed2be76fa1..fa91cf2b10b 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/mount-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/mount-test.js @@ -146,7 +146,7 @@ moduleFor( }); let expectedBacktrackingMessage = backtrackingMessageFor('name', 'Person \\(Ben\\)', { - renderTree: ['application', 'route-with-mount', 'chat', 'application', 'this.person.name'], + renderTree: ['application', 'route-with-mount', 'chat', 'this.person.name'], }); await this.visit('/'); diff --git a/packages/@ember/-internals/metal/lib/property_get.ts b/packages/@ember/-internals/metal/lib/property_get.ts index 08a7b090133..bc1f8e08c0c 100644 --- a/packages/@ember/-internals/metal/lib/property_get.ts +++ b/packages/@ember/-internals/metal/lib/property_get.ts @@ -6,7 +6,7 @@ import { assert, deprecate } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import { consumeTag, - deprecateMutationsInAutotrackingTransaction, + deprecateMutationsInTrackingTransaction, isTracking, tagFor, track, @@ -119,7 +119,7 @@ export function _getProp(obj: object, keyName: string) { typeof (obj as MaybeHasUnknownProperty).unknownProperty === 'function' ) { if (DEBUG) { - deprecateMutationsInAutotrackingTransaction!(() => { + deprecateMutationsInTrackingTransaction!(() => { value = (obj as MaybeHasUnknownProperty).unknownProperty!(keyName); }); } else { diff --git a/yarn.lock b/yarn.lock index 56375ca3508..90892227b73 100644 --- a/yarn.lock +++ b/yarn.lock @@ -913,142 +913,142 @@ resolved "https://registry.yarnpkg.com/@ember/edition-utils/-/edition-utils-1.2.0.tgz#a039f542dc14c8e8299c81cd5abba95e2459cfa6" integrity sha512-VmVq/8saCaPdesQmftPqbFtxJWrzxNGSQ+e8x8LLe3Hjm36pJ04Q8LeORGZkAeOhldoUX9seLGmSaHeXkIqoog== -"@glimmer/compiler@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/compiler/-/compiler-0.56.1.tgz#fe391a65f794f85483f4d1ab4c84910b37a822a7" - integrity sha512-W+vP8ykJt8VS4q5C9vE/7RDKLgeB6lcA9Lw6WP8rzs278hGGOz5yr1PKFKKoqY6x0lisIohdsqlHZ+cw0HMsZQ== - dependencies: - "@glimmer/interfaces" "^0.56.1" - "@glimmer/syntax" "^0.56.1" - "@glimmer/util" "^0.56.1" - "@glimmer/wire-format" "^0.56.1" +"@glimmer/compiler@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/compiler/-/compiler-0.57.2.tgz#844b38b045a2d2f6cde382d100900cb8b64d38de" + integrity sha512-/2FDT/g7gEAzkn75hIhk/71iiLqbnaEY0dumeWY8vr89gfZ6jD4dOfhrofYp8+vdkkTWTu9v6ps/fYFIhu7i2g== + dependencies: + "@glimmer/interfaces" "^0.57.2" + "@glimmer/syntax" "^0.57.2" + "@glimmer/util" "^0.57.2" + "@glimmer/wire-format" "^0.57.2" "@simple-dom/interface" "^1.4.0" -"@glimmer/encoder@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/encoder/-/encoder-0.56.1.tgz#202514cae28710f68a828b2db3db955e62c6a9b3" - integrity sha512-vIQTtHzqjm/7qC9EtR6zqcqzU7SabgyUDZ0jdsLIyhjv7SZGq5qFWlonkHDnB8/o3lzAuwcxhjOY2y10nOX/yw== +"@glimmer/encoder@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/encoder/-/encoder-0.57.2.tgz#6bc6d637eedb0020293e8e7f724b6fcb94f21c04" + integrity sha512-Z41y8agv9KaeOTXuNjFrBUfAA7cFMrv3ykoIlg538KT4iuW6pbLrXZvb7bU5PSNgQhXZZ/0ASc7ldanrO6HdIA== dependencies: - "@glimmer/interfaces" "^0.56.1" - "@glimmer/vm" "^0.56.1" + "@glimmer/interfaces" "^0.57.2" + "@glimmer/vm" "^0.57.2" "@glimmer/env@0.1.7", "@glimmer/env@^0.1.7": version "0.1.7" resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc= -"@glimmer/interfaces@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.56.1.tgz#599d305fac56a1a757932c514d0e938ef2186135" - integrity sha512-+0KvSd7c9QmkEeCFHaBDub1DBeTONw+x6MZUcb/MlA3FfNis2aFs7kHVkjkdzp0Ust54Wn448dgWZFW27EuVJA== +"@glimmer/interfaces@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.57.2.tgz#6cf59f970103439333459c499a3602b19937168e" + integrity sha512-wdG01BZzbT9lOvl9hLJbnCfJX2i9aEtVksM/5BsFY/ljwSGnzO5YkQU/PYQniaW5dgezPHnyq5jIH2g5LWyvtw== dependencies: "@simple-dom/interface" "^1.4.0" -"@glimmer/low-level@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/low-level/-/low-level-0.56.1.tgz#d813bd5dbdd5914287623f0c3bfc3eedf97a279e" - integrity sha512-02S6C0HnQ4jTmhqBNXpA+9vtIduFJpfPzKKAREHuosWWNZnhQAziAowAUd3/MXZZkl2YDv6pRN30mT8NBMpRWg== +"@glimmer/low-level@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/low-level/-/low-level-0.57.2.tgz#33b7361437230b1dc9d33e1ff0209ca25f9e4d21" + integrity sha512-s5CX0dio2SzWhROY4VL5hkj8+emTk/ZluHC76Mz4iL28EHoAmHOsYBsgfIler2R2iL47624WrdPwh+C0rZmiLA== -"@glimmer/node@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/node/-/node-0.56.1.tgz#94c276c1ddcb2a3ea7dba592e493c487b3da7337" - integrity sha512-2vw0OtfrrSy/FbjPfqu3DNs5oYGo7D4/ahyq0O4v4y1ACtkcSx768yj4iBe0Jxce69sDb24zYwq13UA0JUwN2w== +"@glimmer/node@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/node/-/node-0.57.2.tgz#c814bbfbf00aed6e07392c41582f31a1cbb8a0cd" + integrity sha512-ah+HjBbraTM6GTmYw+fKW9vQf/rStMyDBxgeaUVMm86GTrSecLmZFJZUWBjmmgVEBgb06qKPgdQlOcku2SHEVQ== dependencies: - "@glimmer/interfaces" "^0.56.1" - "@glimmer/runtime" "^0.56.1" - "@glimmer/util" "^0.56.1" + "@glimmer/interfaces" "^0.57.2" + "@glimmer/runtime" "^0.57.2" + "@glimmer/util" "^0.57.2" "@simple-dom/document" "^1.4.0" "@simple-dom/interface" "^1.4.0" -"@glimmer/opcode-compiler@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/opcode-compiler/-/opcode-compiler-0.56.1.tgz#def91e1fa4f73049ad8a5827f90d3c457f162a6c" - integrity sha512-W2X+mA45PMkq4ZsGPqa7EqrMOSvWg7WC406yCwpLALMz7xueHN1aM/FdHxB2yVX0nppriKCgcqWfRFWeiM++SA== - dependencies: - "@glimmer/encoder" "^0.56.1" - "@glimmer/interfaces" "^0.56.1" - "@glimmer/program" "^0.56.1" - "@glimmer/reference" "^0.56.1" - "@glimmer/util" "^0.56.1" - "@glimmer/vm" "^0.56.1" - "@glimmer/wire-format" "^0.56.1" - -"@glimmer/program@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/program/-/program-0.56.1.tgz#f31a83a94a2095b2bc3bd0a8522439140c3503d4" - integrity sha512-ldu39AIIdOg5Mmg1bdl1f86xI6yLtHX52wUYWyowdlLO6r0UmdlDoeygKCtawJMSI1G/Gb4+fhcvyyg75rGXZw== - dependencies: - "@glimmer/encoder" "^0.56.1" - "@glimmer/interfaces" "^0.56.1" - "@glimmer/util" "^0.56.1" - -"@glimmer/reference@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.56.1.tgz#6760d1a143b17f20e16556d7cf8ce9a68e07fe5a" - integrity sha512-buPBW/5nmeIVqZQXNKRGS4UOT/zaZ2j0R+ARMRXJ/nVKF6IMchtWx8cAMxw3dO9jZBwX5R4uoZwr5tOSSMm3HQ== +"@glimmer/opcode-compiler@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/opcode-compiler/-/opcode-compiler-0.57.2.tgz#1b09b7356c81b3ff1354cd3225f08276ab30678a" + integrity sha512-hPCvH4VKY8+l3qzkuSPpcAnSh0hhJXHcuIPb06RKZwVfdK7l4A4C2Jv1jYuPUHru0in18H/0xOpHn7uvpBgvwQ== + dependencies: + "@glimmer/encoder" "^0.57.2" + "@glimmer/interfaces" "^0.57.2" + "@glimmer/program" "^0.57.2" + "@glimmer/reference" "^0.57.2" + "@glimmer/util" "^0.57.2" + "@glimmer/vm" "^0.57.2" + "@glimmer/wire-format" "^0.57.2" + +"@glimmer/program@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/program/-/program-0.57.2.tgz#6b1acb3d9a2d3d6f0d07d70052fb93467886fa1b" + integrity sha512-NoI1QxjAREulAM/SlvKJojuFLcpjpFaZ6XaWMNkYca84UTA09esyAv1dYgZQhwQMdHUOrQyrmsFQg/a3kiagGg== + dependencies: + "@glimmer/encoder" "^0.57.2" + "@glimmer/interfaces" "^0.57.2" + "@glimmer/util" "^0.57.2" + +"@glimmer/reference@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.57.2.tgz#378c0d3644d4a98c4138c3205f6d4f0b5e004e92" + integrity sha512-xkUsl4cYR9ZOBEsNOmdxmb7iQnfTzeQZSGOD7H2fP9RqKGXR4mpNuDyP2YDCs2bI5JChDo3QvPp24RHmDjd8rA== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/interfaces" "^0.56.1" - "@glimmer/util" "^0.56.1" - "@glimmer/validator" "^0.56.1" + "@glimmer/interfaces" "^0.57.2" + "@glimmer/util" "^0.57.2" + "@glimmer/validator" "^0.57.2" -"@glimmer/runtime@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/runtime/-/runtime-0.56.1.tgz#258bfc8abbe86709ce188dac75603d060fa0f7e1" - integrity sha512-IHI3+KvZ4xH5TEYNgQzLxM0ei4ScGuVN2XhomfFKbe906D8DgnqoAHAUyiOUh8aVmVp92npz8R5T/Txps4ZkLA== +"@glimmer/runtime@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/runtime/-/runtime-0.57.2.tgz#f7502ecab591b4363b532928189d49ed64611ae3" + integrity sha512-QmsYJI8kBv9MBFWDALCcCX26KtvfQ/e8ltkJraApYzozmHVNAVikKLQvcBVd+1XasUoI0l8MI9G/NWqk7ulu8A== dependencies: "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "^0.56.1" - "@glimmer/low-level" "^0.56.1" - "@glimmer/program" "^0.56.1" - "@glimmer/reference" "^0.56.1" - "@glimmer/util" "^0.56.1" - "@glimmer/validator" "^0.56.1" - "@glimmer/vm" "^0.56.1" - "@glimmer/wire-format" "^0.56.1" + "@glimmer/interfaces" "^0.57.2" + "@glimmer/low-level" "^0.57.2" + "@glimmer/program" "^0.57.2" + "@glimmer/reference" "^0.57.2" + "@glimmer/util" "^0.57.2" + "@glimmer/validator" "^0.57.2" + "@glimmer/vm" "^0.57.2" + "@glimmer/wire-format" "^0.57.2" "@simple-dom/interface" "^1.4.0" -"@glimmer/syntax@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.56.1.tgz#361989b70ed3482762f33ecb07dae52cefa76e87" - integrity sha512-4TdtIQVFo9UfIVzXnXpMuzsA4mX06oF9NER8FmIPjBosNiQsYB7P8sABSG+2rtWgsh6CkFXkwvxZ++BB+alwOw== +"@glimmer/syntax@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.57.2.tgz#f5c910d67027fbfda707b385d3ce03ecd324e2ee" + integrity sha512-gWMSSd0AqTRtTtqpjCY/qpyQqplNoqEVVGXwlHyao/Fzc7fmCoKyDmq7+nL19iU8O9wLKcwpIdYTm0cvEXJlKA== dependencies: - "@glimmer/interfaces" "^0.56.1" - "@glimmer/util" "^0.56.1" + "@glimmer/interfaces" "^0.57.2" + "@glimmer/util" "^0.57.2" handlebars "^4.7.4" simple-html-tokenizer "^0.5.9" -"@glimmer/util@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.56.1.tgz#0947f75df9a1b30e3c0c505bc2be2e776b4364ae" - integrity sha512-g7R5hMtZ2BLF+AsYhSE1xoh0gOJALof4/JL6zovYvqrsKTLYGK1Qe3RKXSt8dPav8Ac0LXt+cOd6jHPGSrEs+A== +"@glimmer/util@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.57.2.tgz#d44da407d2971b45982aef072915c75c6bbcf028" + integrity sha512-PIF29qQbR5w70UKZN/CXtSwGdDd5bolz5vKobPRgFHeigZUyICqvd74/PFe9gOzKWtCGt0Y8pi9BlAiVDXA1Fw== dependencies: "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "^0.56.1" + "@glimmer/interfaces" "^0.57.2" "@simple-dom/interface" "^1.4.0" -"@glimmer/validator@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.56.1.tgz#584c0d6c68a0e2bfd92fe25626da70173b0ed9de" - integrity sha512-UDqM4NZLx5x1YJqbYt9LPxn6fzFU5bv5S306b51Bjj0MaNun3QRHw8D5RzrZaMufMr72Dph/4YyN2zKMavfmIA== +"@glimmer/validator@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.57.2.tgz#7c37a33268c491280cc598fb3212c767f6fb3fce" + integrity sha512-e8WdKZod9Tznp62vHOd3SgyVFCD995z9PAmONvq4kDDONdBRTwFQaz72TaDB44bG6S3PL73s8GiuO7Iar0HX1g== dependencies: "@glimmer/env" "^0.1.7" -"@glimmer/vm@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/vm/-/vm-0.56.1.tgz#4c21a8fb5d492c1cb85228215cee22623fdd03c8" - integrity sha512-6Eb9EZmSFeb8M6DE+HfIZlWhKG8VyU3o7GSJw6n3J+1DNTfMID41NdS0Y8nd+gA6N1UJvEeC2QpKg4d8XCa50A== +"@glimmer/vm@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/vm/-/vm-0.57.2.tgz#c65c965eaad79faef53b6de92539fecf95445840" + integrity sha512-n7WwbASKo3AxOvtGXS6Wbk0zQh0Bd57NRTgrWGpdy4Ojw9TvaV/hOjYdRI1vxiS1T933N2VlDxLEtPzj1rg6Jw== dependencies: - "@glimmer/interfaces" "^0.56.1" - "@glimmer/util" "^0.56.1" + "@glimmer/interfaces" "^0.57.2" + "@glimmer/util" "^0.57.2" -"@glimmer/wire-format@^0.56.1": - version "0.56.1" - resolved "https://registry.yarnpkg.com/@glimmer/wire-format/-/wire-format-0.56.1.tgz#40ce098eabb3c9ac06afcb35cd1c5228f52d38b4" - integrity sha512-5HMysobNYWh4HFWh+LH5k3BZUTnLngyp6V1VJo7DgQ5iC+8c57V+M3HBuQOB7n6EBT0+sO49xMoylX/rywoCuA== +"@glimmer/wire-format@^0.57.2": + version "0.57.2" + resolved "https://registry.yarnpkg.com/@glimmer/wire-format/-/wire-format-0.57.2.tgz#294519d14da76e8d11eb7872daa2a23737e7cc70" + integrity sha512-g4EKDtImDHssNYkqwsb+VwS6f3LfogRuQlvMsk3LkACXYvwrvyBHJApKeCB3YvCbza7KMyYrfzcpzcBKIHcZhA== dependencies: - "@glimmer/interfaces" "^0.56.1" - "@glimmer/util" "^0.56.1" + "@glimmer/interfaces" "^0.57.2" + "@glimmer/util" "^0.57.2" "@simple-dom/document@^1.4.0": version "1.4.0"