<commit_before>/* @internal */
namespace ts.JsTyping {

    export interface TypingResolutionHost {
        directoryExists(path: string): boolean;
        fileExists(fileName: string): boolean;
        readFile(path: string, encoding?: string): string | undefined;
        readDirectory(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string> | undefined, depth?: number): string[];
    }

    interface PackageJson {
        _requiredBy?: string[];
        dependencies?: MapLike<string>;
        devDependencies?: MapLike<string>;
        name?: string;
        optionalDependencies?: MapLike<string>;
        peerDependencies?: MapLike<string>;
        types?: string;
        typings?: string;
    }

    export interface CachedTyping {
        typingLocation: string;
        version: Semver;
    }

    /* @internal */
    export function isTypingUpToDate(cachedTyping: CachedTyping, availableTypingVersions: MapLike<string>) {
        const availableVersion = Semver.parse(getProperty(availableTypingVersions, `ts${versionMajorMinor}`) || getProperty(availableTypingVersions, "latest")!);
        return !availableVersion.greaterThan(cachedTyping.version);
    }

    /* @internal */
    export const nodeCoreModuleList: ReadonlyArray<string> = [
        "assert",
        "async_hooks",
        "buffer",
        "child_process",
        "cluster",
        "console",
        "constants",
        "crypto",
        "dgram",
        "dns",
        "domain",
        "events",
        "fs",
        "http",
        "https",
        "http2",
        "inspector",
        "net",
        "os",
        "path",
        "perf_hooks",
        "process",
        "punycode",
        "querystring",
        "readline",
        "repl",
        "stream",
        "string_decoder",
        "timers",
        "tls",
        "tty",
        "url",
        "util",
        "v8",
        "vm",
        "zlib"
    ];

    /* @internal */
    export const nodeCoreModules = arrayToSet(nodeCoreModuleList);

    /**
     * A map of loose file names to library names that we are confident require typings
     */
    export type SafeList = ReadonlyMap<string>;

    export function loadSafeList(host: TypingResolutionHost, safeListPath: Path): SafeList {
        const result = readConfigFile(safeListPath, path => host.readFile(path));
        return createMapFromTemplate<string>(result.config);
    }

    export function loadTypesMap(host: TypingResolutionHost, typesMapPath: Path): SafeList | undefined {
        const result = readConfigFile(typesMapPath, path => host.readFile(path));
        if (result.config) {
            return createMapFromTemplate<string>(result.config.simpleMap);
        }
        return undefined;
    }

    /**
     * @param host is the object providing I/O related operations.
     * @param fileNames are the file names that belong to the same project
     * @param projectRootPath is the path to the project root directory
     * @param safeListPath is the path used to retrieve the safe list
     * @param packageNameToTypingLocation is the map of package names to their cached typing locations and installed versions
     * @param typeAcquisition is used to customize the typing acquisition process
     * @param compilerOptions are used as a source for typing inference
     */
    export function discoverTypings(
        host: TypingResolutionHost,
        log: ((message: string) => void) | undefined,
        fileNames: string[],
        projectRootPath: Path,
        safeList: SafeList,
        packageNameToTypingLocation: ReadonlyMap<CachedTyping>,
        typeAcquisition: TypeAcquisition,
        unresolvedImports: ReadonlyArray<string>,
        typesRegistry: ReadonlyMap<MapLike<string>>):
        { cachedTypingPaths: string[], newTypingNames: string[], filesToWatch: string[] } {

        if (!typeAcquisition || !typeAcquisition.enable) {
            return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
        }

        // A typing name to typing file path mapping
        const inferredTypings = createMap<string>();

        // Only infer typings for .js and .jsx files
        fileNames = mapDefined(fileNames, fileName => {
            const path = normalizePath(fileName);
            if (hasJavaScriptFileExtension(path)) {
                return path;
            }
        });

        const filesToWatch: string[] = [];

        if (typeAcquisition.include) addInferredTypings(typeAcquisition.include, "Explicitly included types");
        const exclude = typeAcquisition.exclude || [];

        // Directories to search for package.json, bower.json and other typing information
        const possibleSearchDirs = arrayToSet(fileNames, getDirectoryPath);
        possibleSearchDirs.set(projectRootPath, true);
        possibleSearchDirs.forEach((_true, searchDir) => {
            const packageJsonPath = combinePaths(searchDir, "package.json");
            getTypingNamesFromJson(packageJsonPath, filesToWatch);

            const bowerJsonPath = combinePaths(searchDir, "bower.json");
            getTypingNamesFromJson(bowerJsonPath, filesToWatch);

            const bowerComponentsPath = combinePaths(searchDir, "bower_components");
            getTypingNamesFromPackagesFolder(bowerComponentsPath, filesToWatch);

            const nodeModulesPath = combinePaths(searchDir, "node_modules");
            getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch);
        });
        getTypingNamesFromSourceFileNames(fileNames);

        // add typings for unresolved imports
        if (unresolvedImports) {
            const module = deduplicate<string>(
                unresolvedImports.map(moduleId => nodeCoreModules.has(moduleId) ? "node" : moduleId),
                equateStringsCaseSensitive,
                compareStringsCaseSensitive);
            addInferredTypings(module, "Inferred typings from unresolved imports");
        }
        // Add the cached typing locations for inferred typings that are already installed
        packageNameToTypingLocation.forEach((typing, name) => {
            if (inferredTypings.has(name) && inferredTypings.get(name) === undefined && typesRegistry.has(name) && isTypingUpToDate(typing, typesRegistry.get(name)!)) {
                inferredTypings.set(name, typing.typingLocation);
            }
        });

        // Remove typings that the user has added to the exclude list
        for (const excludeTypingName of exclude) {
            const didDelete = inferredTypings.delete(excludeTypingName);
            if (didDelete && log) log(`Typing for ${excludeTypingName} is in exclude list, will be ignored.`);
        }
<commit_msg>Replace has with get and check undefined<commit_after>/* @internal */
namespace ts.JsTyping {

    export interface TypingResolutionHost {
        directoryExists(path: string): boolean;
        fileExists(fileName: string): boolean;
        readFile(path: string, encoding?: string): string | undefined;
        readDirectory(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string> | undefined, depth?: number): string[];
    }

    interface PackageJson {
        _requiredBy?: string[];
        dependencies?: MapLike<string>;
        devDependencies?: MapLike<string>;
        name?: string;
        optionalDependencies?: MapLike<string>;
        peerDependencies?: MapLike<string>;
        types?: string;
        typings?: string;
    }

    export interface CachedTyping {
        typingLocation: string;
        version: Semver;
    }

    /* @internal */
    export function isTypingUpToDate(cachedTyping: CachedTyping, availableTypingVersions: MapLike<string>) {
        const availableVersion = Semver.parse(getProperty(availableTypingVersions, `ts${versionMajorMinor}`) || getProperty(availableTypingVersions, "latest")!);
        return !availableVersion.greaterThan(cachedTyping.version);
    }

    /* @internal */
    export const nodeCoreModuleList: ReadonlyArray<string> = [
        "assert",
        "async_hooks",
        "buffer",
        "child_process",
        "cluster",
        "console",
        "constants",
        "crypto",
        "dgram",
        "dns",
        "domain",
        "events",
        "fs",
        "http",
        "https",
        "http2",
        "inspector",
        "net",
        "os",
        "path",
        "perf_hooks",
        "process",
        "punycode",
        "querystring",
        "readline",
        "repl",
        "stream",
        "string_decoder",
        "timers",
        "tls",
        "tty",
        "url",
        "util",
        "v8",
        "vm",
        "zlib"
    ];

    /* @internal */
    export const nodeCoreModules = arrayToSet(nodeCoreModuleList);

    /**
     * A map of loose file names to library names that we are confident require typings
     */
    export type SafeList = ReadonlyMap<string>;

    export function loadSafeList(host: TypingResolutionHost, safeListPath: Path): SafeList {
        const result = readConfigFile(safeListPath, path => host.readFile(path));
        return createMapFromTemplate<string>(result.config);
    }

    export function loadTypesMap(host: TypingResolutionHost, typesMapPath: Path): SafeList | undefined {
        const result = readConfigFile(typesMapPath, path => host.readFile(path));
        if (result.config) {
            return createMapFromTemplate<string>(result.config.simpleMap);
        }
        return undefined;
    }

    /**
     * @param host is the object providing I/O related operations.
     * @param fileNames are the file names that belong to the same project
     * @param projectRootPath is the path to the project root directory
     * @param safeListPath is the path used to retrieve the safe list
     * @param packageNameToTypingLocation is the map of package names to their cached typing locations and installed versions
     * @param typeAcquisition is used to customize the typing acquisition process
     * @param compilerOptions are used as a source for typing inference
     */
    export function discoverTypings(
        host: TypingResolutionHost,
        log: ((message: string) => void) | undefined,
        fileNames: string[],
        projectRootPath: Path,
        safeList: SafeList,
        packageNameToTypingLocation: ReadonlyMap<CachedTyping>,
        typeAcquisition: TypeAcquisition,
        unresolvedImports: ReadonlyArray<string>,
        typesRegistry: ReadonlyMap<MapLike<string>>):
        { cachedTypingPaths: string[], newTypingNames: string[], filesToWatch: string[] } {

        if (!typeAcquisition || !typeAcquisition.enable) {
            return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
        }

        // A typing name to typing file path mapping
        const inferredTypings = createMap<string>();

        // Only infer typings for .js and .jsx files
        fileNames = mapDefined(fileNames, fileName => {
            const path = normalizePath(fileName);
            if (hasJavaScriptFileExtension(path)) {
                return path;
            }
        });

        const filesToWatch: string[] = [];

        if (typeAcquisition.include) addInferredTypings(typeAcquisition.include, "Explicitly included types");
        const exclude = typeAcquisition.exclude || [];

        // Directories to search for package.json, bower.json and other typing information
        const possibleSearchDirs = arrayToSet(fileNames, getDirectoryPath);
        possibleSearchDirs.set(projectRootPath, true);
        possibleSearchDirs.forEach((_true, searchDir) => {
            const packageJsonPath = combinePaths(searchDir, "package.json");
            getTypingNamesFromJson(packageJsonPath, filesToWatch);

            const bowerJsonPath = combinePaths(searchDir, "bower.json");
            getTypingNamesFromJson(bowerJsonPath, filesToWatch);

            const bowerComponentsPath = combinePaths(searchDir, "bower_components");
            getTypingNamesFromPackagesFolder(bowerComponentsPath, filesToWatch);

            const nodeModulesPath = combinePaths(searchDir, "node_modules");
            getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch);
        });
        getTypingNamesFromSourceFileNames(fileNames);

        // add typings for unresolved imports
        if (unresolvedImports) {
            const module = deduplicate<string>(
                unresolvedImports.map(moduleId => nodeCoreModules.has(moduleId) ? "node" : moduleId),
                equateStringsCaseSensitive,
                compareStringsCaseSensitive);
            addInferredTypings(module, "Inferred typings from unresolved imports");
        }
        // Add the cached typing locations for inferred typings that are already installed
        packageNameToTypingLocation.forEach((typing, name) => {
            const registryEntry = typesRegistry.get(name);
            if (inferredTypings.has(name) && inferredTypings.get(name) === undefined && registryEntry !== undefined && isTypingUpToDate(typing, typesRegistry.get(name)!)) {
                inferredTypings.set(name, typing.typingLocation);
            }
        });

        // Remove typings that the user has added to the exclude list
        for (const excludeTypingName of exclude) {
            const didDelete = inferredTypings.delete(excludeTypingName);
            if (didDelete && log) log(`Typing for ${excludeTypingName} is in exclude list, will be ignored.`);
        }

{'fraction_non_alphanumeric': 0.09814460315122957, 'fraction_numerical': 0.0002945074363127669, 'mean_word_length': 2.698066975224612, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 53, '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': '4005367', 'n_tokens_mistral': 3581, 'n_tokens_neox': 3504, 'n_words': 902}