Skip to content

⚡️ Speed up function fix_imports_inside_blocks by 171% in PR #1901 (cf-fix-imports-inside-blocks)#1903

Merged
mohammedahmed18 merged 2 commits intocf-fix-imports-inside-blocksfrom
codeflash/optimize-pr1901-2026-03-25T17.27.15
Mar 25, 2026
Merged

⚡️ Speed up function fix_imports_inside_blocks by 171% in PR #1901 (cf-fix-imports-inside-blocks)#1903
mohammedahmed18 merged 2 commits intocf-fix-imports-inside-blocksfrom
codeflash/optimize-pr1901-2026-03-25T17.27.15

Conversation

@codeflash-ai
Copy link
Contributor

@codeflash-ai codeflash-ai bot commented Mar 25, 2026

⚡️ This pull request contains optimizations for PR #1901

If you approve this dependent PR, these changes will be merged into the original PR branch cf-fix-imports-inside-blocks.

This PR will be automatically closed if the original PR is merged.


📄 171% (1.71x) speedup for fix_imports_inside_blocks in codeflash/languages/javascript/edit_tests.py

⏱️ Runtime : 3.59 milliseconds 1.32 milliseconds (best of 88 runs)

📝 Explanation and details

The optimization consolidated three separate regex substitutions into a single combined pattern with a callback function, reducing the number of full-string scans from three to one. The original code applied _INDENTED_DEFAULT_IMPORT_RE.sub(), then _INDENTED_NAMED_IMPORT_RE.sub(), then _INDENTED_NAMESPACE_IMPORT_RE.sub() in sequence, each traversing the entire input string. The optimized version uses one alternation-based regex (_COMBINED_IMPORT_RE) that matches all three import types in a single pass, delegating replacement logic to _replace_import() which branches on which capture groups are populated. Line profiler shows the hot loop (the three consecutive .sub() calls accounting for 100% of original runtime) is now a single .sub() call, cutting per-iteration cost from ~81 µs to ~28 µs across typical inputs. No correctness or metric regressions observed.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 69 Passed
🌀 Generated Regression Tests 69 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
⚙️ Click to see Existing Unit Tests
Test File::Test Function Original ⏱️ Optimized ⏱️ Speedup
test_languages/test_javascript_support.py::TestFixImportsInsideBlocks.test_import_inside_describe_block 14.9μs 5.42μs 176%✅
test_languages/test_javascript_support.py::TestFixImportsInsideBlocks.test_import_inside_jest_mock_default 17.6μs 6.54μs 169%✅
test_languages/test_javascript_support.py::TestFixImportsInsideBlocks.test_import_inside_jest_mock_named 14.8μs 5.47μs 170%✅
test_languages/test_javascript_support.py::TestFixImportsInsideBlocks.test_mixed_top_level_and_indented 16.5μs 6.15μs 168%✅
test_languages/test_javascript_support.py::TestFixImportsInsideBlocks.test_namespace_import_inside_block 13.5μs 5.26μs 158%✅
test_languages/test_javascript_support.py::TestFixImportsInsideBlocks.test_top_level_imports_preserved 11.7μs 3.58μs 228%✅
🌀 Click to see Generated Regression Tests
import pytest  # used for our unit tests

from codeflash.languages.javascript.edit_tests import fix_imports_inside_blocks


def test_default_import_conversion_simple():
    # A top-level import should remain unchanged (no leading whitespace).
    top_level = "import top from 'top';\n"
    # An indented import inside a function should be converted to a require().
    indented = "    import foo from 'bar';\n"
    src = "function test() {\n" + indented + "}\n" + top_level
    # Run the fixer
    out = fix_imports_inside_blocks(src)  # 14.2μs -> 5.45μs (161% faster)
    # The indented import must be converted to a const require(...) preserving indentation.
    assert "    const foo = require('bar');\n" in out
    # The top-level import must remain as an import statement.
    assert "import top from 'top';\n" in out


def test_named_import_conversion_and_whitespace():
    # Named imports should be converted to "const { ... } = require('...');"
    src = (
        "describe('suite', function() {\n"
        '  import { a, b } from "mymod"\n'  # No semicolon, double quotes
        "  // other code\n"
        "});\n"
    )
    out = fix_imports_inside_blocks(src)  # 13.9μs -> 5.31μs (162% faster)
    # Expect the exact inner content to be preserved inside the braces and single quotes used.
    assert "  const { a, b } = require('mymod');\n" in out
    # The comment and other parts should remain unchanged.
    assert "  // other code\n" in out


def test_namespace_import_and_tabs():
    # Namespace imports (import * as X from 'Y') should become const X = require('Y')
    src = "it('test', () => {\n\timport * as ns from 'nsmod';\n\tconst x = 1;\n});\n"
    out = fix_imports_inside_blocks(src)  # 12.9μs -> 5.11μs (152% faster)
    # Tab indentation must be preserved and replaced correctly.
    assert "\tconst ns = require('nsmod');\n" in out
    # Other code lines must remain.
    assert "\tconst x = 1;\n" in out


def test_multiple_imports_and_mixed():
    # Multiple different indented imports inside a block should all be converted.
    src = (
        "function wrapper() {\n"
        "    import a from 'A';\n"
        "    import {b, c} from 'B';\n"
        '\timport * as D from "D";\n'
        "    const untouched = true;\n"
        "}\n"
        "import top from 'Top';\n"  # top-level import must remain
    )
    out = fix_imports_inside_blocks(src)  # 20.9μs -> 8.56μs (144% faster)
    # Check each converted form appears exactly once.
    assert "    const a = require('A');\n" in out
    assert "    const {b, c} = require('B');\n" in out
    # Note: the namespace import used double quotes originally; replacement uses single quotes.
    assert "\tconst D = require('D');\n" in out
    # Top-level import should be unchanged.
    assert "import top from 'Top';\n" in out
    # Ensure other code remains
    assert "    const untouched = true;\n" in out


def test_no_change_for_non_indented_imports_and_strings():
    # A top-level import (no leading whitespace) should not be touched.
    src = "import top from 'top';\nconst s = \"    import fake from 'nope'\";\n"
    out = fix_imports_inside_blocks(src)  # 7.94μs -> 2.11μs (276% faster)
    # Both the top-level import and the string literal must remain unchanged.
    assert "import top from 'top';\n" in out
    assert "import fake from 'nope'" in out  # inside quotes should remain


def test_empty_input_returns_empty():
    # An empty string should return an empty string.
    assert fix_imports_inside_blocks("") == ""  # 5.38μs -> 771ns (598% faster)


def test_preserve_inner_brace_whitespace_for_named_imports():
    # Named imports with extra intra-brace whitespace should preserve that whitespace.
    src = "  import {  a ,  b  } from 'mod';\n"
    out = fix_imports_inside_blocks(src)  # 11.6μs -> 4.15μs (180% faster)
    # The original whitespace inside the braces must be preserved after conversion.
    assert "  const {  a ,  b  } = require('mod');\n" in out


def test_import_with_no_semicolon_and_extra_spaces():
    # The substitution always adds a semicolon; handle imports without semicolons.
    src = "function f() {\n    import foo from 'bar'\n}\n"
    out = fix_imports_inside_blocks(src)  # 12.2μs -> 4.39μs (179% faster)
    # Expect semicolon added in output, preserving indentation.
    assert "    const foo = require('bar');\n" in out


def test_none_input_raises_type_error():
    # Passing None should raise a TypeError because the function expects a string.
    with pytest.raises(TypeError):
        fix_imports_inside_blocks(None)  # 6.16μs -> 3.22μs (91.6% faster)


def test_large_scale_many_imports():
    # Batch 1: Small set of default imports inside a describe block
    src1 = (
        "describe('batch1', function() {\n"
        "    import mod1 from 'lib1';\n"
        "    import mod2 from 'lib2';\n"
        "    import mod3 from 'lib3';\n"
        "});\n"
    )
    out1 = fix_imports_inside_blocks(src1)  # 18.1μs -> 7.34μs (146% faster)
    assert "    const mod1 = require('lib1');\n" in out1
    assert "    const mod2 = require('lib2');\n" in out1
    assert "    const mod3 = require('lib3');\n" in out1  # 11.1μs -> 4.50μs (148% faster)

    # Batch 2: Named imports with varying brace spacing inside arrow functions
    src2 = (
        "it('batch2', () => {\n"
        "  import {x} from 'a';\n"
        "  import { y, z } from 'b';\n"
        "  import {  a , b , c  } from 'c';\n"
        "});\n"
    )
    out2 = fix_imports_inside_blocks(src2)
    assert "  const {x} = require('a');\n" in out2  # 11.1μs -> 4.36μs (154% faster)
    assert "  const { y, z } = require('b');\n" in out2
    assert "  const {  a , b , c  } = require('c');\n" in out2

    # Batch 3: Namespace imports with mixed indentation (spaces and tabs)
    src3 = (
        "beforeEach(() => {\n"
        "\timport * as ns1 from 'ns1';\n"
        "        import * as ns2 from 'ns2';\n"
        "  import * as ns3 from 'ns3';\n"
        "});\n"
    )  # 5.04μs -> 1.19μs (323% faster)
    out3 = fix_imports_inside_blocks(src3)
    assert "\tconst ns1 = require('ns1');\n" in out3
    assert "        const ns2 = require('ns2');\n" in out3  # 13.2μs -> 5.05μs (161% faster)
    assert "  const ns3 = require('ns3');\n" in out3

    # Batch 4: Top-level imports that should remain unchanged
    src4 = "import top1 from 'top1';\nimport {x, y} from 'top2';\nimport * as topns from 'topns';\n"
    out4 = fix_imports_inside_blocks(src4)  # 12.4μs -> 4.53μs (173% faster)
    assert "import top1 from 'top1';\n" in out4
    assert "import {x, y} from 'top2';\n" in out4
    assert "import * as topns from 'topns';\n" in out4  # 11.9μs -> 3.98μs (198% faster)

    # Batch 5: Complex nested structure with imports in multiple contexts
    src5 = (
        "describe('outer', () => {\n"
        "  import {util} from 'utils';\n"
        "  test('inner', () => {\n"
        "    import lib from 'libname';\n"
        "    const value = 42;\n"
        "  });\n"
        "  import top_nested from 'topmod';\n"
        "});\n"
    )
    out5 = fix_imports_inside_blocks(src5)
    assert "  const {util} = require('utils');\n" in out5  # 8.88μs -> 2.77μs (221% faster)
    assert "    const lib = require('libname');\n" in out5
    assert "  import top_nested from 'topmod';\n" in out5

    # Batch 6: Imports with single and double quotes
    src6 = (
        "function mixed() {\n"
        "  import a from 'single';\n"
        '  import b from "double";\n'
        "  import {c} from 'single2';\n"
        '  import {d} from "double2";\n'
        "}\n"
    )
    out6 = fix_imports_inside_blocks(src6)
    assert "  const a = require('single');\n" in out6
    assert "  const b = require('double');\n" in out6  # 103μs -> 38.9μs (165% faster)
    assert "  const {c} = require('single2');\n" in out6
    assert "  const {d} = require('double2');\n" in out6

    # Batch 7: Imports with and without semicolons
    src7 = (
        "afterEach(function() {\n"
        "    import x from 'a';\n"
        "    import y from 'b'\n"
        "    import {z} from 'c';\n"
        "    import {w} from 'd'\n"
        "});\n"
    )
    out7 = fix_imports_inside_blocks(src7)  # 12.3μs -> 4.57μs (170% faster)
    assert "    const x = require('a');\n" in out7
    assert "    const y = require('b');\n" in out7
    assert "    const {z} = require('c');\n" in out7
    assert "    const {w} = require('d');\n" in out7

    # Batch 8: String literals containing import statements (should NOT be converted)
    src8 = (
        "describe('strings', () => {\n"
        "  const code1 = \"    import fake from 'nope'\";\n"
        "  const code2 = '    import also_fake from \\'nope\\'';\n"
        "  import real from 'yes';\n"
        "});\n"
    )
    out8 = fix_imports_inside_blocks(src8)
    assert "import fake from 'nope'" in out8  # still in string, not converted
    assert "import also_fake from" in out8  # still in string, not converted
    assert "  import real from 'yes';\n" in out8  # top-level in describe should remain

    # Batch 9: Large number of similar imports (100+ items in one structure)
    batch9_lines = ["function bigBatch() {\n"]
    for i in range(50):
        batch9_lines.append(f"    import item{i} from 'pkg{i}';\n")
    batch9_lines.append("}\n")
    src9 = "".join(batch9_lines)
    out9 = fix_imports_inside_blocks(src9)
    for i in range(50):
        assert f"    const item{i} = require('pkg{i}');\n" in out9

    # Batch 10: Mixed patterns with code between imports
    src10 = (
        "test('interleaved', () => {\n"
        "  import first from 'f';\n"
        "  let x = 1;\n"
        "  import {second} from 's';\n"
        "  x = x + 2;\n"
        "  import * as third from 't';\n"
        "  return x;\n"
        "});\n"
    )
    out10 = fix_imports_inside_blocks(src10)
    assert "  const first = require('f');\n" in out10
    assert "  const {second} = require('s');\n" in out10
    assert "  const third = require('t');\n" in out10
    assert "  let x = 1;\n" in out10
    assert "  x = x + 2;\n" in out10
# function to test
from codeflash.languages.javascript.edit_tests import fix_imports_inside_blocks


def test_default_import_indented_single_quotes():
    """Test conversion of indented default import with single quotes."""
    source = "    import x from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.1μs -> 3.85μs (189% faster)
    expected = "    const x = require('module');"
    assert result == expected


def test_default_import_indented_double_quotes():
    """Test conversion of indented default import with double quotes."""
    source = '    import x from "module";'
    result = fix_imports_inside_blocks(source)  # 11.2μs -> 3.72μs (202% faster)
    expected = "    const x = require('module');"
    assert result == expected


def test_named_import_indented_single_quotes():
    """Test conversion of indented named import with single quotes."""
    source = "    import { a, b } from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.4μs -> 3.88μs (194% faster)
    expected = "    const { a, b } = require('module');"
    assert result == expected


def test_named_import_indented_double_quotes():
    """Test conversion of indented named import with double quotes."""
    source = '    import { a, b } from "module";'
    result = fix_imports_inside_blocks(source)  # 11.4μs -> 3.82μs (199% faster)
    expected = "    const { a, b } = require('module');"
    assert result == expected


def test_namespace_import_indented_single_quotes():
    """Test conversion of indented namespace import with single quotes."""
    source = "    import * as mod from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.3μs -> 4.06μs (179% faster)
    expected = "    const mod = require('module');"
    assert result == expected


def test_namespace_import_indented_double_quotes():
    """Test conversion of indented namespace import with double quotes."""
    source = '    import * as mod from "module";'
    result = fix_imports_inside_blocks(source)  # 11.3μs -> 3.91μs (188% faster)
    expected = "    const mod = require('module');"
    assert result == expected


def test_top_level_import_unchanged():
    """Test that top-level (non-indented) imports are NOT converted."""
    source = "import x from 'module';"
    result = fix_imports_inside_blocks(source)  # 6.74μs -> 1.64μs (310% faster)
    # Should remain unchanged because it's not indented
    assert result == source


def test_top_level_named_import_unchanged():
    """Test that top-level named imports are NOT converted."""
    source = "import { a, b } from 'module';"
    result = fix_imports_inside_blocks(source)  # 7.06μs -> 1.60μs (341% faster)
    assert result == source


def test_multiple_indented_imports():
    """Test conversion of multiple indented imports in sequence."""
    source = """function test() {
    import x from 'module1';
    import y from 'module2';
}"""
    result = fix_imports_inside_blocks(source)  # 15.3μs -> 6.26μs (144% faster)
    expected = """function test() {
    const x = require('module1');
    const y = require('module2');
}"""
    assert result == expected


def test_mixed_top_level_and_indented():
    """Test that only indented imports are converted when mixed with top-level."""
    source = """import a from 'top-level';
function test() {
    import b from 'inside';
}"""
    result = fix_imports_inside_blocks(source)  # 13.0μs -> 4.42μs (195% faster)
    expected = """import a from 'top-level';
function test() {
    const b = require('inside');
}"""
    assert result == expected


def test_tab_indentation():
    """Test conversion works with tab indentation."""
    source = "\timport x from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.0μs -> 3.73μs (194% faster)
    expected = "\tconst x = require('module');"
    assert result == expected


def test_multiple_spaces_indentation():
    """Test conversion works with various space indentations."""
    source = "        import x from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.4μs -> 3.64μs (213% faster)
    expected = "        const x = require('module');"
    assert result == expected


def test_jest_mock_callback():
    """Test typical jest.mock() callback scenario."""
    source = """jest.mock('module', () => {
    import helper from 'helper-module';
    return { test: helper };
});"""
    result = fix_imports_inside_blocks(source)  # 13.8μs -> 5.25μs (163% faster)
    expected = """jest.mock('module', () => {
    const helper = require('helper-module');
    return { test: helper };
});"""
    assert result == expected


def test_describe_block_with_import():
    """Test import inside describe block."""
    source = """describe('test', () => {
    import setup from 'setup-module';
});"""
    result = fix_imports_inside_blocks(source)  # 12.2μs -> 4.39μs (179% faster)
    expected = """describe('test', () => {
    const setup = require('setup-module');
});"""
    assert result == expected


def test_empty_string():
    """Test with empty input string."""
    source = ""
    result = fix_imports_inside_blocks(source)  # 5.39μs -> 741ns (627% faster)
    assert result == ""


def test_no_imports():
    """Test string with no imports."""
    source = "const x = 5;\nconst y = 10;"
    result = fix_imports_inside_blocks(source)  # 6.83μs -> 1.71μs (299% faster)
    assert result == source


def test_import_without_semicolon():
    """Test indented import without trailing semicolon."""
    source = "    import x from 'module'"
    result = fix_imports_inside_blocks(source)  # 11.2μs -> 3.95μs (184% faster)
    expected = "    const x = require('module');"
    assert result == expected


def test_named_import_single_member():
    """Test named import with single member."""
    source = "    import { a } from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.3μs -> 4.02μs (180% faster)
    expected = "    const { a } = require('module');"
    assert result == expected


def test_named_import_many_members():
    """Test named import with many members."""
    source = "    import { a, b, c, d, e, f } from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.5μs -> 4.00μs (188% faster)
    expected = "    const { a, b, c, d, e, f } = require('module');"
    assert result == expected


def test_named_import_with_spaces():
    """Test named import with various spacing."""
    source = "    import {   a  ,  b  } from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.5μs -> 3.80μs (204% faster)
    expected = "    const {   a  ,  b  } = require('module');"
    assert result == expected


def test_module_path_with_slash():
    """Test import with module path containing slashes."""
    source = "    import x from '@org/module/sub';"
    result = fix_imports_inside_blocks(source)  # 11.4μs -> 3.79μs (201% faster)
    expected = "    const x = require('@org/module/sub');"
    assert result == expected


def test_module_path_with_dot():
    """Test import with relative module path."""
    source = "    import x from '../lib/module';"
    result = fix_imports_inside_blocks(source)  # 11.2μs -> 3.69μs (202% faster)
    expected = "    const x = require('../lib/module');"
    assert result == expected


def test_module_path_with_dot_dot_slash():
    """Test import with parent directory relative path."""
    source = "    import x from '../../module';"
    result = fix_imports_inside_blocks(source)  # 11.1μs -> 3.67μs (204% faster)
    expected = "    const x = require('../../module');"
    assert result == expected


def test_scoped_package_name():
    """Test import from scoped npm package."""
    source = "    import x from '@babel/core';"
    result = fix_imports_inside_blocks(source)  # 11.1μs -> 3.77μs (194% faster)
    expected = "    const x = require('@babel/core');"
    assert result == expected


def test_import_variable_name_underscore():
    """Test import with variable name containing underscore."""
    source = "    import my_var from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.1μs -> 3.74μs (198% faster)
    expected = "    const my_var = require('module');"
    assert result == expected


def test_import_variable_name_camelcase():
    """Test import with camelCase variable name."""
    source = "    import myVar from 'module';"
    result = fix_imports_inside_blocks(source)  # 10.8μs -> 3.68μs (195% faster)
    expected = "    const myVar = require('module');"
    assert result == expected


def test_nested_function_with_import():
    """Test import inside nested function."""
    source = """function outer() {
    function inner() {
        import x from 'module';
    }
}"""
    result = fix_imports_inside_blocks(source)  # 13.8μs -> 4.97μs (178% faster)
    expected = """function outer() {
    function inner() {
        const x = require('module');
    }
}"""
    assert result == expected


def test_deeply_nested_import():
    """Test import with deep indentation (nested blocks)."""
    source = "                import x from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.5μs -> 3.73μs (209% faster)
    expected = "                const x = require('module');"
    assert result == expected


def test_tabs_and_spaces_mixed():
    """Test import with mixed tabs and spaces."""
    source = "\t    import x from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.0μs -> 3.65μs (201% faster)
    expected = "\t    const x = require('module');"
    assert result == expected


def test_multiline_code_block():
    """Test multiple imports in a complex code block."""
    source = """if (condition) {
    import a from 'module1';
    let x = 5;
    import { b, c } from 'module2';
    import * as utils from 'utils';
}"""
    result = fix_imports_inside_blocks(source)  # 19.7μs -> 8.33μs (137% faster)
    expected = """if (condition) {
    const a = require('module1');
    let x = 5;
    const { b, c } = require('module2');
    const utils = require('utils');
}"""
    assert result == expected


def test_import_with_extra_whitespace_before_semicolon():
    """Test import with whitespace before semicolon."""
    source = "    import x from 'module'   ;"
    result = fix_imports_inside_blocks(source)  # 8.80μs -> 3.22μs (174% faster)
    expected = "    const x = require('module');"
    assert result == expected


def test_import_module_name_numbers():
    """Test import from module with numbers in name."""
    source = "    import x from 'module123';"
    result = fix_imports_inside_blocks(source)  # 11.4μs -> 3.75μs (205% faster)
    expected = "    const x = require('module123');"
    assert result == expected


def test_import_module_name_dashes():
    """Test import from module with dashes in name."""
    source = "    import x from 'my-module-name';"
    result = fix_imports_inside_blocks(source)  # 11.0μs -> 3.63μs (204% faster)
    expected = "    const x = require('my-module-name');"
    assert result == expected


def test_import_single_char_variable():
    """Test import with single character variable name."""
    source = "    import x from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.0μs -> 3.53μs (212% faster)
    expected = "    const x = require('module');"
    assert result == expected


def test_import_numeric_start_not_matched():
    """Test that imports with invalid variable names are not matched."""
    source = "    import 1var from 'module';"
    result = fix_imports_inside_blocks(source)  # 11.1μs -> 3.64μs (205% faster)
    # Should not be converted as 1var is not a valid identifier
    assert result == source


def test_array_destructure_not_confused():
    """Test that array destructuring is not confused with imports."""
    source = "    const [a, b] = require('module');"
    result = fix_imports_inside_blocks(source)  # 7.44μs -> 1.98μs (275% faster)
    assert result == source


def test_comment_above_import():
    """Test import with comment above it."""
    source = """    // This is a comment
    import x from 'module';"""
    result = fix_imports_inside_blocks(source)  # 12.4μs -> 4.45μs (179% faster)
    expected = """    // This is a comment
    const x = require('module');"""
    assert result == expected


def test_multiple_consecutive_imports():
    """Test multiple consecutive indented imports."""
    source = """    import a from 'a';
    import b from 'b';
    import c from 'c';"""
    result = fix_imports_inside_blocks(source)  # 15.7μs -> 6.31μs (149% faster)
    expected = """    const a = require('a');
    const b = require('b');
    const c = require('c');"""
    assert result == expected


def test_import_no_indent_not_converted():
    """Test that imports without indentation are preserved."""
    source = "import x from 'module';"
    result = fix_imports_inside_blocks(source)  # 6.78μs -> 1.56μs (334% faster)
    assert result == source


def test_import_with_line_following():
    """Test import with code on following line."""
    source = """    import x from 'module';
    console.log(x);"""
    result = fix_imports_inside_blocks(source)  # 12.3μs -> 4.54μs (170% faster)
    expected = """    const x = require('module');
    console.log(x);"""
    assert result == expected


def test_return_type_is_string():
    """Test that return type is string."""
    source = "    import x from 'module';"
    result = fix_imports_inside_blocks(source)  # 10.9μs -> 3.53μs (209% faster)
    assert isinstance(result, str)


def test_hundred_imports():
    """Test conversion of 100 indented imports with varied paths."""
    source_lines = []
    paths = [
        "react",
        "@babel/core",
        "lodash",
        "./utils",
        "../helpers",
        "@org/pkg1",
        "very-long-package-name",
        "pkg-with-many-dots.util",
        "./src/helpers/module",
        "@types/node",
        "custom-lib-v2",
        "framework/core",
        "plugin.system",
        "@company/internal-lib",
    ]

    var_names = [
        "React",
        "babel",
        "lodash",
        "utils",
        "helpers",
        "orgPkg",
        "pkgName",
        "dotUtils",
        "moduleHelper",
        "types",
        "customLib",
        "frameworkCore",
        "pluginSystem",
        "internalLib",
    ]

    for i in range(100):
        path = paths[i % len(paths)]
        var_name = var_names[i % len(var_names)]
        if i < 50:
            source_lines.append(f"    import {var_name + str(i)} from '{path + str(i % 5)}';")
        elif i < 75:
            mods = ", ".join([var_name + "_" + str(j) for j in range(3)])
            source_lines.append("    import {{ {} }} from '{}';".format(mods, path + "_ns_" + str(i)))
        else:
            source_lines.append(
                "    import * as {} from '{}';".format(var_name + "_all_" + str(i), path + "_all_" + str(i))
            )

    source = "\n".join(source_lines)
    result = fix_imports_inside_blocks(source)  # 270μs -> 99.3μs (172% faster)
    assert "import " not in result or "import(" in result
    assert result.count("const") == 100
    assert result.count("require") == 100


def test_large_mixed_code():
    """Test processing large file with mixed code and imports using varied patterns."""
    source_lines = []

    patterns = [
        ("default", "import x from '{}'"),
        ("named", "import {{ a, b }} from '{}'"),
        ("namespace", "import * as ns from '{}'"),
        ("default", "import libCore from '@lib/core'"),
        ("named", "import {{ setup, teardown }} from '@test/helpers'"),
    ]

    modules = [
        "pkg1",
        "pkg2",
        "@org/module",
        "./local",
        "../parent",
        "@babel/parser",
        "lodash",
        "react-dom",
        "@types/jest",
        "webpack",
        "typescript",
        "eslint",
        "prettier",
    ]

    for i in range(50):
        source_lines.append(f"function func{i}() {{")
        pattern_idx = i % len(patterns)
        module_idx = i % len(modules)

        if pattern_idx == 0:
            source_lines.append(f"    import lib{i} from '{modules[module_idx]}';")
        elif pattern_idx == 1:
            source_lines.append(f"    import {{ fn{i}_a, fn{i}_b }} from '{modules[module_idx]}';")
        elif pattern_idx == 2:
            source_lines.append(f"    import * as m{i} from '{modules[module_idx]}';")
        elif pattern_idx == 3:
            source_lines.append(f"    import core{i} from '@lib/core';")
        else:
            source_lines.append(f"    import {{ setup{i}, teardown{i} }} from '@test/helpers';")

        source_lines.append("    let result = {};")
        source_lines.append("}")

    source = "\n".join(source_lines)
    result = fix_imports_inside_blocks(source)  # 196μs -> 73.0μs (169% faster)
    assert result.count("const") == 50
    assert result.count("require") == 50
    assert "const lib" in result or "const m" in result or "const setup" in result or "const core" in result


def test_deeply_nested_structure():
    """Test with moderately nested structure (50 levels) using varied code."""
    source_lines = []
    indent_level = 0

    for i in range(50):
        indent = "  " * indent_level
        if i % 4 == 0:
            source_lines.append(indent + f"if (condition{i}) {{")
        elif i % 4 == 1:
            source_lines.append(indent + "while (active) {")
        elif i % 4 == 2:
            source_lines.append(indent + "for (let j = 0; j < n; j++) {")
        else:
            source_lines.append(indent + f"function handler{i}() {{")

        indent_level += 1

    indent = "  " * indent_level
    source_lines.append(indent + "import x from 'module';")
    source_lines.append(indent + "import {{ a, b }} from 'utils';")

    for i in range(50):
        indent_level -= 1
        indent = "  " * indent_level
        source_lines.append(indent + "}")

    source = "\n".join(source_lines)
    result = fix_imports_inside_blocks(source)  # 329μs -> 108μs (204% faster)
    assert "const x = require('module');" in result
    assert "const { a, b } = require('utils');" in result
    assert "import x from 'module';" not in result


def test_many_different_import_types():
    """Test with many imports of different types using diverse patterns."""
    source_lines = []

    module_templates = [
        "package{i}",
        "@org/module{i}",
        "@babel/plugin-{i}",
        "./src/lib/util{i}",
        "../helpers/mod{i}",
        "@types/node{i}",
        "framework-{i}",
        "@company/internal-{i}",
    ]

    var_templates = ["lib{i}", "pkg{i}", "util{i}", "helper{i}", "core{i}", "system{i}", "engine{i}"]

    for i in range(100):
        template_idx = i % len(module_templates)
        var_template_idx = i % len(var_templates)
        module_name = module_templates[template_idx].format(i=i)
        var_name = var_templates[var_template_idx].format(i=i)

        if i % 3 == 0:
            source_lines.append(f"    import {var_name} from '{module_name}';")
        elif i % 3 == 1:
            deps = ", ".join([var_name + "_a", var_name + "_b", var_name + "_c"])
            source_lines.append(f"    import {{ {deps} }} from '{module_name}';")
        else:
            source_lines.append(f"    import * as {var_name} from '{module_name}';")

    source = "\n".join(source_lines)
    result = fix_imports_inside_blocks(source)  # 265μs -> 94.6μs (181% faster)
    assert "import " not in result or "import(" in result
    assert result.count("const") == 100


def test_large_string_with_many_require_calls():
    """Test processing large source with existing require calls mixed in using varied code."""
    source_lines = []

    import_modules = [
        "react",
        "lodash",
        "@babel/core",
        "./utils",
        "../helpers",
        "webpack",
        "typescript",
        "@org/pkg",
        "custom-lib",
        "@types/node",
    ]

    total_imports = 0
    for i in range(200):
        if i % 2 == 0:
            module = import_modules[i % len(import_modules)]
            if i % 10 < 5:
                source_lines.append(f"    import x{i} from '{module + str(i)}';")
                total_imports += 1
            else:
                source_lines.append(f"    import {{ a{i}, b{i} }} from '{module + str(i)}';")
                total_imports += 1
        else:
            require_modules = ["lodash", "path", "fs", "@lib/core", "custom-util"]
            module = require_modules[i % len(require_modules)]
            source_lines.append(f"    const y{i} = require('{module + str(i)}');")

    source = "\n".join(source_lines)
    result = fix_imports_inside_blocks(source)  # 342μs -> 128μs (167% faster)
    assert result.count("const") == 200
    assert result.count("require") == 200


def test_realistic_jest_mock_file():
    """Test realistic jest mock file with varied mock patterns and imports."""
    source_lines = ["import globalSetup from 'setup';", ""]

    mock_types = [
        ("helper", "helper_util"),
        ("utils", "common_utils"),
        ("service", "api_service"),
        ("config", "test_config"),
        ("mock", "mock_factory"),
    ]

    for i in range(50):
        mock_type, mock_subtype = mock_types[i % len(mock_types)]
        source_lines.append(f"jest.mock('module{i}', () => {{")

        if i % 3 == 0:
            source_lines.append(f"    import {mock_type + str(i)} from '{mock_subtype}_{i}';")
            source_lines.append(f"    import {{ fn, setup }} from 'utils_{i}';")
        elif i % 3 == 1:
            source_lines.append(f"    import * as {mock_type} from '{i}_namespace';")
            source_lines.append(f"    import {{ config }} from 'config_{i}';")
        else:
            source_lines.append(f"    import lib from '@lib/core_{i}';")
            source_lines.append(f"    import {{ a, b, c }} from 'multi_import_{i}';")

        source_lines.append("    return { " + mock_type + ": helper };")
        source_lines.append("});")
        source_lines.append("")

    source = "\n".join(source_lines)
    result = fix_imports_inside_blocks(source)  # 344μs -> 124μs (178% faster)
    assert source_lines[0] in result
    assert result.count("const") >= 100


def test_performance_many_close_imports():
    """Test performance with many consecutive imports using varied patterns."""
    source_lines = []

    patterns = [
        "    import lib from 'module';",
        "    import {{ a, b, c }} from 'package';",
        "    import * as ns from 'namespace';",
        "    import helper from '@lib/helper';",
        "    import {{ fn }} from '@utils/core';",
    ]

    for i in range(500):
        source_lines.append(
            patterns[i % len(patterns)]
            .replace("module", "module" + str(i))
            .replace("package", "pkg" + str(i))
            .replace("namespace", "ns" + str(i))
        )

    source = "\n".join(source_lines)
    result = fix_imports_inside_blocks(source)  # 924μs -> 375μs (146% faster)
    assert result.count("const") == 500
    assert "import " not in result or "import(" in result


def test_large_module_path():
    """Test with very long module paths."""
    long_path = "very/long/path/" * 50 + "module"
    source = f"    import x from '{long_path}';"
    result = fix_imports_inside_blocks(source)  # 31.6μs -> 10.5μs (202% faster)
    expected = f"    const x = require('{long_path}');"
    assert result == expected


def test_many_named_imports_single_line():
    """Test single line with many named imports using diverse names."""
    names_list = [
        "fn1",
        "fn2",
        "helper",
        "setup",
        "teardown",
        "init",
        "cleanup",
        "configure",
        "validate",
        "process",
        "transform",
        "parse",
        "stringify",
        "encode",
        "decode",
        "serialize",
        "deserialize",
        "map",
        "filter",
        "reduce",
    ]

    names = ", ".join(names_list * 5)[:1500]
    source = f"    import {{ {names} }} from 'module';"
    result = fix_imports_inside_blocks(source)  # 25.4μs -> 4.32μs (489% faster)
    expected = f"    const {{ {names} }} = require('module');"
    assert result == expected

To edit these changes git checkout codeflash/optimize-pr1901-2026-03-25T17.27.15 and push.

Codeflash Static Badge

The optimization consolidated three separate regex substitutions into a single combined pattern with a callback function, reducing the number of full-string scans from three to one. The original code applied `_INDENTED_DEFAULT_IMPORT_RE.sub()`, then `_INDENTED_NAMED_IMPORT_RE.sub()`, then `_INDENTED_NAMESPACE_IMPORT_RE.sub()` in sequence, each traversing the entire input string. The optimized version uses one alternation-based regex (`_COMBINED_IMPORT_RE`) that matches all three import types in a single pass, delegating replacement logic to `_replace_import()` which branches on which capture groups are populated. Line profiler shows the hot loop (the three consecutive `.sub()` calls accounting for 100% of original runtime) is now a single `.sub()` call, cutting per-iteration cost from ~81 µs to ~28 µs across typical inputs. No correctness or metric regressions observed.
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Mar 25, 2026
@claude
Copy link
Contributor

claude bot commented Mar 25, 2026

Claude finished @codeflash-ai[bot]'s task in 3m 18s —— View job


PR Review Summary

  • Triage PR — SMALL (1 file, 38 additions / 6 deletions, all production code)
  • Lint and typecheck — fixed issues, pushed
  • Resolve stale threads — none found
  • Review diff
  • Duplicate detection
  • Summary comment
  • Handle other open optimization PRs

Prek Checks

Prek passed. Mypy found 3 errors (2 × no-redef for duplicate function, 1 × missing re.Match type parameter) — fixed and pushed.

Code Review

Bug fixed (auto-corrected): The optimization PR introduced _replace_import twice — an exact duplicate of the function at the end of the file. In Python the second definition silently overwrites the first (so behavior is correct), but mypy flags it as [no-redef]. Removed the duplicate and fixed re.Matchre.Match[str] to match the codebase convention (see languages/javascript/instrument.py:1127).

Optimization correctness: The consolidation of three sequential regex passes (_INDENTED_DEFAULT_IMPORT_RE, _INDENTED_NAMED_IMPORT_RE, _INDENTED_NAMESPACE_IMPORT_RE) into a single alternation-based _COMBINED_IMPORT_RE is semantically correct. The callback _replace_import correctly branches on which capture groups are populated, and the group indices match the regex structure. The re.MULTILINE flag is preserved. The 171% speedup claim is plausible — replacing 3 full-string scans with 1 is a well-known optimization.

No other issues — no security concerns, no breaking API changes, no accidental file inclusions.

Duplicate Detection

No duplicates detected. The new _replace_import helper is only used locally within edit_tests.py.

Other Open Optimization PRs


@mohammedahmed18 mohammedahmed18 merged commit 7b12f5f into cf-fix-imports-inside-blocks Mar 25, 2026
25 of 27 checks passed
@mohammedahmed18 mohammedahmed18 deleted the codeflash/optimize-pr1901-2026-03-25T17.27.15 branch March 25, 2026 17:52
claude bot pushed a commit that referenced this pull request Mar 25, 2026
The optimization PR #1903 replaced the three individual regex patterns with
_COMBINED_IMPORT_RE, but left the originals in place. Remove the dead code.

Co-authored-by: mohammed ahmed <undefined@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant