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 CFR class file viewer #3247

Merged
merged 3 commits into from
Nov 8, 2021
Merged

Conversation

Arthurm1
Copy link
Contributor

Adds a class file decompiler to the list of source analysis tools

@s5bug put me onto this while discussing an issue with Scala 3. It was easier to understand what was going on than using javap so I thought it might help to integrate it into Metals

This includes a fix for using javap on java source files - it was looking in the wrong dir for the class file. I haven't added any Java tests to FileDecoderProviderLspSuite because I don't think didOpen triggers a java file compilation with Metals yet, so it won't compile a single Java file and therefore can't test the analysis of the output - or am I wrong?

Other options besides CFR are fernflower and procyon. I figure if CFR isn't good enough then users can raise issues and other decompilers can be added/substituted.

I imagine this will also be handy for implementing scalameta/metals-feature-requests#210

@ckipp01 Hopefully this is easy to add to VI. In the VSCode PR I've also setup the .cfr file extension to use Java textmate grammar. That's built into VSCode - hence I've just amended the language contribution point to use an additional extension.

License question: Do I have to include a reference to CFR in NOTICE.md? I've added a dependency on CFR but not included source code.

@Arthurm1
Copy link
Contributor Author

Timeout on DebugDiscoverySuite on Windows only - spurious I assume?

@s5bug
Copy link

s5bug commented Oct 31, 2021

FTR, the way I actually used CFR (I don't have it installed) is via http://www.javadecompilers.com/... This looks really helpful. How does one use it?

@Arthurm1
Copy link
Contributor Author

Arthurm1 commented Nov 1, 2021

I've added it into the "Metals Analyse Source" file context menu to go with the other file analysis tools.
It can be run on java, scala or class files. Or run the "Metals: Show decompiled with CFR" command on the current java/scala file

image

Copy link
Member

@dos65 dos65 left a comment

Choose a reason for hiding this comment

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

@Arthurm1 Thx for this new decoder!

Mostly looks good, I have a bit of minor comments/questions.

I haven't added any Java tests to FileDecoderProviderLspSuite because I don't think didOpen triggers a java file compilation with Metals yet, so it won't compile a single Java file and therefore can't test the analysis of the output - or am I wrong?

I've double-checked that - didOpen triggers compilation for java files.

@Arthurm1
Copy link
Contributor Author

Arthurm1 commented Nov 2, 2021

@dos65 I was looking in the wrong area for class files. I've now added tests for java files and for missing files leading to errors.

} catch {
case NonFatal(e) =>
scribe.error(e.toString())
Future.successful(DecoderResponse.failed(path.toURI, e))
}
}

private def decodeCFRFromClassFile(
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 run CFR using ShellRunner and download the dependency on demand? This would mean we wouldn't need to add the additional dependency to Metals.

I see there is a main that can be used https://github.com/leibnitz27/cfr/blob/9f5a97cf76d94d3ac695887abc6bbfb740c70a9c/src/org/benf/cfr/reader/Main.java

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could do. It's only 2MB but I guess it all adds up. Is there someplace where this is already done - where I can nick the code?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, it all adds up and especially if it's a tool used by more advanced developers this might not be needed to download at all

That should be for example in the NewProjectProvider, it uses gitter8 by downloading it and running with the current java home.

Copy link
Contributor

Choose a reason for hiding this comment

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

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 - ShellRunner#runJava made this very easy to change.

ckipp01 added a commit to ckipp01/nvim-metals that referenced this pull request Nov 2, 2021
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!

@tgodzik tgodzik merged commit a598c91 into scalameta:main Nov 8, 2021
ckipp01 added a commit to ckipp01/nvim-metals that referenced this pull request Nov 8, 2021
@Arthurm1 Arthurm1 deleted the class_file_viewer branch November 8, 2021 19:17
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