<commit_before>(function() {
  'use strict';

  var L20n = {
    Context: Context,
    getContext: function L20n_getContext(id) {
      return new Context(id);
    },
  };

// skip _imports_positions
// more logic to build() than parse/fetch etc.

  function Resource(id, parser) {
    var self = this;

    this.id = id;
    this.resources = [];
    this.source = null;
    this.isReady = false;
    this.ast = {
      type: 'LOL',
      body: [],
    };

    this.build = build;
    this.fetch = fetch;
    this.parse = parse;
    this.buildImports = buildImports;
    this.flatten = flatten;

    var _imports_positions = [];

    function build(nesting, async) {
      if (nesting >= 7) {
        throw new ContextError("Too many nested imports.");
      }
      return fetch(async)
        .then(parse)
        .then(buildImports.bind(this, nesting + 1, async))
        .then(flatten);
    }

    function fetch(async) {
      var source = when.defer();
      if (self.id === null || self.source) {
        source.resolve();
        return source.promise;
      }
      L20n.IO.load(self.id, async).then(
        function loadResource_success(text) {
          L20n.IO.bind(self.id, text);
          self.source = text;
          source.resolve();
        },
        function loadResource_failure() {
          source.resolve();
        }
      );
      return source.promise;
    }

    function parse() {
      var ast = when.defer();
      if (!self.source) {
        ast.resolve();
        return ast.promise;
      }
      self.ast = parser.parse(self.source);
      ast.resolve();
      return ast.promise;
    }

    function buildImports(nesting, async) {
      if (self.ast) {
        var imports = self.ast.body.filter(function(elem, i) {
          if (elem.type == 'ImportStatement') {
            _imports_positions.push(i);
            return true;
          }
          return false;
        });

        imports.forEach(function(imp) {
          var uri = relativeToSelf(imp.uri.content);
          var res = new Resource(uri, parser);
          self.resources.push(res);
        });
      }

      var imports_built = [];
      self.resources.forEach(function(res) {
        imports_built.push(res.build(nesting, async));
      });

      return when.all(imports_built);
    }

    function flatten() {
      var flat = when.defer();
      // FIXME reversing the loop here breaks the order of overwriting entities
      for (var i = self.resources.length-1; i >= 0; i--) {
        var pos = _imports_positions[i] || 0;
        // XXX this used to concatenate a Source's ast.body;  why?
        Array.prototype.splice.apply(self.ast.body,
          [pos, 1].concat(self.resources[i].ast.body));
      }
      self.isReady = true;
      flat.resolve();
      return flat.promise;
    }

    function relativeToSelf(url) {
      if (self.id === null || url[0] == '/') {
        return url;
      } 
      var dirname = self.id.split('/').slice(0, -1).join('/');
      if (dirname) {
        // strip the trailing slash if present
        if (dirname[dirname.length - 1] == '/') {
          dirname = dirname.slice(0, dirname.length - 1);
        }
        return dirname + '/' + url;
      } else {
        return './' + url;
      }
    }

  }

  function Locale(id, parser, compiler) {
    this.id = id;
    this.resource = new Resource(null, parser);

    this.compile = compile;
    this.getEntry = getEntry;
    this.entries = null;

    this.isReady = false;<commit_msg>Remove promises from Resource's methods which are always synchronous<commit_after>(function() {
  'use strict';

  var L20n = {
    Context: Context,
    getContext: function L20n_getContext(id) {
      return new Context(id);
    },
  };

// skip _imports_positions
// more logic to build() than parse/fetch etc.

  function Resource(id, parser) {
    var self = this;

    this.id = id;
    this.resources = [];
    this.source = null;
    this.isReady = false;
    this.ast = {
      type: 'LOL',
      body: [],
    };

    this.build = build;
    this.fetch = fetch;
    this.parse = parse;
    this.buildImports = buildImports;
    this.flatten = flatten;

    var _imports_positions = [];

    function build(nesting, async) {
      if (nesting >= 7) {
        throw new ContextError("Too many nested imports.");
      }
      return fetch(async)
        .then(parse)
        .then(buildImports.bind(this, nesting + 1, async))
        .then(flatten);
    }

    function fetch(async) {
      if (self.id === null || self.source) {
        var source = when.defer();
        source.resolve();
        return source.promise;
      }
      return L20n.IO.load(self.id, async).then(
        function loadResource_success(text) {
          L20n.IO.bind(self.id, text);
          self.source = text;
        },
        function loadResource_failure() {
        }
      );
    }

    function parse() {
      if (self.source) {
        self.ast = parser.parse(self.source);
      }
    }

    function buildImports(nesting, async) {
      if (self.ast) {
        var imports = self.ast.body.filter(function(elem, i) {
          if (elem.type == 'ImportStatement') {
            _imports_positions.push(i);
            return true;
          }
          return false;
        });

        imports.forEach(function(imp) {
          var uri = relativeToSelf(imp.uri.content);
          var res = new Resource(uri, parser);
          self.resources.push(res);
        });
      }

      var imports_built = [];
      self.resources.forEach(function(res) {
        imports_built.push(res.build(nesting, async));
      });

      return when.all(imports_built);
    }

    function flatten() {
      // FIXME reversing the loop here breaks the order of overwriting entities
      for (var i = self.resources.length-1; i >= 0; i--) {
        var pos = _imports_positions[i] || 0;
        // XXX this used to concatenate a Source's ast.body;  why?
        Array.prototype.splice.apply(self.ast.body,
          [pos, 1].concat(self.resources[i].ast.body));
      }
      self.isReady = true;
    }

    function relativeToSelf(url) {
      if (self.id === null || url[0] == '/') {
        return url;
      } 
      var dirname = self.id.split('/').slice(0, -1).join('/');
      if (dirname) {
        // strip the trailing slash if present
        if (dirname[dirname.length - 1] == '/') {
          dirname = dirname.slice(0, dirname.length - 1);
        }
        return dirname + '/' + url;
      } else {
        return './' + url;
      }
    }

  }

  function Locale(id, parser, compiler) {
    this.id = id;
    this.resource = new Resource(null, parser);

    this.compile = compile;
    this.getEntry = getEntry;
    this.entries = null;

    this.isReady = false;
{'fraction_non_alphanumeric': 0.1366863905325444, 'fraction_numerical': 0.005917159763313609, 'mean_word_length': 1.9117140396210164, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '5124507', 'n_tokens_mistral': 2151, 'n_tokens_neox': 2069, 'n_words': 471}