Repository: objectionary/eo
Issue: sonarcube is complaining about our quality of code

We have pretty bad results in SonarCube: https://sonarcloud.io/summary/new_code?id=com.objectionary%3Aeo Let's try to fix at least the major problems.

Changed files:
eo-runtime/src/main/java/org/eolang/Main.java, eo-maven-plugin/src/main/java/org/eolang/maven/DepDirs.java, eo-runtime/src/main/java/org/eolang/ExprReduce.java, eo-parser/src/main/java/org/eolang/parser/RedundantParentheses.java, eo-runtime/src/main/java/org/eolang/PhDefault.java, eo-maven-plugin/src/main/java/org/eolang/maven/footprint/FtDefault.java, eo-maven-plugin/src/main/java/org/eolang/maven/Coordinates.java, eo-maven-plugin/src/main/java/org/eolang/maven/dependencies/DcsDepgraph.java, eo-runtime/src/main/java/org/eolang/Dataized.java, eo-runtime/src/main/java/org/eolang/BytesOf.java, eo-maven-plugin/src/main/java/org/eolang/maven/util/Walk.java, eo-maven-plugin/src/main/java/org/eolang/maven/UnplaceMojo.java

diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/Coordinates.java b/eo-maven-plugin/src/main/java/org/eolang/maven/Coordinates.java
index 92649073c..90f76c3f1 100644
--- a/eo-maven-plugin/src/main/java/org/eolang/maven/Coordinates.java
+++ b/eo-maven-plugin/src/main/java/org/eolang/maven/Coordinates.java
@@ -23,6 +23,7 @@
  */
 package org.eolang.maven;
 
+import javax.annotation.Nonnull;
 import org.apache.maven.model.Dependency;
 
 /**
@@ -69,12 +70,12 @@ public final class Coordinates implements Comparable<Coordinates> {
     }
 
     @Override
-    public int compareTo(final Coordinates other) {
+    public int compareTo(@Nonnull final Coordinates other) {
         return this.toString().compareTo(other.toString());
     }
 
     @Override
-    public boolean equals(final Object other) {
+    public boolean equals(@Nonnull final Object other) {
         return this.toString().equals(other.toString());
     }
 
diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/DepDirs.java b/eo-maven-plugin/src/main/java/org/eolang/maven/DepDirs.java
index a069c0b2b..a46f285d9 100644
--- a/eo-maven-plugin/src/main/java/org/eolang/maven/DepDirs.java
+++ b/eo-maven-plugin/src/main/java/org/eolang/maven/DepDirs.java
@@ -31,6 +31,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import org.cactoos.list.ListEnvelope;
 
 /**
@@ -62,15 +63,17 @@ final class DepDirs extends ListEnvelope<String> {
         final List<String> names = new LinkedList<>();
         if (Files.exists(dir)) {
             final String home = dir.toAbsolutePath().toString();
-            names.addAll(
-                Files.find(dir, 4, (t, u) -> true)
-                    .filter(file -> file.toFile().isDirectory())
-                    .map(file -> file.toAbsolutePath().toString())
-                    .filter(name -> !name.equals(home))
-                    .map(name -> name.substring(home.length() + 1))
-                    .filter(name -> name.split(Pattern.quote(File.separator)).length == 4)
-                    .collect(Collectors.toList())
-            );
+            try (Stream<Path> paths = Files.find(dir, 4, (t, u) -> true)) {
+                names.addAll(
+                    paths
+                        .filter(file -> file.toFile().isDirectory())
+                        .map(file -> file.toAbsolutePath().toString())
+                        .filter(name -> !name.equals(home))
+                        .map(name -> name.substring(home.length() + 1))
+                        .filter(name -> name.split(Pattern.quote(File.separator)).length == 4)
+                        .collect(Collectors.toList())
+                );
+            }
         }
         return names;
     }
diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/UnplaceMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/UnplaceMojo.java
index aaaadbd79..873d97fc9 100644
--- a/eo-maven-plugin/src/main/java/org/eolang/maven/UnplaceMojo.java
+++ b/eo-maven-plugin/src/main/java/org/eolang/maven/UnplaceMojo.java
@@ -25,6 +25,7 @@ package org.eolang.maven;
 
 import com.jcabi.log.Logger;
 import java.io.IOException;
+import java.nio.file.DirectoryStream;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -264,7 +265,7 @@ public final class UnplaceMojo extends SafeMojo {
             Files.delete(file);
             deleted = true;
         }
-        while (!Files.newDirectoryStream(dir).iterator().hasNext()) {
+        while (UnplaceMojo.isEmpty(dir)) {
             final Path curdir = dir;
             dir = curdir.getParent();
             Files.delete(curdir);
@@ -276,4 +277,20 @@ public final class UnplaceMojo extends SafeMojo {
         }
         return deleted;
     }
+
+    /**
+     * Check if folder is empty.
+     * @param path Folder to be checked
+     * @return True if folder is empty and False otherwise
+     * @throws IOException In case of I/O issues
+     */
+    private static boolean isEmpty(final Path path) throws IOException {
+        boolean empty = false;
+        if (Files.isDirectory(path)) {
+            try (DirectoryStream<Path> directory = Files.newDirectoryStream(path)) {
+                empty = !directory.iterator().hasNext();
+            }
+        }
+        return empty;
+    }
 }
diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/dependencies/DcsDepgraph.java b/eo-maven-plugin/src/main/java/org/eolang/maven/dependencies/DcsDepgraph.java
index d3a233e1a..fa6fbf1c9 100644
--- a/eo-maven-plugin/src/main/java/org/eolang/maven/dependencies/DcsDepgraph.java
+++ b/eo-maven-plugin/src/main/java/org/eolang/maven/dependencies/DcsDepgraph.java
@@ -51,6 +51,7 @@ import org.twdata.maven.mojoexecutor.MojoExecutor;
  *
  * @see <a href="https://github.com/ferstl/depgraph-maven-plugin">here</a>
  * @since 0.28.11
+ * @checkstyle NoJavadocForOverriddenMethodsCheck (200 lines)
  */
 public final class DcsDepgraph implements Iterable<Dependency> {
 
@@ -187,6 +188,14 @@ public final class DcsDepgraph implements Iterable<Dependency> {
             this.file = path;
         }
 
+        /**
+         * Returns an iterator over elements of type {@code T}.
+         *
+         * @return Iterator.
+         * @todo #1897:30m Close `JsonReader` object in `DcsJson`.
+         *  SonarCloud mandates readers to be closed.
+         *  Use try-with-resources or close this "JsonReader" in a "finally" clause. (line 203)
+         */
         @Override
         public Iterator<Dependency> iterator() {
             try {
diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/footprint/FtDefault.java b/eo-maven-plugin/src/main/java/org/eolang/maven/footprint/FtDefault.java
index 99cd041b2..dbfa20cbf 100644
--- a/eo-maven-plugin/src/main/java/org/eolang/maven/footprint/FtDefault.java
+++ b/eo-maven-plugin/src/main/java/org/eolang/maven/footprint/FtDefault.java
@@ -41,6 +41,7 @@ import org.eolang.maven.util.Home;
  * Program footprint of EO compilation process.
  * <p>The footprint consists of file in {@link #main} folder</p>
  * @since 1.0
+ * @checkstyle NoJavadocForOverriddenMethodsCheck (100 lines)
  */
 public final class FtDefault implements Footprint {
 
@@ -75,6 +76,18 @@ public final class FtDefault implements Footprint {
         );
     }
 
+    /**
+     * Get list of saved regular files with ext.
+     *
+     * @param ext File extension
+     * @return List of files
+     * @throws IOException In case of IO issues
+     * @todo #1897:30m Close `Stream` object in `FtDefault`.
+     *  Connections, streams, files, and other classes that implement the
+     *  Closeable interface or its super-interface,
+     *  AutoCloseable, needs to be closed after use.
+     *  Use try-with-resources or close this "Stream" in a "finally" clause.. (line 90)
+     */
     @Override
     public List<Path> list(final String ext) throws IOException {
         final List<Path> res;
diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/util/Walk.java b/eo-maven-plugin/src/main/java/org/eolang/maven/util/Walk.java
index d49782847..2777c66df 100644
--- a/eo-maven-plugin/src/main/java/org/eolang/maven/util/Walk.java
+++ b/eo-maven-plugin/src/main/java/org/eolang/maven/util/Walk.java
@@ -116,6 +116,12 @@ public final class Walk extends ListEnvelope<Path> {
      * List them all.
      * @param dir The dir
      * @return List
+     * @throws IOException If fails
+     * @todo #1897:30m Close `Stream` object in `Walk`.
+     *  Connections, streams, files, and other classes that implement the
+     *  Closeable interface or its super-interface,
+     *  AutoCloseable, needs to be closed after use.
+     *  Use try-with-resources or close this "Stream" in a "finally" clause.. (line 131)
      */
     private static List<Path> list(final Path dir) {
         try {
diff --git a/eo-parser/src/main/java/org/eolang/parser/RedundantParentheses.java b/eo-parser/src/main/java/org/eolang/parser/RedundantParentheses.java
index fb508e602..a4d9bb39b 100644
--- a/eo-parser/src/main/java/org/eolang/parser/RedundantParentheses.java
+++ b/eo-parser/src/main/java/org/eolang/parser/RedundantParentheses.java
@@ -100,8 +100,17 @@ final class RedundantParentheses implements Predicate<String> {
 
     /**
      * Clears raw expression from text literals and returns it as an array of chars.
-     * @param expression Raw experession
+     * @param expression Raw expression
      * @return Expression as an array of chars.
+     * @todo #1897:30m Refactor regexp in `RedundantParenthesis`.
+     *  The Java regex engine uses recursive method calls to implement backtracking.
+     *  Therefore when a repetition inside a regular expression contains multiple paths
+     *  (i.e. the body of the repetition contains an alternation (|), an optional
+     *  element or another repetition), trying to match the regular expression can cause a
+     *  stack overflow on large inputs. This does not happen when using a possessive quantifier
+     *  (such as *+ instead of *) or when using a character class inside a repetition
+     *  (e.g. [ab]* instead of (a|b)*).
+     *  Refactor this repetition that can lead to a stack overflow for large inputs. (line 113)
      */
     private static char[] expressionChars(final String expression) {
         return expression.replaceAll(
diff --git a/eo-runtime/src/main/java/org/eolang/BytesOf.java b/eo-runtime/src/main/java/org/eolang/BytesOf.java
index 6b59551b3..69aeef7aa 100644
--- a/eo-runtime/src/main/java/org/eolang/BytesOf.java
+++ b/eo-runtime/src/main/java/org/eolang/BytesOf.java
@@ -142,7 +142,7 @@ public final class BytesOf implements Bytes {
                 } else {
                     byte dst = (byte) (bytes[source] << mod);
                     if (source + 1 < bytes.length) {
-                        dst |= bytes[source + 1] >>> (Byte.SIZE - mod) & carry;
+                        dst |= bytes[source + 1] >>> (Byte.SIZE - mod) & carry & 0xFF;
                     }
                     bytes[index] = dst;
                 }
@@ -156,7 +156,7 @@ public final class BytesOf implements Bytes {
                 } else {
                     byte dst = (byte) ((0xff & bytes[source]) >>> mod);
                     if (source - 1 >= 0) {
-                        dst |= bytes[source - 1] << (Byte.SIZE - mod) & carry;
+                        dst |= bytes[source - 1] << (Byte.SIZE - mod) & carry & 0xFF;
                     }
                     bytes[index] = dst;
                 }
@@ -176,7 +176,7 @@ public final class BytesOf implements Bytes {
                 final int zeros = BytesOf.numberOfLeadingZeros(
                     bytes[index]
                 );
-                bytes[index] = (byte) (bytes[index] ^ (-1 << (Byte.SIZE - zeros)));
+                bytes[index] = (byte) (bytes[index] & 0xFF ^ (-1 << (Byte.SIZE - zeros)));
                 if (zeros != Byte.SIZE) {
                     break;
                 }
diff --git a/eo-runtime/src/main/java/org/eolang/Dataized.java b/eo-runtime/src/main/java/org/eolang/Dataized.java
index 87d8f89ce..f4e46a559 100644
--- a/eo-runtime/src/main/java/org/eolang/Dataized.java
+++ b/eo-runtime/src/main/java/org/eolang/Dataized.java
@@ -126,4 +126,15 @@ public final class Dataized {
     public <T> T take(final Class<T> type) {
         return type.cast(this.take());
     }
+
+    /**
+     * Clean up resources.
+     * This includes call of {@link ThreadLocal#remove()} method to prevent
+     * memory leaks.
+     */
+    public static void cleanUp() {
+        Dataized.LEVEL.remove();
+        Dataized.MAX_LEVEL.remove();
+    }
+
 }
diff --git a/eo-runtime/src/main/java/org/eolang/ExprReduce.java b/eo-runtime/src/main/java/org/eolang/ExprReduce.java
index a31eed108..be7fd20a3 100644
--- a/eo-runtime/src/main/java/org/eolang/ExprReduce.java
+++ b/eo-runtime/src/main/java/org/eolang/ExprReduce.java
@@ -84,6 +84,14 @@ public final class ExprReduce<T> implements Expr {
     @Override
     public Phi get(final Phi rho) {
         final Optional<T> acc = this.arguments.get(rho, this.param).stream().reduce(this.reduction);
+        if (!acc.isPresent()) {
+            throw new IllegalStateException(
+                String.format(
+                    "Unable to reduce expression for %s",
+                    rho
+                )
+            );
+        }
         return new Data.ToPhi(acc.get());
     }
 
diff --git a/eo-runtime/src/main/java/org/eolang/Main.java b/eo-runtime/src/main/java/org/eolang/Main.java
index 609d771ff..b6403ffff 100644
--- a/eo-runtime/src/main/java/org/eolang/Main.java
+++ b/eo-runtime/src/main/java/org/eolang/Main.java
@@ -214,7 +214,7 @@ public final class Main {
                 )
             )
         ) {
-            return input.lines().findFirst().get();
+            return input.lines().findFirst().orElse("N/A");
         }
     }
 
diff --git a/eo-runtime/src/main/java/org/eolang/PhDefault.java b/eo-runtime/src/main/java/org/eolang/PhDefault.java
index 28f2df6ad..461b9e27f 100644
--- a/eo-runtime/src/main/java/org/eolang/PhDefault.java
+++ b/eo-runtime/src/main/java/org/eolang/PhDefault.java
@@ -284,6 +284,16 @@ public abstract class PhDefault implements Phi, Cloneable {
         return "?";
     }
 
+    /**
+     * Clean up resources.
+     * This includes call of {@link ThreadLocal#remove()} method to prevent
+     * memory leaks.
+     */
+    public static void cleanUp() {
+        PhDefault.TERMS.remove();
+        PhDefault.NESTING.remove();
+    }
+
     /**
      * Add new attribute.
      *