<commit_before>/**
 * @file hh_client proxy
 */

'use strict';

import * as ps from 'child_process';
import * as vscode from 'vscode';

export function start(hhClient: string): boolean {
    try {
        ps.execFileSync(hhClient, ['start', vscode.workspace.rootPath]);
        return true;
    } catch (err) {
        if (err.status === 77) {
            // server was already running
            return true;
        }
        return false;
    }
}

export async function check(): Promise<CheckResponse> {
    return run(['check']);
}

export async function color(fileName: string): Promise<ColorResponse> {
    return run(['--color', fileName]);
}

export async function typeAtPos(fileName: string, line: number, character: number): Promise<string> {
    const arg: string = fileName + ':' + line + ':' + character;
    const args: string[] = ['--type-at-pos', arg];
    const typeAtPos: TypeAtPosResponse = await run(args);

    if (!typeAtPos || !typeAtPos.type || typeAtPos.type === '(unknown)' || typeAtPos.type === '_' || typeAtPos.type === 'noreturn') {
        return;
    }
    return typeAtPos.type;
}

export async function outline(text: string): Promise<OutlineResponse[]> { // tslint:disable-line
    return run(['--outline'], text);
}

export async function search(query: string): Promise<SearchResponse> {
    return run(['--search', query]);
}

export async function ideFindRefs(text: string, line: number, character: number): Promise<IdeFindRefsResponse> {
    return run(['--ide-find-refs', line + ':' + character], text);
}

export async function ideHighlightRefs(text: string, line: number, character: number): Promise<IdeHighlightRefsResponse> {
    return run(['--ide-highlight-refs', line + ':' + character], text);
}

export async function ideGetDefinition(text: string, line: number, character: number): Promise<IdeGetDefinitionResponse> {
    return run(['--ide-get-definition', line + ':' + character], text);
}

export async function autoComplete(text: string, position: number): Promise<AutoCompleteResponse> {
    // Insert hh_client autocomplete token at cursor position.
    const autoTok: string = 'AUTO332';
    const input = [text.slice(0, position), autoTok, text.slice(position)].join('');
    return run(['--auto-complete'], input);
}

export async function format(text: string, startPos: number, endPos: number): Promise<FormatResponse> {
    return run(['--format', '' + startPos, '' + endPos], text);
}

async function run(args: string[], stdin: string = null): Promise<any> { // tslint:disable-line
    return new Promise<any>((resolve, reject) => { // tslint:disable-line
        args = args.concat(['--json', vscode.workspace.rootPath]);
        const hhClient = vscode.workspace.getConfiguration('hack').get('clientPath') || 'hh_client'; // tslint:disable-line
        const p = ps.execFile(String(hhClient), args, { maxBuffer: 1024 * 1024 }, (err: any, stdout, stderr) => { // tslint:disable-line
            if (err !== null && err.code !== 0 && err.code !== 2) {
                // any hh_client failure other than typecheck errors
                console.error('Hack: hh_client execution error: ' + err);
                resolve(null);
            }
            if (!stdout) {
                // all hh_client --check output goes to stderr by default
                stdout = stderr;<commit_msg>Added proper docker exec commands when calling run function. Also replaced local filepath with docker container source code path so that hh_client can find proper filepaths<commit_after>/**
 * @file hh_client proxy
 */

'use strict';

import * as ps from 'child_process';
import * as vscode from 'vscode';

export function start(hhClient: string): boolean {
    try {
        const useDocker = vscode.workspace.getConfiguration('hack').get('useDocker')
        if (useDocker) {
            const dockerContainerName = String(vscode.workspace.getConfiguration('hack').get('dockerContainerName'))
            const dockerSourcePath = String(vscode.workspace.getConfiguration('hack').get('dockerSourcePath'))
            ps.execFileSync('docker', ['exec', '-i', dockerContainerName, 'hh_client', 'start', dockerSourcePath]);
        } else {
            ps.execFileSync(hhClient, ['start', vscode.workspace.rootPath]);
        }
        return true;
    } catch (err) {
        if (err.status === 77) {
            // server was already running
            return true;
        }
        return false;
    }
}

export async function check(): Promise<CheckResponse> {
    return run(['check']);
}

export async function color(fileName: string): Promise<ColorResponse> {
    return run(['--color', getDockerSourcePath(fileName)]);
}
function getDockerSourcePath(fileName: string): string {
    const dockerSourcePath = String(vscode.workspace.getConfiguration('hack').get('dockerSourcePath'))
    return fileName.replace(vscode.workspace.rootPath, dockerSourcePath)
}
export async function typeAtPos(fileName: string, line: number, character: number): Promise<string> {
    const arg: string = getDockerSourcePath(fileName) + ':' + line + ':' + character;
    const args: string[] = ['--type-at-pos', arg];
    const typeAtPos: TypeAtPosResponse = await run(args);

    if (!typeAtPos || !typeAtPos.type || typeAtPos.type === '(unknown)' || typeAtPos.type === '_' || typeAtPos.type === 'noreturn') {
        return;
    }
    return typeAtPos.type;
}

export async function outline(text: string): Promise<OutlineResponse[]> { // tslint:disable-line
    return run(['--outline'], text);
}

export async function search(query: string): Promise<SearchResponse> {
    return run(['--search', query]);
}

export async function ideFindRefs(text: string, line: number, character: number): Promise<IdeFindRefsResponse> {
    return run(['--ide-find-refs', line + ':' + character], text);
}

export async function ideHighlightRefs(text: string, line: number, character: number): Promise<IdeHighlightRefsResponse> {
    return run(['--ide-highlight-refs', line + ':' + character], text);
}

export async function ideGetDefinition(text: string, line: number, character: number): Promise<IdeGetDefinitionResponse> {
    return run(['--ide-get-definition', line + ':' + character], text);
}

export async function autoComplete(text: string, position: number): Promise<AutoCompleteResponse> {
    // Insert hh_client autocomplete token at cursor position.
    const autoTok: string = 'AUTO332';
    const input = [text.slice(0, position), autoTok, text.slice(position)].join('');
    return run(['--auto-complete'], input);
}

export async function format(text: string, startPos: number, endPos: number): Promise<FormatResponse> {
    return run(['--format', '' + startPos, '' + endPos], text);
}

async function run(args: string[], stdin: string = null): Promise<any> { // tslint:disable-line
    return new Promise<any>((resolve, reject) => { // tslint:disable-line
        let hhClient = vscode.workspace.getConfiguration('hack').get('clientPath') || 'hh_client'; // tslint:disable-line
        const useDocker = vscode.workspace.getConfiguration('hack').get('useDocker');
        if (useDocker) {
            const dockerContainerName = String(vscode.workspace.getConfiguration('hack').get('dockerContainerName'))
            const dockerSourcePath = String(vscode.workspace.getConfiguration('hack').get('dockerSourcePath'))

            const dockerargs = ['exec', '-i', dockerContainerName, 'hh_client']
            hhClient = 'docker';

            if (dockerSourcePath) {
                args = args.concat(['--json', dockerSourcePath]);
                args = dockerargs.concat(args)
                console.log("docker", args.join(" "))
            } else {
                console.error('Hack: hh_client execution invalid docker source path ');
            }
        } else {
            args = args.concat(['--json', vscode.workspace.rootPath]);
        }
        const p = ps.execFile(String(hhClient), args, { maxBuffer: 1024 * 1024 }, (err: any, stdout, stderr) => { // tslint:disable-line
            if (err !== null && err.code !== 0 && err.code !== 2) {
                // any hh_client failure other than typecheck errors
                console.error('Hack: hh_client execution error: ' + err);
                resolve(null);
            }
            if (!stdout) {
                // all hh_client --check output goes to stderr by default
                stdout = stderr;
{'fraction_non_alphanumeric': 0.1458259114119463, 'fraction_numerical': 0.0038000237501484386, 'mean_word_length': 3.3345342254246013, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, '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': '7338632', 'n_tokens_mistral': 2457, 'n_tokens_neox': 2376, 'n_words': 624}