<p dir="auto">So I'm currently adding in logic to handle the removal of arbitrary nodes that would result in invalid code.</p>
<p dir="auto">There are currently two ways to tackle this:</p>
<ol dir="auto">
<li>Detect it and throw compiler errors</li>
<li>Detect it and fix it up on a case-by-case basis.</li>
</ol>
<h2 dir="auto"></h2>
<p dir="auto">For example, when removing the <code class="notranslate">foo</code> <code class="notranslate">callee</code> of a <code class="notranslate">CallExpression</code> the following <em>could</em> be done:</p>
<h3 dir="auto">Change the callee to undefined</h3>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="bar(foo(&quot;bar&quot;));"><pre class="notranslate"><span class="pl-en">bar</span><span class="pl-kos">(</span><span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-s">"bar"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">=&gt;</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="bar(undefined(&quot;bar&quot;));"><pre class="notranslate"><span class="pl-en">bar</span><span class="pl-kos">(</span><span class="pl-c1">undefined</span><span class="pl-kos">(</span><span class="pl-s">"bar"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<h3 dir="auto">Noop the function</h3>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="bar(foo(&quot;bar&quot;));"><pre class="notranslate"><span class="pl-en">bar</span><span class="pl-kos">(</span><span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-s">"bar"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">=&gt;</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="bar(undefined);"><pre class="notranslate"><span class="pl-en">bar</span><span class="pl-kos">(</span><span class="pl-c1">undefined</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">(Arguments are turned into a <code class="notranslate">SequenceExpression</code>, "pure" values are removed from it, and we ensure it evaluates to <code class="notranslate">undefined</code> by pushing it onto the sequence expression)</p>
<h3 dir="auto">Throw an error</h3>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="bar(foo(&quot;bar&quot;));"><pre class="notranslate"><span class="pl-en">bar</span><span class="pl-kos">(</span><span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-s">"bar"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">=&gt;</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="CompilerError: Invalid removal of `CallExpression` `callee`."><pre class="notranslate"><span class="pl-v">CompilerError</span>: <span class="pl-v">Invalid</span> <span class="pl-s1">removal</span> <span class="pl-k">of</span> <span class="pl-s">`CallExpression`</span> <span class="pl-s">`callee`</span><span class="pl-kos">.</span></pre></div>
<hr>
<p dir="auto">Unsure how to handle these, ideally I'd like idiomatic transforms. Having to worry about the context whenever you want to remove a node is gross, it leads to duplicating every single contextual validation permutation which is pretty nasty. Leaning more towards the noop case since at least that doesn't result in broken code.</p>
<h2 dir="auto">Bug Report</h2>
<p dir="auto">Following code works correctly with Typescript compiler but fails with Babel.</p>
<p dir="auto"><strong>Current behavior</strong><br>
A clear and concise description of the behavior.</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 undoable(target: any, propertyKey: string) {
  Object.defineProperty(target, propertyKey, {
    get: function () {
      return 'customFoo';
    },
  });
}

class PropModel {
  @undoable foo?: string;
}

const g = new PropModel();
console.log(g.foo); // her is 'undefined' with Babel, but 'customFoo' with Typescript"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">undoable</span><span class="pl-kos">(</span><span class="pl-s1">target</span>: <span class="pl-s1">any</span><span class="pl-kos">,</span> <span class="pl-s1">propertyKey</span>: <span class="pl-s1">string</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">defineProperty</span><span class="pl-kos">(</span><span class="pl-s1">target</span><span class="pl-kos">,</span> <span class="pl-s1">propertyKey</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
    <span class="pl-en">get</span>: <span class="pl-k">function</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-s">'customFoo'</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-k">class</span> <span class="pl-v">PropModel</span> <span class="pl-kos">{</span>
  @<span class="pl-s1">undoable</span> <span class="pl-c1">foo</span>?: <span class="pl-c1">string</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">const</span> <span class="pl-s1">g</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">PropModel</span><span class="pl-kos">(</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">g</span><span class="pl-kos">.</span><span class="pl-c1">foo</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// her is 'undefined' with Babel, but 'customFoo' with Typescript</span></pre></div>
<p dir="auto"><strong>Expected behavior</strong><br>
A clear and concise description of what you expected to happen (or code).</p>
<p dir="auto">I am able to override class protptype in the decorator.</p>
<p dir="auto"><strong>Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command, .eslintrc)</strong></p>
<ul dir="auto">
<li>Filename: <code class="notranslate">babel.config.js</code></li>
</ul>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;presets&quot;: [&quot;next/babel&quot;],
  &quot;plugins&quot;: [
    &quot;jsx-control-statements&quot;,
    [&quot;@babel/plugin-proposal-decorators&quot;, { &quot;legacy&quot;: true }],
    [&quot;@babel/plugin-proposal-class-properties&quot;, { &quot;loose&quot;: true }]
  ],
  &quot;env&quot;: {
    &quot;test&quot;: {
      &quot;plugins&quot;: [&quot;babel-plugin-istanbul&quot;]
    }
  }
}"><pre class="notranslate"><span class="pl-kos">{</span>
  <span class="pl-s">"presets"</span>: <span class="pl-kos">[</span><span class="pl-s">"next/babel"</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-s">"plugins"</span>: <span class="pl-kos">[</span>
    <span class="pl-s">"jsx-control-statements"</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">"legacy"</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-s">"@babel/plugin-proposal-class-properties"</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-s">"loose"</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-s">"env"</span>: <span class="pl-kos">{</span>
    <span class="pl-s">"test"</span>: <span class="pl-kos">{</span>
      <span class="pl-s">"plugins"</span>: <span class="pl-kos">[</span><span class="pl-s">"babel-plugin-istanbul"</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>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  System:
    OS: Windows 10 10.0.18363
  Binaries:
    Node: 12.16.2 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.4 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 6.14.4 - C:\Program Files\nodejs\npm.CMD"><pre class="notranslate"><code class="notranslate">  System:
    OS: Windows 10 10.0.18363
  Binaries:
    Node: 12.16.2 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.4 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 6.14.4 - C:\Program Files\nodejs\npm.CMD
</code></pre></div>
<ul dir="auto">
<li>Monorepo: No</li>
<li>How you are using Babel: Webpack</li>
</ul>
<p dir="auto"><strong>Possible Solution</strong></p>

<p dir="auto"><strong>Additional context</strong><br>
Add any other context about the problem here. Or a screenshot if applicable</p>