Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement basic semantic highlighting (method calls, local vars) #32

Merged
merged 10 commits into from Mar 31, 2022

Conversation

wildmaples
Copy link
Contributor

@wildmaples wildmaples commented Mar 30, 2022

Issue

Some of: https://github.com/Shopify/sorbet-issues/issues/518 (Add semantic highlighting)

Changes

  • Add semantic highlighting for local variables and methods - f call, v call and normal calls (see unit test cases for a better picture on what each of those calls are) ➡️ This is primarily @vinistock work 🙏 😄

  • Cover the case where a method call receiver is a variable (e.g. var = "yo"; var.upcase)

  • Modified tests to be more human readable - namely just putting the deltas in a hash with readable key, then translating them before asserting

  • Add error to ensure we don't get bitten by the same issue where children nodes were being added after the parents. Consider the following:

    "hello".upcase
    

    syntax_tree visits the call #upcase before the receiver "hello". However, we want to add "hello" before #upcase, which is the in-order traversal VSCode API requires. (I think that makes sense because that's how the code is presented in view.) If we add the call token before the receiver token, we would come up with the wrong delta calculations and we'd like to avoid that by raising an error.

Real time testing

I wrote a bit if people are curious how to test this in real time: https://github.com/Shopify/sorbet-issues/issues/518#issuecomment-1083391665

@wildmaples wildmaples self-assigned this Mar 30, 2022
@@ -77,13 +77,20 @@ def add_token(location, classification)
line = @parser.line_counts[location.start_line - 1]
column = location.start_char - line.start

if row < @current_row
raise InvalidTokenRowError, "Invalid token row detected: "\
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't add a test case for this because... this method is private, and well, it's a little hard to unit test this particular case.


def visit_assign(node)
case node.target
when SyntaxTree::ARefField
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not implement visit_a_ref_field and whatever the visit_ method correspond to the else branch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

✅ Done in 73d376f

private

def add_token(location, classification)
length = location.end_char - location.start_char
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we copy part of the explanation at https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens to explain what's going on here please? 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

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

✅ Added the comment in d22c414

I didn't add how each delta is calculated but I just linked the doc instead - is that okay?

lib/ruby_lsp/requests/semantic_highlighting.rb Outdated Show resolved Hide resolved
lib/ruby_lsp/requests/semantic_highlighting.rb Outdated Show resolved Hide resolved
Copy link
Member

@paracycle paracycle left a comment

Choose a reason for hiding this comment

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

Thanks!

@wildmaples
Copy link
Contributor Author

Thanks everyone for the review!

For full disclosure: in this current PR, instance variable reference and fields are both being counted as a local variable. We initially intended to try to fix it before merging. However, I did some digging to realize that it will be a larger change. It's because VarField and VarRef are both being counted as local variables but in reality the nodes could be the parent of a variety of other nodes aside from local variables, one of them being instance variables.

I chatted with @vinistock and we are ok with merging this for now and working on instance variables next. 👍

@wildmaples wildmaples merged commit 6e55ec1 into main Mar 31, 2022
@wildmaples wildmaples deleted the add_semantic_highlighting branch March 31, 2022 22:02
@shopify-shipit shopify-shipit bot temporarily deployed to production April 26, 2022 17:02 Inactive
bjarosze pushed a commit to bjarosze/ruby-lsp that referenced this pull request Mar 8, 2024
…lint-import-resolver-typescript-2.7.0

Bump eslint-import-resolver-typescript from 2.5.0 to 2.7.0
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.

None yet

4 participants