Skip to content

workspace/symbol returns duplicate results (Nx per symbol) from iterating all entry points sharing the same root #679

Description

@chuonglm2012

Title: workspace/symbol returns duplicate results (N× per symbol) due to iterating all entry points sharing the same root

Labels: bug


Setup

  • odoo-ls version: 1.5.1
  • Config: odoo_path = sources/, addons_paths = [overlay/community, overlay/enterprise, overlay/custom], plus workspaceFolders = [extra-addons] sent in initialize

Describe the bug

workspace/symbol returns each logical symbol exactly 5 times — identical name, kind, containerName, and location.uri. For symbols with multiple distinct definitions (e.g. _compute_qc_result has 5 implementations across different models), the response contains 25 entries (5 distinct × 5 duplicates each).

textDocument/documentSymbol (document outline) returns the canonical single copy — the duplication is workspace-level only.

Root cause

In workspace_symbols.rs, get_workspace_symbols iterates all entry points:

for entry in ep_mgr.borrow().iter_all() {
    if entry.borrow().typ == EntryPointType::BUILTIN
        || entry.borrow().typ == EntryPointType::PUBLIC {
        continue;
    }
    WorkspaceSymbolFeature::browse_symbol(
        session, &entry.borrow().root, &query, ...
    );
}

The issue is that iter_all() returns 5 separate entry points that all share the same root symbol:

# Type Path Origin
1 MAIN sources/ set_main_entry (odoo_path)
2 ADDON sources/addons/ Auto-discovered odoo_path + "/addons" (odoo.rs ~L505)
3 ADDON overlay/community addons_paths[0] (odoo.rs ~L518)
4 ADDON overlay/enterprise addons_paths[1]
5 ADDON overlay/custom addons_paths[2]

All ADDON entry points set entry.root = related.root (entry_point.rs ~L160), meaning they share the MAIN entry point's root. browse_symbol then performs a full tree traversal for each entry point, yielding identical results N times.

Possible fixes

  1. Dedup entry points by root before iterating in get_workspace_symbols — skip entry points whose root Rc pointer equals one already visited (preferred: avoids redundant traversal).
  2. Dedup results after collection using a composite key (name, location.uri, containerName).

Reproduction

Any setup with odoo_path + multiple addons_paths where odoo_path/addons also exists on disk (standard Odoo layouts). Minimum config:

[[config]]
name = "test"
odoo_path = "/path/to/sources"
addons_paths = ["/path/to/overlay/community", "/path/to/overlay/custom"]

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions