Skip to content

explore: TS/JS parser captures "import " inside any string as a bogus dependency #548

@justrach

Description

@justrach

Problem

parseTsLine (src/explore.zig:3932) decides a line is an import statement with:

if (containsAny(line, &.{ "import ", "require(" })) {

containsAny matches "import " anywhere on the line, not just at statement position. extractStringLiteral then returns the first quoted run and appendImportPath does no filtering — so any line whose string/comment merely contains "import " becomes a dependency edge. For example:

export const ERROR = 'failed to import the config module';

adds failed to import the config module to the dep graph (outline.imports).

#542 added a guard against exactly this for its new } from / export … from branch ("so arbitrary from \"...\" inside strings/comments is not mistaken for a dependency"), but the original single-line import /require( branch was never guarded.

Failing test (src/test_parser.zig)

test "issue-548: a string containing 'import ' is not captured as a dependency" {
    var arena = std.heap.ArenaAllocator.init(testing.allocator);
    defer arena.deinit();
    var explorer = Explorer.init(arena.allocator(), Explorer.DEFAULT_CONTENT_CACHE_CAPACITY);

    try explorer.indexFile("src/msg.ts", "export const ERROR = 'failed to import the config module';");
    var outline = (try explorer.getOutline("src/msg.ts", testing.allocator)) orelse return error.TestUnexpectedResult;
    defer outline.deinit();
    for (outline.imports.items) |imp| {
        try testing.expect(!std.mem.eql(u8, imp, "failed to import the config module"));
    }

    // Regression guard: a real single-line import is still captured.
    try explorer.indexFile("src/dep.ts", "import { real } from './real-dep.ts';");
    var outline2 = (try explorer.getOutline("src/dep.ts", testing.allocator)) orelse return error.TestUnexpectedResult;
    defer outline2.deinit();
    try expectOutlineImport(&outline2, "./real-dep.ts");
}

Fails on the current release tip (725/726, this test red): the bogus string is present in outline.imports.

Expected

Only actual import statements produce dependency edges. A string whose value merely contains "import " must not.

Fix

Match the import token at statement position — startsWith(line, "import ") (the line is already trimmed when parseTsLine runs) instead of containsAny(line, &.{"import "}); keep require( detection. (A similar guard for require( inside strings is lower priority.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:p2Medium priority

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions