<h2 dir="auto">Bug Report</h2>
<p dir="auto"><strong>Current Behavior</strong><br>
Babel parser gets confused when using decorators.</p>
<p dir="auto"><strong>Additional context/Screenshots</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    Module parse failed: Can not use keyword 'await' outside an async function (86:8)
    You may need an appropriate loader to handle this file type.
    |       key: &quot;t&quot;,
    |       value: function value() {
    &gt;         await this.s();
    |       }
    |     }, {
     @ ./src/index.js 7:13-40"><pre class="notranslate">    <span class="pl-v">Module</span> <span class="pl-s1">parse</span> <span class="pl-s1">failed</span>: <span class="pl-v">Can</span> <span class="pl-s1">not</span> <span class="pl-s1">use</span> <span class="pl-s1">keyword</span> '<span class="pl-k">await</span>' outside an async function (86:8)
    You may need an appropriate loader to handle this file type.
    |       key: "t",
    |       value: function value() {
    &gt;         await this.s();
    |       }
    |     }, {
     @ ./src/index.js 7:13-40</pre></div>
<p dir="auto">As you can see <code class="notranslate">await this.s()</code> is within an <code class="notranslate">async</code> so there should be no problem.<br>
Remove the decorator then the problem is gone immediately.</p>
<p dir="auto"><strong>Input Code</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="
function decorator(Class) {
     return function (...args) {
          return new Class(...args);
     }
}

@decorator
class Test {
     constructor(props) {
     }

     async t() {
          await this.s()
     }

     async s() {
     }
}

new Test();"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">decorator</span><span class="pl-kos">(</span><span class="pl-v">Class</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
     <span class="pl-k">return</span> <span class="pl-k">function</span> <span class="pl-kos">(</span>...<span class="pl-s1">args</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
          <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-v">Class</span><span class="pl-kos">(</span>...<span class="pl-s1">args</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
     <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

@<span class="pl-s1">decorator</span>
<span class="pl-k">class</span> <span class="pl-v">Test</span> <span class="pl-kos">{</span>
     <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-s1">props</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
     <span class="pl-kos">}</span>

     <span class="pl-k">async</span> <span class="pl-en">t</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
          <span class="pl-k">await</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">s</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
     <span class="pl-kos">}</span>

     <span class="pl-k">async</span> <span class="pl-en">s</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
     <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">new</span> <span class="pl-v">Test</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Expected behavior/code</strong><br>
This is supposed to compile just fine.</p>
<p dir="auto"><strong>Babel Configuration (.babelrc, package.json, cli command)</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="module.exports = function (api) {
     //console.log('----------------------------test-------------------------');
     api.cache(true);

     const presets = [
          ['@babel/preset-env'],
     ];

     const plugins = [
          ['@babel/plugin-transform-runtime'],
          ['@babel/plugin-proposal-decorators', {decoratorsBeforeExport: false}],
          ['@babel/plugin-proposal-class-properties'],
     ];

     return {
          presets: presets,
          plugins: plugins,
     };

};"><pre class="notranslate"><span class="pl-smi">module</span><span class="pl-kos">.</span><span class="pl-en">exports</span> <span class="pl-c1">=</span> <span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">api</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
     <span class="pl-c">//console.log('----------------------------test-------------------------');</span>
     <span class="pl-s1">api</span><span class="pl-kos">.</span><span class="pl-en">cache</span><span class="pl-kos">(</span><span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

     <span class="pl-k">const</span> <span class="pl-s1">presets</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span>
          <span class="pl-kos">[</span><span class="pl-s">'@babel/preset-env'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
     <span class="pl-kos">]</span><span class="pl-kos">;</span>

     <span class="pl-k">const</span> <span class="pl-s1">plugins</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span>
          <span class="pl-kos">[</span><span class="pl-s">'@babel/plugin-transform-runtime'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
          <span class="pl-kos">[</span><span class="pl-s">'@babel/plugin-proposal-decorators'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">decoratorsBeforeExport</span>: <span class="pl-c1">false</span><span class="pl-kos">}</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
          <span class="pl-kos">[</span><span class="pl-s">'@babel/plugin-proposal-class-properties'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
     <span class="pl-kos">]</span><span class="pl-kos">;</span>

     <span class="pl-k">return</span> <span class="pl-kos">{</span>
          <span class="pl-c1">presets</span>: <span class="pl-s1">presets</span><span class="pl-kos">,</span>
          <span class="pl-c1">plugins</span>: <span class="pl-s1">plugins</span><span class="pl-kos">,</span>
     <span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Environment</strong></p>
<ul dir="auto">
<li>Babel version(s): 7.1.0</li>
<li>Node/npm version: [Node 8.12 / NPM 6.4.1]</li>
<li>OS: [Ubuntu 16.04 LTS]</li>
<li>How you are using Babel: ['cli', 'webpack']</li>
</ul>
<h2 dir="auto">Bug Report</h2>
<p dir="auto">Hello, first let me thank the Babel contributors for your hard work. Unfortunately, I had an issue using the <code class="notranslate">@babel/plugin-proposal-decorators</code> plugin.</p>
<p dir="auto"><strong>Current Behavior</strong><br>
The async keyword will be stripped of a class' method if the class has a decorator. The erroneous behavior is not reproduced while the plugin is active if the class is not decorated.</p>
<p dir="auto"><strong>Input Code</strong><br>
Here is <a href="https://github.com/VoidOutput/decorator-bug">a repo</a> with a minimal reproducible example.</p>
<p dir="auto">Summary of the issue follows</p>
<p dir="auto">Given the following code</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function Decorator ({ property } = {}) {
  return function ClassDecorator (classDescriptor) {
    console.log(property)
    return classDescriptor
  }
}

@Decorator({
  property: true
})
class GenericClass {
  async method () {
    await Promise.resolve()

    return true
  }
}"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-v">Decorator</span> <span class="pl-kos">(</span><span class="pl-kos">{</span> property <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-k">function</span> <span class="pl-v">ClassDecorator</span> <span class="pl-kos">(</span><span class="pl-s1">classDescriptor</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">property</span><span class="pl-kos">)</span>
    <span class="pl-k">return</span> <span class="pl-s1">classDescriptor</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

@<span class="pl-v">Decorator</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">property</span>: <span class="pl-c1">true</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-k">class</span> <span class="pl-v">GenericClass</span> <span class="pl-kos">{</span>
  <span class="pl-k">async</span> <span class="pl-en">method</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">await</span> <span class="pl-v">Promise</span><span class="pl-kos">.</span><span class="pl-en">resolve</span><span class="pl-kos">(</span><span class="pl-kos">)</span>

    <span class="pl-k">return</span> <span class="pl-c1">true</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">This code will then become (when stripped of babel internal functions):</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function Decorator({
  property
} = {}) {
  return function ClassDecorator(classDescriptor) {
    console.log(property);
    return classDescriptor;
  };
}

let GenericClass = _decorate([Decorator({
  property: true
})], function (_initialize) {
  class GenericClass {
    constructor() {
      _initialize(this);
    }

  }

  return {
    F: GenericClass,
    d: [{
      kind: &quot;method&quot;,
      key: &quot;method&quot;,

      value() {
        await Promise.resolve();
        return true;
      }

    }]
  };
});"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-v">Decorator</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  property
<span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-k">function</span> <span class="pl-v">ClassDecorator</span><span class="pl-kos">(</span><span class="pl-s1">classDescriptor</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">property</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">return</span> <span class="pl-s1">classDescriptor</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">let</span> <span class="pl-v">GenericClass</span> <span class="pl-c1">=</span> <span class="pl-en">_decorate</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-v">Decorator</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">property</span>: <span class="pl-c1">true</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">_initialize</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">class</span> <span class="pl-v">GenericClass</span> <span class="pl-kos">{</span>
    <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
      <span class="pl-s1">_initialize</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>

  <span class="pl-kos">}</span>

  <span class="pl-k">return</span> <span class="pl-kos">{</span>
    <span class="pl-c1">F</span>: <span class="pl-v">GenericClass</span><span class="pl-kos">,</span>
    <span class="pl-c1">d</span>: <span class="pl-kos">[</span><span class="pl-kos">{</span>
      <span class="pl-c1">kind</span>: <span class="pl-s">"method"</span><span class="pl-kos">,</span>
      <span class="pl-c1">key</span>: <span class="pl-s">"method"</span><span class="pl-kos">,</span>

      <span class="pl-en">value</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">await</span> <span class="pl-v">Promise</span><span class="pl-kos">.</span><span class="pl-en">resolve</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-k">return</span> <span class="pl-c1">true</span><span class="pl-kos">;</span>
      <span class="pl-kos">}</span>

    <span class="pl-kos">}</span><span class="pl-kos">]</span>
  <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Note the lack of an async keyword on the <code class="notranslate">value</code> function. This causes browser or linters to correctly point out the syntax error.</p>
<p dir="auto"><strong>Expected behavior/code</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="  // ...

  return {
    F: GenericClass,
    d: [{
      kind: &quot;method&quot;,
      key: &quot;method&quot;,

      async value() {
        await Promise.resolve();
        return true;
      }

    }]
  };

  // ..."><pre class="notranslate">  <span class="pl-c">// ...</span>

  <span class="pl-k">return</span> <span class="pl-kos">{</span>
    <span class="pl-c1">F</span>: <span class="pl-v">GenericClass</span><span class="pl-kos">,</span>
    <span class="pl-c1">d</span>: <span class="pl-kos">[</span><span class="pl-kos">{</span>
      <span class="pl-c1">kind</span>: <span class="pl-s">"method"</span><span class="pl-kos">,</span>
      <span class="pl-c1">key</span>: <span class="pl-s">"method"</span><span class="pl-kos">,</span>

      <span class="pl-k">async</span> <span class="pl-en">value</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">await</span> <span class="pl-v">Promise</span><span class="pl-kos">.</span><span class="pl-en">resolve</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-k">return</span> <span class="pl-c1">true</span><span class="pl-kos">;</span>
      <span class="pl-kos">}</span>

    <span class="pl-kos">}</span><span class="pl-kos">]</span>
  <span class="pl-kos">}</span><span class="pl-kos">;</span>

  <span class="pl-c">// ...</span></pre></div>
<p dir="auto">or maybe</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="  // ...

  return {
    F: GenericClass,
    d: [{
      kind: &quot;method&quot;,
      key: &quot;method&quot;,

      value() {
        return (async () =&gt; {
          await Promise.resolve();
          return true;
        })();
      }

    }]
  };

  // ..."><pre class="notranslate">  <span class="pl-c">// ...</span>

  <span class="pl-k">return</span> <span class="pl-kos">{</span>
    <span class="pl-c1">F</span>: <span class="pl-v">GenericClass</span><span class="pl-kos">,</span>
    <span class="pl-c1">d</span>: <span class="pl-kos">[</span><span class="pl-kos">{</span>
      <span class="pl-c1">kind</span>: <span class="pl-s">"method"</span><span class="pl-kos">,</span>
      <span class="pl-c1">key</span>: <span class="pl-s">"method"</span><span class="pl-kos">,</span>

      <span class="pl-en">value</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">return</span> <span class="pl-kos">(</span><span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
          <span class="pl-k">await</span> <span class="pl-v">Promise</span><span class="pl-kos">.</span><span class="pl-en">resolve</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
          <span class="pl-k">return</span> <span class="pl-c1">true</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
      <span class="pl-kos">}</span>

    <span class="pl-kos">}</span><span class="pl-kos">]</span>
  <span class="pl-kos">}</span><span class="pl-kos">;</span>

  <span class="pl-c">// ...</span></pre></div>
<p dir="auto"><strong>Babel Configuration (.babelrc, package.json, cli command)</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;plugins&quot;: [
    [ &quot;@babel/plugin-proposal-decorators&quot;, { &quot;decoratorsBeforeExport&quot;: true } ]
  ]
}"><pre class="notranslate"><span class="pl-kos">{</span>
  <span class="pl-s">"plugins"</span>: <span class="pl-kos">[</span>
    <span class="pl-kos">[</span> <span class="pl-s">"@babel/plugin-proposal-decorators"</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-s">"decoratorsBeforeExport"</span>: <span class="pl-c1">true</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span>
  <span class="pl-kos">]</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>Environment</strong></p>
<ul dir="auto">
<li>Babel version: v7.1.0</li>
<li>Node/npm version: Node 10/NPM 6</li>
<li>OS: Windows 10</li>
<li>Monorepo: yes</li>
<li>How you are using Babel: <code class="notranslate">cli</code>, <code class="notranslate">loader</code></li>
</ul>
<p dir="auto">Note: This issue was first discovered using the loader along with Webpack but was reproduced later with the CLI.</p>
<p dir="auto"><strong>Additional context</strong></p>
<p dir="auto">I have tried to search for similar issues on Google and this repo's issue tracker but could not find someone with the same experience. My apologies if this is already known and/or was already posted.</p>
<p dir="auto">Please do not hesitate to ask if you need more details.</p>
<p dir="auto">Thanks in advance for your time. Have a nice day.</p>