Giter Club home page Giter Club logo

codemetrics's Introduction

License: GPL v3 JCS-ELPA

Code Metrics

Plugin shows complexity information

CI

This plugin implements live calculation of the Cognitive Complexity metric, which was proposed by G. Ann Campbell in Cognitive Complexity - A new way of measuring understandability (c) SonarSource S.A. 2016-2021, Switzerland.

Abstract: Cyclomatic Complexity was initially formulated as a measurement of the "testability and maintainability" of the control flow of a module. While it excels at measuring the former, its underlying mathematical model is unsatisfactory at producing a value that measures the latter. This white paper describes a new metric that breaks from the use of mathematical models to evaluate code in order to remedy Cyclomatic Complexity’s shortcomings and produce a measurement that more accurately reflects the relative difficulty of understanding, and therefore of maintaining methods, classes, and applications.

Table of Contents

πŸ’Ύ Installation

πŸ” Method 1. with straight.el and use-package:

(use-package codemetrics
  :straight (codemetrics :type git :host github :repo "jcs-elpa/codemetrics"))

πŸ” Method 2. Manual

git clone https://github.com/jcs-elpa/codemetrics /path/to/lib

then in Emacs:

(add-to-list 'load-path "/path/to/lib")
(require 'codemetrics)

or

(use-package codemetrics
  :load-path "/path/to/lib")

πŸ–₯ Usage

The simplest way to start using this package:

(codemetrics-mode 1)

πŸ“š Use it as a library

These are functions you can use to analyze:

Functions Description
codemetrics-analyze Analyze a string with major-mode
codemetrics-region Analyze region
codemetrics-buffer Analyze the whole buffer

All these functions return the score data indicating the complexity.

πŸ”¨ Supported languages

⚠️ Please sort these two lists alphabetically!

These languages are fairly complete:

  • Bash
  • C / C++ / C#
  • Elisp
  • Go
  • Java / JavaScript / JSX / Julia
  • Kotlin
  • Lua
  • PHP / Python
  • Ruby / Rust
  • Swift
  • TypeScript / TSX

These languages are in development:

  • Agda
  • Elm
  • Elixir
  • OCaml
  • Scala (upstream, kinda buggy)

πŸ“ Customization

Although codemetrics aims to have good analysis rules out of the box for all supported definitions, people will indubitably have their own preferences or desired functionality. The following section outlines how to add your own analysis definitions and analysis functions to make codemetrics work for you. If there are any improvements you find for existing or new languages, please do raise a PR so that others may benefit from better analysis in the future!

βšͺ Analysis on new nodes

Code-Metrics defines all its analysis definitions in the variable codemetrics-rules which is an alist with the key of the alist being the mode and the value being another alist of analysis definitions.

;; Example of codemetrics-rules' structure
'((c-mode      . c-analysis-definitions)  ; <language>-analysis-definitions is structured as shown below
  (csharp-mode . csharp-analysis-definitions)
  (go-mode     . go-analysis-definitions)
  (scala-mode  . scala-analysis-definitions)
  ...)

;; Examle of a analysis definition alist
(setq csharp-analysis-definitions
    (if_statement   . (1 t))
    ("&&"           . codemetrics-rules--logical-operators))

So you can select whatever node that you want to analyze on it.

To find what node you'll want to analyze, refer to the tree-sitter documentation about viewing nodes. tree-sitter-debug and tree-sitter-query-builder are both very useful for this.

❔ Example

Let's look at a quick example of adding a new analysis definition. Let's say you want to add analysis to go-mode's if_statement. The analysis definition that is needed will be '(if_statement . (1 t)). To add this to the codemetrics-rules, you can do something like the following.

(push '(if_statement . (1 t)) (alist-get 'go-mode codemetrics-rules))

Now the new analysis definition should be usable by codemetrics!

πŸ” Writing new analysis functions

For more complex analysis, you can write your own analysis rules!

  • node - (optional) the targeted tree-sitter node, in this example, if_statement will be the targeting node.
  • depth - (optional) current depth of from the root tree.
  • nested - (optional) current nested level apply from current complexity algorithm.

Then the function needs to return an integer represent the score and a boolean represent increment of the nested level in the form (score-to-add . nested?). This can be useful if you want to add extra conditional logic onto your analysis.

As an example of an analysis function, take a look at the definition of the basic codemetrics-rules--class-declaration.

(defun codemetrics-rules--class-declaration (_node depth _nested)
  "..."
  (codemetrics-with-complexity
    (if (< 1 depth)  ; if class inside class,
        '(1 nil)     ; we score 1, but don't increase nested level
      '(0 nil))
    '(1 nil)))

πŸ”— References

πŸ› οΈ Contribute

PRs Welcome Elisp styleguide Donate on paypal Become a patron

If you would like to contribute to this project, you may either clone and make pull requests to this repository. Or you can clone the project and establish your own branch of this tool. Any methods are welcome!

πŸ”¬ Development

To run the test locally, you will need the following tools:

Install all dependencies and development dependencies:

$ eask install-deps --dev

To test the package's installation:

$ eask package
$ eask install

To test compilation:

$ eask compile

πŸͺ§ The following steps are optional, but we recommend you follow these lint results!

The built-in checkdoc linter:

$ eask lint checkdoc

The standard package linter:

$ eask lint package

πŸ“ P.S. For more information, find the Eask manual at https://emacs-eask.github.io/.

❓ How to add an analysis rules?

When adding a new analysis rules, add the analysis definition function to codemetrics.el itself near where the other rules functions live and then add the parser to codemetrics-rules.el file. Finally, if you are adding support for a new language, remember to add it to the codemetrics-rules variable.

When creating a new parser, name it codemetrics-rules-<language>.

When creating a new analysis function, name it codemetrics-rules-<language>-<feature> or something similar.

πŸ” Where can I look for tree-sitter node?

Here are some techniques for finding your desired nodes in tree-sitter.

To look for the correct node you have three options:

  • look at the tree-sitter-[lang]/grammar.js implementation. In the above example, if_statement node is defined in the tree-sitter-c-sharp's grammar.js file
  • open a file of your language choice in emacs and M-x tree-sitter-debug-mode. This will display the whole s-expr representing your file
  • (message "%S" (tsc-node-to-sexp)) in your function to display what your function is seeing

⚠️ Warning

Make sure you look into the correct repository. Repositories are managed under tree-sitter-langs's using git submodule. Some tree-sitter module aren't using the latest version!

⚜️ License

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

See LICENSE for details.

codemetrics's People

Contributors

dependabot[bot] avatar jcs090218 avatar themkat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

codemetrics's Issues

Need a better GIF file

The current GIF file in the readme is not very attractive. πŸ€” We need a new one.

Request for a how-to-debug section in the readme

This looks great, so I tried the package :)

I mostly have Swift code lying around, so I fired up eglot/tree-sitter-mode/codemetrics in Emacs 28.2.

The annotations in the buffer look very tasty -- but I couldn't get the % to increase e.g. here:

CleanShot 2023-04-01 at 09 10 31

It's likely because the function itself returns a closure, and so it appears to 'exit early'. But all the complexity is inside the returned closure. That's my guess because this works:

CleanShot 2023-04-01 at 09 13 52

It'd be great if you could add a getting started section to the README to help folks like me troubleshoot this and e.g. inspect the data codemetrics returns. πŸ™

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.