Skip to content

Conversation

@madushajg
Copy link
Member

@madushajg madushajg commented Nov 19, 2025

Purpose

Improve the auto-reveal behavior to precisely highlight the corresponding item in the tree view based on the user’s navigation in the active webview.
Addresses: wso2/product-ballerina-integrator#1947

Screen.Recording.2025-11-19.at.20.48.26.mov

Summary by CodeRabbit

  • Improvements
    • Enhanced project explorer synchronization to track editor navigation more effectively
    • Improved tree view refresh handling for more responsive updates
    • Refined file path resolution in workspace context

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

Walkthrough

The changes implement a cross-extension communication mechanism that enables the Ballerina state machine to notify the BI project explorer of view and position changes. This is accomplished through a new command NOTIFY_PROJECT_EXPLORER that dispatches position-aware tree navigation updates, along with enhanced project explorer logic to match and reveal tree items based on document path and cursor position.

Changes

Cohort / File(s) Change Summary
Command Infrastructure
workspaces/ballerina/ballerina-core/src/interfaces/constants.ts
Added NOTIFY_PROJECT_EXPLORER command constant mapping to 'BI.project-explorer.notify' in BI_COMMANDS object.
State Machine Event Dispatch
workspaces/ballerina/ballerina-extension/src/stateMachine.ts
Extended imports to include BI_COMMANDS and NodePosition. Introduced notifyTreeView helper function (note: appears duplicated in file) to dispatch project explorer updates. Added calls to notifyTreeView across multiple state transitions (UPDATE_PROJECT_ROOT, OPEN_VIEW, VIEW_INIT/VIEW_UPDATE, extensionReady paths) to synchronize tree state.
Data Mapper Path Handling
workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/datamapper.ts
Implemented workspace-aware file path computation in generateContextTypesCore; derives relative targetFilePath from workspacePath and projectPath, then uses it in emitted code blocks instead of the original filePath.
Project Explorer Command Registration
workspaces/bi/bi-extension/src/project-explorer/activate.ts
Added imports for MACHINE_VIEW and NodePosition. Wired tree view into data provider via setTreeView(projectTree). Registered BI_COMMANDS.NOTIFY_PROJECT_EXPLORER command handler to forward position/view events to dataProvider.revealInTreeView(...).
Project Explorer Provider Enhancement
workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts
Extended imports to include MACHINE_VIEW and NodePosition. Added position property to ProjectExplorerEntry class. Introduced revealInTreeView public method with helper methods for path/position matching (findItemByPathAndPosition, searchChildrenByPathAndPosition, matchesPathAndPosition, positionsMatch). Added internal state fields (_treeView, _isRefreshing, _pendingRefresh) and setTreeView method for tree view lifecycle management. Updated refresh logic to handle concurrent refreshes with pending queue. Updated project data loading to deduplicate by projectPath.

Sequence Diagram(s)

sequenceDiagram
    participant SM as State Machine
    participant CMD as BI Command Bus
    participant ACT as Project Explorer<br/>Activate
    participant PROV as Project Explorer<br/>Provider
    participant TV as Tree View

    SM->>CMD: notifyTreeView()<br/>(NOTIFY_PROJECT_EXPLORER)
    CMD->>ACT: Command Handler
    ACT->>PROV: revealInTreeView(documentUri,<br/>projectPath,<br/>position, view)
    activate PROV
    PROV->>PROV: findItemByPathAndPosition()
    PROV->>PROV: matchesPathAndPosition()
    PROV->>TV: treeView.reveal(item)
    deactivate PROV
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring extra attention:

  • Duplicated notifyTreeView function: The summary indicates the function appears twice in stateMachine.ts; verify if this is intentional or a merge conflict oversight.
  • Concurrent refresh handling: Review the logic for _isRefreshing and _pendingRefresh flags in project-explorer-provider.ts to ensure no race conditions or state inconsistencies.
  • Position matching logic: The matchesPathAndPosition, searchChildrenByPathAndPosition, and positionsMatch methods implement path traversal and position comparison; verify correctness of the tree search and position matching strategies.
  • Project deduplication: Confirm that filtering projects by unique projectPath in getProjectStructureData doesn't inadvertently drop relevant tree nodes.

Possibly related PRs

Suggested reviewers

  • hevayo
  • gigara
  • kanushka

Poem

🐰 A command hops through the UI land,
Tree views dance to position's demand,
State and explorer now shake hands,
With paths and positions precisely planned,
Together they bloom—a synchronized band! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive The PR description covers Purpose and includes a video demonstration, but is missing several critical template sections required for comprehensive documentation. Add Goals, Approach, Release note, Documentation, Automation tests (unit/integration), Security checks, and Test environment sections to provide complete context for review and release planning.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: re-enabling auto-reveal functionality in the tree view based on active webview navigation.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a91be70 and c6058a5.

📒 Files selected for processing (5)
  • workspaces/ballerina/ballerina-core/src/interfaces/constants.ts (1 hunks)
  • workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/datamapper.ts (2 hunks)
  • workspaces/ballerina/ballerina-extension/src/stateMachine.ts (8 hunks)
  • workspaces/bi/bi-extension/src/project-explorer/activate.ts (3 hunks)
  • workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts (5 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: madushajg
Repo: wso2/vscode-extensions PR: 868
File: workspaces/bi/bi-extension/src/utils.ts:224-242
Timestamp: 2025-11-10T15:05:11.309Z
Learning: The workspaces/bi/bi-extension and workspaces/ballerina/ballerina-extension are separate VS Code extensions that are packaged and distributed independently, so they cannot share code via imports and must maintain their own implementations of common utilities.
📚 Learning: 2025-11-05T10:31:47.583Z
Learnt from: madushajg
Repo: wso2/vscode-extensions PR: 830
File: workspaces/ballerina/ballerina-extension/test/ai/post_proccess/post.test.ts:0-0
Timestamp: 2025-11-05T10:31:47.583Z
Learning: In the workspaces/ballerina/ballerina-extension project, the tsconfig.json uses "rootDirs": ["src", "test"], which allows test files to import from src using shorter relative paths. For example, from test/ai/post_proccess/, the import '../../stateMachine' correctly resolves to src/stateMachine.ts due to this configuration.

Applied to files:

  • workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/datamapper.ts
  • workspaces/ballerina/ballerina-extension/src/stateMachine.ts
  • workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts
📚 Learning: 2025-11-10T15:05:11.309Z
Learnt from: madushajg
Repo: wso2/vscode-extensions PR: 868
File: workspaces/bi/bi-extension/src/utils.ts:224-242
Timestamp: 2025-11-10T15:05:11.309Z
Learning: The workspaces/bi/bi-extension and workspaces/ballerina/ballerina-extension are separate VS Code extensions that are packaged and distributed independently, so they cannot share code via imports and must maintain their own implementations of common utilities.

Applied to files:

  • workspaces/bi/bi-extension/src/project-explorer/activate.ts
  • workspaces/ballerina/ballerina-extension/src/stateMachine.ts
  • workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts
📚 Learning: 2025-11-10T15:04:50.474Z
Learnt from: madushajg
Repo: wso2/vscode-extensions PR: 868
File: workspaces/bi/bi-extension/src/utils.ts:153-169
Timestamp: 2025-11-10T15:04:50.474Z
Learning: The workspaces/bi/bi-extension and workspaces/ballerina/ballerina-extension are separate, independently deployable VSCode extensions in the wso2/vscode-extensions repository. Code duplication between these extensions is acceptable and often necessary to maintain their independence, rather than creating cross-extension dependencies.

Applied to files:

  • workspaces/bi/bi-extension/src/project-explorer/activate.ts
  • workspaces/ballerina/ballerina-extension/src/stateMachine.ts
  • workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts
🧬 Code graph analysis (3)
workspaces/bi/bi-extension/src/project-explorer/activate.ts (2)
workspaces/ballerina/ballerina-core/src/interfaces/constants.ts (1)
  • BI_COMMANDS (31-57)
workspaces/ballerina/ballerina-core/src/interfaces/bi.ts (1)
  • NodePosition (23-23)
workspaces/ballerina/ballerina-extension/src/stateMachine.ts (2)
workspaces/ballerina/ballerina-core/src/interfaces/bi.ts (1)
  • NodePosition (23-23)
workspaces/ballerina/ballerina-core/src/interfaces/constants.ts (1)
  • BI_COMMANDS (31-57)
workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts (2)
workspaces/ballerina/ballerina-core/src/interfaces/bi.ts (1)
  • NodePosition (23-23)
workspaces/ballerina/ballerina-core/src/interfaces/constants.ts (1)
  • BI_COMMANDS (31-57)
🔇 Additional comments (23)
workspaces/ballerina/ballerina-extension/src/features/ai/service/datamapper/datamapper.ts (2)

828-828: LGTM! Correctly uses workspace-relative path.

The change to use targetFilePath ensures that generated code blocks reference the correct workspace-relative path, which aligns with the PR's objective to improve navigation and auto-reveal behavior in workspace projects.


803-822: The review comment's analysis is incorrect—the code patterns are not identical at all three locations.

Lines 354-361 and 675-682 are genuinely duplicated and could be refactored, but lines 803-822 implement fundamentally different logic:

  • Lines 354-361 & 675-682: Assume absoluteCustomFunctionsPath is already absolute; simply choose between workspace-relative or project-relative paths based on whether workspacePath exists.
  • Lines 803-822: Handle the case where filePath may be relative or absolute (using path.isAbsolute and path.join), requiring additional processing before computing the relative path.

The suggested refactoring conflates these different implementations and would lose functionality. While extracting logic from lines 354-361 and 675-682 is reasonable, including 803-822 in the same helper would be incorrect.

Likely an incorrect or invalid review comment.

workspaces/ballerina/ballerina-core/src/interfaces/constants.ts (1)

31-57: New BI command constant is consistent and well-scoped

NOTIFY_PROJECT_EXPLORER follows the existing BI command naming and namespace; no issues from a stability or API standpoint.

workspaces/ballerina/ballerina-extension/src/stateMachine.ts (8)

5-24: Core import changes look correct

Bringing in BI_COMMANDS, NodePosition and the state-machine utility helpers from @wso2/ballerina-core / local utils is consistent with how they’re used later in the file; no issues here.


111-121: UPDATE_PROJECT_ROOT now syncs tree view with project root

The added notifyTreeView call after buildProjectsStructure and notifyCurrentWebview ensures the explorer is updated when the project root changes, while still resolving the pending root-update promise. This is a sensible place to hook the notification and should be safe given the existing async flow.


161-175: UPDATE_PROJECT_LOCATION tree notification is aligned with context updates

You first assign the new documentUri / position (with sensible fallbacks) and then notify the tree with the effective values. This keeps the explorer in sync with location-only changes without altering the active view, which matches the intent of this transition.


178-221: Initial BI / non-BI flows now notify the tree correctly

The added assign actions plus notifyTreeView in both initialize.onDone branches correctly:

  • Capture isBI, projectPath, workspacePath, scope, org, package.
  • Emit a tree notification keyed by event.data.projectPath and the current view.

This should give the project explorer enough information to highlight the appropriate project root right after discovery.


296-325: extensionReady.OPEN_VIEW: good sequencing of context update and tree notification

Using an action array to:

  1. Assign all viewLocation fields into context, including projectPath.
  2. Then call notifyTreeView with the just-updated values,

keeps the tree, webview, and machine context aligned. This wiring looks correct.


381-432: viewReady transitions correctly drive tree auto‑reveal

Both OPEN_VIEW and VIEW_UPDATE now:

  • Rehydrate context from event.viewLocation (with appropriate fallbacks).
  • Immediately call notifyTreeView with the current project path, document URI, position, and view.

This ensures the explorer tracks navigation within an already-active view. The separation between OPEN_VIEW (full re-init) and VIEW_UPDATE (position-only change) reads clean and matches the state machine’s design.


471-473: Project info fetch now prefers workspacePath, avoiding multi-project ambiguity

Switching getProjectInfo to use context.workspacePath || context.projectPath should remove ambiguity in multi-project workspaces while still working for single-project cases. This is a straightforward and correct improvement.


1023-1035: notifyTreeView helper centralizes BI explorer notifications

Wrapping commands.executeCommand(BI_COMMANDS.NOTIFY_PROJECT_EXPLORER, …) in notifyTreeView keeps the various call sites concise and consistent; having the payload shape defined in one place makes future changes easier.

workspaces/bi/bi-extension/src/project-explorer/activate.ts (3)

18-18: Extended imports are consistent with new reveal behavior

Importing MACHINE_VIEW and NodePosition alongside the command constants matches their usage in the new command handler; no issues here.


39-43: Tree view reference is correctly wired into the data provider

Calling projectExplorerDataProvider.setTreeView(projectTree) right after creation gives the provider the tree handle needed for revealInTreeView without changing existing activation flow.


66-95: NOTIFY_PROJECT_EXPLORER command registration is correctly forwarded

Registering BI_COMMANDS.NOTIFY_PROJECT_EXPLORER and delegating to dataProvider.revealInTreeView(documentUri, projectPath, position, view) matches the payload emitted from the Ballerina state machine and keeps the reveal logic encapsulated in the provider. This wiring looks sound.

workspaces/bi/bi-extension/src/project-explorer/project-explorer-provider.ts (9)

22-32: Core imports align with new tree and position features

Pulling in DIRECTORY_MAP, project-structure types, VisualizerLocation, MACHINE_VIEW, and NodePosition is consistent with the new provider responsibilities and type usage; no concerns here.


44-61: Storing NodePosition on ProjectExplorerEntry is appropriate

Adding the position field and threading it through the constructor allows precise mapping from tree items back to source locations, which is exactly what auto-reveal needs. The defaulting and assignment are straightforward.


72-85: TreeView reference and refresh state flags are well-placed

The new _treeView, _isRefreshing, _pendingRefresh fields and setTreeView method give the provider enough internal state to:

  • Support reveal operations.
  • Manage concurrent refresh requests.

This is a good encapsulation of tree view concerns inside the provider.


86-122: Refresh re-entrancy and error handling improvements look solid

The updated refresh:

  • Coalesces overlapping refresh calls via _isRefreshing and _pendingRefresh.
  • Clears _data before repopulating and fires a change notification once.
  • Logs errors with a clear [ProjectExplorer] prefix and still restores a consistent empty state.
  • Executes any pending refresh after the current one finishes.

This should reduce flicker and redundant work without introducing recursion issues.


124-153: revealInTreeView entrypoint correctly coordinates path/position‑based reveal

The public revealInTreeView method:

  • Safely no-ops when the tree view hasn’t been set.
  • Prefers documentUri when present, otherwise falls back to projectPath when the view is not WorkspaceOverview.
  • Only reveals when a matching item is found, with select/focus/expand flags set.

This is a clean abstraction for external callers.


155-193: Recursive search helpers are structured clearly

findItemByPathAndPosition and searchChildrenByPathAndPosition walk the tree depth‑first, checking each node via a centralized matcher. The recursion and early returns are straightforward and should perform adequately for typical project sizes.


221-226: Position equality check is precise and appropriate

Comparing all four fields (startLine, startColumn, endLine, endColumn) for equality is a reasonable definition of “same node” in this context. If you later need fuzzy matching (e.g., line-only), it can be relaxed here without touching callers.


276-336: Project deduplication in getProjectStructureData avoids duplicate roots

Using a Map keyed by project.projectPath to build filteredProjects ensures that:

  • Each physical project path appears once in the tree.
  • isSingleProject is computed on the de‑duplicated list.

This should prevent duplicated roots when the state context includes repeated projects.


514-531: File entry construction now correctly carries positions into the tree

Passing comp.position into the ProjectExplorerEntry constructor wires AST positions from ProjectStructureArtifactResponse all the way into the tree, enabling accurate auto-reveal. The extra isCodicon argument (false) maintains previous icon behavior.

@madushajg madushajg changed the base branch from main to bi-1.5.x November 19, 2025 15:42
@kanushka kanushka merged commit 83593d2 into wso2:bi-1.5.x Nov 20, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants