Skip to content

Commit

Permalink
Merge pull request #1255 from dfreeman/leave-blocks-alone
Browse files Browse the repository at this point in the history
Don't call `customizeComponentName` on curly components
  • Loading branch information
rwjblue authored Jan 30, 2021
2 parents 8224439 + 5c0cf6c commit 40171c1
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,52 @@ module('[glimmer-compiler] precompile', ({ test }) => {
assert.equal(componentName, 'rental', 'customized component name was used');
});

test('customizeComponentName is not invoked on curly components', function (assert) {
let wire = JSON.parse(
precompile('{{#my-component}}hello{{/my-component}}', {
customizeComponentName(input: string) {
return input.toUpperCase();
},
})
);

let block: WireFormat.SerializedTemplateBlock = JSON.parse(wire.block);

let [[, componentNameExpr]] = block[0] as [WireFormat.Statements.Block];

glimmerAssert(
Array.isArray(componentNameExpr) &&
componentNameExpr[0] === SexpOpcodes.GetFreeAsComponentHead,
`component name is a free variable lookup`
);

let componentName = block[3][componentNameExpr[1]];
assert.equal(componentName, 'my-component', 'original component name was used');
});

test('customizeComponentName is not invoked on angle-bracket-like name invoked with curlies', function (assert) {
let wire = JSON.parse(
precompile('{{#MyComponent}}hello{{/MyComponent}}', {
customizeComponentName(input: string) {
return input.toUpperCase();
},
})
);

let block: WireFormat.SerializedTemplateBlock = JSON.parse(wire.block);

let [[, componentNameExpr]] = block[0] as [WireFormat.Statements.Block];

glimmerAssert(
Array.isArray(componentNameExpr) &&
componentNameExpr[0] === SexpOpcodes.GetFreeAsComponentHead,
`component name is a free variable lookup`
);

let componentName = block[3][componentNameExpr[1]];
assert.equal(componentName, 'MyComponent', 'original component name was used');
});

test('lowercased names are not resolved or customized in resolution mode', (assert) => {
let wire = JSON.parse(
precompile('<rental />', {
Expand Down
9 changes: 8 additions & 1 deletion packages/@glimmer/syntax/lib/symbol-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Core, Dict, SexpOpcodes } from '@glimmer/interfaces';
import { dict } from '@glimmer/util';

import { ASTv2 } from '..';
import { isUpperCase } from './utils';

export abstract class SymbolTable {
static top(
Expand Down Expand Up @@ -86,7 +87,13 @@ export class ProgramSymbolTable extends SymbolTable {
}

allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number {
if (resolution.resolution() === SexpOpcodes.GetFreeAsComponentHead) {
// If the name in question is an uppercase (i.e. angle-bracket) component invocation, run
// the optional `customizeComponentName` function provided to the precompiler.
if (
resolution.resolution() === SexpOpcodes.GetFreeAsComponentHead &&
resolution.isAngleBracket &&
isUpperCase(name)
) {
name = this.customizeComponentName(name);
}

Expand Down
8 changes: 8 additions & 0 deletions packages/@glimmer/syntax/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,11 @@ export function printLiteral(literal: ASTv1.Literal): string {
return JSON.stringify(literal.value);
}
}

export function isUpperCase(tag: string): boolean {
return tag[0] === tag[0].toUpperCase() && tag[0] !== tag[0].toLowerCase();
}

export function isLowerCase(tag: string): boolean {
return tag[0] === tag[0].toLowerCase() && tag[0] !== tag[0].toUpperCase();
}
2 changes: 1 addition & 1 deletion packages/@glimmer/syntax/lib/v2-a/loose-resolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function BlockSyntaxContext(node: ASTv1.BlockStatement): ASTv2.FreeVarRes

export function ComponentSyntaxContext(node: ASTv1.PathExpression): ASTv2.FreeVarResolution | null {
if (isSimplePath(node)) {
return ASTv2.LooseModeResolution.namespaced(ASTv2.FreeVarNamespace.Component);
return ASTv2.LooseModeResolution.namespaced(ASTv2.FreeVarNamespace.Component, true);
} else {
return null;
}
Expand Down
9 changes: 1 addition & 8 deletions packages/@glimmer/syntax/lib/v2-a/normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { SourceSpan } from '../source/span';
import { SpanList } from '../source/span-list';
import { BlockSymbolTable, ProgramSymbolTable, SymbolTable } from '../symbol-table';
import { generateSyntaxError } from '../syntax-error';
import { isLowerCase, isUpperCase } from '../utils';
import * as ASTv1 from '../v1/api';
import b from '../v1/parser-builders';
import * as ASTv2 from './api';
Expand Down Expand Up @@ -866,14 +867,6 @@ class ElementChildren extends Children {
}
}

function isUpperCase(tag: string): boolean {
return tag[0] === tag[0].toUpperCase() && tag[0] !== tag[0].toLowerCase();
}

function isLowerCase(tag: string): boolean {
return tag[0] === tag[0].toLowerCase() && tag[0] !== tag[0].toUpperCase();
}

function printPath(node: ASTv1.PathExpression | ASTv1.CallNode): string {
if (node.type !== 'PathExpression' && node.path.type === 'PathExpression') {
return printPath(node.path);
Expand Down
17 changes: 11 additions & 6 deletions packages/@glimmer/syntax/lib/v2-a/objects/resolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export class StrictResolution {
serialize(): SerializedResolution {
return 'Strict';
}

readonly isAngleBracket = false;
}

export const STRICT_RESOLUTION = new StrictResolution();
Expand All @@ -46,11 +48,14 @@ export class LooseModeResolution {
*
* @see {NamespacedAmbiguity}
*/
static namespaced(namespace: FreeVarNamespace): LooseModeResolution {
return new LooseModeResolution({
namespaces: [namespace],
fallback: false,
});
static namespaced(namespace: FreeVarNamespace, isAngleBracket = false): LooseModeResolution {
return new LooseModeResolution(
{
namespaces: [namespace],
fallback: false,
},
isAngleBracket
);
}

/**
Expand Down Expand Up @@ -136,7 +141,7 @@ export class LooseModeResolution {
return new LooseModeResolution({ namespaces: [FreeVarNamespace.Helper], fallback: true });
}

constructor(readonly ambiguity: Ambiguity) {}
constructor(readonly ambiguity: Ambiguity, readonly isAngleBracket = false) {}

resolution(): GetContextualFreeOp {
if (this.ambiguity.namespaces.length === 0) {
Expand Down

0 comments on commit 40171c1

Please sign in to comment.