std::shared_ptr<SerializedScope> ESTreeIRGen::serializeScope(
    FunctionContext *ctx,
    bool includeGlobal) {
  // Serialize the global scope if and only if it's the only scope.
  // We serialize the global scope to avoid re-declaring variables,
  // and only do it once to avoid creating spurious scopes.
  if (!ctx || (ctx->function->isGlobalScope() && !includeGlobal))
    return lexicalScopeChain;

  auto scope = std::make_shared<SerializedScope>();
  auto *func = ctx->function;
  assert(func && "Missing function when saving scope");

  scope->originalName = func->getOriginalOrInferredName();
  if (auto *closure = func->getLazyClosureAlias()) {
    scope->closureAlias = closure->getName();
  }
  for (auto *var : func->getFunctionScope()->getVariables()) {
    scope->variables.push_back(var->getName());
  }
  scope->parentScope = serializeScope(ctx->getPreviousContext(), false);
  return scope;
}
std::shared_ptr<SerializedScope> ESTreeIRGen::serializeScope(
    FunctionContext *ctx,
    bool includeGlobal) {
   
   
   
  if (!ctx || (ctx->function->isGlobalScope() && !includeGlobal))
    return lexicalScopeChain;

  auto scope = std::make_shared<SerializedScope>();
  auto *func = ctx->function;
  assert(func && "Missing function when saving scope");

  scope->originalName = func->getOriginalOrInferredName();
  if (auto *closure = func->getLazyClosureAlias()) {
    scope->closureAlias = closure->getName();
  }
  for (auto *var : func->getFunctionScope()->getVariables()) {
    scope->variables.push_back(var->getName());
  }
  scope->parentScope = serializeScope(ctx->getPreviousContext(), false);
  return scope;
}