push ex4 and ex5

This commit is contained in:
tuanvu
2025-12-12 12:58:32 +01:00
parent 98ecd56e6b
commit 749bb02e57
9 changed files with 91 additions and 79 deletions

View File

@@ -4,7 +4,14 @@ import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.*; import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.visitor.VoidVisitorWithDefaults; import com.github.javaparser.ast.visitor.VoidVisitorWithDefaults;
import java.io.PrintWriter;
public class GetterChecker extends VoidVisitorWithDefaults<Void> { public class GetterChecker extends VoidVisitorWithDefaults<Void> {
private final PrintWriter out;
public GetterChecker(PrintWriter out) {
this.out = out;
}
@Override @Override
public void visit(CompilationUnit unit, Void arg) { public void visit(CompilationUnit unit, Void arg) {
for(TypeDeclaration<?> type : unit.getTypes()) { for(TypeDeclaration<?> type : unit.getTypes()) {
@@ -16,13 +23,14 @@ public class GetterChecker extends VoidVisitorWithDefaults<Void> {
public void visit(final ClassOrInterfaceDeclaration n, final Void arg) { public void visit(final ClassOrInterfaceDeclaration n, final Void arg) {
if (!n.isPublic()) if (!n.isPublic())
return; return;
System.out.println(n.getNameAsString());
out.println(n.getNameAsString());
for (FieldDeclaration field : n.getFields()) { for (FieldDeclaration field : n.getFields()) {
if (!field.isPrivate()) continue; if (!field.isPrivate()) continue;
for (VariableDeclarator variable : field.getVariables()) { for (VariableDeclarator variable : field.getVariables()) {
boolean hasGetter = false; boolean hasGetter = false;
String fieldName = variable.getNameAsString(); String fieldName = variable.getNameAsString();
System.out.println("---------------"+fieldName+"---------------"); out.println("---------------"+fieldName+"---------------");
String getterName1 = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); String getterName1 = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
for (MethodDeclaration method : n.getMethods()) { for (MethodDeclaration method : n.getMethods()) {
@@ -32,10 +40,10 @@ public class GetterChecker extends VoidVisitorWithDefaults<Void> {
} }
} }
if (!hasGetter) { if (!hasGetter) {
System.out.println(" Missing getter for field: " + fieldName); out.println(" Missing getter for field: " + fieldName);
} }
} }
} }
super.visit(n, arg); out.println(" ");
} }
} }

View File

@@ -10,6 +10,7 @@ import com.github.javaparser.utils.SourceRoot;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@@ -28,10 +29,13 @@ public class Main {
} }
SourceRoot root = new SourceRoot(file.toPath()); SourceRoot root = new SourceRoot(file.toPath());
GetterChecker checker = new GetterChecker();
root.parse("", (localPath, absolutePath, result) -> { try (PrintWriter writer = new PrintWriter("result_exercise4.txt")) {
result.ifSuccessful(unit -> unit.accept(checker, null)); GetterChecker checker = new GetterChecker(writer);
return SourceRoot.Callback.Result.DONT_SAVE; root.parse("", (localPath, absolutePath, result) -> {
}); result.ifSuccessful(unit -> unit.accept(checker, null));
return SourceRoot.Callback.Result.DONT_SAVE;
});
}
} }
} }

View File

@@ -63,6 +63,14 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@@ -0,0 +1,43 @@
package fr.istic.vv;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.expr.ConditionalExpr;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import java.io.PrintWriter;
public class CyclomaticComplexity extends VoidVisitorAdapter<Void> {
private PrintWriter out;
public CyclomaticComplexity(PrintWriter out) {
this.out = out;
}
@Override
public void visit(MethodDeclaration method, Void arg) {
System.out.println("Found method: " + method.getDeclarationAsString());
int cc = 1;
for (Node node : method.findAll(Node.class)) {
if (node instanceof IfStmt
|| node instanceof ForStmt
|| node instanceof WhileStmt
|| node instanceof DoStmt
|| node instanceof CatchClause
|| node instanceof ConditionalExpr) {
cc++;
} else if (node instanceof SwitchEntry) {
SwitchEntry se = (SwitchEntry) node;
if (!(se.getLabels().isEmpty())) {
cc++;
}
}
}
String resultLine = method.getNameAsString()+ ": " + cc;
out.println(resultLine);
out.flush();
}
}

View File

@@ -1,20 +1,13 @@
package fr.istic.vv; package fr.istic.vv;
import com.github.javaparser.Problem;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.visitor.VoidVisitor;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import com.github.javaparser.utils.SourceRoot; import com.github.javaparser.utils.SourceRoot;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.io.PrintWriter;
import java.nio.file.Paths;
public class Main { public class Main {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
if(args.length == 0) { if(args.length == 0) {
System.err.println("Should provide the path to the source code"); System.err.println("Should provide the path to the source code");
@@ -28,12 +21,12 @@ public class Main {
} }
SourceRoot root = new SourceRoot(file.toPath()); SourceRoot root = new SourceRoot(file.toPath());
PublicElementsPrinter printer = new PublicElementsPrinter(); try (PrintWriter writer = new PrintWriter("result_exercise5.txt")) {
root.parse("", (localPath, absolutePath, result) -> { CyclomaticComplexity checker = new CyclomaticComplexity(writer);
result.ifSuccessful(unit -> unit.accept(printer, null)); root.parse("", (localPath, absolutePath, result) -> {
return SourceRoot.Callback.Result.DONT_SAVE; result.ifSuccessful(unit -> unit.accept(checker, null));
}); return SourceRoot.Callback.Result.DONT_SAVE;
});
}
} }
} }

View File

@@ -1,48 +0,0 @@
package fr.istic.vv;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.visitor.VoidVisitorWithDefaults;
// This class visits a compilation unit and
// prints all public enum, classes or interfaces along with their public methods
public class PublicElementsPrinter extends VoidVisitorWithDefaults<Void> {
@Override
public void visit(CompilationUnit unit, Void arg) {
for(TypeDeclaration<?> type : unit.getTypes()) {
type.accept(this, null);
}
}
public void visitTypeDeclaration(TypeDeclaration<?> declaration, Void arg) {
if(!declaration.isPublic()) return;
System.out.println(declaration.getFullyQualifiedName().orElse("[Anonymous]"));
for(MethodDeclaration method : declaration.getMethods()) {
method.accept(this, arg);
}
// Printing nested types in the top level
for(BodyDeclaration<?> member : declaration.getMembers()) {
if (member instanceof TypeDeclaration)
member.accept(this, arg);
}
}
@Override
public void visit(ClassOrInterfaceDeclaration declaration, Void arg) {
visitTypeDeclaration(declaration, arg);
}
@Override
public void visit(EnumDeclaration declaration, Void arg) {
visitTypeDeclaration(declaration, arg);
}
@Override
public void visit(MethodDeclaration declaration, Void arg) {
if(!declaration.isPublic()) return;
System.out.println(" " + declaration.getDeclarationAsString(true, true));
}
}

View File

@@ -4,11 +4,13 @@ Pick a Java project from Github (see the [instructions](../sujet.md) for suggest
## Answer ## Answer
We clone the project `commons-math` Nous avons cloné le projet `commons-math`
https://github.com/apache/commons-math https://github.com/apache/commons-math
We found a problem that it's not worth to change
On a trouvé un problème quil ne vaut pas la peine de changer :
`./commons-math/commons-math-core/src/main/java/org/apache/commons/math4/core/jdkmath/AccurateMath.java:396: UselessParentheses: Useless parentheses around `0.5 * t`.` `./commons-math/commons-math-core/src/main/java/org/apache/commons/math4/core/jdkmath/AccurateMath.java:396: UselessParentheses: Useless parentheses around `0.5 * t`.`
And here is the code that PMD a indiqué:
Et voici le code que PMD a indiqué:
``` ```
if (x >= LOG_MAX_VALUE) { if (x >= LOG_MAX_VALUE) {
// Avoid overflow (MATH-905). // Avoid overflow (MATH-905).
@@ -16,9 +18,9 @@ And here is the code that PMD a indiqué:
return (0.5 * t) * t; return (0.5 * t) * t;
``` ```
As we can see the parentheses didn't cause any harm here but it is a true positive Comme on peut le voir, les parenthèses ne causent aucun problème ici, mais cest un vrai positif.
For a false positive, we found this one: Pour un faux positif, nous avons trouvé celui-ci:
`./commons-math/commons-math-legacy-core/src/test/java/org/apache/commons/math4/legacy/core/IntegerSequenceTest.java:255: UnusedLocalVariable: Avoid unused local variables such as 'inc'.` `./commons-math/commons-math-legacy-core/src/test/java/org/apache/commons/math4/legacy/core/IntegerSequenceTest.java:255: UnusedLocalVariable: Avoid unused local variables such as 'inc'.`
``` ```
@@ -33,4 +35,6 @@ For a false positive, we found this one:
``` ```
Because the purpose of the test is to trigger the bug when create object.
Parce que le but du test est de déclencher le bug lors de la création de lobjet.