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

Boutahar Naoual #29

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ Implémenter les règles suivantes :
| LINT_REG_003 |HIGH|Les variables locales commencent par une minuscule |
| LINT_REG_004 |HIGH|Les attributs d'une classe commencent par une minuscule |
| LINT_REG_005 |MEDIUM|Les constantes d'une classe sont écrites en majuscule, avec des `_` comme séparateur|
| LINT_REG_006 |HIGHEST|Les expressions booléennes ne doivent avoir plus que `2` opérandes |
| LINT_REG_007 |LOW|Les éléments d'une énumeration sont en majuscule, avec des `_` comme séparateur|
~~| LINT_REG_006 |HIGHEST|Les expressions booléennes ne doivent avoir plus que `2` opérandes |~~
~~| LINT_REG_007 |LOW|Les éléments d'une énumeration sont en majuscule, avec des `_` comme séparateur|~~
| LINT_REG_008 |HIGHEST|Le corps d'une méthode ne doit pas dépasser `30` lignes|
| LINT_REG_009 |HIGH|Les instanciations anonymes sont à remplacer par des expressions `lambda`|
| LINT_REG_010 |MEDIUM|Les expressions `lambda` intuitives sont à remplacer par `method reference` |
~~| LINT_REG_009 |HIGH|Les instanciations anonymes sont à remplacer par des expressions `lambda`|~~
~~| LINT_REG_010 |MEDIUM|Les expressions `lambda` intuitives sont à remplacer par `method reference` |~~
| LINT_REG_011 |HIGHEST|Le nombre de méthodes ne doit pas dépasser `20` méthodes déclarées par classe|
| LINT_REG_012 |HIGHEST|Le nombre de paramètres d'une méthode/constructeur ne doit dépasser `2`|
| LINT_REG_013 |HIGHEST|Les attributs de classe doivent avoir une visibilité déclarée|
| LINT_REG_014 |LOW|Préférer l'utilisation d'une seule instruction de sortie `(return, throw)` dans les méthodes|
| LINT_REG_015|LOW|Ne pas catcher les exceptions sans les logger|
| LINT_REG_016|MEDIUM|Les variables non utilisées sont à supprimer|
| LINT_REG_017|MEDIUM|Les méthodes privées non utilisées sont à supprimer|
| LINT_REG_018 |LOW|les clauses `if` , `else` doivent avoir des accolades |
~~| LINT_REG_012 |HIGHEST|Le nombre de paramètres d'une méthode/constructeur ne doit dépasser `2`|~~
~~| LINT_REG_013 |HIGHEST|Les attributs de classe doivent avoir une visibilité déclarée|~~
~~| LINT_REG_014 |LOW|Préférer l'utilisation d'une seule instruction de sortie `(return, throw)` dans les méthodes|~~
~~| LINT_REG_015|LOW|Ne pas catcher les exceptions sans les logger|~~
~~| LINT_REG_016|MEDIUM|Les variables non utilisées sont à supprimer|~~
~~| LINT_REG_017|MEDIUM|Les méthodes privées non utilisées sont à supprimer|~~
~~| LINT_REG_018 |LOW|les clauses `if` , `else` doivent avoir des accolades |~~

Si une règle est bloquante, alors remonter l'erreur est mettre fin à l'analyse du fichier en cours.
### INPUT :
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/ensao/gi5/lint/constantes/Constantes.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
public class Constantes {
public static final String LINT_REG_000 = "LINT_REG_000";
public static final String LINT_REG_001 = "LINT_REG_001";
public static final String LINT_REG_002 = "LINT_REG_002";
public static final String LINT_REG_003 = "LINT_REG_003";
public static final String LINT_REG_004 = "LINT_REG_004";
public static final String LINT_REG_005 ="LINT_REG_005" ;
public static final String LINT_REG_011 = "LINT_REG_011";
public static final String LINT_REG_008 = "LINT_REG_008";

private Constantes() {
throw new IllegalStateException("not to be instantiated");
Expand Down
47 changes: 47 additions & 0 deletions src/main/java/com/ensao/gi5/lint/rules/AttributesNamingRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.ensao.gi5.lint.rules;

import com.ensao.gi5.lint.constantes.Constantes;
import com.ensao.gi5.lint.rules.violations.Violation;
import com.ensao.gi5.lint.wrapper.CompilationUnitWrapper;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;

import java.util.List;

public class AttributesNamingRule extends Rule{

protected AttributesNamingRule(String id, Level level) {
super(Constantes.LINT_REG_004, Level.HIGH);
}

@Override
public void apply(CompilationUnitWrapper compilationUnit) {
final List<TypeDeclaration<?>> types = compilationUnit.getTypes();
types.stream()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use visitor pattern to avoid going through the structure

.forEach(type -> {
type.getMembers().stream()
.filter(member -> member instanceof FieldDeclaration && !((FieldDeclaration) member).isFinal())
.map(member -> (FieldDeclaration) member)
.forEach(field -> {
field.getVariables().stream()
.filter(variable -> !Character.isLowerCase(variable.getNameAsString().charAt(0)))
.forEach(variable -> {
String message = "attribute " + variable.getNameAsString() + " must start with lowercase letter.";
final Violation violation = new Violation();
violation.setDescription(message);
violation.setFileName(compilationUnit.getFileName());
violation.setLine(field.getBegin().get().line);
addViolation(violation);

});
});
});
}



@Override
public boolean isActive() {
return true;
}
}
39 changes: 39 additions & 0 deletions src/main/java/com/ensao/gi5/lint/rules/ConstantsNamingRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.ensao.gi5.lint.rules;

import com.ensao.gi5.lint.constantes.Constantes;
import com.ensao.gi5.lint.rules.violations.Violation;
import com.ensao.gi5.lint.wrapper.CompilationUnitWrapper;
import com.github.javaparser.ast.body.TypeDeclaration;

import java.util.List;

public class ConstantsNamingRule extends Rule{
protected ConstantsNamingRule() {
super(Constantes.LINT_REG_005, Level.MEDIUM);
}

@Override
public void apply(CompilationUnitWrapper compilationUnit) {
final List<TypeDeclaration<?>> types = compilationUnit.getTypes();

types.stream()
.forEach(type -> {
type.getFields().stream()
.filter(field -> field.isStatic() && field.isFinal() && !field.getVariables().get(0).getNameAsString().matches("^[A-Z_]+$"))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get(0) has to be generalized,
a declaration may have more than one field :

private String foo, bar;

.forEach(field -> {
String message = "The constant " + field.getVariables().get(0).getNameAsString() + " must be in uppercase and separated with _ .";
final Violation violation = new Violation();
violation.setDescription(message);
violation.setFileName(compilationUnit.getFileName());
violation.setLine(type.getName().getBegin().get().line);
addViolation(violation);
});
});

}

@Override
public boolean isActive() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.ensao.gi5.lint.rules;

import com.ensao.gi5.lint.constantes.Constantes;
import com.ensao.gi5.lint.rules.violations.Violation;
import com.ensao.gi5.lint.wrapper.CompilationUnitWrapper;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;

import java.util.List;

public class LocalVariablesNamingRule extends Rule {
protected LocalVariablesNamingRule() {
super(Constantes.LINT_REG_003, Level.HIGH);
}

@Override
public void apply(CompilationUnitWrapper compilationUnit) {
final List<TypeDeclaration<?>> types = compilationUnit.getTypes();
types.stream()
.forEach(type -> {
type.findAll(MethodDeclaration.class)
.stream()
.forEach(method -> {
method.findAll(VariableDeclarator.class)
.stream()
.filter(var -> !Character.isLowerCase(var.getNameAsString().charAt(0)))
.forEach(var -> {
String message = "The local variable " + var.getNameAsString() + " must start with lowercase letter.";
final Violation violation = new Violation();
violation.setDescription(message);
violation.setFileName(compilationUnit.getFileName());
violation.setLine(var.getName().getBegin().get().line);
addViolation(violation);
});
});
});
}


@Override
public boolean isActive() {
return true;
}
}
40 changes: 40 additions & 0 deletions src/main/java/com/ensao/gi5/lint/rules/MethodLinesRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.ensao.gi5.lint.rules;

import com.ensao.gi5.lint.constantes.Constantes;
import com.ensao.gi5.lint.rules.violations.Violation;
import com.ensao.gi5.lint.wrapper.CompilationUnitWrapper;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;

import java.util.List;

public class MethodLinesRule extends Rule{
protected MethodLinesRule(String id, Level level) {
super(Constantes.LINT_REG_008, Level.HIGHEST);
}

@Override
public void apply(CompilationUnitWrapper compilationUnitWrapper) {
List<TypeDeclaration<?>> types = compilationUnitWrapper.getTypes();
for (TypeDeclaration<?> type : types) {
List<MethodDeclaration> methods = type.getMethods();
for (MethodDeclaration method : methods) {
int lineCount = method.getEnd().get().line - method.getBegin().get().line;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optinal::get is to be called conditionally

if (lineCount > 30) {
String message = "The method " + method.getNameAsString() + " has a body that exceeds 30 lines.";
final Violation violation = new Violation();
violation.setDescription(message);
violation.setFileName(compilationUnitWrapper.getFileName());
violation.setLine(method.getBegin().get().line);
addViolation(violation);
}
}
}
}


@Override
public boolean isActive() {
return true;
}
}
38 changes: 38 additions & 0 deletions src/main/java/com/ensao/gi5/lint/rules/MethodsNumberRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.ensao.gi5.lint.rules;

import com.ensao.gi5.lint.constantes.Constantes;
import com.ensao.gi5.lint.rules.violations.Violation;
import com.ensao.gi5.lint.wrapper.CompilationUnitWrapper;
import com.github.javaparser.ast.body.TypeDeclaration;

import java.util.List;

public class MethodsNumberRule extends Rule{
protected MethodsNumberRule(String id, Level level) {
super(Constantes.LINT_REG_011, Level.HIGHEST);
}

@Override
public void apply(CompilationUnitWrapper compilationUnitWrapper) {
List<TypeDeclaration<?>> types = compilationUnitWrapper.getTypes();
for (TypeDeclaration<?> type : types) {
int methodCount = (int) type.getMethods().stream()
.filter(bodyDeclaration -> bodyDeclaration.isMethodDeclaration())
.count();
if (methodCount > 20) {
String message = "The class " + type.getNameAsString() + " has more than 20 methods declared.";
final Violation violation = new Violation();
violation.setDescription(message);
violation.setFileName(compilationUnitWrapper.getFileName());
violation.setLine(type.getName().getBegin().get().line);
addViolation(violation);
}
}
}


@Override
public boolean isActive() {
return true;
}
}
46 changes: 46 additions & 0 deletions src/main/java/com/ensao/gi5/lint/rules/TypesNamingRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.ensao.gi5.lint.rules;

import com.ensao.gi5.lint.rules.violations.Violation;
import com.ensao.gi5.lint.constantes.Constantes;
import com.ensao.gi5.lint.wrapper.CompilationUnitWrapper;
import com.github.javaparser.ast.body.TypeDeclaration;
import java.util.List;

public class TypesNamingRule extends Rule{

protected TypesNamingRule() {
super(Constantes.LINT_REG_002, Level.HIGHEST);
}

@Override
public void apply(CompilationUnitWrapper compilationUnit) {
// Obtenir tous les types déclarés dans le fichier
final List<TypeDeclaration<?>> types = compilationUnit.getTypes();

types.stream()
.filter(type -> !Character.isUpperCase(type.getNameAsString().charAt(0)) || type.getNameAsString().contains("_"))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!Character.isUpperCase ==> Character.isLowerCase

.forEach(type -> {
String message = "";
if (!Character.isUpperCase(type.getNameAsString().charAt(0))) {
message += "NAme of Type " + type.getNameAsString() + " must start with uppercase letter.";
}
if (type.getNameAsString().contains("_")) {
message += " Le nom du type " + type.getNameAsString() + " ne doit pas contenir de tirets bas.";
}
final Violation violation = new Violation();
violation.setDescription(message);
violation.setFileName(compilationUnit.getFileName());
violation.setLine(type.getName().getBegin().get().line);
addViolation(violation);
});



}

@Override
public boolean isActive() {
return true;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.visitor.VoidVisitor;

import java.util.ArrayList;
Expand All @@ -21,6 +22,9 @@ public CompilationUnitWrapper(CompilationUnit compilationUnit, String fileName)
}

public NodeList<ImportDeclaration> getImports() {return compilationUnit.getImports();}
public List<TypeDeclaration<?>> getTypes() {
return compilationUnit.getTypes();
}

public <A> void accept(VoidVisitor<A> v, A arg) {
compilationUnit.accept(v, arg);}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.ensao.gi5.lint.wrapper;

import java.lang.reflect.Modifier;
import com.github.javaparser.ast.body.TypeDeclaration;

public class TypeDeclarationWrapper {
private TypeDeclaration typeDeclaration;
private String fileName;

public TypeDeclarationWrapper(TypeDeclaration typeDeclaration, String fileName) {
this.typeDeclaration = typeDeclaration;
this.fileName = fileName;
}

public String getName() {
return typeDeclaration.getName().asString();
}

public String getFileName() {
return fileName;
}



public boolean isPrivate() {
return typeDeclaration.getModifiers().contains(Modifier.PRIVATE);
}

public boolean isProtected() {
return typeDeclaration.getModifiers().contains(Modifier.PROTECTED);
}

public boolean isPublic() {
return typeDeclaration.getModifiers().contains(Modifier.PUBLIC);
}
}