refactory: adjust expression resolve strategy
This commit is contained in:
parent
2cf795860d
commit
a778caf06c
|
@ -167,11 +167,6 @@ public class CandidateTypes extends TypeEntity {
|
|||
super.resolveExpressions(inferer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeEntity getLastExpressionType() {
|
||||
System.err.println("error: getLastExpressionType should not been invoked");
|
||||
return super.getLastExpressionType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMixin(GenericName moduleName) {
|
||||
|
|
|
@ -116,6 +116,7 @@ public abstract class ContainerEntity extends DecoratedEntity {
|
|||
public void addExpression(Object key, Expression expression) {
|
||||
expressions().put(key, expression);
|
||||
expressionList().add(expression);
|
||||
expressionCount = expressionList.size();
|
||||
}
|
||||
|
||||
public boolean containsExpression(Object key) {
|
||||
|
@ -133,10 +134,12 @@ public abstract class ContainerEntity extends DecoratedEntity {
|
|||
for (FunctionEntity func : this.getFunctions()) {
|
||||
func.inferLocalLevelEntities(inferer);
|
||||
}
|
||||
resolvedMixins = identiferToContainerEntity(inferer, getMixins());
|
||||
if (inferer.isEagerExpressionResolve()) {
|
||||
this.resolveExpressions(inferer);
|
||||
reloadExpression(inferer.getRepo());
|
||||
resolveExpressions(inferer);
|
||||
cacheExpressions();
|
||||
}
|
||||
resolvedMixins = identiferToContainerEntity(inferer, getMixins());
|
||||
}
|
||||
|
||||
private Collection<GenericName> getMixins() {
|
||||
|
@ -165,13 +168,18 @@ public abstract class ContainerEntity extends DecoratedEntity {
|
|||
* @param inferer
|
||||
*/
|
||||
public void resolveExpressions(Inferer inferer) {
|
||||
|
||||
if (this instanceof FunctionEntity) {
|
||||
((FunctionEntity)this).linkReturnToLastExpression();
|
||||
}
|
||||
|
||||
if (expressionList==null) return;
|
||||
if(expressionList.size()>10000) return;
|
||||
for (Expression expression : expressionList) {
|
||||
// 1. if expression's type existed, break;
|
||||
if (expression.getType() != null)
|
||||
continue;
|
||||
if (expression.isDot) { // wait for previous
|
||||
if (expression.isDot()) { // wait for previous
|
||||
continue;
|
||||
}
|
||||
if (expression.getRawType() == null && expression.getIdentifier() == null)
|
||||
|
@ -190,7 +198,7 @@ public abstract class ContainerEntity extends DecoratedEntity {
|
|||
String composedName = expression.getIdentifier().toString();
|
||||
Expression theExpr = expression;
|
||||
if (entity==null) {
|
||||
while(theExpr.getParent()!=null && theExpr.getParent().isDot) {
|
||||
while(theExpr.getParent()!=null && theExpr.getParent().isDot()) {
|
||||
theExpr = theExpr.getParent();
|
||||
if (theExpr.getIdentifier()==null) break;
|
||||
composedName = composedName + "." + theExpr.getIdentifier().toString();
|
||||
|
@ -251,7 +259,6 @@ public abstract class ContainerEntity extends DecoratedEntity {
|
|||
}
|
||||
|
||||
private void cacheExpressionListToFile() {
|
||||
expressionCount = this.expressionList.size();
|
||||
if (expressionCount ==0) return;
|
||||
try {
|
||||
FileOutputStream fileOut = new FileOutputStream(TemporaryFile.getInstance().exprPath(this.id));
|
||||
|
@ -284,15 +291,6 @@ public abstract class ContainerEntity extends DecoratedEntity {
|
|||
}
|
||||
}
|
||||
|
||||
public TypeEntity getLastExpressionType() {
|
||||
if (expressionList==null) return null;
|
||||
for (int i = this.expressionList.size() - 1; i >= 0; i--) {
|
||||
Expression expr = this.expressionList.get(i);
|
||||
if (expr.isStatement)
|
||||
return expr.getType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Expression> expressionList() {
|
||||
if (expressionList==null)
|
||||
|
@ -303,17 +301,6 @@ public abstract class ContainerEntity extends DecoratedEntity {
|
|||
public boolean containsExpression() {
|
||||
return expressions().size() > 0;
|
||||
}
|
||||
|
||||
public String dumpExpressions() {
|
||||
if (expressionList==null) return "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Expression exp : expressionList) {
|
||||
sb.append(exp.toString()).append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The entry point of lookup functions. It will treat multi-declare entities and
|
||||
|
|
|
@ -110,6 +110,7 @@ public abstract class Entity {
|
|||
public void addRelation(Relation relation) {
|
||||
if (relations==null)
|
||||
relations = new ArrayList<>();
|
||||
if (relation.getEntity()==null) return;
|
||||
relations.add(relation);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,59 +28,104 @@ import java.io.Serializable;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import depends.entity.repo.EntityRepo;
|
||||
import depends.relations.Inferer;
|
||||
|
||||
/**
|
||||
* Expression
|
||||
*/
|
||||
public class Expression implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Integer id;
|
||||
public String text; // for debug purpose
|
||||
private GenericName rawType; //the raw type name
|
||||
private GenericName identifier; // the varName, or method name, etc.
|
||||
public boolean isSet = false; // is a set relation from right to leftHand
|
||||
public boolean isDot = false; // is a dot expression, will decuce variable tfype left to right
|
||||
public boolean isCall() {
|
||||
return isCall;
|
||||
}
|
||||
|
||||
public void setCall(boolean isCall) {
|
||||
this.isCall = isCall;
|
||||
}
|
||||
|
||||
private String text; // for debug purpose
|
||||
private GenericName rawType; // the raw type name
|
||||
private GenericName identifier; // the varName, or method name, etc.
|
||||
private boolean isSet = false; // is a set relation from right to leftHand
|
||||
private boolean isDot = false; // is a dot expression, will decuce variable tfype left to right
|
||||
private boolean isCall = false;
|
||||
public boolean isLogic = false;
|
||||
public boolean isCreate = false;
|
||||
public boolean isCast = false;
|
||||
public boolean isThrow = false;
|
||||
public boolean isStatement = false; //statement is only used for return type calcuation in some langs such as ruby
|
||||
//they will not be treat as real expressions in case of relation calculation
|
||||
public boolean deriveTypeFromChild = true;
|
||||
public Integer deduceTypeBasedId; //by default, parent expression type determined by most left child
|
||||
|
||||
private boolean isLogic = false;
|
||||
private boolean isCreate = false;
|
||||
private boolean isCast = false;
|
||||
private boolean isThrow = false;
|
||||
private boolean isStatement = false; //statement is only used for return type calcuation in some langs such as ruby
|
||||
//they will not be treat as real expressions in case of relation calculation
|
||||
private boolean deriveTypeFromChild = true;
|
||||
private Integer deduceTypeBasedId; //by default, parent expression type determined by most left child
|
||||
|
||||
private Integer parentId = -1;
|
||||
private List<Integer> deducedTypeVarsId = new ArrayList<>();
|
||||
private List<Integer> deducedTypeFunctionsId = new ArrayList<>();
|
||||
|
||||
private transient Expression parent;
|
||||
private transient TypeEntity type; // the type we care - for relation calculation.
|
||||
//for leaf, it equals to referredEntity.getType. otherwise, depends on child's type strategy
|
||||
private transient Entity referredEntity;
|
||||
|
||||
private transient List<VarEntity> deducedTypeVars = new ArrayList<>();
|
||||
private List<Integer> deducedTypeVarsId = new ArrayList<>();
|
||||
|
||||
private transient List<FunctionEntity> deducedTypeFunctions= new ArrayList<>();
|
||||
public TypeEntity getType() {
|
||||
return type;
|
||||
private List<Integer> deducedTypeFunctionsId = new ArrayList<>();
|
||||
|
||||
private Integer referredEntityId;
|
||||
private transient Entity referredEntity;
|
||||
|
||||
private transient TypeEntity type; // the type we care - for relation calculation.
|
||||
//for leaf, it equals to referredEntity.getType. otherwise, depends on child's type strategy
|
||||
|
||||
/*
|
||||
* */
|
||||
|
||||
public Expression() {
|
||||
deducedTypeVars = new ArrayList<>();
|
||||
deducedTypeFunctions = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Expression(Integer id) {
|
||||
this.id = id;
|
||||
deducedTypeVars = new ArrayList<>();
|
||||
deducedTypeFunctions = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setType(TypeEntity type, Entity referredEntity, Inferer inferer) {
|
||||
if (this.referredEntity==null && referredEntity!=null) {
|
||||
this.referredEntity = referredEntity;
|
||||
public void reload(EntityRepo repo, ArrayList<Expression> expressionList) {
|
||||
this.deducedTypeFunctions = new ArrayList<>();
|
||||
this.deducedTypeVars = new ArrayList<>();
|
||||
|
||||
//recover parent relation
|
||||
if (parentId!=-1) {
|
||||
for (Expression expr:expressionList) {
|
||||
if (expr.id==parentId) {
|
||||
parent = expr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type instanceof CandidateTypes) {
|
||||
return ;
|
||||
//recover deducedTypeFunctionsId
|
||||
if (deducedTypeFunctionsId!=null) {
|
||||
for (Integer funcId:this.deducedTypeFunctionsId) {
|
||||
this.deducedTypeFunctions.add((FunctionEntity) repo.getEntity(funcId));
|
||||
}
|
||||
}
|
||||
|
||||
//recover deducedTypeVars
|
||||
if (deducedTypeVarsId!=null) {
|
||||
for (Integer varId:this.deducedTypeVarsId) {
|
||||
this.deducedTypeVars.add((VarEntity) repo.getEntity(varId));
|
||||
}
|
||||
}
|
||||
|
||||
//referer referredEntity -- TODO:maybe not require
|
||||
if (this.referredEntityId!=null && this.referredEntity==null)
|
||||
this.referredEntity = repo.getEntity(this.referredEntityId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set type of the expression
|
||||
* @param type
|
||||
* @param referredEntity
|
||||
* @param inferer
|
||||
*/
|
||||
public void setType(TypeEntity type, Entity referredEntity, Inferer inferer) {
|
||||
if (this.getReferredEntity()==null && referredEntity!=null) {
|
||||
this.setReferredEntity(referredEntity);
|
||||
}
|
||||
|
||||
boolean changedType = false;
|
||||
if (this.type==null && type!=null) {
|
||||
this.type = type;
|
||||
|
@ -97,38 +142,12 @@ public class Expression implements Serializable{
|
|||
changedType = true;
|
||||
}
|
||||
if (this.referredEntity==null)
|
||||
this.referredEntity = this.type;
|
||||
this.setReferredEntity(this.type);
|
||||
|
||||
if (changedType)
|
||||
deduceTheParentType(inferer);
|
||||
}
|
||||
|
||||
public Expression() {
|
||||
deducedTypeVars = new ArrayList<>();
|
||||
deducedTypeFunctions = new ArrayList<>();
|
||||
}
|
||||
public Expression(Integer id) {
|
||||
this.id = id;
|
||||
deducedTypeVars = new ArrayList<>();
|
||||
deducedTypeFunctions = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append("[").append(text).append("]").append("|")
|
||||
.append("rawType:").append(rawType).append("|")
|
||||
.append("identifier:").append(identifier).append("|")
|
||||
.append("prop:").append(isDot?"[dot]":"")
|
||||
.append(isSet?"[set]":"")
|
||||
.append(isLogic?"[bool]":"")
|
||||
.append(isCall?"[call]":"").append("|")
|
||||
.append(isCreate?"[new]":"").append("|")
|
||||
.append(isThrow?"[throw]":"").append("|")
|
||||
.append("parent:").append(parent==null?"nil":parent.text).append("|")
|
||||
.append("type:").append(type).append("|");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* deduce type of parent based on child's type
|
||||
|
@ -183,19 +202,16 @@ public class Expression implements Serializable{
|
|||
else {
|
||||
parent.setType(type, null, inferer);
|
||||
}
|
||||
if (parent.referredEntity==null)
|
||||
parent.referredEntity = parent.type;
|
||||
if (parent.getReferredEntity()==null)
|
||||
parent.setReferredEntity(parent.type);
|
||||
}
|
||||
|
||||
private void setReferredEntity(Entity referredEntity) {
|
||||
this.referredEntity = referredEntity;
|
||||
if (this.referredEntity!=null)
|
||||
this.referredEntityId = referredEntity.getId();
|
||||
}
|
||||
|
||||
public Entity getReferredEntity() {
|
||||
return referredEntity;
|
||||
}
|
||||
|
||||
|
||||
public void addDeducedTypeVar(VarEntity var) {
|
||||
this.deducedTypeVars.add(var);
|
||||
this.deducedTypeVarsId.add(var.getId());
|
||||
|
@ -219,30 +235,6 @@ public class Expression implements Serializable{
|
|||
}
|
||||
}
|
||||
|
||||
public void reload(EntityRepo repo, ArrayList<Expression> expressionList) {
|
||||
this.deducedTypeFunctions = new ArrayList<>();
|
||||
this.deducedTypeVars = new ArrayList<>();
|
||||
if (parentId!=-1) {
|
||||
for (Expression expr:expressionList) {
|
||||
if (expr.id==parentId) {
|
||||
parent = expr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (deducedTypeFunctionsId!=null) {
|
||||
for (Integer funcId:this.deducedTypeFunctionsId) {
|
||||
this.deducedTypeFunctions.add((FunctionEntity) repo.getEntity(funcId));
|
||||
}
|
||||
}
|
||||
|
||||
if (deducedTypeVarsId!=null) {
|
||||
for (Integer varId:this.deducedTypeVarsId) {
|
||||
this.deducedTypeVars.add((VarEntity) repo.getEntity(varId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GenericName getIdentifier() {
|
||||
return this.identifier;
|
||||
|
@ -259,17 +251,6 @@ public class Expression implements Serializable{
|
|||
this.identifier = GenericName.build(name);
|
||||
}
|
||||
|
||||
private boolean validName(String name) {
|
||||
if (name==null) return false;
|
||||
if (name.toLowerCase().equals("<literal>")) return true;
|
||||
if (name.toLowerCase().equals("<built-in>")) return true;
|
||||
boolean result = name.matches("([a-zA-Z0-9_]|(\\.)|(\\-))*");
|
||||
// if (result==false) {
|
||||
// System.err.println("expression name " + name);
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setIdentifier(GenericName name) {
|
||||
if (name==null) return;
|
||||
if (!validName(name.getName())){
|
||||
|
@ -298,6 +279,110 @@ public class Expression implements Serializable{
|
|||
public Expression getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
|
||||
public boolean isCall() {
|
||||
return isCall;
|
||||
}
|
||||
|
||||
public boolean isSet() {
|
||||
return isSet;
|
||||
}
|
||||
|
||||
public void setSet(boolean isSet) {
|
||||
this.isSet = isSet;
|
||||
}
|
||||
|
||||
public boolean isDot() {
|
||||
return isDot;
|
||||
}
|
||||
|
||||
public void setDot(boolean isDot) {
|
||||
this.isDot = isDot;
|
||||
}
|
||||
|
||||
public boolean isLogic() {
|
||||
return isLogic;
|
||||
}
|
||||
|
||||
public void setLogic(boolean isLogic) {
|
||||
this.isLogic = isLogic;
|
||||
}
|
||||
|
||||
public boolean isCreate() {
|
||||
return isCreate;
|
||||
}
|
||||
|
||||
public void setCreate(boolean isCreate) {
|
||||
this.isCreate = isCreate;
|
||||
}
|
||||
|
||||
public boolean isCast() {
|
||||
return isCast;
|
||||
}
|
||||
|
||||
public void setCast(boolean isCast) {
|
||||
this.isCast = isCast;
|
||||
}
|
||||
|
||||
public boolean isThrow() {
|
||||
return isThrow;
|
||||
}
|
||||
|
||||
public void setThrow(boolean isThrow) {
|
||||
this.isThrow = isThrow;
|
||||
}
|
||||
|
||||
public boolean isStatement() {
|
||||
return isStatement;
|
||||
}
|
||||
|
||||
public void setStatement(boolean isStatement) {
|
||||
this.isStatement = isStatement;
|
||||
}
|
||||
|
||||
public void setCall(boolean isCall) {
|
||||
this.isCall = isCall;
|
||||
}
|
||||
|
||||
public void disableDriveTypeFromChild() {
|
||||
deriveTypeFromChild = false ;
|
||||
}
|
||||
|
||||
public Entity getReferredEntity() {
|
||||
return referredEntity;
|
||||
}
|
||||
|
||||
public TypeEntity getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
private boolean validName(String name) {
|
||||
if (name==null) return false;
|
||||
if (name.toLowerCase().equals("<literal>")) return true;
|
||||
if (name.toLowerCase().equals("<built-in>")) return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append("[").append(text).append("]").append("|")
|
||||
.append("rawType:").append(rawType).append("|")
|
||||
.append("identifier:").append(identifier).append("|")
|
||||
.append("prop:").append(isDot?"[dot]":"")
|
||||
.append(isSet?"[set]":"")
|
||||
.append(isLogic?"[bool]":"")
|
||||
.append(isCall?"[call]":"")
|
||||
.append(isCreate?"[new]":"")
|
||||
.append(isThrow?"[throw]":"").append("|")
|
||||
.append("parent:").append(parent==null?"nil":parent.text).append("|")
|
||||
.append("type:").append(type).append("|");
|
||||
return s.toString();
|
||||
}
|
||||
}
|
|
@ -94,9 +94,6 @@ public class FunctionEntity extends ContainerEntity{
|
|||
if (throwTypes.size()<throwTypesIdentifiers.size())
|
||||
throwTypes = identiferToEntities(inferer,this.throwTypesIdentifiers);
|
||||
super.inferLocalLevelEntities(inferer);
|
||||
if (this.returnTypes.size()==0 && this.getLastExpressionType()!=null) {
|
||||
this.returnTypes.add(this.getLastExpressionType());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,6 +137,13 @@ public class FunctionEntity extends ContainerEntity{
|
|||
}
|
||||
return super.lookupVarLocally(varName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void linkReturnToLastExpression() {
|
||||
if (expressionList()==null) return;
|
||||
for (int i = expressionList().size() - 1; i >= 0; i--) {
|
||||
Expression expr = expressionList().get(i);
|
||||
if (expr.isStatement())
|
||||
expr.addDeducedTypeFunction(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,11 +62,12 @@ public abstract class HandlerContext {
|
|||
currentFileEntity = new FileEntity(fileName, idGenerator.generateId(),true);
|
||||
pushToStack(currentFileEntity);
|
||||
entityRepo.add(currentFileEntity);
|
||||
entityRepo.addFile(currentFileEntity);
|
||||
return currentFileEntity;
|
||||
}
|
||||
|
||||
|
||||
public void done() {
|
||||
entityRepo.addFile(this.currentFile());
|
||||
}
|
||||
|
||||
public TypeEntity foundNewType(GenericName name) {
|
||||
TypeEntity currentTypeEntity = new TypeEntity(name, this.latestValidContainer(),
|
||||
|
|
|
@ -70,9 +70,6 @@ public class CppHandlerContext extends HandlerContext {
|
|||
return functionEntity;
|
||||
}
|
||||
|
||||
public void doneFile(FileEntity currentFile) {
|
||||
entityRepo.addFile(currentFileEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileEntity startFile(String fileName) {
|
||||
|
|
|
@ -90,6 +90,7 @@ public class CdtCppFileParser extends CppFileParser {
|
|||
tu.accept(bridge);
|
||||
fileEntity = entityRepo.getEntity(fileFullPath);
|
||||
((FileEntity)fileEntity).cacheAllExpressions();
|
||||
bridge.done();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,8 +98,6 @@ public class CppVisitor extends ASTVisitor {
|
|||
|
||||
@Override
|
||||
public int visit(IASTTranslationUnit tu) {
|
||||
context.doneFile(context.currentFile());
|
||||
|
||||
for (String incl:preprocessorHandler.getDirectIncludedFiles(tu.getAllPreprocessorStatements(),context.currentFile().getQualifiedName())) {
|
||||
context.foundNewImport(new FileImport(incl));
|
||||
}
|
||||
|
@ -372,4 +370,8 @@ public class CppVisitor extends ASTVisitor {
|
|||
}
|
||||
return super.visit(parameterDeclaration);
|
||||
}
|
||||
|
||||
public void done() {
|
||||
context.done();
|
||||
}
|
||||
}
|
|
@ -60,13 +60,13 @@ public class ExpressionUsage {
|
|||
Expression parent = findParentInStack(ctx);
|
||||
//If parent already a call
|
||||
if (parent!=null ) {
|
||||
if (ctx instanceof IASTIdExpression && (parent.isCall() || parent.isCast)) {
|
||||
if (ctx instanceof IASTIdExpression && (parent.isCall() || parent.isCast())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* create expression and link it with parent*/
|
||||
Expression expression = new Expression(idGenerator.generateId());
|
||||
expression.text = ctx.getRawSignature(); //for debug purpose. no actual effect
|
||||
expression.setText( ctx.getRawSignature());
|
||||
context.lastContainer().addExpression(ctx,expression);
|
||||
expression.setParent(parent);
|
||||
|
||||
|
@ -76,13 +76,13 @@ public class ExpressionUsage {
|
|||
return;
|
||||
}
|
||||
|
||||
expression.isSet = isSet(ctx);
|
||||
expression.setSet(isSet(ctx));
|
||||
expression.setCall((ctx instanceof IASTFunctionCallExpression)?true:false);
|
||||
expression.isLogic = isLogic(ctx);
|
||||
expression.setLogic(isLogic(ctx));
|
||||
if (ctx instanceof ICPPASTNewExpression){
|
||||
expression.isCreate = true;
|
||||
expression.setCreate(true);;
|
||||
}
|
||||
expression.isDot = isDot(ctx);
|
||||
expression.setDot(isDot(ctx));
|
||||
|
||||
/**
|
||||
* | expression bop='.'
|
||||
|
@ -99,16 +99,16 @@ public class ExpressionUsage {
|
|||
if (ctx instanceof ICPPASTNewExpression) {
|
||||
expression.setRawType(GenericName.build(ASTStringUtilExt.getTypeIdString(((ICPPASTNewExpression)ctx).getTypeId())));
|
||||
expression.setCall(true);
|
||||
expression.deriveTypeFromChild = false;
|
||||
expression.disableDriveTypeFromChild();
|
||||
}
|
||||
|
||||
if (ctx instanceof IASTCastExpression) {
|
||||
expression.isCast=true;
|
||||
expression.setCast(true);
|
||||
expression.setRawType(GenericName.build(ASTStringUtilExt.getTypeIdString(((IASTCastExpression)ctx).getTypeId())));
|
||||
expression.deriveTypeFromChild = false;
|
||||
expression.disableDriveTypeFromChild();
|
||||
|
||||
}
|
||||
if (expression.isDot) {
|
||||
if (expression.isDot()) {
|
||||
IASTExpression op2 = ((IASTBinaryExpression)ctx).getOperand2();
|
||||
if (op2 instanceof IASTIdExpression)
|
||||
expression.setIdentifier(ASTStringUtilExt.getName(((IASTIdExpression)op2).getName()));
|
||||
|
|
|
@ -69,6 +69,7 @@ public class JavaFileParser implements depends.extractor.FileParser{
|
|||
Entity fileEntity = entityRepo.getEntity(fileFullPath);
|
||||
((FileEntity)fileEntity).cacheAllExpressions();
|
||||
interpreter.clearDFA();
|
||||
bridge.done();
|
||||
|
||||
}catch (Exception e) {
|
||||
System.err.println("error encountered during parse..." );
|
||||
|
|
|
@ -361,6 +361,9 @@ public class JavaListener extends JavaParserBaseListener {
|
|||
context.currentType().addTypeParameter(GenericName.build(typeParam.IDENTIFIER().getText()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void done() {
|
||||
context.done();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,12 +56,12 @@ public class ExpressionUsage {
|
|||
return;
|
||||
}
|
||||
|
||||
expression.isSet = isSet(ctx);
|
||||
expression.setSet (isSet(ctx));
|
||||
expression.setCall(ctx.methodCall()==null?false:true);
|
||||
expression.isLogic = isLogic(ctx);
|
||||
expression.isDot = isDot(ctx);
|
||||
expression.setLogic (isLogic(ctx));
|
||||
expression.setDot(isDot(ctx));
|
||||
if (ctx.creator()!=null ||ctx.innerCreator()!=null){
|
||||
expression.isCreate = true;
|
||||
expression.setCreate( true);
|
||||
}
|
||||
/**
|
||||
* | expression bop='.'
|
||||
|
@ -82,26 +82,26 @@ public class ExpressionUsage {
|
|||
if (ctx.NEW()!=null && ctx.creator()!=null) {
|
||||
expression.setRawType(CreatorContextHelper.getCreatorType(ctx.creator()));
|
||||
expression.setCall(true);
|
||||
expression.deriveTypeFromChild = false;
|
||||
expression.disableDriveTypeFromChild();
|
||||
}
|
||||
|
||||
if (ctx.typeCast()!=null) {
|
||||
expression.isCast=true;
|
||||
expression.setCast(true);
|
||||
expression.setRawType(ctx.typeCast().typeType().getText());
|
||||
expression.deriveTypeFromChild = false;
|
||||
expression.disableDriveTypeFromChild();
|
||||
}
|
||||
|
||||
if (ctx.bop!=null && ctx.bop.getText().equals("instanceof")) {
|
||||
expression.isCast=true;
|
||||
expression.setCast(true);
|
||||
expression.setRawType(ctx.typeType().getText());
|
||||
expression.deriveTypeFromChild = false;
|
||||
expression.disableDriveTypeFromChild();
|
||||
}
|
||||
|
||||
if (ctx.creator()!=null) {
|
||||
expression.deriveTypeFromChild = false;
|
||||
expression.disableDriveTypeFromChild();
|
||||
}
|
||||
|
||||
if (expression.isDot) {
|
||||
if (expression.isDot()) {
|
||||
if (ctx.IDENTIFIER()!=null)
|
||||
expression.setIdentifier(ctx.IDENTIFIER().getText());
|
||||
else if (ctx.methodCall()!=null)
|
||||
|
|
|
@ -74,7 +74,7 @@ public class PomFileParser implements FileParser {
|
|||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(bridge, parser.document());
|
||||
fileEntity = entityRepo.getEntity(fileFullPath);
|
||||
// fileEntity.inferEntities(inferer);
|
||||
bridge.done();
|
||||
((FileEntity)fileEntity).cacheAllExpressions();
|
||||
}
|
||||
|
||||
|
|
|
@ -164,5 +164,8 @@ public class PomListener extends XMLParserBaseListener {
|
|||
return name;
|
||||
}
|
||||
|
||||
public void done() {
|
||||
context.done();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public class ExpressionUsage {
|
|||
}else {
|
||||
/* create expression and link it with parent*/
|
||||
expression = new Expression(idGenerator.generateId());
|
||||
expression.text = ctx.getText();
|
||||
expression.setText(ctx.getText());
|
||||
context.lastContainer().addExpression(ctx,expression);
|
||||
expression.setParent(parent);
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ public class ExpressionUsage {
|
|||
if (ctx instanceof Expr_stmtContext) {
|
||||
Expr_stmtContext exprAssign = (Expr_stmtContext)ctx;
|
||||
if (exprAssign.assign_part()!=null) {
|
||||
expression.isSet = true;
|
||||
expression.setSet(true);
|
||||
expression.setIdentifier(exprAssign.testlist_star_expr().getText());
|
||||
if (isValidIdentifier(expression.getIdentifier())) {
|
||||
makeSureVarExist(expression.getIdentifier());
|
||||
|
@ -100,8 +100,7 @@ public class ExpressionUsage {
|
|||
}
|
||||
}
|
||||
if (ctx instanceof Raise_stmtContext) {
|
||||
expression.isThrow = true;
|
||||
expression.deriveTypeFromChild = true;
|
||||
expression.setThrow (true);
|
||||
}
|
||||
if (ctx instanceof Return_stmtContext) {
|
||||
deduceReturnTypeInCaseOfReturn((Return_stmtContext)ctx,expression);
|
||||
|
@ -141,7 +140,7 @@ public class ExpressionUsage {
|
|||
//atom
|
||||
Expression atomExpr = new Expression(idGenerator.generateId());
|
||||
atomExpr.setParent(expression);
|
||||
atomExpr.text = exprCtx.atom().getText();
|
||||
atomExpr.setText(exprCtx.atom().getText());
|
||||
atomExpr.setIdentifier(exprCtx.atom().getText());
|
||||
context.lastContainer().addExpression(exprCtx.atom(),atomExpr);
|
||||
processAtom(exprCtx.atom(),atomExpr);
|
||||
|
@ -152,12 +151,12 @@ public class ExpressionUsage {
|
|||
for (TrailerContext trailer:exprCtx.trailer()) {
|
||||
if (trailer.name()!=null) {
|
||||
Expression trailerExpr = new Expression(idGenerator.generateId());
|
||||
trailerExpr.text = trailer.getText();
|
||||
trailerExpr.setText(trailer.getText());
|
||||
context.lastContainer().addExpression(trailer,trailerExpr);
|
||||
trailerExpr.setParent(expression);
|
||||
|
||||
//doted name = member access or method call
|
||||
trailerExpr.isDot = true;
|
||||
trailerExpr.setDot(true);;
|
||||
trailerExpr.setIdentifier(trailer.name().getText());
|
||||
if (trailer.arguments()!=null) {
|
||||
if (trailer.arguments().OPEN_PAREN()!=null) {
|
||||
|
@ -218,7 +217,7 @@ public class ExpressionUsage {
|
|||
}
|
||||
Entity typeEntity = context.foundEntityWithName(funcName);
|
||||
if (typeEntity instanceof TypeEntity && typeEntity.getId() > 0) {
|
||||
theExpression.isCreate = true;
|
||||
theExpression.setCreate(true);
|
||||
theExpression.setType(typeEntity.getType(), typeEntity, inferer);
|
||||
theExpression.setRawType(typeEntity.getRawName());
|
||||
return;
|
||||
|
@ -232,7 +231,7 @@ public class ExpressionUsage {
|
|||
GenericName funcName = theExpression.getIdentifier();
|
||||
Entity typeEntity = context.foundEntityWithName(funcName);
|
||||
if (typeEntity instanceof TypeEntity && typeEntity.getId() > 0) {
|
||||
theExpression.getParent().isCreate = true;
|
||||
theExpression.getParent().setCreate(true);
|
||||
theExpression.setType(typeEntity.getType(), typeEntity, inferer);
|
||||
theExpression.getParent().setRawType(typeEntity.getRawName());
|
||||
return;
|
||||
|
|
|
@ -384,5 +384,7 @@ public class PythonCodeListener extends PythonParserBaseListener{
|
|||
expressionUsage.stopExpr();
|
||||
super.exitAssert_stmt(ctx);
|
||||
}
|
||||
|
||||
public void done() {
|
||||
context.done();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,10 +50,9 @@ public class PythonFileParser implements FileParser {
|
|||
PythonCodeListener bridge = new PythonCodeListener(fileFullPath, entityRepo,inferer, includeFileLocator, processor);
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(bridge, parser.file_input());
|
||||
|
||||
fileEntity = entityRepo.getEntity(fileFullPath);
|
||||
fileEntity.inferEntities(inferer);
|
||||
((FileEntity)fileEntity).cacheAllExpressions();
|
||||
bridge.done();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -81,10 +81,10 @@ public class ExpressionUsage {
|
|||
Expression parent = findParentInStack(ctx);
|
||||
/* create expression and link it with parent */
|
||||
expression = new Expression(idGenerator.generateId());
|
||||
expression.text = ctx.toString();
|
||||
expression.setText(ctx.toString());
|
||||
expression.setParent(parent);
|
||||
if (ctx instanceof NewlineNode) {
|
||||
expression.isStatement = true;
|
||||
expression.setStatement(true);
|
||||
}
|
||||
|
||||
context.lastContainer().addExpression(ctx, expression);
|
||||
|
@ -105,12 +105,12 @@ public class ExpressionUsage {
|
|||
expression.setIdentifier(helper.getName(ctx));
|
||||
}
|
||||
if (ctx instanceof AssignableNode) {
|
||||
expression.isSet = true;
|
||||
expression.setSet(true);
|
||||
} else if (helper.isFunctionCall(ctx)) {
|
||||
String name = helper.getName(ctx);
|
||||
expression.setCall(true);
|
||||
if (name.equals("new")) {
|
||||
expression.isCreate = true;
|
||||
expression.setCreate(true);
|
||||
List<Node> childNodes = ctx.childNodes();
|
||||
if (childNodes.size() > 0) {
|
||||
expression.setIdentifier(helper.getName(ctx.childNodes().get(0)));
|
||||
|
@ -118,10 +118,9 @@ public class ExpressionUsage {
|
|||
expression.setIdentifier(context.currentType().getRawName());
|
||||
}
|
||||
expression.setRawType(expression.getIdentifier());
|
||||
expression.deriveTypeFromChild = false;
|
||||
expression.disableDriveTypeFromChild();
|
||||
} else if (name.equals("raise")) {
|
||||
expression.isThrow = true;
|
||||
expression.deriveTypeFromChild = true;
|
||||
expression.setThrow (true);
|
||||
} else if (helper.isArithMeticOperator(name)) {
|
||||
expression.setIdentifier("<operator>");
|
||||
expression.setRawType(Inferer.buildInType.getQualifiedName());
|
||||
|
@ -129,11 +128,11 @@ public class ExpressionUsage {
|
|||
expression.setIdentifier(name);
|
||||
expression.setRawType(helper.getReciever(ctx));
|
||||
if (expression.getRawType() != null) {
|
||||
expression.isDot = true;
|
||||
expression.setDot(true);
|
||||
}
|
||||
|
||||
if (ctx instanceof VCallNode || ctx instanceof FCallNode) {
|
||||
expression.deriveTypeFromChild = false;
|
||||
expression.disableDriveTypeFromChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.concurrent.ExecutorService;
|
|||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.jrubyparser.CompatVersion;
|
||||
import org.jrubyparser.NodeVisitor;
|
||||
import org.jrubyparser.Parser;
|
||||
import org.jrubyparser.ast.Node;
|
||||
import org.jrubyparser.parser.ParserConfiguration;
|
||||
|
@ -79,10 +80,11 @@ public class JRubyFileParser implements FileParser {
|
|||
ParserConfiguration config = new ParserConfiguration(0, version);
|
||||
try {
|
||||
Node node = rubyParser.parse("<code>", in, config);
|
||||
node.accept(new JRubyVisitor(fileFullPath, entityRepo, includesFileLocator,executor,inferer,parserCreator));
|
||||
JRubyVisitor parser = new JRubyVisitor(fileFullPath, entityRepo, includesFileLocator,executor,inferer,parserCreator);
|
||||
node.accept(parser);
|
||||
fileEntity = entityRepo.getEntity(fileFullPath);
|
||||
fileEntity.inferEntities(inferer);
|
||||
((FileEntity)fileEntity).cacheAllExpressions();
|
||||
parser.done();
|
||||
}catch(Exception e) {
|
||||
System.err.println("parsing error in "+fileFullPath);
|
||||
}
|
||||
|
|
|
@ -307,4 +307,8 @@ public class JRubyVisitor extends NoopVisitor {
|
|||
expressionUsage.foundExpression(node);
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
public void done() {
|
||||
context.done();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -342,5 +342,9 @@ public class Inferer {
|
|||
this.isCollectUnsolvedBindings = isCollectUnsolvedBindings;
|
||||
}
|
||||
|
||||
public EntityRepo getRepo() {
|
||||
return repo;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -86,8 +86,6 @@ public class RelationCounter {
|
|||
|
||||
|
||||
private void computeContainerRelations(ContainerEntity entity) {
|
||||
entity.reloadExpression(repo);
|
||||
entity.resolveExpressions(inferer);
|
||||
for (VarEntity var:entity.getVars()) {
|
||||
if (var.getType()!=null)
|
||||
entity.addRelation(buildRelation(DependencyType.CONTAIN,var.getType()));
|
||||
|
@ -105,15 +103,18 @@ public class RelationCounter {
|
|||
entity.addRelation(buildRelation(DependencyType.MIXIN,mixin));
|
||||
}
|
||||
|
||||
entity.reloadExpression(repo);
|
||||
if (!inferer.isEagerExpressionResolve())
|
||||
{
|
||||
entity.resolveExpressions(inferer);
|
||||
}
|
||||
for (Expression expression:entity.expressionList()){
|
||||
if (expression.isStatement) {
|
||||
if (expression.isStatement()) {
|
||||
continue;
|
||||
}
|
||||
Entity referredEntity = expression.getReferredEntity();
|
||||
addRelationFromExpression(entity, expression, referredEntity);
|
||||
}
|
||||
|
||||
|
||||
entity.clearExpressions();
|
||||
}
|
||||
|
||||
|
@ -148,15 +149,15 @@ public class RelationCounter {
|
|||
matched = true;
|
||||
|
||||
}
|
||||
if (expression.isCreate) {
|
||||
if (expression.isCreate()) {
|
||||
entity.addRelation(buildRelation(DependencyType.CREATE,referredEntity));
|
||||
matched = true;
|
||||
}
|
||||
if (expression.isThrow) {
|
||||
if (expression.isThrow()) {
|
||||
entity.addRelation(buildRelation(DependencyType.THROW,referredEntity));
|
||||
matched = true;
|
||||
}
|
||||
if (expression.isCast) {
|
||||
if (expression.isCast()) {
|
||||
entity.addRelation(buildRelation(DependencyType.CAST,referredEntity));
|
||||
matched = true;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ public abstract class ParserTest {
|
|||
for (Relation r:inEntity.getRelations()) {
|
||||
if (r.getType().equals(dependencyType)) {
|
||||
relation = r;
|
||||
if (r.getEntity()==null) continue;
|
||||
if (r.getEntity().getQualifiedName().equals(dependedEntityFullName))
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ public class DuplicateDeclarationTest extends CppParserTest {
|
|||
public void duplication_declaration_should_be_resolved() throws IOException {
|
||||
|
||||
String[] srcs = new String[] {
|
||||
" ",
|
||||
"./src/test/resources/cpp-code-examples/DuplicationDeclarationCouldBeResolved.cpp",
|
||||
};
|
||||
|
||||
for (String src:srcs) {
|
||||
|
|
|
@ -6,7 +6,9 @@ import java.io.IOException;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import depends.deptypes.DependencyType;
|
||||
import depends.entity.Entity;
|
||||
import depends.relations.Inferer;
|
||||
|
||||
public class UsingTest extends CppParserTest{
|
||||
@Before
|
||||
|
@ -26,7 +28,10 @@ public class UsingTest extends CppParserTest{
|
|||
}
|
||||
inferer.resolveAllBindings();
|
||||
Entity e = repo.getEntity("foo");
|
||||
assertEquals(4,e.getRelations().size());
|
||||
this.assertContainsRelation(e, DependencyType.RETURN, Inferer.buildInType.getQualifiedName());
|
||||
this.assertContainsRelation(e, DependencyType.CONTAIN, "A.C");
|
||||
this.assertContainsRelation(e, DependencyType.CONTAIN, "B.X");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -41,6 +46,8 @@ public class UsingTest extends CppParserTest{
|
|||
}
|
||||
inferer.resolveAllBindings();
|
||||
Entity e = repo.getEntity("bar");
|
||||
assertEquals(4,e.getRelations().size());
|
||||
this.assertContainsRelation(e, DependencyType.RETURN, Inferer.buildInType.getQualifiedName());
|
||||
this.assertContainsRelation(e, DependencyType.CONTAIN, "A.C");
|
||||
this.assertContainsRelation(e, DependencyType.CONTAIN, "B.X");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public class JavaVarResolveTest extends JavaParserTest{
|
|||
JavaFileParser parser = createParser(src);
|
||||
parser.parse();
|
||||
inferer.resolveAllBindings();
|
||||
assertEquals(16,entityRepo.getEntity("ValidateAll.validate").getRelations().size());
|
||||
assertEquals(13,entityRepo.getEntity("ValidateAll.validate").getRelations().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -218,9 +218,9 @@ public class PythonImportTest extends PythonParserTest {
|
|||
}
|
||||
inferer.resolveAllBindings();
|
||||
FunctionEntity func = (FunctionEntity)repo.getEntity(withPackageName(srcs[0],"in_the_forest"));
|
||||
this.assertContainsRelation(func, DependencyType.CALL, withPackageName(srcs[1],"Duck.quack"));
|
||||
this.assertContainsRelation(func, DependencyType.CALL, withPackageName(srcs[1],"Bird.quack"));
|
||||
this.assertContainsRelation(func, DependencyType.CALL, withPackageName(srcs[1],"Doge.quack"));
|
||||
this.assertContainsRelation(func, DependencyType.CALL, withPackageName(srcs[1],"Bird.quack"));
|
||||
this.assertContainsRelation(func, DependencyType.CALL, withPackageName(srcs[1],"Duck.quack"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -30,9 +30,6 @@ public class RubyReturnTypeDedudceTest extends RubyParserTest {
|
|||
|
||||
function = (FunctionEntity)(entityRepo.getEntity("Class.implicitReturn"));
|
||||
this.assertContainReturnType(function,"Class1");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue