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

Scala 3 type completion #4174

Merged
merged 17 commits into from
Aug 1, 2022
Merged

Conversation

vzmerr
Copy link
Collaborator

@vzmerr vzmerr commented Jul 20, 2022

it partially resolves #3954
it partially resolves #3956

  • filtering out invalid trait, object, class, import, or apply method completions according to position for scala 3.
  • adding square bracket suffix where relevant for type, new, and instantiation completions, for scala 3.
  • adding curly brace suffix in new completions of trait, abstract, java interface types for scala 3.
  • applying filtering without enriching with symbols on the interpolate completions

Not covered in the PR:

scalameta/metals-feature-requests#292

  • member completion for Scala 3 as in:
object A {
  new scala.Iterable@@
}

Covering it requires covering the case for CompletionKind.Members in enrichWithSymbolSearch and filtering out the non-members, in a similar way to the postProcess method in CompletionApplication.

@vzmerr vzmerr marked this pull request as draft July 20, 2022 14:19
@vzmerr vzmerr force-pushed the scala-3-type-completion branch 2 times, most recently from a104745 to 8afd9b9 Compare July 21, 2022 17:13
@vzmerr
Copy link
Collaborator Author

vzmerr commented Jul 26, 2022

help needed on detecting the existing type parameter in the following code:
def foo ArrayBuffer@@[Int] = ???
I have tried printing different members of the symbol, including its paramSymss; as well as printing the Tree path. But I could not get to detecting the existing type parameter.

@vzmerr vzmerr force-pushed the scala-3-type-completion branch 3 times, most recently from 0dc2199 to bf7da78 Compare July 26, 2022 11:58
@vzmerr vzmerr marked this pull request as ready for review July 26, 2022 11:59
@vzmerr vzmerr force-pushed the scala-3-type-completion branch 2 times, most recently from f762df5 to 2804d6b Compare July 26, 2022 13:33
Copy link
Contributor

@tgodzik tgodzik left a comment

Choose a reason for hiding this comment

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

Thanks for working on this! I left a lot of comments, but almost all of them are minor. I think the PR improves things a lot.

end match
else ""

val bracketSuffix =
Copy link
Member

@tanishiking tanishiking Jul 27, 2022

Choose a reason for hiding this comment

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

I think it's still needed. Currently we never put multiple suffixes with $0 at the same time.

However, it's extremely difficult for me to understand there won't be multiple $0 because each of them is not explicitly separated by if/else if/else. We (Metals developers in the future) have to read all of the code around here to check all those conditions won't be all true in any cases, to prevent Metals from putting multiple braces. That leads to the code being error-prone.

@tanishiking
Copy link
Member

Is this ready for review? Please let me know when it's ready by re-request review :)

Copy link
Member

@tanishiking tanishiking left a comment

Choose a reason for hiding this comment

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

I left some comments, but most of them are about refactoring.

Comment on lines 200 to 202
&& (symbol.toString.startsWith(
"trait"
) // trait A{ def doSomething: Int}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
&& (symbol.toString.startsWith(
"trait"
) // trait A{ def doSomething: Int}
&& (symbol.is(Trait)) // trait A{ def doSomething: Int}

can you explain which test will fail? I think it shouldn't be flaky (if it is, it's a compiler bug and we should report it)

Copy link
Member

Choose a reason for hiding this comment

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

(sorry for duplicated comment, but I want to discuss this in another thread)

Copy link
Collaborator Author

@vzmerr vzmerr Jul 28, 2022

Choose a reason for hiding this comment

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

oh, I would mention the test case. Generally the flags are flaky. I have it on my todo list to put the issue on dotty and add the link in here. As an example, checking the is(Trait) flag on some cases was retuning false, while calling it on .info.typeSymbol. was returning true. We discussed it with Vadim on Metals team Slack, but certainly it has to get formally documented somewhere.

Copy link
Collaborator Author

@vzmerr vzmerr Jul 29, 2022

Choose a reason for hiding this comment

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

this was the type5 test in CompletionSnippetSuite that used to fail before but now passes. So I reverted to using flags 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Update: the reason the demo was failing was the use of Flags.Trait instead of toString.startsWith("trait ")
Now that I reverted to using toString, the demo works correctly. I am now scratching my head.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was thinking about that. But it is actually coming from scala.collection.mutable

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I wonder how I can add a test that fails with Flags.Trait and why type5 is now passing regardless.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It turned out that it was Intellisense that was messing up with things.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I created this Issue in Dotty to explain the problem scala/scala3#15790

Copy link
Member

Choose a reason for hiding this comment

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

Thank you for taking a look!
Let's go with the current implementation, and we can refactor later 👍

@tanishiking
Copy link
Member

I'm still wondering why we can't use Trait flag https://github.com/scalameta/metals/pull/4174/files#r932450969, and I left some comments about refactoring but otherwise it looks good to me, this is great improvement! ❤️

@vzmerr vzmerr requested a review from tanishiking July 29, 2022 09:26
Copy link
Contributor

@tgodzik tgodzik left a comment

Choose a reason for hiding this comment

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

LGTM from my side! Just one comment.

Copy link
Member

@kpodsiad kpodsiad left a comment

Choose a reason for hiding this comment

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

I wonder, can code from Completions.scala be extracted to object TypeCompletions.scala?

@vzmerr
Copy link
Collaborator Author

vzmerr commented Jul 29, 2022

Update

There seems to be a Dotty bug which causes the requiredPackage in toSymbols method of CompilerSearchVisitor to drop java from java.io and turn it into just object io
But types such as java.io.StringBufferInputStream must be specified with their package, or they won't be recognised by the compiler.
I am not familiar with the exact purpose of the toSymbols method though. Help would be appreciated.

This bug is causing the StringBufferInputStream to be suggested as a completion to StringBuffe@@ without any clue for the user about the package it can be found in.

Also, technically speaking, I do not understand the exact purpose of the toSymbols method there. We are feeding it java.io which is the correct package. and also StringBufferInputStream. Then the method just messes it up and erases the package information in producing the symbol. What's the purpose of that?

I can fix it in this PR or I can put it in a followup?

@dos65 Hey Vadim, can you please a take a look here?

Update

Oh, sorry, adding a test in CompletionSuite showed that the package information was not removed from the symbol.

Currently, due to this exception, the completions also crash and do not show up properly in demo.

Copy link
Member

@tanishiking tanishiking left a comment

Choose a reason for hiding this comment

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

Looks like unit tests are failing, but it's LGTM:+1: thank you so much for working on this!

Also, technically speaking, I do not understand the exact purpose of the toSymbols method there. We are feeding it java.io which is the correct package. and also StringBufferInputStream. Then the method just messes it up and erases the package information in producing the symbol. What's the purpose of that?
I can fix it in this PR or I can put it in a followup?

Thank you for finding the issue! You can create an issue and work on that in a follow-up 👍


For what it's worth, in my opinion, if I were you, I will make a PR as small as possible and try to do one thing in one PR.
For example

  • You're doing 4 things in this PR (as you explained in the PR description)
    • Instead, you might be able to create a PR for each thing.
    • (Of course, you can do more than one thing if it's comfortable for you, or if the changes are an atomic changes).
    • If you do multiple things in one PR
      • PR will be bigger, if PR is bigger, it takes more time to merge the PR in general 😭
      • it makes it harder for reviews to review the diff because reviews can't tell which parts of diff are for which purpose.
        • If you want to do more than one thing, it would be good if you can explicitly separate the commits, Add better Scala CLI support #3790 is a good example. This PR is doing two things, but he did those things in a different commit. Therefore we could (relatively) easily review the change (even though it's gigantic).
  • toSymbols issue is somehow related to this change, but is it necessary to fix in this PR?
    • if it's trivial, we can fix it immediately, but if it may take some efforts (or requires some investigations), I would recommend you to do it in a separate follow-up PR 👍
    • I mentioned something around Flags.Trait, but I didn't mean "you have to fix the problem right now, otherwise you can't merge it" (sorry if you felt pressured 🙇). You can open an issue (as you did 👍 ) and follow-up it later :)

@vzmerr
Copy link
Collaborator Author

vzmerr commented Aug 1, 2022

Looks like unit tests are failing, but it's LGTM👍 thank you so much for working on this!

Also, technically speaking, I do not understand the exact purpose of the toSymbols method there. We are feeding it java.io which is the correct package. and also StringBufferInputStream. Then the method just messes it up and erases the package information in producing the symbol. What's the purpose of that?
I can fix it in this PR or I can put it in a followup?

Thank you for finding the issue! You can create an issue and work on that in a follow-up 👍

For what it's worth, in my opinion, if I were you, I will make a PR as small as possible and try to do one thing in one PR. For example

  • You're doing 4 things in this PR (as you explained in the PR description)

    • Instead, you might be able to create a PR for each thing.

    • (Of course, you can do more than one thing if it's comfortable for you, or if the changes are an atomic changes).

    • If you do multiple things in one PR

      • PR will be bigger, if PR is bigger, it takes more time to merge the PR in general 😭

      • it makes it harder for reviews to review the diff because reviews can't tell which parts of diff are for which purpose.

        • If you want to do more than one thing, it would be good if you can explicitly separate the commits, Add better Scala CLI support #3790 is a good example. This PR is doing two things, but he did those things in a different commit. Therefore we could (relatively) easily review the change (even though it's gigantic).
  • toSymbols issue is somehow related to this change, but is it necessary to fix in this PR?

    • if it's trivial, we can fix it immediately, but if it may take some efforts (or requires some investigations), I would recommend you to do it in a separate follow-up PR 👍
    • I mentioned something around Flags.Trait, but I didn't mean "you have to fix the problem right now, otherwise you can't merge it" (sorry if you felt pressured 🙇). You can open an issue (as you did 👍 ) and follow-up it later :)

Thank you so much for taking the time to write this detailed feedback 👍
I would just be fixing the tests and pushing.

vzmerr and others added 16 commits August 1, 2022 10:59
…ompletions according to position for scala 3.

adding square bracket suffix where relevant for type, new, and instantiation completions, for scala 3.
adding curly brace suffix in new completions of trait, abstract, java interface types for scala 3.
adjust CompletionInterpolatorSuite and CompletionWorkspaceSuite
Co-authored-by: Tomasz Godzik <tgodzik@users.noreply.github.com>
Co-authored-by: Kamil Podsiadło <37124721+kpodsiad@users.noreply.github.com>
correct detection of traits
@tanishiking tanishiking merged commit 36b68ec into scalameta:main Aug 1, 2022
tanishiking added a commit to tanishiking/metals that referenced this pull request Aug 9, 2022
tanishiking added a commit that referenced this pull request Aug 9, 2022
* Revert "Add more test cases for package completions and fix issues"

This reverts commit c328f09.

* Revert "bugfix: Show package completions"

This reverts commit 417eebc.

* Revert "Scala 3 type completion (#4174)"

This reverts commit 36b68ec.
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.

[Scala 3] Add type completions [Scala 3] Add new completions
4 participants