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

Implement metrics for Java code #359

Closed
Luni-4 opened this issue Nov 16, 2020 · 19 comments · Fixed by #694 or #786
Closed

Implement metrics for Java code #359

Luni-4 opened this issue Nov 16, 2020 · 19 comments · Fixed by #694 or #786
Labels
good first issue Good for newcomers

Comments

@Luni-4
Copy link
Collaborator

Luni-4 commented Nov 16, 2020

Currently no metrics have been implemented for the Java code

@Luni-4 Luni-4 added enhancement New feature or request good first issue Good for newcomers labels Nov 16, 2020
@marco-c
Copy link
Collaborator

marco-c commented Nov 16, 2020

As part of fixing this, we can write some docs on how to add a new language.

@marco-c marco-c removed the enhancement New feature or request label Nov 16, 2020
@dburriss
Copy link
Contributor

I would like to pick this up but not too sure what it entails. I have been looking through the implementations and think I understand some of it. I have only been learning Rust for a few weeks so it might take a while but since this has been open for almost a year I imagine it is not urgent. Eventually, I would like to add Go and C# but it appears Java has some implementation already so I thought this would be a good place to start.

I could start with investigating the different elements that need implementing and documenting those if it does not exist already? This could for the basis of documentation mentioned.

@Luni-4
Copy link
Collaborator Author

Luni-4 commented Oct 12, 2021

Hello! Thanks for your help! :)

Well, for now Java has only some utilities functions, as you can see in the checker.rs file. I think your strategy is pretty good:

  1. Look for what we need to implement for Java or any other missing language you prefer.
    As an example, I'm showing you the Loc implementation for the Python language https://github.com/mozilla/rust-code-analysis/blob/master/src/metrics/loc.rs#L184
    We have used a trait because the Loc metric can be computed differently according to the chosen language.
    Instead here we have added a test to check if our implementation is correct.
  2. Pick up a metric (we can start with Loc) and construct a markdown file that explains how to implement that metric for a generic language. In this file, we also need to specify to add tests to verify our implementation
  3. Follow up the instructions contained in the markdown file and implement the metric

@dburriss
Copy link
Contributor

Entirely possible I am missing something here and this all exists but the metrics seem to rely on some sort of language grammar being generated?
This is done by adding the necessary tree_sitter lib to rust-code-analysis/tree/master/enums/src and adding it to the necessary language call and macro? This seems implemented for Java so not a big deal but I would like to circle around eventually and tackle Go (seems to be some mentions in the codebase) and C# (nothing).

I imagined it is going to be fairly iterative.

A few docs I can imagine:

With the rough sketch of how things work done here, I write it up so I am explaining it back to you to be sure I understand. Then I implement and come back and flesh out the docs with more detail as I learn.

Of course with enough help I am sure we could document it all up front, it just was not how I imagined doing it when I started poking around.

Something I probably need to look into is more on how Rust generates its docs.

Is that far off what you imagined?
P.S. I am going to be AFK for 2 weeks so will pick this up when I am back online.

@marco-c
Copy link
Collaborator

marco-c commented Oct 14, 2021

This sounds fine, steps 2 and 3 @Luni-4 was mentioning should happen at the same time (while implementing the metric, you write down what you are doing and at the end you reorganize what you wrote in nice docs).

@Luni-4 can you explain @dburriss how to add a new tree-sitter grammar?

@Luni-4
Copy link
Collaborator Author

Luni-4 commented Oct 14, 2021

@marco-c Sure!

@dburriss If you want to add a new tree-sitter-grammar to rust-code-analysis you need to:

  1. Verify either upstream or in some other repository whether the grammar is available for the current tree-sitter version used in this repository (in our case 0.19)

For the enums crate part:

  1. Add your grammar crate here
  2. Add your language here
  3. Add your language below this line
  4. Launch the recreate-grammars.sh to recreate all grammars

For the rust-code-analysis part:

  1. Add your grammar here
  2. Add your grammar to the mod here
  3. Define your grammar here

At this point, you should be able to compile rust-code-analysis with the grammar. After that you can implement the metrics for that language using the steps provided above.

I completely agree with your docs, I think they could be pretty helpful for the new contributors, especially the tutorial style. We can add them into our official docs that are all defined here

If you need some help, feel free to ask anytime

@dburriss
Copy link
Contributor

I wanted to check some assumptions:

for (int i = 0; i < 100;  i++) {
  System.out.println(i);
}

For LLOC, the value should be 4? 3 for the statements inside the for and 1 for the println? I think that matches the Python behavior

Another check?

class HelloWorldApp {
  public static void main(String[] args) {
    System.out.println(\"Hello World!\"); // Display the string.
  }
}

How many LLOC does the above have? Put another way, do package NS, class declaration, and members count toward LLOC?

Currently, mine is counting 2 for the above but I think it should only be the 1 println?

P.S. I cannot set debug points inside the compute when running the tests anymore. I swear I could before yesterday. Unfortunately, pulling master required me to update rust version, and at the same time I managed to lose my IDE (trying CLion) setup when creating the 2 new branches. Did anyone experience anything like that with the new update?

@Luni-4
Copy link
Collaborator Author

Luni-4 commented Oct 27, 2021

I wanted to check some assumptions:

for (int i = 0; i < 100;  i++) {
  System.out.println(i);
}

For LLOC, the value should be 4? 3 for the statements inside the for and 1 for the println? I think that matches the Python behavior

Exactly, in this case LLOC is 4 due to the statements you have described

class HelloWorldApp {
  public static void main(String[] args) {
    System.out.println(\"Hello World!\"); // Display the string.
  }
}

How many LLOC does the above have? Put another way, do package NS, class declaration, and members count toward LLOC?

Currently, mine is counting 2 for the above but I think it should only be the 1 println?

First of all, we should ask: what are statements in Java?

I found this article from Oracle. In the case above, only the println should be counted as statement, so LLOC is 1.

P.S. I cannot set debug points inside the compute when running the tests anymore. I swear I could before yesterday. Unfortunately, pulling master required me to update rust version, and at the same time I managed to lose my IDE (trying CLion) setup when creating the 2 new branches. Did anyone experience anything like that with the new update?

Yep, we have updated master to the new Rust version such that the Rust 2021 edition, which adds interesting improvements, is enabled. Hmm, I don't have much experience with that IDE, could you try to reset your configuration in some way?

@dburriss
Copy link
Contributor

dburriss commented Feb 7, 2022

Hi. Working on this again.
I am having some trouble with something but want to check it is something I should be solving.

if (x == 1)

Is one logical line.

if ( (x == 1) || (x==2) )

I had assumed this was 2 logical lines but reading the link from @Luni-4 I am thinking I may have been wrong. Although it never talks about the semantics of a compound predicate, my understanding now is that it is a single expression and so a single logical line. Do you agree?

@marco-c
Copy link
Collaborator

marco-c commented Feb 7, 2022

I believe it is to be considered a single lloc. I guess you can confirm with a C++ snippet, which should be exactly the same in this case.

@marco-c
Copy link
Collaborator

marco-c commented Feb 10, 2022

#786 is adding support for cyclomatic complexity calculation for Java.

@marco-c
Copy link
Collaborator

marco-c commented Mar 23, 2022

#694 added loc metrics.

This was linked to pull requests Mar 23, 2022
@dburriss
Copy link
Contributor

#811 adds Halstead metrics

@dburriss
Copy link
Contributor

#823 Adds nom metrics

@dburriss
Copy link
Contributor

#822 Adds exit metrics

@dburriss
Copy link
Contributor

dburriss commented Apr 14, 2022

@marco-c

image

@marco-c
Copy link
Collaborator

marco-c commented Jun 29, 2023

@dburriss @Luni-4 anything else left before closing this?

@dburriss
Copy link
Contributor

@marco-c It's not directly related to the metric calculation but the Halstead ops check is still giving unexpected values #849

@marco-c
Copy link
Collaborator

marco-c commented Jun 29, 2023

OK, let's close this and consider that as a separate follow-up bug that we have to fix.

@marco-c marco-c closed this as completed Jun 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
3 participants