<commit_before>import * as minimatch from 'minimatch';
import * as _ from 'lodash';
import {tokenize, TokenType} from './tokenizer';
import {provideStructure, IStructureInfo} from './structure-provider';
import {PositionInfo} from './utils';
import {IProposalProvider, IRequest, IProposal} from './provider-api'

export default class RootProvider {
  public selector: string = '.source.json';
  public inclusionPriority: number = 1;

  constructor(private providers: Array<IProposalProvider> = []) { }

  getSuggestions({editor, bufferPosition, activatedManually, prefix}): Promise<IProposal> {
    if (editor.lineTextForBufferRow(bufferPosition.row).charAt(bufferPosition.column - 1) === ',' && !activatedManually) {
      return Promise.resolve([]); // hack, to prevent activation right after inserting a comma
    }

    const providers = this.getMatchingProviders(editor.buffer.file.getBaseName());
    if (providers.length === 0) {
      return Promise.resolve([]); // no provider no proposals
    }
    return tokenize(editor.getText())
      .then(tokens => provideStructure(tokens, bufferPosition))
      .then(structure => {
        const request = this.buildRequest(structure, prefix);
        return Promise.all(providers.map(provider => provider.getProposals(request)))
          .then(proposals => Array.prototype.concat.apply([], proposals));
      });
  }

  buildRequest(structure: IStructureInfo, prefix: string): IRequest {
    const {contents, positionInfo, tokens} = structure;

    const shouldAddComma = (info: PositionInfo) => {
      if (!info || !info.nextToken || !tokens || tokens.length === 0) {
        return false;
      }
      if (info.nextToken && _.includes([TokenType.END_ARRAY, TokenType.END_OBJECT], info.nextToken.type)) {
        return false;
      }
      return !(info.nextToken && _.includes([TokenType.END_ARRAY, TokenType.END_OBJECT], info.nextToken.type)) && info.nextToken.type !== TokenType.COMMA;
    }

    return {
      contents,
      prefix: prefix,
      segments: positionInfo ? positionInfo.segments : null,
      token: positionInfo ? (positionInfo.editedToken) ? positionInfo.editedToken.src : null : null,
      isKeyPosition: !!(positionInfo && positionInfo.keyPosition),
      isValuePosition: !!(positionInfo && positionInfo.valuePosition),
      isBetweenQuotes: !!(positionInfo && positionInfo.editedToken && positionInfo.editedToken.type === TokenType.STRING),
      shouldAddComma: !!shouldAddComma(positionInfo),
      isFileEmpty: tokens.length === 0
    }
  }

  getMatchingProviders(file: string) {
    return this.providers.filter(p => minimatch(file, p.getFilePattern()))
  }

  onDidInsertSuggestion(request: IRequest) {
    // noop for now
  }

  dispose() {
    // noop for now
  }
}<commit_msg>Signature fix<commit_after>import * as minimatch from 'minimatch';
import * as _ from 'lodash';
import {tokenize, TokenType} from './tokenizer';
import {provideStructure, IStructureInfo} from './structure-provider';
import {PositionInfo} from './utils';
import {IProposalProvider, IRequest, IProposal} from './provider-api'

export default class RootProvider {
  public selector: string = '.source.json';
  public inclusionPriority: number = 1;

  constructor(private providers: Array<IProposalProvider> = []) { }

  getSuggestions({editor, bufferPosition, activatedManually, prefix}): Promise<Array<IProposal>> {
    if (editor.lineTextForBufferRow(bufferPosition.row).charAt(bufferPosition.column - 1) === ',' && !activatedManually) {
      return Promise.resolve([]); // hack, to prevent activation right after inserting a comma
    }

    const providers = this.getMatchingProviders(editor.buffer.file.getBaseName());
    if (providers.length === 0) {
      return Promise.resolve([]); // no provider no proposals
    }
    return tokenize(editor.getText())
      .then(tokens => provideStructure(tokens, bufferPosition))
      .then(structure => {
        const request = this.buildRequest(structure, prefix);
        return Promise.all(providers.map(provider => provider.getProposals(request)))
          .then(proposals => Array.prototype.concat.apply([], proposals));
      });
  }

  buildRequest(structure: IStructureInfo, prefix: string): IRequest {
    const {contents, positionInfo, tokens} = structure;

    const shouldAddComma = (info: PositionInfo) => {
      if (!info || !info.nextToken || !tokens || tokens.length === 0) {
        return false;
      }
      if (info.nextToken && _.includes([TokenType.END_ARRAY, TokenType.END_OBJECT], info.nextToken.type)) {
        return false;
      }
      return !(info.nextToken && _.includes([TokenType.END_ARRAY, TokenType.END_OBJECT], info.nextToken.type)) && info.nextToken.type !== TokenType.COMMA;
    }

    return {
      contents,
      prefix: prefix,
      segments: positionInfo ? positionInfo.segments : null,
      token: positionInfo ? (positionInfo.editedToken) ? positionInfo.editedToken.src : null : null,
      isKeyPosition: !!(positionInfo && positionInfo.keyPosition),
      isValuePosition: !!(positionInfo && positionInfo.valuePosition),
      isBetweenQuotes: !!(positionInfo && positionInfo.editedToken && positionInfo.editedToken.type === TokenType.STRING),
      shouldAddComma: !!shouldAddComma(positionInfo),
      isFileEmpty: tokens.length === 0
    }
  }

  getMatchingProviders(file: string) {
    return this.providers.filter(p => minimatch(file, p.getFilePattern()))
  }

  onDidInsertSuggestion(request: IRequest) {
    // noop for now
  }

  dispose() {
    // noop for now
  }
}
{'fraction_non_alphanumeric': 0.13047300861614208, 'fraction_numerical': 0.0017583963425356075, 'mean_word_length': 3.464678178963893, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 20, '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': '6396884', 'n_tokens_mistral': 1646, 'n_tokens_neox': 1568, 'n_words': 347}