Git Product home page Git Product logo

logifix's Introduction

Logifix

Logifix

Logifix is a Datalog-based tool for automatically fixing static analysis violations in Java source code. Logifix can be used to fix static analysis violations for static analyzers such as SonarQube, PMD or SpotBugs, but also to modernize legacy code or even to automatically enforce custom rules specific to your code base.

Demo

demo.mp4

Getting started

1. Install

Prebuilt and dependency-free binaries are provided for macOS and GNU-based Linux systems.

Ubuntu/Debian
curl -L https://github.com/lyxell/logifix/releases/latest/download/logifix-x86_64-linux-gnu.gz | gunzip -c - > /tmp/logifix
chmod +x /tmp/logifix
sudo mv /tmp/logifix /usr/local/bin
macOS
curl -L https://github.com/lyxell/logifix/releases/latest/download/logifix-x86_64-macos.gz | gunzip -c - > /tmp/logifix
chmod +x /tmp/logifix
sudo mv /tmp/logifix /usr/local/bin

2. Run

  • Run logifix path/to/your/project in your terminal, run logifix --help to get help

What is Logifix?

Logifix is an analysis-guided rewrite system for Java source code. This means that you define (or use predefined) analyses and transformations that all work together to improve your code. The analyses and transformations are written in the highly declarative logic-based language Datalog and are combined and chained automatically by the rewrite engine.

Features

Intelligent equational reasoning

Logifix is more than a search-and-replace system. It performs rewrites in multiple steps and can achieve intelligent equational reasoning by building articulation points in the rewrite graph.

Speed

Logifix is implemented in a high-performance Datalog dialect that is synthesized into multi-threaded C++ code. It is heavily parallelized even when working on a single file and usually analyzes large projects of thousands of files in a few seconds on modern hardware. If your project is slow to analyze it is considered a bug and you should file a bug report.

Mergeability

Logifix is engineered to produce human-like patches that are ready-to-merge by design without requiring manual modifications.

Examples

Here is a few examples of patches generated by Logifix.

Fix inefficient iteration over Map#keySet

  public static void sign(String token, Map<String, String> params) {
      List<String> list = new ArrayList();
      String tokenClientSlat = "";
-     for (String key : params.keySet()) {
+     for (Map.Entry<String, String> entry : params.entrySet()) {
+         String key = entry.getKey();
          if (key.equals("token_client_salt")) {
-             tokenClientSlat = params.get(key);
+             tokenClientSlat = entry.getValue();
          }
-         String paramString = key + "=" + params.get(key);
+         String paramString = key + "=" + entry.getValue();
          list.add(paramString);
      }
      Collections.sort(list);

Simplify code using try-with-resources

          continue;
      } 
-     try {
-         JarFile nextJarFile = new JarFile(absNextFile);
-         try {
-             Attributes attrs = getMainAttrs(nextJarFile);
-             Set<Extension> newExtensions = getReferencedExtensions(attrs);
-             result.addAll(newExtensions);
-             filesToProcess.addAll(extensionsToFiles(newExtensions));
-         } finally {
-             nextJarFile.close();
-         }
+     try (JarFile nextJarFile = new JarFile(absNextFile)) {
+         Attributes attrs = getMainAttrs(nextJarFile);
+         Set<Extension> newExtensions = getReferencedExtensions(attrs);
+         result.addAll(newExtensions);
+         filesToProcess.addAll(extensionsToFiles(newExtensions));
      } catch (Exception e) {
          invalidLibPaths.append(nextFile.getPath()).append(" ");
      }

Simplify code using Map::computeIfAbsent

  private final Map<Class<?>, String> requestQueueNameCache = new ConcurrentHashMap<>();
     
  public String getRequestQueueName(Class<?> remoteInterface) {
-     String str = requestQueueNameCache.get(remoteInterface);
-     if (str == null) {
-         str = "{" + name + ":" + remoteInterface.getName() + "}";
-         requestQueueNameCache.put(remoteInterface, str);
-     }
-     return str;
+     return requestQueueNameCache.computeIfAbsent(remoteInterface, k -> "{" + name + ":" + k.getName() + "}");
  }

Simplify code using streams

  @Override
  public List<SpoonFile> getAllJavaFiles() {
-     List<SpoonFile> result = new ArrayList<>();
-
-     for (SpoonFile f : getAllFiles()) {
-         if (f.isJava()) {
-             result.add(f);
-         }
-     }
-
-     return result;
+     return getAllFiles().stream().filter(SpoonFile::isJava).collect(Collectors.toList());
  } 

FAQ

Where can I find the predefined transformations?

See docs/predefined-transformations.md or the source code src/rules.

Can I create my own transformations?

Yes! See docs/creating-your-own-transformations.md.

How do I build from source?

See docs/building.md.

Related projects

If you find this project interesting, be sure to check out these as well:

logifix's People

Contributors

lyxell avatar

Stargazers

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

Watchers

 avatar  avatar

logifix's Issues

Merge inside same branch

Rewrites in the same branch are currently merged together with everything else.
This should be changed so that rewrites in the same branch are merged together, before presented to the user.

Example:

class Test {
    void test() {
        String message = "";
        try {
            String buf = message;
        } catch (Exception e) {
            System.out.println("ok!");
        }
    }
}

Implement automatic indentation

Rule 3824 now works but it needs automatic indentation. This need to be done as a post-processing step outside Datalog as it is not feasible to do it in Datalog.

Add more real world tests for rule 2095

Consider rule for unhoisting bang into or-statement

in apache/dubbo dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/MemberUtils.java

@@ -42,7 +42,7 @@ import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.ofT
 public interface MemberUtils {

     static boolean matches(Element member, ElementKind kind) {
-        return member == null || kind == null ? false : kind.equals(member.getKind());
+        return !(member == null || kind == null) && kind.equals(member.getKind());
     }

     static boolean isPublicNonStatic(Element member) {

could be written

@@ -42,7 +42,7 @@ import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.ofT
 public interface MemberUtils {

     static boolean matches(Element member, ElementKind kind) {
-        return member == null || kind == null ? false : kind.equals(member.getKind());
+        return member != null && kind != null && kind.equals(member.getKind());
     }

     static boolean isPublicNonStatic(Element member) {

Consider custom cleanup rules

The output of some rewrite rules may sometimes be prettified further.

Examples:

  • !!x => x
  • !(x == y) => x != y
  • System.out.println("") => System.out.println()

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.