Skip to content

Commit

Permalink
[FEATURE strict-mode] Update VM for Strict Mode
Browse files Browse the repository at this point in the history
Updates the Glimmer VM to the latest version, which includes strict
mode. Strict mode is currently guarded behind a canary flag, but for the
most part only involves changes to the VM. The biggest changes are to
the template compiler's `compile` function, which has to change in order
to still be functional as scope values must be provided in some way, and
the resolver, which needs to provide keyword built-ins now in strict
templates.

Release notes for the VM: https://github.com/glimmerjs/glimmer-vm/releases/tag/v0.69.0
  • Loading branch information
Chris Garrett committed Dec 11, 2020
1 parent 23ee5d1 commit ac20b89
Show file tree
Hide file tree
Showing 29 changed files with 690 additions and 231 deletions.
24 changes: 12 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,19 @@
},
"devDependencies": {
"@babel/preset-env": "^7.9.5",
"@glimmer/compiler": "0.68.1",
"@glimmer/compiler": "0.69.3",
"@glimmer/env": "^0.1.7",
"@glimmer/global-context": "0.68.1",
"@glimmer/interfaces": "0.68.1",
"@glimmer/manager": "0.68.1",
"@glimmer/destroyable": "0.68.1",
"@glimmer/owner": "0.68.1",
"@glimmer/node": "0.68.1",
"@glimmer/opcode-compiler": "0.68.1",
"@glimmer/program": "0.68.1",
"@glimmer/reference": "0.68.1",
"@glimmer/runtime": "0.68.1",
"@glimmer/validator": "0.68.1",
"@glimmer/global-context": "0.69.3",
"@glimmer/interfaces": "0.69.3",
"@glimmer/manager": "0.69.3",
"@glimmer/destroyable": "0.69.3",
"@glimmer/owner": "0.69.3",
"@glimmer/node": "0.69.3",
"@glimmer/opcode-compiler": "0.69.3",
"@glimmer/program": "0.69.3",
"@glimmer/reference": "0.69.3",
"@glimmer/runtime": "0.69.3",
"@glimmer/validator": "0.69.3",
"@simple-dom/document": "^1.4.0",
"@types/qunit": "^2.9.1",
"@types/rsvp": "^4.0.3",
Expand Down
9 changes: 8 additions & 1 deletion packages/@ember/-internals/glimmer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ export { default as Checkbox } from './lib/components/checkbox';
export { default as TextField } from './lib/components/text-field';
export { default as TextArea } from './lib/components/textarea';
export { default as LinkComponent } from './lib/components/link-to';
export { InputComponent as Input } from './lib/components/input';
export { default as Component } from './lib/component';
export { default as Helper, helper } from './lib/helper';
export { SafeString, escapeExpression, htmlSafe, isHTMLSafe } from './lib/utils/string';
Expand All @@ -387,12 +388,18 @@ export {
export { setupEngineRegistry, setupApplicationRegistry } from './lib/setup-registry';
export { DOMChanges, NodeDOMTreeConstruction, DOMTreeConstruction } from './lib/dom';

export { default as array } from './lib/helpers/array';
export { default as hash } from './lib/helpers/hash';
export { default as concat } from './lib/helpers/concat';
export { default as get } from './lib/helpers/get';
export { default as fn } from './lib/helpers/fn';
export { default as on } from './lib/modifiers/on';

// needed for test
// TODO just test these through public API
// a lot of these are testing how a problem was solved
// rather than the problem was solved
export { INVOKE } from './lib/helpers/action';
export { default as on } from './lib/modifiers/on';
export { default as OutletView } from './lib/views/outlet';
export { OutletState } from './lib/utils/outlet';
export { setComponentManager } from './lib/utils/managers';
Expand Down
22 changes: 16 additions & 6 deletions packages/@ember/-internals/glimmer/lib/component-managers/curly.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Factory, getOwner } from '@ember/-internals/owner';
import { Factory, getOwner, Owner } from '@ember/-internals/owner';
import { enumerableSymbol, guidFor, symbol } from '@ember/-internals/utils';
import { addChildView, setElementView, setViewElement } from '@ember/-internals/views';
import { assert, debugFreeze } from '@ember/debug';
Expand All @@ -21,6 +21,7 @@ import {
WithDynamicLayout,
WithDynamicTagName,
} from '@glimmer/interfaces';
import { setOwner } from '@glimmer/owner';
import {
childRefFor,
createComputeRef,
Expand All @@ -29,7 +30,7 @@ import {
valueForRef,
} from '@glimmer/reference';
import { reifyPositional } from '@glimmer/runtime';
import { EMPTY_ARRAY, unwrapTemplate } from '@glimmer/util';
import { _WeakSet, EMPTY_ARRAY, unwrapTemplate } from '@glimmer/util';
import {
beginTrackFrame,
beginUntrackFrame,
Expand All @@ -40,7 +41,7 @@ import {
valueForTag,
} from '@glimmer/validator';
import { SimpleElement } from '@simple-dom/interface';
import { DynamicScope } from '../renderer';
import { DynamicScope, Renderer } from '../renderer';
import RuntimeResolver from '../resolver';
import { isTemplateFactory } from '../template';
import {
Expand Down Expand Up @@ -124,7 +125,10 @@ type ComponentFactory = Factory<
positionalParams: string | string[] | undefined | null;
name: string;
}
>;
> & {
name: string;
positionalParams: string | string[] | undefined | null;
};

export default class CurlyComponentManager
implements
Expand Down Expand Up @@ -188,7 +192,7 @@ export default class CurlyComponentManager
return prepared;
}

const { positionalParams } = ComponentClass.class!;
const { positionalParams } = ComponentClass.class ?? ComponentClass;

// early exits
if (
Expand Down Expand Up @@ -355,7 +359,9 @@ export default class CurlyComponentManager
}

getDebugName(definition: ComponentFactory): string {
return definition.fullName || definition.normalizedName || definition.class!.name;
return (
definition.fullName || definition.normalizedName || definition.class?.name || definition.name
);
}

getSelf({ rootRef }: ComponentStateBucket): Reference {
Expand Down Expand Up @@ -551,3 +557,7 @@ export const CURLY_CAPABILITIES: InternalComponentCapabilities = {
};

export const CURLY_COMPONENT_MANAGER = new CurlyComponentManager();

export function isCurlyManager(manager: object): boolean {
return manager === CURLY_COMPONENT_MANAGER;
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,26 @@ export default class InternalManager
implements
InternalComponentManager<InternalComponentState, EmberInternalComponentConstructor>,
WithCreateInstance {
static for(name: string): (owner: Owner) => InternalManager {
return (owner: Owner) => new InternalManager(owner, name);
static for(
definition: EmberInternalComponentConstructor,
name: string
): (owner: Owner) => InternalManager {
return (owner: Owner) => new InternalManager(owner, definition, name);
}

constructor(private owner: Owner, private name: string) {}
constructor(
private owner: Owner,
private ComponentClass: EmberInternalComponentConstructor,
private name: string
) {}

getCapabilities(): InternalComponentCapabilities {
return CAPABILITIES;
}

create(
env: Environment,
ComponentClass: EmberInternalComponentConstructor,
_definition: unknown,
args: VMArguments,
_dynamicScope: DynamicScope,
caller: Reference
Expand All @@ -64,7 +71,8 @@ export default class InternalManager
args.positional.length === 0
);

let instance = new ComponentClass(this.owner, args.named.capture(), valueForRef(caller));
let { ComponentClass, owner } = this;
let instance = new ComponentClass(owner, args.named.capture(), valueForRef(caller));

let state = { env, instance };

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getFactoryFor } from '@ember/-internals/container';
import { Owner } from '@ember/-internals/owner';
import { _instrumentStart } from '@ember/instrumentation';
import { DEBUG } from '@glimmer/env';
import {
Expand All @@ -21,8 +22,8 @@ import CurlyComponentManager, {
class RootComponentManager extends CurlyComponentManager {
component: Component;

constructor(component: Component) {
super();
constructor(owner: Owner, component: Component) {
super(owner);
this.component = component;
}

Expand Down Expand Up @@ -99,8 +100,8 @@ export class RootComponentDefinition implements ComponentDefinition {
capabilities = capabilityFlagsFrom(ROOT_CAPABILITIES);
compilable = null;

constructor(component: Component) {
this.manager = new RootComponentManager(component);
constructor(owner: Owner, component: Component) {
this.manager = new RootComponentManager(owner, component);
this.state = getFactoryFor(component);
}
}
4 changes: 2 additions & 2 deletions packages/@ember/-internals/glimmer/lib/component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { get, PROPERTY_DID_CHANGE } from '@ember/-internals/metal';
import { getOwner } from '@ember/-internals/owner';
import { getOwner, Owner } from '@ember/-internals/owner';
import { TargetActionSupport } from '@ember/-internals/runtime';
import {
ActionSupport,
Expand All @@ -17,7 +17,7 @@ import { isUpdatableRef, updateRef } from '@glimmer/reference';
import { normalizeProperty } from '@glimmer/runtime';
import { createTag, dirtyTag } from '@glimmer/validator';
import { Namespace } from '@simple-dom/interface';
import {
import CurlyComponentManager, {
ARGS,
BOUNDS,
CURLY_COMPONENT_MANAGER,
Expand Down
16 changes: 13 additions & 3 deletions packages/@ember/-internals/glimmer/lib/components/input.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/**
@module @ember/component
*/
import { setInternalComponentManager } from '@glimmer/manager';
import { assert } from '@ember/debug';
import { setComponentTemplate, setInternalComponentManager } from '@glimmer/manager';
import InternalManager from '../component-managers/internal';
import InputTemplate from '../templates/input';
import InternalComponent from './internal';

/**
See [Ember.Templates.components.Input](/ember/release/classes/Ember.Templates.components/methods/Input?anchor=Input).
Expand Down Expand Up @@ -117,6 +118,15 @@ export default class Input extends InternalComponent {
}
}

setInternalComponentManager(InternalManager.for('input'), Input);
// Use an opaque handle so implementation details are
export const InputComponent = {
// Factory interface
create(): never {
throw assert('Use constructor instead of create');
},
};

setInternalComponentManager(InternalManager.for(Input, 'input'), InputComponent);
setComponentTemplate(InputTemplate, InputComponent);

Input.toString = () => '@ember/component/input';
6 changes: 0 additions & 6 deletions packages/@ember/-internals/glimmer/lib/components/internal.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { Owner, setOwner } from '@ember/-internals/owner';
import { guidFor } from '@ember/-internals/utils';
import { assert } from '@ember/debug';
import { Reference, valueForRef } from '@glimmer/reference';

export default class InternalComponent {
// Factory interface
static create(): never {
throw assert('Use constructor instead of create');
}

static get class(): typeof InternalComponent {
return this;
}
Expand Down
4 changes: 3 additions & 1 deletion packages/@ember/-internals/glimmer/lib/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ interface ViewRegistry {
}

export abstract class Renderer {
private _owner: Owner;
private _rootTemplate: Template;
private _viewRegistry: ViewRegistry;
private _destinedForDOM: boolean;
Expand All @@ -295,6 +296,7 @@ export abstract class Renderer {
destinedForDOM = false,
builder = clientBuilder
) {
this._owner = owner;
this._rootTemplate = rootTemplate(owner);
this._viewRegistry = viewRegistry;
this._destinedForDOM = destinedForDOM;
Expand Down Expand Up @@ -342,7 +344,7 @@ export abstract class Renderer {
}

appendTo(view: Component, target: SimpleElement): void {
let definition = new RootComponentDefinition(view);
let definition = new RootComponentDefinition(this._owner, view);
this._appendDefinition(view, curry(definition, null), target);
}

Expand Down
Loading

0 comments on commit ac20b89

Please sign in to comment.