<commit_before>/* @flow */
import t from 'flow-runtime';
import flowRuntimeMobx from 'flow-runtime-mobx';
import * as flowConfigParser from 'flow-config-parser';
import React from 'react';
import ReactDOM from 'react-dom';
import {observable, computed} from 'mobx';
import * as mobx from 'mobx';
import * as mobxReact from 'mobx-react';

const sharedState = observable({
  isReady: false
});

const Worker: any = require("./compiler.worker");

type Deferred<T> = {
  promise: Promise<T>;
  resolve: (t: T) => void;
  reject: (e: Error) => void;
};

let SEQUENCE = 0;
const queue: {[key: number]: Deferred<any>} = {};

const sharedWorker = new Worker();
sharedWorker.onmessage = (event: MessageEvent) => {
  sharedState.isReady = true;
  const [id, transformed, compiled, errorMessage] = (event: any).data;
  const deferred = queue[id];
  if (!deferred) {
    return;
  }
  delete queue[id];
  if (errorMessage) {
    deferred.reject(new Error(errorMessage));
  }
  else {
    deferred.resolve([transformed, compiled]);
  }
};

function defer <T> (): Deferred<T> {
  const deferred = {};
  deferred.promise = new Promise((resolve, reject) => {
    deferred.resolve = resolve;
    deferred.reject = reject
  });
  return deferred;
}

function compile (code: string, options: Object): Promise<[string, string]> {
  let id = SEQUENCE++;
  const deferred = defer();
  queue[id] = deferred;
  sharedWorker.postMessage([id, code, options]);
  return deferred.promise;
}

type FakeConsole = {
  log (...args: any[]): any;
  warn (...args: any[]): any;
  error (...args: any[]): any;
}

function makeFakeConsole (faker: FakeConsole): FakeConsole {
  Object.setPrototypeOf(faker, console);
  return faker;
}

export default class Compiler {
  @observable code: string;
  @observable transformed: string;
  @observable compiled: string;
  @observable shouldAssert: boolean;
  @observable shouldWarn: boolean;
  @observable shouldDecorate: boolean;
  @observable error: string;
  @observable log: Array<['log' | 'warn' | 'error' | 'react', string]> = [];

  @computed get isReady (): boolean {
    return sharedState.isReady;
  }

  fakeConsole: FakeConsole = makeFakeConsole({
    log: (...args: any[]) => {
      console.log(...args);
      this.log.push(['log', args.map(String).join(' ')]);
    },
    warn: (...args: any[]) => {
      console.warn(...args);
      this.log.push(['warn', args.map(String).join(' ')]);
    },
    error: (...args: any[]) => {
      console.error(...args);
      this.log.push(['error', args.map(String).join(' ')]);
    }
  });

  constructor (code: string) {
    this.code = code;
    this.transformed = '';
    this.compiled = '';
    this.error = '';
    this.shouldDecorate = true;
    this.shouldAssert = true;
    this.shouldWarn = false;
    this.updateCode(this.code);
  }

  async updateCode (code: string) {
    this.code = code;
    try {
      const [transformed, compiled] = await compile(code, {
        assert: this.shouldAssert,
        decorate: this.shouldDecorate,
        warn: this.shouldWarn
      });

      this.transformed = transformed;
      this.compiled = compiled;
      this.error = '';<commit_msg>nicer fake console.log<commit_after>/* @flow */
import t from 'flow-runtime';
import flowRuntimeMobx from 'flow-runtime-mobx';
import * as flowConfigParser from 'flow-config-parser';
import React from 'react';
import ReactDOM from 'react-dom';
import {observable, computed} from 'mobx';
import * as mobx from 'mobx';
import * as mobxReact from 'mobx-react';

const sharedState = observable({
  isReady: false
});

const Worker: any = require("./compiler.worker");
const cycles = new Set();

type Deferred<T> = {
  promise: Promise<T>;
  resolve: (t: T) => void;
  reject: (e: Error) => void;
};

let SEQUENCE = 0;
const queue: {[key: number]: Deferred<any>} = {};

const sharedWorker = new Worker();
sharedWorker.onmessage = (event: MessageEvent) => {
  sharedState.isReady = true;
  const [id, transformed, compiled, errorMessage] = (event: any).data;
  const deferred = queue[id];
  if (!deferred) {
    return;
  }
  delete queue[id];
  if (errorMessage) {
    deferred.reject(new Error(errorMessage));
  }
  else {
    deferred.resolve([transformed, compiled]);
  }
};

function defer <T> (): Deferred<T> {
  const deferred = {};
  deferred.promise = new Promise((resolve, reject) => {
    deferred.resolve = resolve;
    deferred.reject = reject
  });
  return deferred;
}

function compile (code: string, options: Object): Promise<[string, string]> {
  let id = SEQUENCE++;
  const deferred = defer();
  queue[id] = deferred;
  sharedWorker.postMessage([id, code, options]);
  return deferred.promise;
}

type FakeConsole = {
  log (...args: any[]): any;
  warn (...args: any[]): any;
  error (...args: any[]): any;
};

function makeFakeConsole (faker: FakeConsole): FakeConsole {
  Object.setPrototypeOf(faker, console);
  return faker;
}

function prepareLogItem (input: any): string {
  if (input == null || typeof input !== 'object') {
    return String(input);
  }
  else if (cycles.has(input)) {
    return '[[Cyclic Reference]]';
  }
  cycles.add(input);
  let result;
  if (Array.isArray(input)) {
    result = `[${input.map(prepareLogItem).join(', ')}]`;
  }
  else {
    const props = Object.keys(input).map(key => `${key}: ${prepareLogItem(input[key])}`);
    if (typeof input.constructor === 'function' && input.constructor !== Object) {
      result = `${input.constructor.name} {\n${indent(props.join(',\n'))}\n}`;
    }
    else {
      result = `{\n${indent(props.join(',\n'))}\n}`
    }
  }
  cycles.delete(input);
  return result;
}

function indent (input: string): string {
  const lines = input.split('\n');
  const {length} = lines;
  for (let i = 0; i < length; i++) {
    lines[i] = `  ${lines[i]}`;
  }
  return lines.join('\n');
}


export default class Compiler {
  @observable code: string;
  @observable transformed: string;
  @observable compiled: string;
  @observable shouldAssert: boolean;
  @observable shouldWarn: boolean;
  @observable shouldDecorate: boolean;
  @observable error: string;
  @observable log: Array<['log' | 'warn' | 'error' | 'react', string]> = [];

  @computed get isReady (): boolean {
    return sharedState.isReady;
  }

  fakeConsole: FakeConsole = makeFakeConsole({
    log: (...args: any[]) => {
      console.log(...args);
      this.log.push(['log', args.map(prepareLogItem).join(' ')]);
    },
    warn: (...args: any[]) => {
      console.warn(...args);
      this.log.push(['warn', args.map(prepareLogItem).join(' ')]);
    },
    error: (...args: any[]) => {
      console.error(...args);
      this.log.push(['error', args.map(prepareLogItem).join(' ')]);
    }
  });

  constructor (code: string) {
    this.code = code;
    this.transformed = '';
    this.compiled = '';
    this.error = '';
    this.shouldDecorate = true;
    this.shouldAssert = true;
    this.shouldWarn = false;
    this.updateCode(this.code);
  }

  async updateCode (code: string) {
    this.code = code;
    try {
      const [transformed, compiled] = await compile(code, {
        assert: this.shouldAssert,
        decorate: this.shouldDecorate,
        warn: this.shouldWarn
      });

      this.transformed = transformed;
      this.compiled = compiled;
      this.error = '';
{'fraction_non_alphanumeric': 0.17188358045030203, 'fraction_numerical': 0.00041186161449752884, 'mean_word_length': 3.431265206812652, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 32, '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': '6190618', 'n_tokens_mistral': 2413, 'n_tokens_neox': 2376, 'n_words': 585}