<commit_before>/* @internal */
namespace ts.codefix {
    registerCodeFix({
        errorCodes: [Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code],
        getCodeActions: getActionsForJSDocTypes
    });

    function getActionsForJSDocTypes(context: CodeFixContext): CodeAction[] | undefined {
        const sourceFile = context.sourceFile;
        const node = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
        const decl = ts.findAncestor(node, n => n.kind === SyntaxKind.VariableDeclaration);
        if (!decl) return;
        const checker = context.program.getTypeChecker();

        const jsdocType = (decl as VariableDeclaration).type;
        const original = getTextOfNode(jsdocType);
        const type = checker.getTypeFromTypeNode(jsdocType);
        const actions = [createAction(jsdocType, sourceFile.fileName, original, checker.typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.NoTruncation))];
        if (jsdocType.kind === SyntaxKind.JSDocNullableType) {
            // for nullable types, suggest the flow-compatible `T | null | undefined`
            // in addition to the jsdoc/closure-compatible `T | null`
            const replacementWithUndefined = checker.typeToString(checker.getNullableType(type, TypeFlags.Undefined), /*enclosingDeclaration*/ undefined, TypeFormatFlags.NoTruncation);
            actions.push(createAction(jsdocType, sourceFile.fileName, original, replacementWithUndefined));
        }
        return actions;
    }

    function createAction(declaration: TypeNode, fileName: string, original: string, replacement: string): CodeAction {
        return {
            description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Change_0_to_1), [original, replacement]),
            changes: [{
                fileName,
                textChanges: [{
                    span: { start: declaration.getStart(), length: declaration.getWidth() },
                    newText: replacement
                }]
            }],
        };
    }
}
<commit_msg>Provide jsdoc type code fixes for all variable-like decls<commit_after>/* @internal */
namespace ts.codefix {
    registerCodeFix({
        errorCodes: [Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code],
        getCodeActions: getActionsForJSDocTypes
    });

    function getActionsForJSDocTypes(context: CodeFixContext): CodeAction[] | undefined {
        const sourceFile = context.sourceFile;
        const node = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
        const decl = ts.findAncestor(node,
                                     n => n.kind === SyntaxKind.VariableDeclaration ||
                                     n.kind === SyntaxKind.Parameter ||
                                     n.kind === SyntaxKind.PropertyDeclaration ||
                                     n.kind === SyntaxKind.PropertyAssignment);
        if (!decl) return;
        const checker = context.program.getTypeChecker();

        const jsdocType = (decl as VariableDeclaration).type;
        if (!jsdocType) return;
        const original = getTextOfNode(jsdocType);
        const type = checker.getTypeFromTypeNode(jsdocType);
        const actions = [createAction(jsdocType, sourceFile.fileName, original, checker.typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.NoTruncation))];
        if (jsdocType.kind === SyntaxKind.JSDocNullableType) {
            // for nullable types, suggest the flow-compatible `T | null | undefined`
            // in addition to the jsdoc/closure-compatible `T | null`
            const replacementWithUndefined = checker.typeToString(checker.getNullableType(type, TypeFlags.Undefined), /*enclosingDeclaration*/ undefined, TypeFormatFlags.NoTruncation);
            actions.push(createAction(jsdocType, sourceFile.fileName, original, replacementWithUndefined));
        }
        return actions;
    }

    function createAction(declaration: TypeNode, fileName: string, original: string, replacement: string): CodeAction {
        return {
            description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Change_0_to_1), [original, replacement]),
            changes: [{
                fileName,
                textChanges: [{
                    span: { start: declaration.getStart(), length: declaration.getWidth() },
                    newText: replacement
                }]
            }],
        };
    }
}

{'fraction_non_alphanumeric': 0.0954849859580903, 'fraction_numerical': 0.0008641175199827177, 'mean_word_length': 2.545176110260337, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7575532', 'n_tokens_mistral': 1190, 'n_tokens_neox': 1153, 'n_words': 241}