<commit_before>/**
 * File was copied and modified from
 * https://typescript-api-playground.glitch.me/#example=Creating%20a%20ts.Program%20and%20SourceFile%20in%20memory%20for%20testing%20without%20file%20system
 * From the SO question
 * https://stackoverflow.com/questions/50574469/can-i-change-the-sourcefile-of-a-node-using-the-typescript-compiler-api
 */

/**
 * 1. Get region
 * 2. Get aurelia view model file
 * 3. split content to instert temporary method (used for actual completion, thus "virtual")
 * 4. From 3. create virtualSourceFile
 * 5. Create language service from 4.
 * 6. Get completions
 */

interface EntryDetailsMapData {
  displayParts: string | undefined;
  documentation: string | undefined;
  kind: CompletionItemKind;
  methodArguments: string[];
}

interface EntryDetailsMap {
  [key: string]: EntryDetailsMapData;
}

import { ts } from 'ts-morph';
import {
  CompletionItem,
  CompletionItemKind,
  CompletionList,
  InsertTextFormat,
  MarkupKind,
  TextDocument,
  TextDocumentPositionParams,
} from 'vscode-languageserver';
import { AureliaProgram } from '../../viewModel/AureliaProgram';
import { AureliaLSP, VIRTUAL_SOURCE_FILENAME } from '../../common/constants';
import {
  createVirtualFileWithContent,
  createVirtualViewModelSourceFile,
  getVirtualLangagueService,
  VIRTUAL_METHOD_NAME,
} from '../virtual/virtualSourceFile';
import { AsyncReturnType } from '../../common/global';
import { ViewRegionInfo } from '../embeddedLanguages/embeddedSupport';

const PARAMETER_NAME = 'parameterName';

/**
 * Returns the virtual competion. (to be used as real completions)
 */
export function getVirtualCompletion(
  aureliaProgram: AureliaProgram,
  virtualSourcefile: ts.SourceFile,
  positionOfAutocomplete: number
) {
  const program = aureliaProgram.getProgram();
  if (!program) {
    throw new Error('Need program');
  }

  const cls = getVirtualLangagueService(virtualSourcefile, program);
  const virtualSourceFilePath = virtualSourcefile.fileName;

  const virtualCompletions = cls
    .getCompletionsAtPosition(
      virtualSourceFilePath,
      positionOfAutocomplete,
      undefined
    )
    ?.entries.filter((result) => {
      return !result?.name.includes(VIRTUAL_METHOD_NAME);
    });

  if (!virtualCompletions) {
    throw new Error('No completions found');
  }

  const virtualCompletionEntryDetails = virtualCompletions
    .map((completion) => {
      return cls.getCompletionEntryDetails(
        virtualSourceFilePath,
        positionOfAutocomplete,<commit_msg>perf(server.virtual): add doc<commit_after>/**
 * File was copied and modified from
 * https://typescript-api-playground.glitch.me/#example=Creating%20a%20ts.Program%20and%20SourceFile%20in%20memory%20for%20testing%20without%20file%20system
 * From the SO question
 * https://stackoverflow.com/questions/50574469/can-i-change-the-sourcefile-of-a-node-using-the-typescript-compiler-api
 */

/**
 * 1. Get region
 * 2. Get aurelia view model file
 * 3. split content to instert temporary method (used for actual completion, thus "virtual")
 * 4. From 3. create virtualSourceFile
 * 5. Create language service from 4.
 * 6. Get completions
 */

interface EntryDetailsMapData {
  displayParts: string | undefined;
  documentation: string | undefined;
  kind: CompletionItemKind;
  methodArguments: string[];
}

interface EntryDetailsMap {
  [key: string]: EntryDetailsMapData;
}

import { ts } from 'ts-morph';
import {
  CompletionItem,
  CompletionItemKind,
  CompletionList,
  InsertTextFormat,
  MarkupKind,
  TextDocument,
  TextDocumentPositionParams,
} from 'vscode-languageserver';
import { AureliaProgram } from '../../viewModel/AureliaProgram';
import { AureliaLSP, VIRTUAL_SOURCE_FILENAME } from '../../common/constants';
import {
  createVirtualFileWithContent,
  createVirtualViewModelSourceFile,
  getVirtualLangagueService,
  VIRTUAL_METHOD_NAME,
} from '../virtual/virtualSourceFile';
import { AsyncReturnType } from '../../common/global';
import { ViewRegionInfo } from '../embeddedLanguages/embeddedSupport';
import { Logger } from '../../common/logging/logger';

const logger = new Logger('virtualCompletion');

const PARAMETER_NAME = 'parameterName';

/**
 * Returns the virtual competion. (to be used as real completions)
 */
export function getVirtualCompletion(
  aureliaProgram: AureliaProgram,
  virtualSourcefile: ts.SourceFile,
  positionOfAutocomplete: number
) {
  const program = aureliaProgram.getProgram();
  if (!program) {
    throw new Error('Need program');
  }

  const cls = getVirtualLangagueService(virtualSourcefile, program);
  const virtualSourceFilePath = virtualSourcefile.fileName;

  // [PERF]: ~0.25
  const virtualCompletions = cls
    .getCompletionsAtPosition(
      virtualSourceFilePath,
      positionOfAutocomplete,
      undefined
    )
    ?.entries.filter((result) => {
      return !result?.name.includes(VIRTUAL_METHOD_NAME);
    });

  if (!virtualCompletions) {
    throw new Error('No completions found');
  }

  const virtualCompletionEntryDetails = virtualCompletions
    .map((completion) => {
      return cls.getCompletionEntryDetails(
        virtualSourceFilePath,
        positionOfAutocomplete,
{'fraction_non_alphanumeric': 0.10913999228692634, 'fraction_numerical': 0.015233320478210566, 'mean_word_length': 4.494703389830509, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 4, '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': '1080786', 'n_tokens_mistral': 1574, 'n_tokens_neox': 1505, 'n_words': 345}