diff --git a/packages/@glimmer/compiler/lib/template-compiler.ts b/packages/@glimmer/compiler/lib/template-compiler.ts index 5c86a787f4..77c908f8b7 100644 --- a/packages/@glimmer/compiler/lib/template-compiler.ts +++ b/packages/@glimmer/compiler/lib/template-compiler.ts @@ -134,11 +134,11 @@ export default class TemplateCompiler implements Processor { typeAttr = attrs[i]; continue; } - this.attribute([attrs[i]], !simple || actionIsComponent); + this.attribute([attrs[i]], !simple || actionIsComponent, action); } if (typeAttr) { - this.attribute([typeAttr], !simple || actionIsComponent); + this.attribute([typeAttr], !simple || actionIsComponent, action); } for (let i = 0; i < action.modifiers.length; i++) { @@ -161,7 +161,8 @@ export default class TemplateCompiler implements Processor { } } - attribute([action]: [AST.AttrNode], isComponent: boolean) { + attribute([action]: [AST.AttrNode], isComponent: boolean, elementNode: AST.ElementNode) { + assertValidArgumentName(action, isComponent, elementNode); let { name, value } = action; let namespace = getAttrNamespace(name); @@ -690,6 +691,19 @@ function assertIsSimplePath(path: AST.Expression, loc: AST.SourceLocation, conte } } +function assertValidArgumentName( + attribute: AST.AttrNode, + isComponent: boolean, + elementNode: AST.ElementNode +) { + if (!isComponent && attribute.name[0] === '@') { + throw new SyntaxError( + `${attribute.name} is not a valid attribute name. @arguments are only allowed on components, but the tag for this element (\`${elementNode.tag}\`) is a regular, non-component HTML element.`, + attribute.loc + ); + } +} + function assertValidYield(statement: AST.MustacheStatement): string { let { pairs } = statement.hash; diff --git a/packages/@glimmer/compiler/test/compiler-test.ts b/packages/@glimmer/compiler/test/compiler-test.ts index bfd11a534b..d7fadc6e04 100644 --- a/packages/@glimmer/compiler/test/compiler-test.ts +++ b/packages/@glimmer/compiler/test/compiler-test.ts @@ -55,6 +55,19 @@ function test(desc: string, template: string, ...expectedStatements: BuilderStat const Append = Builder.Append; const Concat = Builder.Concat; +QUnit.test( + '@arguments are on regular non-component/regular HTML nodes throws syntax error', + function(assert) { + const template = strip` + Link + `; + assert.throws( + () => compile(template), + /@onClick is not a valid attribute name. @arguments are only allowed on components, but the tag for this element \(`a`\) is a regular, non-component HTML element/ + ); + } +); + test('HTML text content', 'content', s`content`); test('Text curlies', '
{{title}}{{title}}
', [