Skip to content

Complete functions from included module #7515

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

Merged
merged 22 commits into from
May 29, 2025

Conversation

nojaf
Copy link
Collaborator

@nojaf nojaf commented May 24, 2025

I noticed that when using include Foo({}), you don't receive completions for anything taken from Foo. This PR addresses that issue.

@zth I'm also adding the cmt viewer since I needed to verify whether the CMT contained all the necessary information. I believe it's great to have this in the master branch already.

@nojaf nojaf requested a review from zth May 24, 2025 10:20
Copy link

pkg-pr-new bot commented May 24, 2025

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript-lang/rescript@7515

@rescript/darwin-arm64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-arm64@7515

@rescript/darwin-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-x64@7515

@rescript/linux-arm64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-arm64@7515

@rescript/linux-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-x64@7515

@rescript/win32-x64

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/win32-x64@7515

commit: 1518f6d

@zth
Copy link
Collaborator

zth commented May 24, 2025

Hmm, are include Foo(...) maybe just not picked up when processing the cmt file? Could you check that? ProcessCmt.ml and ProcessExtra.ml IIRC.

@nojaf
Copy link
Collaborator Author

nojaf commented May 24, 2025

Nope, cmt wise they are there. I checked that with the viewer.

@nojaf
Copy link
Collaborator Author

nojaf commented May 24, 2025

@zth, did some more digging, this really is a scope issue.
Cmt has the right info, the frontend just needs to indicate a module is in scope, somewhat similar to how an open has different meaning.

@zth
Copy link
Collaborator

zth commented May 24, 2025

@zth, did some more digging, this really is a scope issue. Cmt has the right info, the frontend just needs to indicate a module is in scope, somewhat similar to how an open has different meaning.

Nice! Yeah something like open sounds reasonable.

| `Ok (ident, path) -> ident.name :: path |> String.concat "."
in

if String.ends_with ~suffix:includePath source_module_path then
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'm not sure how we could entirely match this.
When the scope is created in the CompletionFrontEnd we doesn't know the exact that.

Copy link
Collaborator Author

@nojaf nojaf left a comment

Choose a reason for hiding this comment

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

@zth ready for review!

@zth
Copy link
Collaborator

zth commented May 26, 2025

@nojaf coming up soon!

@zth zth requested a review from cristianoc May 27, 2025 10:34
@zth
Copy link
Collaborator

zth commented May 27, 2025

I think this looks good, but @cristianoc I think we need your eyes here as well, to check the approach.

@@ -1,6 +1,20 @@
open SharedTypes

let modulePathFromEnv env = env.QueryEnv.file.moduleName :: List.rev env.pathRev
let modulePathFromEnv env =
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is an orthogonal change just for namespaces right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, exactly, when testing this on my local project (which has a namespace), I needed this.

@nojaf nojaf requested a review from cristianoc May 28, 2025 07:58
// ^com
]
}
}
Copy link
Collaborator

@cristianoc cristianoc May 28, 2025

Choose a reason for hiding this comment

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

One distinction between open and include is that only include supports the following:

module M = {
  let x = 3
}

module N = { include M }

let q = N.x

I think it already works (on functors), completing a module N from the outside, so it should just be a matter of adding to the tests.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can that be something for a follow up PR? It is outside of my scope, and thus matters less to me. The PR right now would be a huge win to have.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it already works (on functors), just needs to extend the test a bit.

|> Hashtbl.iter (fun (name, _) (declared : Types.type_expr Declared.t) ->
(* We check all the values if their origin is the same as the include path. *)
match declared.modulePath with
| ModulePath.ExportedModule {name = exportedName}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@cristianoc, this part was a bit weird.
When I have only:

module M = {
  let lex = (a: int) => "foo"
}

module N = {
  include M

  let a = 4
  // let o = a.l
  //            ^com

  // let _ = l
  //          ^com
}

in the test file, it it not needed.

Having the entire tests/analysis_tests/tests/src/IncludeModuleCompletion.res made the match ModulePath.ExportedModule case necessary.
I can't explain this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's indeed almost unexplainable.
Turns out that when the value table is populated, each value declared in env is processed, and the pair (name, position) updated in the table.
Included values exist alongside the original values. So there are two values lex: one from M with module path ExportedModule, and one from include M with module path IncludedModule.
The last second one processed overwrites the first one.
And the order seems kind of arbitrary and changes with small changes to the source file.

Interestingly, when including values from other files, since we use the pair (name, position), there could be accidental clash in the position, which is just a pair of numbers.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@nojaf if included values go to a separate table in LocalTables.ml, is it going to work? Or is there a need for them to be in the value table?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Wow, that is an interesting find. Would have never figured that one out, thanks!
I've added a check not to override under very specific conditions.
@cristianoc is this the way to go here?

Copy link
Collaborator

@cristianoc cristianoc May 29, 2025

Choose a reason for hiding this comment

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

In fact, they could just be a list, as the location and name are never used, except the name for filtering at the end?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

A separate table could work, so a new one based on ModulePath.IncludedModule _?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@cristianoc a separate table works fine.

@nojaf nojaf requested a review from cristianoc May 29, 2025 10:13
@nojaf nojaf requested a review from cristianoc May 29, 2025 16:29
Copy link
Collaborator

@cristianoc cristianoc left a comment

Choose a reason for hiding this comment

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

Good to go I think when CI is green!

@nojaf nojaf merged commit 352fa02 into rescript-lang:master May 29, 2025
16 checks passed
@nojaf
Copy link
Collaborator Author

nojaf commented May 29, 2025

Thanks a lot for your help @cristianoc !

@cristianoc
Copy link
Collaborator

Thanks a lot for your help @cristianoc !

Thank you!

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