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

feat: Import missing extension method #4141

Merged
merged 5 commits into from
Jul 20, 2022

Conversation

tanishiking
Copy link
Member

@tanishiking tanishiking commented Jul 12, 2022

refer scalameta/metals-feature-requests#141

This PR enables Metals to auto-import missing extension method from the workspace (it doesn't support import from third-party libraries).

extension-import

This is done by

  • Index extension methods by ScalaToplevelMtags
  • Show AutoImport code action for value xxx is not a member of yyy.

What I didn't in this PR

  • Auto import given instances
  • Auto import implicit classes
  • completion for extension method and auto-import
    • I'll open an feature-request-issue

@tanishiking tanishiking changed the title feat: Import missing extension method [WIP] feat: Import missing extension method Jul 14, 2022
@tanishiking
Copy link
Member Author

tanishiking commented Jul 14, 2022

Realized it doesn't work with toplevel extensions fixed

@tanishiking tanishiking changed the title [WIP] feat: Import missing extension method feat: Import missing extension method Jul 14, 2022
@@ -142,7 +142,7 @@ trait MtagsIndexer {
definition: m.Position,
kind: s.SymbolInformation.Kind,
properties: Int
): Unit = {
): String = {
Copy link
Member Author

Choose a reason for hiding this comment

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

I changed addSignature to return the added symbol so we can use those symbols as a next owner.

@@ -415,6 +460,7 @@ object ScalaToplevelMtags {
def owner: String
def acceptMembers: Boolean
def produceSourceToplevel: Boolean
def isExtension: Boolean = false
Copy link
Member Author

@tanishiking tanishiking Jul 14, 2022

Choose a reason for hiding this comment

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

  • Added isExntension flag to ExpectTemplate (and Region).
  • if ExpectTemplate.isExtension is true on newline or lbrace, as needsToParseExtension says, enter to new Region where extension is true.
  • In those regions, we will index the symbol of DEFs.

@tanishiking tanishiking requested review from dos65 and tgodzik and removed request for dos65 July 14, 2022 10:52
@tanishiking
Copy link
Member Author

Now, ready for review 👍

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.

Looks good! TopLevels should also be run on dependency sources, so we should suggest extension methods from dependencies also not only from the workspace.

path,
s"""|package x
|def main =
| println(1.<<incr>>)
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we maybe add it to the code actions Scala 3 suite? Or at least it would be nice to see the code action applied to test if it works correctly

Copy link
Member Author

Choose a reason for hiding this comment

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

Tested check edit 6d49fb9 👍

@tanishiking
Copy link
Member Author

TopLevels should also be run on dependency sources, so we should suggest extension methods from dependencies also not only from the workspace.

@tgodzik
Year, it would be awesome to have! Could you give me some pointers on where to code, and where we're testing them? I'm unfamiliar with those areas. FYI @dos65

@tanishiking tanishiking requested a review from tgodzik July 19, 2022 08:26
@dos65
Copy link
Member

dos65 commented Jul 19, 2022

@tanishiking I took a look at TopLevelSuite. It requires some work to make it work for Scala3 .At least, I see that BaseExpectSuite should be parametrized by an input - currently it uses only scala2 input classpath.
I think, it should be ok not to touch this suite in this PR.

@tgodzik
Copy link
Contributor

tgodzik commented Jul 19, 2022

TopLevels should also be run on dependency sources, so we should suggest extension methods from dependencies also not only from the workspace.

@tgodzik Year, it would be awesome to have! Could you give me some pointers on where to code, and where we're testing them? I'm unfamiliar with those areas. FYI @dos65

Wait, don't we already do it? We should be caching toplevels in ScalaToplevelMtags.scala, so esentially extension methods should currently work from dependencies in this PR, or did I totally forget something? Wait, we are talking just about tests, aren't we? 😅

@tanishiking
Copy link
Member Author

Wait, we are talking just about tests, aren't we? 😅

Ahhh, I just mistook Toplevels for something like JarToplevelMtags (whatever), but you meant TopLevelSuite.

So, you mean TopLevelSuite (or maybe another suite that extends BaseExpectSuite) should generate expect files by indexing the symbols using PackageIndex against third-party libraries such as scala-library to verify there's no regression in dependencies symbol indexing?


While @dos65 talks about TopLevelSuite to work on Scala3.
However, it looks like TopLevelSuite already works against Scala3.

In TopSevelSuite,
forInput(..., Scala213) runs Mtags.toplevelsagainsttests/input/src/main/scala/example/*.scala andforInput(..., Scala3) runs Mtags.toplevels against tests/input2/src/main/scala/example/*.scala.
ToplevelSuite concat the result of both Scala213 and Scala3 and then write it to toplevel.expect file.

forInput(InputProperties.scala2(), Scala213)
forInput(InputProperties.scala3(), Scala3)

@dos65
Copy link
Member

dos65 commented Jul 20, 2022

While @dos65 talks about TopLevelSuite to work on Scala3.
However, it looks like TopLevelSuite already works against Scala3.

There is suspicious clause and comment but I'm not sure how it affects this test.

// do not check symtab for Scala 3 since it's not possible currently
if (symtab.info(toplevel).isEmpty && dialect != Scala3) {

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.

Added super minor comments, which we can fix later on. LGTM! Great feature to have, we can comment on the issue to document what is added and what still needs to be done.

Co-authored-by: Tomasz Godzik <tgodzik@users.noreply.github.com>
@tanishiking
Copy link
Member Author

tanishiking commented Jul 20, 2022

There is suspicious clause and comment but I'm not sure how it affects this test.

Hmm, right I'll take a look in another PR 👀

@tanishiking tanishiking merged commit 29176c4 into scalameta:main Jul 20, 2022
@tanishiking tanishiking deleted the import-extension branch July 20, 2022 15:12
tanishiking added a commit to tanishiking/metals that referenced this pull request Aug 26, 2022
close scalameta#4212

In scalameta#4141 we started indexing the
extension methods (for auto-import missing extension methods) in
`workspaceSymbolIndex` where we should index only top-level symbols.

Later in scalameta#4183 we decided to index
those extension method symbols in a separate index
(see more details around here: scalameta#4183 (review)).

This PR refactor import missing extension method to use
the index only for extension method symbols.

This change slightly improve the performance of symbol search
and reduce the memory footprint for symbol index.
tanishiking added a commit that referenced this pull request Aug 26, 2022
close #4212

In #4141 we started indexing the
extension methods (for auto-import missing extension methods) in
`workspaceSymbolIndex` where we should index only top-level symbols.

Later in #4183 we decided to index
those extension method symbols in a separate index
(see more details around here: #4183 (review)).

This PR refactor import missing extension method to use
the index only for extension method symbols.

This change slightly improve the performance of symbol search
and reduce the memory footprint for symbol index.
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.

3 participants