refactory of DependencyGenerator, and add duck type output

This commit is contained in:
Gang ZHANG 2022-09-15 23:49:45 +08:00
parent 57f729a36c
commit 37e4783691
6 changed files with 103 additions and 169 deletions

View File

@ -46,7 +46,8 @@ public class DependencyType {
public static final String PomParent = "Parent";
public static final String PomPlugin = "Plugin";
public static final String PomDependency = "Dependency";
public static final String DuckTypingLabel = "(duck)";
public static ArrayList<String> allDependencies() {
ArrayList<String> depedencyTypes = new ArrayList<String>();

View File

@ -24,6 +24,7 @@ SOFTWARE.
package depends.generator;
import depends.entity.CandidateTypes;
import depends.entity.Entity;
import depends.entity.EntityNameBuilder;
import depends.entity.FileEntity;
@ -32,6 +33,7 @@ import depends.matrix.core.DependencyDetail;
import depends.matrix.core.DependencyMatrix;
import depends.matrix.core.LocationInfo;
import depends.matrix.transform.OrderedMatrixGenerator;
import depends.relations.Relation;
import multilang.depends.util.file.path.EmptyFilenameWritter;
import multilang.depends.util.file.path.FilenameWritter;
import multilang.depends.util.file.strip.EmptyLeadingNameStripper;
@ -39,8 +41,13 @@ import multilang.depends.util.file.strip.ILeadingNameStrippper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import static depends.deptypes.DependencyType.DuckTypingLabel;
public abstract class DependencyGenerator {
private static Logger logger = LoggerFactory.getLogger(DependencyGenerator.class);
@ -56,7 +63,74 @@ public abstract class DependencyGenerator {
return dependencyMatrix;
}
public abstract DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter);
/**
* Build the dependency matrix (without re-mapping file id)
* @param entityRepo which contains entities and relations
* @return the generated dependency matrix
*/
public DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter) {
DependencyMatrix dependencyMatrix = new DependencyMatrix(typeFilter);
Iterator<Entity> iterator = entityRepo.entityIterator();
System.out.println("Start create dependencies matrix....");
while(iterator.hasNext()) {
Entity entity = iterator.next();
if (!entity.inScope()) continue;
if (outputLevelMatch(entity)){
dependencyMatrix.addNode(nameOf(entity),entity.getId());
}
int entityFrom = upToOutputLevelEntityId(entityRepo, entity);
if (entityFrom==-1) continue;
for (Relation relation:entity.getRelations()) {
Entity relatedEntity = relation.getEntity();
if (relatedEntity==null) continue;
List<Entity> relatedEntities = expandEntity(relatedEntity);
String duckTypingFlag = relatedEntity instanceof CandidateTypes? DuckTypingLabel:"";
relatedEntities.forEach(theEntity->{
if (theEntity.getId()>=0) {
int entityTo = upToOutputLevelEntityId(entityRepo,theEntity);
if (entityTo!=-1) {
DependencyDetail detail = buildDescription(entity, theEntity, relation.getFromLine());
detail = rewriteDetail(detail);
dependencyMatrix.addDependency(relation.getType()+duckTypingFlag, entityFrom,entityTo,1,detail);
}
}
});
}
}
System.out.println("Finish create dependencies matrix....");
return dependencyMatrix;
}
private List<Entity> expandEntity(Entity relatedEntity) {
List<Entity> entities = new ArrayList<>();
if (relatedEntity instanceof CandidateTypes) {
entities = Collections.unmodifiableList((List) ((CandidateTypes) relatedEntity).getCandidateTypes());
}else {
entities.add(relatedEntity);
}
return entities;
}
private DependencyDetail rewriteDetail(DependencyDetail detail) {
if (detail==null) return null;
String srcFile = filenameWritter.reWrite(
stripper.stripFilename(detail.getSrc().getFile())
);
String dstFile = filenameWritter.reWrite(
stripper.stripFilename(detail.getDest().getFile()));
return new DependencyDetail(
new LocationInfo(detail.getSrc().getObject(),
srcFile, detail.getSrc().getLineNumber())
,
new LocationInfo(detail.getDest().getObject(),
dstFile, detail.getDest().getLineNumber()));
}
protected abstract int upToOutputLevelEntityId(EntityRepo entityRepo, Entity entity);
protected abstract String nameOf(Entity entity);
protected abstract boolean outputLevelMatch(Entity entity);
protected ILeadingNameStrippper stripper = new EmptyLeadingNameStripper();
protected FilenameWritter filenameWritter = new EmptyFilenameWritter();

View File

@ -24,88 +24,24 @@ SOFTWARE.
package depends.generator;
import depends.entity.CandidateTypes;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.TypeEntity;
import depends.entity.repo.EntityRepo;
import depends.matrix.core.DependencyDetail;
import depends.matrix.core.DependencyMatrix;
import depends.matrix.core.LocationInfo;
import depends.relations.Relation;
import java.util.Iterator;
import java.util.List;
public class FileDependencyGenerator extends DependencyGenerator{
/**
* Build the dependency matrix (without re-mapping file id)
* @param entityRepo which contains entities and relations
* @return the generated dependency matrix
*/
@Override
public DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter) {
DependencyMatrix dependencyMatrix = new DependencyMatrix(typeFilter);
Iterator<Entity> iterator = entityRepo.entityIterator();
System.out.println("Start create dependencies matrix....");
while(iterator.hasNext()) {
Entity entity = iterator.next();
if (!entity.inScope()) continue;
if (entity instanceof FileEntity){
String name = stripper.stripFilename(entity.getDisplayName());
name = filenameWritter.reWrite(name);
dependencyMatrix.addNode(name,entity.getId());
}
int fileEntityFrom = getFileEntityIdNoException(entityRepo, entity);
if (fileEntityFrom==-1) continue;
for (Relation relation:entity.getRelations()) {
Entity relatedEntity = relation.getEntity();
if (relatedEntity==null) continue;
if (relatedEntity instanceof CandidateTypes) {
List<TypeEntity> candidateTypes = ((CandidateTypes)relatedEntity).getCandidateTypes();
for (TypeEntity candidateType:candidateTypes) {
if (candidateType.getId()>=0) {
int fileEntityTo = getFileEntityIdNoException(entityRepo,candidateType);
if (fileEntityTo!=-1) {
DependencyDetail detail = buildDescription(entity,candidateType,relation.getFromLine());
detail = rewriteDetail(detail);
dependencyMatrix.addDependency(relation.getType(), fileEntityFrom,fileEntityTo,1,detail);
}
}
}
}else {
if (relatedEntity.getId()>=0) {
int fileEntityTo = getFileEntityIdNoException(entityRepo,relatedEntity);
if (fileEntityTo!=-1) {
DependencyDetail detail = buildDescription(entity, relatedEntity, relation.getFromLine());
detail = rewriteDetail(detail);
dependencyMatrix.addDependency(relation.getType(), fileEntityFrom,fileEntityTo,1,detail);
}
}
}
}
}
System.out.println("Finish create dependencies matrix....");
return dependencyMatrix;
protected String nameOf(Entity entity) {
String name = stripper.stripFilename(entity.getDisplayName());
return filenameWritter.reWrite(name);
}
private DependencyDetail rewriteDetail(DependencyDetail detail) {
if (detail==null) return null;
String srcFile = filenameWritter.reWrite(
stripper.stripFilename(detail.getSrc().getFile())
);
String dstFile = filenameWritter.reWrite(
stripper.stripFilename(detail.getDest().getFile()));
return new DependencyDetail(
new LocationInfo(detail.getSrc().getObject(),
srcFile, detail.getSrc().getLineNumber())
,
new LocationInfo(detail.getDest().getObject(),
dstFile, detail.getDest().getLineNumber()));
@Override
protected boolean outputLevelMatch(Entity entity) {
return (entity instanceof FileEntity);
}
private int getFileEntityIdNoException(EntityRepo entityRepo, Entity entity) {
@Override
protected int upToOutputLevelEntityId(EntityRepo entityRepo, Entity entity) {
Entity ancestor = entity.getAncestorOfType(FileEntity.class);
if (ancestor==null) {
return -1;

View File

@ -25,47 +25,19 @@ SOFTWARE.
package depends.generator;
import depends.entity.Entity;
import depends.entity.EntityNameBuilder;
import depends.entity.FileEntity;
import depends.entity.FunctionEntity;
import depends.entity.EntityNameBuilder;
import depends.entity.repo.EntityRepo;
import depends.matrix.core.DependencyMatrix;
import depends.relations.Relation;
import java.util.Iterator;
import java.util.List;
public class FunctionDependencyGenerator extends DependencyGenerator {
public DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter) {
DependencyMatrix dependencyMatrix = new DependencyMatrix(typeFilter);
Iterator<Entity> iterator = entityRepo.entityIterator();
while(iterator.hasNext()) {
Entity entity = iterator.next();
if (!entity.inScope()) continue;
if (entity instanceof FunctionEntity) {
String name = getFunctionEntityDisplayName((FunctionEntity)entity);
dependencyMatrix.addNode(name,entity.getId());
}
int entityFrom = getFunctionEntityIdNoException(entity);
if (entityFrom == -1)
continue;
for (Relation relation : entity.getRelations()) {
Entity relatedEntity = relation.getEntity();
if (relatedEntity==null) continue;
if (relatedEntity.getId() >= 0) {
int entityTo = getFunctionEntityIdNoException(relation.getEntity());
if (entityTo == -1)
continue;
dependencyMatrix.addDependency(relation.getType(), entityFrom, entityTo, 1,buildDescription(entity,
relation.getEntity(),relation.getFromLine()));
}
}
}
return dependencyMatrix;
@Override
protected boolean outputLevelMatch(Entity entity) {
return (entity instanceof FunctionEntity);
}
private String getFunctionEntityDisplayName(FunctionEntity entity) {
@Override
protected String nameOf(Entity entity) {
FileEntity file = (FileEntity) entity.getAncestorOfType(FileEntity.class);
String name = stripper.stripFilename(file.getRawName().uniqName());
name = filenameWritter.reWrite(name);
@ -75,8 +47,8 @@ public class FunctionDependencyGenerator extends DependencyGenerator {
return name;
}
private int getFunctionEntityIdNoException(Entity entity) {
@Override
protected int upToOutputLevelEntityId(EntityRepo entityRepo, Entity entity) {
Entity ancestor = entity.getAncestorOfType(FunctionEntity.class);
if (ancestor == null)
return -1;

View File

@ -26,68 +26,16 @@ package depends.generator;
import depends.entity.*;
import depends.entity.repo.EntityRepo;
import depends.matrix.core.DependencyDetail;
import depends.matrix.core.DependencyMatrix;
import depends.matrix.core.LocationInfo;
import depends.relations.Relation;
import java.util.Iterator;
import java.util.List;
public class StructureDependencyGenerator extends DependencyGenerator{
/**
* Build the dependency matrix (without re-mapping file id)
* @param entityRepo which contains entities and relations
* @return the generated dependency matrix
*/
@Override
public DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter) {
DependencyMatrix dependencyMatrix = new DependencyMatrix(typeFilter);
Iterator<Entity> iterator = entityRepo.entityIterator();
System.out.println("Start create dependencies matrix....");
while(iterator.hasNext()) {
Entity entity = iterator.next();
if (!entity.inScope()) continue;
if (isStructureEntityType(entity)){
String name = entity.getQualifiedName() + "|" + entity.getClass().getSimpleName().replace("Entity","");
dependencyMatrix.addNode(name,entity.getId());
}
int fileEntityFrom = getStructureEntityIdNoException(entity);
if (fileEntityFrom==-1) continue;
for (Relation relation:entity.getRelations()) {
Entity relatedEntity = relation.getEntity();
if (relatedEntity==null) continue;
if (relatedEntity instanceof CandidateTypes) {
List<TypeEntity> candidateTypes = ((CandidateTypes)relatedEntity).getCandidateTypes();
for (TypeEntity candidateType:candidateTypes) {
if (candidateType.getId()>=0) {
int fileEntityTo = getStructureEntityIdNoException(candidateType);
if (fileEntityTo!=-1) {
DependencyDetail detail = buildDescription(entity,candidateType,relation.getFromLine());
dependencyMatrix.addDependency(relation.getType(), fileEntityFrom,fileEntityTo,1,detail);
}
}
}
}else {
if (relatedEntity.getId()>=0) {
int fileEntityTo = getStructureEntityIdNoException(relatedEntity);
if (fileEntityTo!=-1) {
DependencyDetail detail = buildDescription(entity, relatedEntity, relation.getFromLine());
dependencyMatrix.addDependency(relation.getType(), fileEntityFrom,fileEntityTo,1,detail);
}
}
}
}
}
System.out.println("Finish create dependencies matrix....");
return dependencyMatrix;
protected String nameOf(Entity entity) {
return entity.getQualifiedName() + "|" + entity.getClass().getSimpleName().replace("Entity","");
}
private boolean isStructureEntityType(Entity entity) {
@Override
protected boolean outputLevelMatch(Entity entity) {
if (entity instanceof FileEntity) return false;
if (entity instanceof TypeEntity) return true; //package included
if (entity instanceof VarEntity && entity.getParent() instanceof TypeEntity) return true;
@ -95,7 +43,8 @@ public class StructureDependencyGenerator extends DependencyGenerator{
return false;
}
private int getStructureEntityIdNoException(Entity entity) {
@Override
protected int upToOutputLevelEntityId(EntityRepo entityRepo, Entity entity) {
Entity ancestor = getAncestorOfType(entity);
if (ancestor==null) {
return -1;
@ -106,7 +55,7 @@ public class StructureDependencyGenerator extends DependencyGenerator{
public Entity getAncestorOfType(Entity fromEntity) {
while(fromEntity!=null) {
if (isStructureEntityType(fromEntity))
if (outputLevelMatch(fromEntity))
return fromEntity;
if (fromEntity.getParent()==null) return null;
fromEntity = fromEntity.getParent();

View File

@ -31,6 +31,8 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import static depends.deptypes.DependencyType.DuckTypingLabel;
public class DependencyMatrix {
private HashMap<String, DependencyPair> dependencyPairs = new HashMap<>();
private ArrayList<String> nodes = new ArrayList<>();
@ -67,7 +69,7 @@ public class DependencyMatrix {
}
public void addDependency(String depType, Integer from, Integer to, int weight,DependencyDetail detail) {
if (typeFilter!=null && (!typeFilter.contains(depType)))
if (typeFilter!=null && (!typeFilter.contains(depType.replace(DuckTypingLabel,""))))
return;
if(from.equals(to) || from == -1 || to == -1) {
return;