Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor template factory #18096

Merged
merged 1 commit into from
Jun 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/@ember/-internals/glimmer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,12 @@
*/

export { default as RootTemplate } from './lib/templates/root';
export { default as template } from './lib/template';
export {
default as template,
counters as templateCacheCounters,
Factory as TemplateFactory,
OwnedTemplate,
} from './lib/template';
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';
Expand Down
45 changes: 22 additions & 23 deletions packages/@ember/-internals/glimmer/lib/component-managers/curly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function aliasIdToElementId(args: Arguments, props: any) {
}

function isTemplateFactory(template: OwnedTemplate | TemplateFactory): template is TemplateFactory {
return typeof (template as TemplateFactory).create === 'function';
return typeof template === 'function';
}

// We must traverse the attributeBindings in reverse keeping track of
Expand Down Expand Up @@ -119,41 +119,41 @@ export default class CurlyComponentManager
};
}

templateFor(component: Component, resolver: RuntimeResolver): OwnedTemplate {
let { layout, layoutName } = component;
templateFor(component: Component): OwnedTemplate {
let { layout: _layout, layoutName } = component;
let owner = getOwner(component);

if (layout !== undefined) {
// This needs to be cached by template.id
if (isTemplateFactory(layout)) {
return resolver.createTemplate(layout, getOwner(component));
} else {
// we were provided an instance already
return layout;
}
}
let layout: TemplateFactory;

if (layoutName) {
let template = owner.lookup<OwnedTemplate>('template:' + layoutName);
if (template) {
return template;
if (_layout === undefined) {
if (layoutName !== undefined) {
layout = owner.lookup<TemplateFactory>(`template:${layoutName}`);
assert(`Layout \`${layoutName}\` not found!`, layout !== undefined);
} else {
layout = owner.lookup(DEFAULT_LAYOUT);
}
} else if (isTemplateFactory(_layout)) {
layout = _layout;
} else {
// we were provided an instance already
return _layout;
}

return owner.lookup<OwnedTemplate>(DEFAULT_LAYOUT);
return layout(owner);
}

getDynamicLayout({ component }: ComponentStateBucket, resolver: RuntimeResolver): Invocation {
const template = this.templateFor(component, resolver);
const layout = template.asWrappedLayout();
getDynamicLayout({ component }: ComponentStateBucket): Invocation {
let template = this.templateFor(component);
let layout = template.asWrappedLayout();

return {
handle: layout.compile(),
symbolTable: layout.symbolTable,
};
}

getTagName(state: ComponentStateBucket): Option<string> {
const { component, hasWrappedElement } = state;
let { component, hasWrappedElement } = state;

if (!hasWrappedElement) {
return null;
Expand Down Expand Up @@ -574,7 +574,6 @@ export const CURLY_CAPABILITIES: ComponentCapabilities = {

const CURLY_COMPONENT_MANAGER = new CurlyComponentManager();
export class CurlyComponentDefinition implements ComponentDefinition {
public template: OwnedTemplate;
public args: CurriedArgs | undefined;
public state: DefinitionState;
public symbolTable: ProgramSymbolTable | undefined;
Expand All @@ -584,7 +583,7 @@ export class CurlyComponentDefinition implements ComponentDefinition {
public name: string,
public ComponentClass: any,
public handle: Option<VMHandle>,
template: OwnedTemplate,
public template?: OwnedTemplate,
args?: CurriedArgs
) {
const layout = template && template.asLayout();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { Destroyable, Opaque, Option } from '@glimmer/util';
import { Owner } from '@ember/-internals/owner';
import { generateControllerFactory } from '@ember/-internals/routing';
import { OwnedTemplateMeta } from '@ember/-internals/views';
import { TemplateFactory } from '../..';
import Environment from '../environment';
import RuntimeResolver from '../resolver';
import { OwnedTemplate } from '../template';
import { RootReference } from '../utils/references';
import AbstractManager from './abstract';

Expand Down Expand Up @@ -54,8 +54,10 @@ class MountManager
implements
WithDynamicLayout<EngineState | EngineWithModelState, OwnedTemplateMeta, RuntimeResolver> {
getDynamicLayout(state: EngineState, _: RuntimeResolver): Invocation {
let template = state.engine.lookup('template:application') as OwnedTemplate;
let templateFactory = state.engine.lookup('template:application') as TemplateFactory;
let template = templateFactory(state.engine);
let layout = template.asLayout();

return {
handle: layout.compile(),
symbolTable: layout.symbolTable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Arguments, ComponentDefinition } from '@glimmer/runtime';
import { DIRTY_TAG } from '../component';
import Environment from '../environment';
import { DynamicScope } from '../renderer';
import RuntimeResolver from '../resolver';
import ComponentStateBucket, { Component } from '../utils/curly-component-state-bucket';
import CurlyComponentManager, {
initialRenderInstrumentDetails,
Expand All @@ -23,8 +22,8 @@ class RootComponentManager extends CurlyComponentManager {
this.component = component;
}

getLayout(_state: DefinitionState, resolver: RuntimeResolver) {
const template = this.templateFor(this.component, resolver);
getLayout(_state: DefinitionState) {
const template = this.templateFor(this.component);
const layout = template.asWrappedLayout();
return {
handle: layout.compile(),
Expand Down
12 changes: 6 additions & 6 deletions packages/@ember/-internals/glimmer/lib/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { BOUNDS } from './component';
import { createRootOutlet } from './component-managers/outlet';
import { RootComponentDefinition } from './component-managers/root';
import Environment from './environment';
import { OwnedTemplate } from './template';
import { Factory as TemplateFactory, OwnedTemplate } from './template';
import { Component } from './utils/curly-component-state-bucket';
import { OutletState } from './utils/outlet';
import { UnboundReference } from './utils/references';
Expand Down Expand Up @@ -246,7 +246,7 @@ interface ViewRegistry {

export abstract class Renderer {
private _env: Environment;
private _rootTemplate: any;
private _rootTemplate: OwnedTemplate;
private _viewRegistry: ViewRegistry;
private _destinedForDOM: boolean;
private _destroyed: boolean;
Expand All @@ -258,13 +258,13 @@ export abstract class Renderer {

constructor(
env: Environment,
rootTemplate: OwnedTemplate,
rootTemplate: TemplateFactory,
viewRegistry: ViewRegistry,
destinedForDOM = false,
builder = clientBuilder
) {
this._env = env;
this._rootTemplate = rootTemplate;
this._rootTemplate = rootTemplate(env.owner);
this._viewRegistry = viewRegistry;
this._destinedForDOM = destinedForDOM;
this._destroyed = false;
Expand Down Expand Up @@ -517,7 +517,7 @@ export class InertRenderer extends Renderer {
builder,
}: {
env: Environment;
rootTemplate: OwnedTemplate;
rootTemplate: TemplateFactory;
_viewRegistry: any;
builder: any;
}) {
Expand All @@ -539,7 +539,7 @@ export class InteractiveRenderer extends Renderer {
builder,
}: {
env: Environment;
rootTemplate: OwnedTemplate;
rootTemplate: TemplateFactory;
_viewRegistry: any;
builder: any;
}) {
Expand Down
60 changes: 14 additions & 46 deletions packages/@ember/-internals/glimmer/lib/resolver.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { privatize as P } from '@ember/-internals/container';
import { ENV } from '@ember/-internals/environment';
import { LookupOptions, Owner, setOwner } from '@ember/-internals/owner';
import { FactoryClass, LookupOptions, Owner } from '@ember/-internals/owner';
import { lookupComponent, lookupPartial, OwnedTemplateMeta } from '@ember/-internals/views';
import {
EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS,
Expand Down Expand Up @@ -49,7 +49,6 @@ import OnModifierManager from './modifiers/on';
import { populateMacros } from './syntax';
import { mountHelper } from './syntax/mount';
import { outletHelper } from './syntax/outlet';
import { Factory as TemplateFactory, Injections, OwnedTemplate } from './template';
import { getModifierManager } from './utils/custom-modifier-manager';
import { getManager } from './utils/managers';
import { ClassBasedHelperReference, SimpleHelperReference } from './utils/references';
Expand Down Expand Up @@ -114,13 +113,9 @@ export default class RuntimeResolver implements IRuntimeResolver<OwnedTemplateMe

private builtInModifiers: IBuiltInModifiers;

// supports directly imported late bound layouts on component.prototype.layout
private templateCache: Map<Owner, Map<TemplateFactory, OwnedTemplate>> = new Map();
private componentDefinitionCache: Map<object, ComponentDefinition | null> = new Map();
private customManagerCache: Map<string, ManagerDelegate<Opaque>> = new Map();

public templateCacheHits = 0;
public templateCacheMisses = 0;
public componentDefinitionCount = 0;
public helperDefinitionCount = 0;

Expand Down Expand Up @@ -213,34 +208,6 @@ export default class RuntimeResolver implements IRuntimeResolver<OwnedTemplateMe

// end CompileTimeLookup

/**
* Creates a template with injections from a directly imported template factory.
* @param templateFactory the directly imported template factory.
* @param owner the owner the template instance would belong to if resolved
*/
createTemplate(factory: TemplateFactory, owner: Owner): OwnedTemplate {
let cache = this.templateCache.get(owner);
let template;
if (cache === undefined) {
cache = new Map();
this.templateCache.set(owner, cache);
} else {
template = cache.get(factory);
}

if (template === undefined) {
const { compiler } = this;
const injections: Injections = { compiler };
setOwner(injections, owner);
template = factory.create(injections);
cache.set(factory, template);
this.templateCacheMisses++;
} else {
this.templateCacheHits++;
}
return template;
}

// needed for lazy compile time lookup
private handle(obj: Opaque) {
if (obj === undefined || obj === null) {
Expand Down Expand Up @@ -290,21 +257,18 @@ export default class RuntimeResolver implements IRuntimeResolver<OwnedTemplateMe
}

private _lookupPartial(name: string, meta: OwnedTemplateMeta): PartialDefinition {
const template = lookupPartial(name, meta.owner);
let templateFactory = lookupPartial(name, meta.owner);
let template = templateFactory(meta.owner);

if (template) {
return new PartialDefinition(name, template);
} else {
throw new Error(`${name} is not a partial`);
}
return new PartialDefinition(name, template);
}

private _lookupModifier(name: string, meta: OwnedTemplateMeta) {
let builtin = this.builtInModifiers[name];

if (builtin === undefined) {
let { owner } = meta;
let modifier = owner.factoryFor(`modifier:${name}`);
let modifier = owner.factoryFor<unknown, FactoryClass>(`modifier:${name}`);
if (modifier !== undefined) {
let managerFactory = getModifierManager<ModifierManagerDelegate<Opaque>>(modifier.class);
let manager = managerFactory!(owner);
Expand Down Expand Up @@ -367,13 +331,13 @@ export default class RuntimeResolver implements IRuntimeResolver<OwnedTemplateMe
let definition: Option<ComponentDefinition> = null;

if (layout !== undefined && component === undefined && ENV._TEMPLATE_ONLY_GLIMMER_COMPONENTS) {
definition = new TemplateOnlyComponentDefinition(layout);
definition = new TemplateOnlyComponentDefinition(layout(owner));
}

if (component !== undefined && component.class !== undefined) {
let wrapper = getManager(component.class);

if (wrapper && wrapper.type === 'component') {
if (wrapper !== null && wrapper.type === 'component') {
let { factory } = wrapper;

if (wrapper.internal) {
Expand All @@ -382,14 +346,18 @@ export default class RuntimeResolver implements IRuntimeResolver<OwnedTemplateMe
definition = new InternalComponentDefinition(
factory(owner) as InternalComponentManager<Opaque>,
component.class,
layout!
layout!(owner)
);
} else {
if (layout === undefined) {
layout = owner.lookup(P`template:components/-default`);
}

definition = new CustomManagerDefinition(
name,
component,
factory(owner) as ManagerDelegate<Opaque>,
layout || owner.lookup<OwnedTemplate>(P`template:components/-default`)
layout!(owner)
);
}
}
Expand All @@ -400,7 +368,7 @@ export default class RuntimeResolver implements IRuntimeResolver<OwnedTemplateMe
name,
component || owner.factoryFor(P`component:-default`),
null,
layout! // TODO fix type
layout !== undefined ? layout(owner) : undefined
);
}

Expand Down
12 changes: 6 additions & 6 deletions packages/@ember/-internals/glimmer/lib/setup-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function setupApplicationRegistry(registry: Registry) {
registry.injection('service:-dom-builder', 'bootOptions', '-environment:main');
registry.injection('renderer', 'builder', 'service:-dom-builder');

registry.register(P`template:-root`, RootTemplate);
registry.register(P`template:-root`, RootTemplate as any);
registry.injection('renderer', 'rootTemplate', P`template:-root`);

registry.register('renderer:-dom', InteractiveRenderer);
Expand All @@ -80,22 +80,22 @@ export function setupApplicationRegistry(registry: Registry) {
}

export function setupEngineRegistry(registry: Registry) {
registry.optionsForType('template', { instantiate: false });

registry.register('view:-outlet', OutletView);
registry.register('template:-outlet', OutletTemplate);
registry.register('template:-outlet', OutletTemplate as any);
Copy link
Contributor

Choose a reason for hiding this comment

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

why does this need as any?

registry.injection('view:-outlet', 'template', 'template:-outlet');

registry.injection('service:-dom-changes', 'document', 'service:-document');
registry.injection('service:-dom-tree-construction', 'document', 'service:-document');

registry.register(P`template:components/-default`, ComponentTemplate);
registry.register(P`template:components/-default`, ComponentTemplate as any);

registry.register('service:-glimmer-environment', Environment);

registry.register(P`template-compiler:main`, TemplateCompiler);
registry.injection(P`template-compiler:main`, 'environment', '-environment:main');

registry.injection('template', 'compiler', P`template-compiler:main`);

registry.optionsForType('helper', { instantiate: false });

registry.register('helper:loc', loc);
Expand All @@ -106,7 +106,7 @@ export function setupEngineRegistry(registry: Registry) {

if (EMBER_GLIMMER_ANGLE_BRACKET_BUILT_INS) {
registry.register('component:input', Input);
registry.register('template:components/input', InputTemplate);
registry.register('template:components/input', InputTemplate as any);

registry.register('component:textarea', TextArea);
} else {
Expand Down
Loading