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

Add Fix for #1202 remove unused include #1227

Merged
merged 8 commits into from
Feb 28, 2022
Merged

Conversation

rahulraina7
Copy link
Contributor

Adds code action to remove unused fixes / include

  1. Send additional diagnostics to push data back to code actions.
  2. Update tests.

Fixes #1202 .

Copy link
Member

@robertoaloi robertoaloi left a comment

Choose a reason for hiding this comment

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

Hi @rahulraina7! This looks great. I believe the only thing missing is to go through the ensure_range function like in the other code actions. Other than that, LGTM!

els_compiler_diagnostics:inclusion_range(Path, Document, include_lib) of
[Range|_] ->
case els_range:inclusion_range(Uri, Document) of
{ok, Range} ->
Range;
_ ->
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Since this has been refactored (nice!), this pattern can be restricted to error.

[ {"function (.*) is unused", fun action_export_function/3}
, {"variable '(.*)' is unused", fun action_ignore_variable/3}
, {"variable '(.*)' is unbound", fun action_suggest_variable/3}
[ {"function (.*) is unused", fun action_export_function/4}
Copy link
Member

Choose a reason for hiding this comment

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

Good that we are now passing the optional data field to the specific functions. It could be a nice way to exchange information. Later on (no need to do it as part of this PR), we could always ensure there's data in a diagnostic when constructing one. We may also want to use a map instead of a binary and base64 encode it to ensure it can be passed around between client and server. See the els_utils:base64_encode_term/1 function and its usages for Call Hierarchy. Again, this is more of a mental note and can be done as a separate task.

-spec action_remove_unused(uri(), range(), binary(), [binary()]) -> [map()].
action_remove_unused(Uri, _Range0, Data, [Var]) ->
{ok, Document} = els_utils:lookup_document(Uri),
case els_range:inclusion_range(Data, Document) of
Copy link
Member

Choose a reason for hiding this comment

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

I suspect we still need to go through the ensure_range function like in the other cases, to avoid situations where the file changed in the meantime, causing text edits not to be applicable any longer. @plux we probably need to figure out a better way to handle this, since this step can easily be missed. Maybe have a synchronization point before applying edits?

Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of using POIs we could store the text that the diagnostic refers to and simply check that the document text in the range that the diagnostic points to is the same. Does that make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@robertoaloi Isn't inclusion_range essentially doing the same thing instead of using POI's its using text from Diagnostics to find a range. I can't directly reuse ensure_range since it wont work for this use-case specifically this line Id =:= SubjectAtom , I can either make another similar function ensure_range_imports which will have the same idea as this one, if it makes sense ?

Copy link
Member

Choose a reason for hiding this comment

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

To me we have two options:

  1. Add a clause to the ensure_range which doesn't perform the conversion to atoms
  2. Probably cleaner, what @plux suggested: store the text that the diagnostic refers to on construction and then check here that this is still a valid "selection".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry I may be missing something.
els_range:inclusion_range looks like this.

inclusion_range(Uri, Document) ->
  Path = binary_to_list(els_uri:path(Uri)),
  case
    els_compiler_diagnostics:inclusion_range(Path, Document, include) ++
    els_compiler_diagnostics:inclusion_range(Path, Document, include_lib) of
    [Range|_] ->
      {ok, Range};
    [] ->
      error
  end.

els_compiler_diagnostics:inclusion_range Looks like this

inclusion_range(IncludePath, Document, include) ->
  POIs       = els_dt_document:pois(Document, [include]),
  IncludeId  = els_utils:include_id(IncludePath),
  [Range || #{id := Id, range := Range} <- POIs, Id =:= IncludeId];

This is what we want right ?

Copy link
Member

Choose a reason for hiding this comment

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

I think you have a point. The major difference (compared to the other code actions) is that we ignore the range returned by the diagnostic and we just fetch it directly from the updated list of POIs. In the other cases we would check whether the range from the updated list of POIs would fit inside the same line of the one reported by the diagnostic (prior versions of Erlang didn't have column numbers in diagnostics). In practice I'm not sure this matters much for unused includes. I am ok to merge this one as-is and to eventually rethink this "checking" strategy, either by taking @plux's approach or by versioning the version of the text.

@robertoaloi robertoaloi merged commit 126c4da into erlang-ls:main Feb 28, 2022
@robertoaloi
Copy link
Member

Thanks!

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.

Add Code Action / Quick Fix to remove unused include
3 participants