Repository: rwjblue/ember-template-lint (js)

Issue:
SyntaxError for nested block params
```hbs
    {{#x-select value=letter action=(action (mut letter)) as |xs|}}
        <option>Filter by the letter...</option>
        {{#each alphabet as |letter|}}
            {{#xs.option value=letter}}{{ letter }}{{/xs.option}}
        {{/each}}
    {{/x-select}}
```

leads to

```
undefined: `xs.option` is not a valid name for a helper on line 23. (cargo/templates/crates): 
`Error: `xs.option` is not a valid name for a helper on line 23.
    at SyntaxError.Error (native)
    at new SyntaxError (/Users/tbieniek/Code/crates.io/node_modules/@glimmer/syntax/dist/commonjs/es5/lib/errors/syntax-error.js:14:27)
    at assertIsSimplePath (/Users/tbieniek/Code/crates.io/node_modules/ember-template-lint/node_modules/@glimmer/compiler/dist/commonjs/es5/lib/template-compiler.js:476:15)
    at TemplateCompiler.prepareHelper (/Users/tbieniek/Code/crates.io/node_modules/ember-template-lint/node_modules/@glimmer/compiler/dist/commonjs/es5/lib/template-compiler.js:342:9)
    at TemplateCompiler.block (/Users/tbieniek/Code/crates.io/node_modules/ember-template-lint/node_modules/@glimmer/compiler/dist/commonjs/es5/lib/template-compiler.js:196:14)
    at /Users/tbieniek/Code/crates.io/node_modules/ember-template-lint/node_modules/@glimmer/compiler/dist/commonjs/es5/lib/template-compiler.js:71:25
    at Array.forEach (native)
    at TemplateCompiler.process (/Users/tbieniek/Code/crates.io/node_modules/ember-template-lint/node_modules/@glimmer/compiler/dist/commonjs/es5/lib/template-compiler.js:64:17)
    at Function.compile (/Users/tbieniek/Code/crates.io/node_modules/ember-template-lint/node_modules/@glimmer/compiler/dist/commonjs/es5/lib/template-compiler.js:57:32)
    at precompile (/Users/tbieniek/Code/crates.io/node_modules/ember-template-lint/node_modules/@glimmer/compiler/dist/commonjs/es5/lib/compiler.js:45:60)
    at Linter.verify (/Users/tbieniek/Code/crates.io/node_modules/ember-template-lint/lib/index.js:110:7)
    at TemplateLinter.processString (/Users/tbieniek/Code/crates.io/node_modules/ember-cli-template-lint/broccoli-template-linter.js:101:28)
    at Promise.then.result.output (/Users/tbieniek/Code/crates.io/node_modules/broccoli-persistent-filter/lib/strategies/persistent.js:41:23)
    at initializePromise (/Users/tbieniek/Code/crates.io/node_modules/rsvp/dist/rsvp.js:589:5)
    at new Promise$1 (/Users/tbieniek/Code/crates.io/node_modules/rsvp/dist/rsvp.js:1077:33)
    at /Users/tbieniek/Code/crates.io/node_modules/broccoli-persistent-filter/lib/strategies/persistent.js:40:18`@ 1 ms
```

am I doing something wrong?

```
$ yarn list ember-cli-template-lint
yarn list v0.25.1
└─ ember-cli-template-lint@0.7.0
```

Pull request:
Fixes the syntax error with contextual component
Fixes #230 

Patch:
diff --git a/lib/index.js b/lib/index.js
index d03ba7c..6621dfd 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -5,6 +5,8 @@ const Minimatch = require('minimatch').Minimatch;
 const getConfig = require('./get-config');
 const stripBom = require('strip-bom');
 
+const TransformDotComponentInvocation = require('./plugins/transform-dot-component-invocation');
+
 const WARNING_SEVERITY = 1;
 const ERROR_SEVERITY = 2;
 
@@ -45,8 +47,8 @@ class Linter {
     }
 
     let rules = this.config.loadedRules;
+    let astPlugins = [TransformDotComponentInvocation];
 
-    let astPlugins = [];
     for (let pluginName in rules) {
 
       let Plugin = rules[pluginName];
diff --git a/lib/plugins/transform-dot-component-invocation.js b/lib/plugins/transform-dot-component-invocation.js
new file mode 100644
index 0000000..cd64476
--- /dev/null
+++ b/lib/plugins/transform-dot-component-invocation.js
@@ -0,0 +1,64 @@
+/**
+  In Ember application before compiling the template, ember preprocess it in order to avoid some syntax errors in glimmer-engine. Refer, https://github.com/emberjs/ember.js/blob/v2.13.3/packages/ember-template-compiler/lib/plugins/transform-dot-component-invocation.js.
+  We need to do the same here to avoid like this error, https://github.com/rwjblue/ember-template-lint/issues/230.
+
+  Transforms dot invocation of closure components to be wrapped
+  with the component helper. This allows for a more static invocation
+  of the component.
+
+  ```handlebars
+    {{#my-component as |comps|}}
+      {{comp.dropdown isOpen=false}}
+    {{/my-component}}
+  ```
+  with
+  ```handlebars
+    {{#my-component as |comps|}}
+      {{component comp.dropdown isOpen=false}}
+    {{/my-component}}
+  ```
+*/
+
+'use strict';
+
+module.exports = function transformDotComponentInvocation(env) {
+  let builders = env.syntax.builders;
+
+  return {
+    name: 'transform-dot-component-invocation',
+
+    visitors: {
+      MustacheStatement: (node) => {
+        if (isInlineInvocation(node.path, node.params, node.hash)) {
+          wrapInComponent(node, builders);
+        }
+      },
+      BlockStatement: (node) => {
+        if (isMultipartPath(node.path)) {
+          wrapInComponent(node, builders);
+        }
+      }
+    }
+  };
+};
+
+function isMultipartPath(path)  {
+  return path.parts.length > 1;
+}
+
+function isInlineInvocation(path, params, hash) {
+  if (isMultipartPath(path)) {
+    if (params.length > 0 || hash.pairs.length > 0) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+function wrapInComponent(node, builder) {
+  let component = node.path;
+  let componentHelper = builder.path('component');
+  node.path = componentHelper;
+  node.params.unshift(component);
+}
\ No newline at end of file


Test patch:
diff --git a/test/unit/recommended-config-test.js b/test/unit/recommended-config-test.js
index c3219c2..74f39b9 100644
--- a/test/unit/recommended-config-test.js
+++ b/test/unit/recommended-config-test.js
@@ -34,4 +34,7 @@ describe('recommended config', function() {
 
 
   ensureValid('<md-autocomplete-wrap id={{autocompleteWrapperId}} role="listbox" layout="row" class="{{if notFloating "md-whiteframe-z1"}} {{if notHidden "md-menu-showing"}}"></md-autocomplete-wrap>');
+
+  // This ensures that we don't face this issue again => https://github.com/rwjblue/ember-template-lint/issues/230
+  ensureValid('{{#foo-bar as |baz|}}{{#baz.derp}}{{/baz.derp}}{{/foo-bar}}');
 });