Skip to content

Add type annotation to convertStoredPropertyToComputed#2496

Open
Padmashree06 wants to merge 3 commits intoswiftlang:mainfrom
Padmashree06:add-convertStoredPropertyTocComputed
Open

Add type annotation to convertStoredPropertyToComputed#2496
Padmashree06 wants to merge 3 commits intoswiftlang:mainfrom
Padmashree06:add-convertStoredPropertyTocComputed

Conversation

@Padmashree06
Copy link
Copy Markdown

Issue: #2459

This PR implements the ConvertStoredPropertyToComputed refactoring in SourceKit-LSP, adopting the new API recently merged in swift-syntax (#3249).

Summary

It integrates cursorInfo into the SyntaxCodeActionScope, allowing the refactoring to resolve types for inferred properties (e.g., let x = 5) by extracting the semantic type from SourceKit's annotated declaration.

Changes

  • Updated SyntaxCodeActionScope to include [CursorInfo]
  • Updated the code action request handler to:
    • Perform a cursorInfo request
    • Add the result to SyntaxCodeActionScope
  • Added ConvertStoredPropertyToComputed to allSyntaxCodeActionProviders in SyntaxCodeActions.swift

Implementation Details

Implemented SyntaxCodeActionProvider for ConvertStoredPropertyToComputed which:

  1. Attempts to resolve the property type via cursorInfo
  2. Falls back to explicit type annotations if semantic info is unavailable
  3. Passes the resolved type to the refactoring context

Copy link
Copy Markdown
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

A few preliminary review comments before I dive deeper into the implementation.

}

private static func extractType(from annotatedDecl: String) -> String? {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Superfluous newline

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thank you for the feedback! I'll remove the unnecessary lines.

import SwiftSyntaxBuilder

extension ConvertStoredPropertyToComputed: SyntaxCodeActionProvider {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Superfluous newline

self.snapshot = snapshot
self.request = request
self.file = file
self.cursorInfo = cursorInfo
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don’t think we set cursorInfo anywhere, do we? Also, we should implement this in a way where the cursor info is only retrieved when it’s actually needed by a refactoring action instead of being set for every syntactic refactoring action.

Copy link
Copy Markdown
Author

@Padmashree06 Padmashree06 Feb 27, 2026

Choose a reason for hiding this comment

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

Thank you for pointing that out!

You’re right, I missed that cursorInfo is not being initialized anywhere. Triggering a cursorInfo request for every syntactic refactoring would indeed be unnecessary overhead.

I’ll remove cursorInfo from SyntaxCodeActionScope. Instead, I’ll first perform a syntactic check to determine whether the type information is missing. Only if semantic resolution is actually required for the refactoring will I trigger a cursorInfo request within the refactoring operation itself, using SwiftLanguageService.cursorInfo.

Please let me know if this approach aligns with your expectations or if there’s anything else I should consider.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, that’s a lot better now with the asynchronous command and it’s the approach I would have preferred until a few weeks ago but now we have codeAction/resolve, which is designed for exactly this workflow. Could you adopt it?


private static func extractType(from annotatedDecl: String) -> String? {

guard let start = annotatedDecl.range(of: "<type>"),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Instead of parsing the annotated description, we should use the typename key.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes thank you! I'll use typename key instead!

@ahoppen
Copy link
Copy Markdown
Member

ahoppen commented Feb 28, 2026

If you have addressed my comments, it seems like you haven’t pushed your latest changes.

@Padmashree06
Copy link
Copy Markdown
Author

I haven’t pushed the changes yet. I was waiting for confirmation before doing so. I’ll push them shortly.

@Padmashree06 Padmashree06 force-pushed the add-convertStoredPropertyTocComputed branch from b80521f to 1ef63e7 Compare March 18, 2026 08:46
@Padmashree06
Copy link
Copy Markdown
Author

@ahoppen I’ve updated the implementation based on your feedback.

  • Cursor info is now fetched only when the type is not explicitly declared.
  • When a type annotation is present, the refactoring is applied inline.
  • Otherwise, the semantic.refactor.convertStoredPropertyToComputed command is executed to retrieve cursor info, infer the type semantically, and perform the conversion to a computed property.
  • I’ve added corresponding CodeAction tests for both cases.

kind: .refactorInline,
command: Command(
title: "Convert Stored Property to Computed Property",
command: "semantic.refactor.convertStoredPropertyToComputed",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Instead of implementing a custom command, do you think you could use the support for codeAction/resolve that @Tabonx added recently in #2549?

self.snapshot = snapshot
self.request = request
self.file = file
self.cursorInfo = cursorInfo
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, that’s a lot better now with the asynchronous command and it’s the approach I would have preferred until a few weeks ago but now we have codeAction/resolve, which is designed for exactly this workflow. Could you adopt it?

@Padmashree06
Copy link
Copy Markdown
Author

Yes, I will modify the implementation to use codeAction/resolve

@Padmashree06 Padmashree06 force-pushed the add-convertStoredPropertyTocComputed branch from 1ef63e7 to 5d2c8b2 Compare April 12, 2026 14:03
@Padmashree06
Copy link
Copy Markdown
Author

@ahoppen I've updated the implementation to use codeAction/resolve

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