<commit_before>import { Statement as StatementSyntax } from './syntax';

import { DOMHelper } from './dom';
import { Reference, OpaqueIterable } from 'glimmer-reference';
import { NULL_REFERENCE, ConditionalReference } from './references';

import {
  Component,
  ComponentManager,
  ComponentDefinition
} from './component/interfaces';

import {
  ModifierManager
} from './modifier/interfaces';

import {
  PathReference
} from 'glimmer-reference';

import {
  HasGuid,
  InternedString,
  intern,
  ensureGuid
} from 'glimmer-util';

import { EvaluatedArgs } from './compiled/expressions/args';

import { InlineBlock } from './compiled/blocks';

import { Destroyable, Dict, Opaque } from 'glimmer-util';

import * as Syntax from './syntax/core';

import IfSyntax from './syntax/builtins/if';
import UnlessSyntax from './syntax/builtins/unless';
import WithSyntax from './syntax/builtins/with';
import EachSyntax from './syntax/builtins/each';

type ScopeSlot = PathReference<Opaque> | InlineBlock;

export interface DynamicScope {
  child(): DynamicScope;
}

export class Scope {
  static root(self: PathReference<Opaque>, size = 0) {
    let refs: PathReference<Opaque>[] = new Array(size + 1);

    for (let i = 0; i <= size; i++) {
      refs[i] = NULL_REFERENCE;
    }

    return new Scope(refs).init({ self });
  }

  // the 0th slot is `self`
  private slots: ScopeSlot[];
  private callerScope: Scope = null;

  constructor(references: ScopeSlot[]) {
    this.slots = references;
  }

  init({ self }: { self: PathReference<Opaque> }): this {
    this.slots[0] = self;
    return this;
  }

  getSelf(): PathReference<Opaque> {
    return this.slots[0] as PathReference<Opaque>;
  }

  getSymbol(symbol: number): PathReference<Opaque> {
    return this.slots[symbol] as PathReference<Opaque>;
  }

  getBlock(symbol: number): InlineBlock {
    return this.slots[symbol] as InlineBlock;
  }

  bindSymbol(symbol: number, value: PathReference<Opaque>) {
    this.slots[symbol] = value;
  }

  bindBlock(symbol: number, value: InlineBlock) {
    this.slots[symbol] = value;
  }

  bindCallerScope(scope: Scope) {
    this.callerScope = scope;
  }

  getCallerScope(): Scope {
    return this.callerScope;
  }

  child(): Scope {
    return new Scope(this.slots.slice());
  }
}

export abstract class Environment {
  protected dom: DOMHelper;
  private createdComponents: Component[] = null;
  private createdManagers: ComponentManager<Component>[] = null;
  private updatedComponents: Component[] = null;
  private updatedManagers: ComponentManager<Component>[] = null;
  private destructors: Destroyable[] = null;

  constructor(dom: DOMHelper) {
    this.dom = dom;
  }

  toConditionalReference(reference: Reference<Opaque>): Reference<boolean> {
    return new ConditionalReference(reference);
  }

  abstract iterableFor(reference: Reference<Opaque>, args: EvaluatedArgs): OpaqueIterable;

  getDOM(): DOMHelper { return this.dom; }

  getIdentity(object: HasGuid): InternedString {
    return intern(ensureGuid(object) + '');
  }

  statement(statement: StatementSyntax): StatementSyntax {
    return this.refineStatement(parseStatement(statement)) || statement;
  }

  protected refineStatement(statement: ParsedStatement): StatementSyntax {
    let {
      isSimple,
      isBlock,
      key,
      args,
      templates
    } = statement;

    if (isSimple && isBlock) {
      switch (key) {
        case 'each':
          return new EachSyntax({ args, templates });
        case 'if':
          return new IfSyntax({ args, templates });
        case 'with':
          return new WithSyntax({ args, templates });
        case 'unless':
          return new UnlessSyntax({ args, templates });
      }
    }
  }

  begin() {
    this.createdComponents = [];
    this.createdManagers = [];
    this.updatedComponents = [];
    this.updatedManagers = [];
    this.destructors = [];
  }

  didCreate<T>(component: T, manager: ComponentManager<T>) {
    this.createdComponents.push(component as any);
    this.createdManagers.push(manager as any);
  }

  didUpdate<T>(component: T, manager: ComponentManager<T>) {
    this.updatedComponents.push(component as any);
    this.updatedManagers.push(manager as any);
  }

  didDestroy(d: Destroyable) {
    this.destructors.push(d);
  }

  commit() {
    for (let i=0; i<this.createdComponents.length; i++) {
      let component = this.createdComponents[i];
      let manager = this.createdManagers[i];
      manager.didCreate(component);
    }

    for (let i=0; i<this.updatedComponents.length; i++) {
      let component = this.updatedComponents[i];
      let manager = this.updatedManagers[i];
      manager.didUpdate(component);
    }

    for (let i=0; i<this.destructors.length; i++) {
      this.destructors[i].destroy();
    }
  }

  hasKeyword(string: InternedString): boolean {
    return false;
  }<commit_msg>Reverse async hooks order to match Ember<commit_after>import { Statement as StatementSyntax } from './syntax';

import { DOMHelper } from './dom';
import { Reference, OpaqueIterable } from 'glimmer-reference';
import { NULL_REFERENCE, ConditionalReference } from './references';

import {
  Component,
  ComponentManager,
  ComponentDefinition
} from './component/interfaces';

import {
  ModifierManager
} from './modifier/interfaces';

import {
  PathReference
} from 'glimmer-reference';

import {
  HasGuid,
  InternedString,
  intern,
  ensureGuid
} from 'glimmer-util';

import { EvaluatedArgs } from './compiled/expressions/args';

import { InlineBlock } from './compiled/blocks';

import { Destroyable, Dict, Opaque } from 'glimmer-util';

import * as Syntax from './syntax/core';

import IfSyntax from './syntax/builtins/if';
import UnlessSyntax from './syntax/builtins/unless';
import WithSyntax from './syntax/builtins/with';
import EachSyntax from './syntax/builtins/each';

type ScopeSlot = PathReference<Opaque> | InlineBlock;

export interface DynamicScope {
  child(): DynamicScope;
}

export class Scope {
  static root(self: PathReference<Opaque>, size = 0) {
    let refs: PathReference<Opaque>[] = new Array(size + 1);

    for (let i = 0; i <= size; i++) {
      refs[i] = NULL_REFERENCE;
    }

    return new Scope(refs).init({ self });
  }

  // the 0th slot is `self`
  private slots: ScopeSlot[];
  private callerScope: Scope = null;

  constructor(references: ScopeSlot[]) {
    this.slots = references;
  }

  init({ self }: { self: PathReference<Opaque> }): this {
    this.slots[0] = self;
    return this;
  }

  getSelf(): PathReference<Opaque> {
    return this.slots[0] as PathReference<Opaque>;
  }

  getSymbol(symbol: number): PathReference<Opaque> {
    return this.slots[symbol] as PathReference<Opaque>;
  }

  getBlock(symbol: number): InlineBlock {
    return this.slots[symbol] as InlineBlock;
  }

  bindSymbol(symbol: number, value: PathReference<Opaque>) {
    this.slots[symbol] = value;
  }

  bindBlock(symbol: number, value: InlineBlock) {
    this.slots[symbol] = value;
  }

  bindCallerScope(scope: Scope) {
    this.callerScope = scope;
  }

  getCallerScope(): Scope {
    return this.callerScope;
  }

  child(): Scope {
    return new Scope(this.slots.slice());
  }
}

export abstract class Environment {
  protected dom: DOMHelper;
  private createdComponents: Component[] = null;
  private createdManagers: ComponentManager<Component>[] = null;
  private updatedComponents: Component[] = null;
  private updatedManagers: ComponentManager<Component>[] = null;
  private destructors: Destroyable[] = null;

  constructor(dom: DOMHelper) {
    this.dom = dom;
  }

  toConditionalReference(reference: Reference<Opaque>): Reference<boolean> {
    return new ConditionalReference(reference);
  }

  abstract iterableFor(reference: Reference<Opaque>, args: EvaluatedArgs): OpaqueIterable;

  getDOM(): DOMHelper { return this.dom; }

  getIdentity(object: HasGuid): InternedString {
    return intern(ensureGuid(object) + '');
  }

  statement(statement: StatementSyntax): StatementSyntax {
    return this.refineStatement(parseStatement(statement)) || statement;
  }

  protected refineStatement(statement: ParsedStatement): StatementSyntax {
    let {
      isSimple,
      isBlock,
      key,
      args,
      templates
    } = statement;

    if (isSimple && isBlock) {
      switch (key) {
        case 'each':
          return new EachSyntax({ args, templates });
        case 'if':
          return new IfSyntax({ args, templates });
        case 'with':
          return new WithSyntax({ args, templates });
        case 'unless':
          return new UnlessSyntax({ args, templates });
      }
    }
  }

  begin() {
    this.createdComponents = [];
    this.createdManagers = [];
    this.updatedComponents = [];
    this.updatedManagers = [];
    this.destructors = [];
  }

  didCreate<T>(component: T, manager: ComponentManager<T>) {
    this.createdComponents.push(component as any);
    this.createdManagers.push(manager as any);
  }

  didUpdate<T>(component: T, manager: ComponentManager<T>) {
    this.updatedComponents.push(component as any);
    this.updatedManagers.push(manager as any);
  }

  didDestroy(d: Destroyable) {
    this.destructors.push(d);
  }

  commit() {
    for (let i=this.createdComponents.length-1; i>=0; i--) {
      let component = this.createdComponents[i];
      let manager = this.createdManagers[i];
      manager.didCreate(component);
    }

    for (let i=this.updatedComponents.length-1; i>=0; i--) {
      let component = this.updatedComponents[i];
      let manager = this.updatedManagers[i];
      manager.didUpdate(component);
    }

    for (let i=0; i<this.destructors.length; i++) {
      this.destructors[i].destroy();
    }
  }

  hasKeyword(string: InternedString): boolean {
    return false;
  }
{'fraction_non_alphanumeric': 0.1290981513634971, 'fraction_numerical': 0.002042692268409764, 'mean_word_length': 3.56078248719143, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1204497', 'n_tokens_mistral': 3084, 'n_tokens_neox': 2991, 'n_words': 704}