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

Bump glimmer-vm packages to 0.24. #15245

Merged
merged 38 commits into from
May 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
993abfb
Bump Glimmer version
chancancode May 17, 2017
10a2e8b
Fix build scripts for latest Glimmer
chancancode May 17, 2017
a574dee
These are built-in now
chancancode May 17, 2017
a7fbb70
Fix macro syntax
chancancode May 17, 2017
6d1983c
Update helpers to use new args
chancancode May 17, 2017
99ac470
✂️ symbolTable part 1
chancancode May 17, 2017
1931603
Fix iterable hook
chancancode May 17, 2017
7467fa2
Fix compilation
chancancode May 17, 2017
7160af0
✂️ getArgs
chancancode May 17, 2017
60e62a7
Fix macros
chancancode May 17, 2017
9921db3
Fix closure component helper
chancancode May 17, 2017
d979a63
[WIP] Fix component args
chancancode May 17, 2017
17f5990
Fix {{hash}}
chancancode May 17, 2017
01e8fde
Merge branch 'master' into bump-glimmer
rwjblue May 18, 2017
68bbd91
Fix `{{mut}}`.
rwjblue May 18, 2017
d44b7d1
Fix `(action`.
rwjblue May 19, 2017
aeed4af
Fix `{{action`.
rwjblue May 19, 2017
d3f6ffa
Fix non-singleton `{{render` tests.
rwjblue May 19, 2017
56da213
Ensure managers return `null` from `prepareArgs` to "pass through".
rwjblue May 23, 2017
887cd9e
Make test helpers clear up renderers upon teardown.
rwjblue May 23, 2017
7a20aa2
fixup! Fix non-singleton `{{render` tests.
rwjblue May 23, 2017
8f8559f
Initial pass at supporting "rest arg" style positionals.
rwjblue May 23, 2017
3da5219
Remove iterableForObject tests.
rwjblue May 23, 2017
2f5f544
Update glimmer versions to 0.24.0-alpha.2.
rwjblue May 23, 2017
23b0d10
Merge remote-tracking branch 'origin/master' into bump-glimmer
rwjblue May 23, 2017
479941a
Split component managers out from syntax definition.
rwjblue May 23, 2017
877dfa9
Fix closure component currying and positional param munging.
rwjblue May 23, 2017
86fcd7c
Fixup layout caching tests.
rwjblue May 23, 2017
3747924
Fix issues with AST transform for `{{this.attrs.foo}}` -> `{{@foo}}`.
rwjblue May 23, 2017
2c89920
Bump glimmer-vm packages to 0.24.0-beta.1.
rwjblue May 23, 2017
a76889e
Ensure that newly created `PositionalArgumentsReference` implements `…
rwjblue May 23, 2017
b519467
Fix `ember-engines-mount-params` feature with glimmer-vm@0.24.
rwjblue May 24, 2017
4461804
Update to glimmer-vm 0.24.0-beta.2.
rwjblue May 24, 2017
3abb295
Fix `glimmer-custom-component-manager` feature for glimmer-vm 0.24.x.
rwjblue May 24, 2017
fab7a33
Bump glimmer-vm packages to 0.24.0-beta.3.
rwjblue May 24, 2017
8ad80ce
Merge remote-tracking branch 'origin/master' into bump-glimmer
rwjblue May 26, 2017
b584963
Bump glimmer-vm packages to 0.24.0-beta.4
rwjblue May 26, 2017
33391a8
Migrate default component manager hooks to abstract base class.
rwjblue May 28, 2017
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
2 changes: 1 addition & 1 deletion broccoli/packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ module.exports.emberPkgES = function _emberPkgES(name, rollup, externs) {
}

module.exports.glimmerPkgES = function _glimmerPkgES(name, externs = []) {
return new Rollup(findLib(name, 'dist/modules'), {
return new Rollup(findLib(name, 'dist/modules/es5'), {
rollup: {
entry: 'index.js',
dest: `${name}.js`,
Expand Down
4 changes: 2 additions & 2 deletions ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ module.exports = function(options) {
let emberTemplateCompiler = emberPkgES('ember-template-compiler');
let emberTemplateCompilerES5 = toES5(emberTemplateCompiler, { annotation: 'ember-template-compiler' });
let glimmerSyntax = toES5(
glimmerPkgES('@glimmer/syntax', ['handlebars', 'simple-html-tokenizer']),
glimmerPkgES('@glimmer/syntax', ['@glimmer/util', 'handlebars', 'simple-html-tokenizer']),
{ annotation: '@glimmer/syntax' }
);
let glimmerCompiler = toES5(
Expand Down Expand Up @@ -384,4 +384,4 @@ function testHarnessFiles() {
jquery(),
qunit()
];
}
}
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@
"link:glimmer": "node bin/yarn-link-glimmer.js"
},
"dependencies": {
"@glimmer/compiler": "^0.22.1",
"@glimmer/node": "^0.22.1",
"@glimmer/reference": "^0.22.1",
"@glimmer/runtime": "^0.22.1",
"@glimmer/util": "^0.22.1",
"@glimmer/compiler": "^0.24.0-beta.4",
"@glimmer/node": "^0.24.0-beta.4",
"@glimmer/reference": "^0.24.0-beta.4",
"@glimmer/runtime": "^0.24.0-beta.4",
"@glimmer/util": "^0.24.0-beta.4",
"broccoli-funnel": "^1.2.0",
"broccoli-merge-trees": "^2.0.0",
"ember-cli-get-component-path-option": "^1.0.0",
Expand Down
68 changes: 68 additions & 0 deletions packages/ember-glimmer/lib/component-managers/abstract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { DEBUG } from 'ember-env-flags';

// implements the ComponentManager interface as defined in glimmer:
// https://github.com/glimmerjs/glimmer-vm/blob/v0.24.0-beta.4/packages/%40glimmer/runtime/lib/component/interfaces.ts#L21

export default class AbstractManager {
constructor() {
this.debugStack = undefined;
}

prepareArgs(definition, args) {
return null;
}

// must be implemented by inheritors, inheritors should also
// call `this._pushToDebugStack` to ensure the rerendering
// assertion messages are properly maintained
create(env, definition, args, dynamicScope, caller, hasBlock) {
if (DEBUG) {
throw new Error('AbstractManager#create must be implemented.');
}
}

layoutFor(definition, bucket, env) {
if (DEBUG) {
throw new Error('AbstractManager#create must be implemented.');
}
}

getSelf(bucket) { return bucket; }

didCreateElement(bucket, element, operations) { }

// inheritors should also call `this.debugStack.pop()` to
// ensure the rerendering assertion messages are properly
// maintained
didRenderLayout(bucket, bounds) { }

didCreate(bucket) { }

getTag(bucket) { return null; }

// inheritors should also call `this._pushToDebugStack`
// to ensure the rerendering assertion messages are
// properly maintained
update(bucket, dynamicScope) { }

// inheritors should also call `this.debugStack.pop()` to
// ensure the rerendering assertion messages are properly
// maintained
didUpdateLayout(bucket, bounds) { }

didUpdate(bucket) { }

getDestructor(bucket) { }
}

if (DEBUG) {
AbstractManager.prototype._pushToDebugStack = function(name, environment) {
this.debugStack = environment.debugStack;
this.debugStack.push(name);
};

AbstractManager.prototype._pushEngineToDebugStack = function(name, environment) {
this.debugStack = environment.debugStack;
this.debugStack.pushEngine(name);
};
}
174 changes: 147 additions & 27 deletions packages/ember-glimmer/lib/component-managers/curly.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { OWNER } from 'ember-utils';
import { OWNER, assign } from 'ember-utils';
import { combineTagged } from '@glimmer/reference';
import {
PrimitiveReference
PrimitiveReference,
ComponentDefinition
} from '@glimmer/runtime';
import {
assert
Expand All @@ -22,23 +24,15 @@ import {
get,
_instrumentStart
} from 'ember-metal';
import {
gatherArgs,
ComponentArgs
} from '../utils/process-args';
import { processComponentArgs } from '../utils/process-args';
import {
dispatchLifeCycleHook,
setViewElement
} from 'ember-views';
import { privatize as P } from 'container';
import AbstractManager from '../syntax/abstract-manager';
import ComponentStateBucket from '../syntax/component-state-bucket';
import {
initialRenderInstrumentDetails,
rerenderInstrumentDetails,
validatePositionalParameters,
processComponentInitializationAssertions
} from '../syntax/curly-component';
import AbstractManager from './abstract';
import ComponentStateBucket from '../utils/curly-component-state-bucket';
import { PropertyReference } from '../utils/references';

const DEFAULT_LAYOUT = P`template:components/-default`;

Expand Down Expand Up @@ -94,7 +88,7 @@ class CurlyComponentLayoutCompiler {
}

compile(builder) {
builder.wrapLayout(this.template.asLayout());
builder.wrapLayout(this.template);
builder.tag.dynamic(tagName);
builder.attrs.dynamic('role', ariaRole);
builder.attrs.static('class', 'ember-view');
Expand All @@ -103,13 +97,69 @@ class CurlyComponentLayoutCompiler {

CurlyComponentLayoutCompiler.id = 'curly';

export class PositionalArgumentReference {
constructor(references) {
this.tag = combineTagged(references);
this._references = references;
}

value() {
return this._references.map(reference => reference.value());
}

get(key) {
return PropertyReference.create(this, key);
}
}

export default class CurlyComponentManager extends AbstractManager {
prepareArgs(definition, args) {
if (definition.ComponentClass) {
validatePositionalParameters(args.named, args.positional.values, definition.ComponentClass.class.positionalParams);
let componentPositionalParamsDefinition = definition.ComponentClass.class.positionalParams;

if (DEBUG && componentPositionalParamsDefinition) {
validatePositionalParameters(args.named, args.positional, componentPositionalParamsDefinition);
}

return gatherArgs(args, definition);
let componentHasRestStylePositionalParams = typeof componentPositionalParamsDefinition === 'string';
let componentHasPositionalParams = componentHasRestStylePositionalParams || componentPositionalParamsDefinition.length > 0;
let needsPositionalParamMunging = componentHasPositionalParams && args.positional.length !== 0;
let isClosureComponent = definition.args;

if (!needsPositionalParamMunging && !isClosureComponent) {
return null;
}

let capturedArgs = args.capture();
// grab raw positional references array
let positional = capturedArgs.positional.references;

// handle prep for closure component with positional params
let curriedNamed;
if (definition.args) {
let remainingDefinitionPositionals = definition.args.positional.slice(positional.length);
positional = positional.concat(remainingDefinitionPositionals);
curriedNamed = definition.args.named;
}

// handle positionalParams
let positionalParamsToNamed;
if (componentHasRestStylePositionalParams) {
positionalParamsToNamed = {
[componentPositionalParamsDefinition]: new PositionalArgumentReference(positional)
};
positional = [];
} else if (componentHasPositionalParams){
positionalParamsToNamed = {};
let length = Math.min(positional.length, componentPositionalParamsDefinition.length);
for (let i = 0; i < length; i++) {
let name = componentPositionalParamsDefinition[i];
positionalParamsToNamed[name] = positional[i];
}
}

let named = assign({}, curriedNamed, positionalParamsToNamed, capturedArgs.named.map);

return { positional, named };
}

create(environment, definition, args, dynamicScope, callerSelfRef, hasBlock) {
Expand All @@ -121,8 +171,8 @@ export default class CurlyComponentManager extends AbstractManager {

let factory = definition.ComponentClass;

let processedArgs = ComponentArgs.create(args);
let { props } = processedArgs.value();
let capturedArgs = args.named.capture();
let props = processComponentArgs(capturedArgs);

aliasIdToElementId(args, props);

Expand Down Expand Up @@ -154,7 +204,7 @@ export default class CurlyComponentManager extends AbstractManager {
}
}

let bucket = new ComponentStateBucket(environment, component, processedArgs, finalizer);
let bucket = new ComponentStateBucket(environment, component, capturedArgs, finalizer);

if (args.named.has('class')) {
bucket.classRef = args.named.get('class');
Expand Down Expand Up @@ -266,19 +316,16 @@ export default class CurlyComponentManager extends AbstractManager {
bucket.finalizer = _instrumentStart('render.component', rerenderInstrumentDetails, component);

if (!args.tag.validate(argsRevision)) {
let { attrs, props } = args.value();
let props = processComponentArgs(args);

bucket.argsRevision = args.tag.value();

let oldAttrs = component.attrs;
let newAttrs = attrs;

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

dispatchLifeCycleHook(component, 'didUpdateAttrs', oldAttrs, newAttrs);
dispatchLifeCycleHook(component, 'didReceiveAttrs', oldAttrs, newAttrs);
dispatchLifeCycleHook(component, 'didUpdateAttrs');
dispatchLifeCycleHook(component, 'didReceiveAttrs');
}

if (environment.isInteractive) {
Expand Down Expand Up @@ -306,3 +353,76 @@ export default class CurlyComponentManager extends AbstractManager {
return stateBucket;
}
}

export function validatePositionalParameters(named, positional, positionalParamsDefinition) {
if (DEBUG) {
if (!named || !positional || !positional.length) {
return;
}

let paramType = typeof positionalParamsDefinition;

if (paramType === 'string') {
assert(`You cannot specify positional parameters and the hash argument \`${positionalParamsDefinition}\`.`, !named.has(positionalParamsDefinition));
} else {
if (positional.length < positionalParamsDefinition.length) {
positionalParamsDefinition = positionalParamsDefinition.slice(0, positional.length);
}

for (let i = 0; i < positionalParamsDefinition.length; i++) {
let name = positionalParamsDefinition[i];

assert(
`You cannot specify both a positional param (at position ${i}) and the hash argument \`${name}\`.`,
!named.has(name)
);
}
}
}
}

export function processComponentInitializationAssertions(component, props) {
assert(`classNameBindings must not have spaces in them: ${component.toString()}`, (() => {
let { classNameBindings } = component;
for (let i = 0; i < classNameBindings.length; i++) {
let binding = classNameBindings[i];
if (binding.split(' ').length > 1) {
return false;
}
}
return true;
})());

assert('You cannot use `classNameBindings` on a tag-less component: ' + component.toString(), (() => {
let { classNameBindings, tagName } = component;
return tagName !== '' || !classNameBindings || classNameBindings.length === 0;
})());

assert('You cannot use `elementId` on a tag-less component: ' + component.toString(), (() => {
let { elementId, tagName } = component;
return tagName !== '' || props.id === elementId || (!elementId && elementId !== '');
})());

assert('You cannot use `attributeBindings` on a tag-less component: ' + component.toString(), (() => {
let { attributeBindings, tagName } = component;
return tagName !== '' || !attributeBindings || attributeBindings.length === 0;
})());
}

export function initialRenderInstrumentDetails(component) {
return component.instrumentDetails({ initialRender: true });
}

export function rerenderInstrumentDetails(component) {
return component.instrumentDetails({ initialRender: false });
}

const MANAGER = new CurlyComponentManager();

export class CurlyComponentDefinition extends ComponentDefinition {
constructor(name, ComponentClass, template, args, customManager) {
super(name, customManager || MANAGER, ComponentClass);
this.template = template;
this.args = args;
}
}
Loading