gr.uom.java.xmi.decomposition.CompositeStatementObject Maven / Gradle / Ivy
package gr.uom.java.xmi.decomposition;
import static gr.uom.java.xmi.Constants.JAVA;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import gr.uom.java.xmi.LocationInfo;
import gr.uom.java.xmi.LocationInfo.CodeElementType;
import gr.uom.java.xmi.diff.CodeRange;
public class CompositeStatementObject extends AbstractStatement {
private List statementList;
private List expressionList;
private List variableDeclarations;
private Optional tryContainer;
private LocationInfo locationInfo;
public CompositeStatementObject(CompilationUnit cu, String filePath, ASTNode statement, int depth, CodeElementType codeElementType) {
super();
this.setDepth(depth);
this.locationInfo = new LocationInfo(cu, filePath, statement, codeElementType);
this.statementList = new ArrayList();
this.expressionList = new ArrayList();
this.variableDeclarations = new ArrayList();
}
public void addStatement(AbstractStatement statement) {
statement.setIndex(statementList.size());
statementList.add(statement);
statement.setParent(this);
statement.getVariableDeclarations().stream().forEach(variableDeclaration -> {
variableDeclaration.getScope().setParentSignature(this.getSignature());
});
}
public List getStatements() {
return statementList;
}
public Optional getTryContainer() {
return tryContainer;
}
public void setTryContainer(TryStatementObject tryContainer) {
this.tryContainer = Optional.ofNullable(tryContainer);
}
public List getAllStatements() {
List allStatements = new ArrayList<>();
for(AbstractStatement statement : statementList) {
allStatements.add(statement);
if(statement instanceof CompositeStatementObject) {
CompositeStatementObject composite = (CompositeStatementObject)statement;
allStatements.addAll(composite.getAllStatements());
}
}
return allStatements;
}
public void addExpression(AbstractExpression expression) {
//an expression has the same index and depth as the composite statement it belong to
expression.setDepth(this.getDepth());
expression.setIndex(this.getIndex());
expressionList.add(expression);
expression.setOwner(this);
expression.getVariableDeclarations().stream().forEach(variableDeclaration -> {
variableDeclaration.getScope().setParentSignature(this.getSignature());
});
}
public List getExpressions() {
return expressionList;
}
public void addVariableDeclaration(VariableDeclaration declaration) {
this.variableDeclarations.add(declaration);
declaration.getScope().setParentSignature(this.getSignature());
}
@Override
public List getLeaves() {
List leaves = new ArrayList();
for(AbstractStatement statement : statementList) {
leaves.addAll(statement.getLeaves());
}
return leaves;
}
public List getInnerNodes() {
List innerNodes = new ArrayList();
for(AbstractStatement statement : statementList) {
if(statement instanceof CompositeStatementObject) {
CompositeStatementObject composite = (CompositeStatementObject)statement;
innerNodes.addAll(composite.getInnerNodes());
}
}
innerNodes.add(this);
return innerNodes;
}
public boolean contains(AbstractCodeFragment fragment) {
if(fragment instanceof StatementObject) {
return getLeaves().contains(fragment);
}
else if(fragment instanceof CompositeStatementObject) {
return getInnerNodes().contains(fragment);
}
else if(fragment instanceof AbstractExpression) {
return getExpressions().contains(fragment);
}
return false;
}
public void resetArgumentization() {
super.resetArgumentization();
for(AbstractExpression expression : expressionList) {
expression.resetArgumentization();
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(locationInfo.getCodeElementType().getName());
if(expressionList.size() > 0) {
sb.append("(");
for(int i=0; i 0) {
sb.append("(");
for(int i=0; i getVariables() {
List variables = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
variables.addAll(expression.getVariables());
}
return variables;
}
@Override
public List getTypes() {
List types = new ArrayList();
for(AbstractExpression expression : expressionList) {
types.addAll(expression.getTypes());
}
return types;
}
@Override
public List getVariableDeclarations() {
List variableDeclarations = new ArrayList();
//special handling for enhanced-for formal parameter
variableDeclarations.addAll(this.variableDeclarations);
for(AbstractExpression expression : expressionList) {
variableDeclarations.addAll(expression.getVariableDeclarations());
}
return variableDeclarations;
}
@Override
public List getMethodInvocations() {
List list = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
list.addAll(expression.getMethodInvocations());
}
return list;
}
@Override
public List getAnonymousClassDeclarations() {
List anonymousClassDeclarations = new ArrayList();
for(AbstractExpression expression : expressionList) {
anonymousClassDeclarations.addAll(expression.getAnonymousClassDeclarations());
}
return anonymousClassDeclarations;
}
@Override
public List getStringLiterals() {
List stringLiterals = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
stringLiterals.addAll(expression.getStringLiterals());
}
return stringLiterals;
}
@Override
public List getCharLiterals() {
List charLiterals = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
charLiterals.addAll(expression.getCharLiterals());
}
return charLiterals;
}
@Override
public List getNumberLiterals() {
List numberLiterals = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
numberLiterals.addAll(expression.getNumberLiterals());
}
return numberLiterals;
}
@Override
public List getNullLiterals() {
List nullLiterals = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
nullLiterals.addAll(expression.getNullLiterals());
}
return nullLiterals;
}
@Override
public List getBooleanLiterals() {
List booleanLiterals = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
booleanLiterals.addAll(expression.getBooleanLiterals());
}
return booleanLiterals;
}
@Override
public List getTypeLiterals() {
List typeLiterals = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
typeLiterals.addAll(expression.getTypeLiterals());
}
return typeLiterals;
}
@Override
public List getInfixExpressions() {
List infixExpressions = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
infixExpressions.addAll(expression.getInfixExpressions());
}
return infixExpressions;
}
@Override
public List getInfixOperators() {
List infixOperators = new ArrayList();
for(AbstractExpression expression : expressionList) {
infixOperators.addAll(expression.getInfixOperators());
}
return infixOperators;
}
@Override
public List getArrayAccesses() {
List arrayAccesses = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
arrayAccesses.addAll(expression.getArrayAccesses());
}
return arrayAccesses;
}
@Override
public List getPrefixExpressions() {
List prefixExpressions = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
prefixExpressions.addAll(expression.getPrefixExpressions());
}
return prefixExpressions;
}
@Override
public List getPostfixExpressions() {
List postfixExpressions = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
postfixExpressions.addAll(expression.getPostfixExpressions());
}
return postfixExpressions;
}
@Override
public List getThisExpressions() {
List thisExpressions = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
thisExpressions.addAll(expression.getThisExpressions());
}
return thisExpressions;
}
@Override
public List getArguments() {
List arguments = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
arguments.addAll(expression.getArguments());
}
return arguments;
}
@Override
public List getParenthesizedExpressions() {
List parenthesizedExpressions = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
parenthesizedExpressions.addAll(expression.getParenthesizedExpressions());
}
return parenthesizedExpressions;
}
@Override
public List getCastExpressions() {
List castExpressions = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
castExpressions.addAll(expression.getCastExpressions());
}
return castExpressions;
}
@Override
public List getTernaryOperatorExpressions() {
List ternaryOperatorExpressions = new ArrayList();
for(AbstractExpression expression : expressionList) {
ternaryOperatorExpressions.addAll(expression.getTernaryOperatorExpressions());
}
return ternaryOperatorExpressions;
}
@Override
public List getLambdas() {
List lambdas = new ArrayList();
for(AbstractExpression expression : expressionList) {
lambdas.addAll(expression.getLambdas());
}
return lambdas;
}
@Override
public List getCreations() {
List list = new ArrayList<>();
for(AbstractExpression expression : expressionList) {
list.addAll(expression.getCreations());
}
return list;
}
public List getAllCreations() {
List list = new ArrayList<>();
list.addAll(getCreations());
for(AbstractStatement statement : statementList) {
if(statement instanceof CompositeStatementObject) {
CompositeStatementObject composite = (CompositeStatementObject)statement;
list.addAll(composite.getAllCreations());
}
else if(statement instanceof StatementObject) {
StatementObject statementObject = (StatementObject)statement;
list.addAll(statementObject.getCreations());
for(LambdaExpressionObject lambda : statementObject.getLambdas()) {
list.addAll(lambda.getAllCreations());
}
for(AnonymousClassDeclarationObject anonymous : statementObject.getAnonymousClassDeclarations()) {
list.addAll(anonymous.getCreations());
}
}
}
return list;
}
public List getAllMethodInvocations() {
List list = new ArrayList<>();
list.addAll(getMethodInvocations());
for(AbstractStatement statement : statementList) {
if(statement instanceof CompositeStatementObject) {
CompositeStatementObject composite = (CompositeStatementObject)statement;
list.addAll(composite.getAllMethodInvocations());
}
else if(statement instanceof StatementObject) {
StatementObject statementObject = (StatementObject)statement;
list.addAll(statementObject.getMethodInvocations());
for(LambdaExpressionObject lambda : statementObject.getLambdas()) {
list.addAll(lambda.getAllOperationInvocations());
}
for(AnonymousClassDeclarationObject anonymous : statementObject.getAnonymousClassDeclarations()) {
list.addAll(anonymous.getMethodInvocations());
}
}
}
return list;
}
public List getAllAnonymousClassDeclarations() {
List anonymousClassDeclarations = new ArrayList();
anonymousClassDeclarations.addAll(getAnonymousClassDeclarations());
for(AbstractStatement statement : statementList) {
if(statement instanceof CompositeStatementObject) {
CompositeStatementObject composite = (CompositeStatementObject)statement;
anonymousClassDeclarations.addAll(composite.getAllAnonymousClassDeclarations());
}
else if(statement instanceof StatementObject) {
StatementObject statementObject = (StatementObject)statement;
anonymousClassDeclarations.addAll(statementObject.getAnonymousClassDeclarations());
}
}
return anonymousClassDeclarations;
}
public List getAllLambdas() {
List lambdas = new ArrayList();
lambdas.addAll(getLambdas());
for(AbstractStatement statement : statementList) {
if(statement instanceof CompositeStatementObject) {
CompositeStatementObject composite = (CompositeStatementObject)statement;
lambdas.addAll(composite.getAllLambdas());
}
else if(statement instanceof StatementObject) {
StatementObject statementObject = (StatementObject)statement;
lambdas.addAll(statementObject.getLambdas());
}
}
return lambdas;
}
public List getAllVariables() {
List variables = new ArrayList<>();
for(LeafExpression variable : getVariables()) {
variables.add(variable.getString());
}
for(AbstractStatement statement : statementList) {
if(statement instanceof CompositeStatementObject) {
CompositeStatementObject composite = (CompositeStatementObject)statement;
variables.addAll(composite.getAllVariables());
}
else if(statement instanceof StatementObject) {
StatementObject statementObject = (StatementObject)statement;
for(LeafExpression variable : statementObject.getVariables()) {
variables.add(variable.getString());
}
}
}
return variables;
}
public List getAllVariableDeclarations() {
List variableDeclarations = new ArrayList();
variableDeclarations.addAll(getVariableDeclarations());
for(AbstractStatement statement : statementList) {
if(statement instanceof CompositeStatementObject) {
CompositeStatementObject composite = (CompositeStatementObject)statement;
variableDeclarations.addAll(composite.getAllVariableDeclarations());
}
else if(statement instanceof StatementObject) {
StatementObject statementObject = (StatementObject)statement;
variableDeclarations.addAll(statementObject.getVariableDeclarations());
for(LambdaExpressionObject lambda : statementObject.getLambdas()) {
variableDeclarations.addAll(lambda.getParameters());
if(lambda.getBody() != null) {
variableDeclarations.addAll(lambda.getBody().getAllVariableDeclarations());
}
}
}
}
return variableDeclarations;
}
public List getVariableDeclarationsInScope(LocationInfo location) {
List variableDeclarations = new ArrayList();
for(VariableDeclaration variableDeclaration : getAllVariableDeclarations()) {
if(variableDeclaration.getScope().subsumes(location)) {
variableDeclarations.add(variableDeclaration);
}
}
return variableDeclarations;
}
@Override
public int statementCount() {
int count = 0;
if(!this.getString().equals(JAVA.OPEN_BLOCK))
count++;
for(AbstractStatement statement : statementList) {
count += statement.statementCount();
}
return count;
}
public LocationInfo getLocationInfo() {
return locationInfo;
}
public VariableDeclaration getVariableDeclaration(String variableName) {
List variableDeclarations = getAllVariableDeclarations();
List matchingDeclarations = new ArrayList<>();
for(VariableDeclaration declaration : variableDeclarations) {
if(declaration.getVariableName().equals(variableName)) {
matchingDeclarations.add(declaration);
}
}
if(matchingDeclarations.size() > 0) {
return matchingDeclarations.get(matchingDeclarations.size()-1);
}
return null;
}
public Map> aliasedVariables() {
Map> map = new LinkedHashMap>();
for(AbstractCodeFragment statement : getLeaves()) {
String s = statement.getString();
if(!s.startsWith(JAVA.THIS_DOT) && s.endsWith(JAVA.STATEMENT_TERMINATION)) {
String firstLine = s.substring(0, s.indexOf("\n"));
if(firstLine.contains(JAVA.ASSIGNMENT)) {
String variable = s.substring(0, s.indexOf(JAVA.ASSIGNMENT));
String value = s.substring(s.indexOf(JAVA.ASSIGNMENT)+1, s.indexOf(JAVA.STATEMENT_TERMINATION));
if(map.containsKey(value)) {
map.get(value).add(variable);
}
else {
Set set = new LinkedHashSet();
set.add(variable);
map.put(value, set);
}
}
}
}
return map;
}
public Map> aliasedAttributes() {
Map> map = new LinkedHashMap>();
for(AbstractCodeFragment statement : getLeaves()) {
String s = statement.getString();
if(s.startsWith(JAVA.THIS_DOT) && s.endsWith(JAVA.STATEMENT_TERMINATION)) {
String firstLine = s.substring(0, s.indexOf("\n"));
if(firstLine.contains(JAVA.ASSIGNMENT)) {
String attribute = s.substring(5, s.indexOf(JAVA.ASSIGNMENT));
String value = s.substring(s.indexOf(JAVA.ASSIGNMENT)+1, s.indexOf(JAVA.STATEMENT_TERMINATION));
if(map.containsKey(value)) {
map.get(value).add(attribute);
}
else {
Set set = new LinkedHashSet();
set.add(attribute);
map.put(value, set);
}
}
}
}
Set keysToBeRemoved = new LinkedHashSet();
for(String key : map.keySet()) {
if(map.get(key).size() <= 1) {
keysToBeRemoved.add(key);
}
}
for(String key : keysToBeRemoved) {
map.remove(key);
}
return map;
}
public CodeRange codeRange() {
return locationInfo.codeRange();
}
public boolean isBlock() {
return this.locationInfo.getCodeElementType().equals(CodeElementType.BLOCK) ||
this.locationInfo.getCodeElementType().equals(CodeElementType.FINALLY_BLOCK) ||
this.locationInfo.getCodeElementType().equals(CodeElementType.CATCH_CLAUSE);
}
public boolean isLoop() {
return this.locationInfo.getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT) ||
this.locationInfo.getCodeElementType().equals(CodeElementType.FOR_STATEMENT) ||
this.locationInfo.getCodeElementType().equals(CodeElementType.WHILE_STATEMENT) ||
this.locationInfo.getCodeElementType().equals(CodeElementType.DO_STATEMENT);
}
public CompositeStatementObject loopWithVariables(String currentElementName, String collectionName) {
for(CompositeStatementObject innerNode : getInnerNodes()) {
if(innerNode.getLocationInfo().getCodeElementType().equals(CodeElementType.ENHANCED_FOR_STATEMENT)) {
boolean currentElementNameMatched = false;
for(VariableDeclaration declaration : innerNode.getVariableDeclarations()) {
if(declaration.getVariableName().equals(currentElementName)) {
currentElementNameMatched = true;
break;
}
}
boolean collectionNameMatched = false;
for(AbstractExpression expression : innerNode.getExpressions()) {
for(LeafExpression variable : expression.getVariables()) {
if(variable.getString().equals(collectionName)) {
collectionNameMatched = true;
break;
}
}
}
if(currentElementNameMatched && collectionNameMatched) {
return innerNode;
}
}
else if(innerNode.getLocationInfo().getCodeElementType().equals(CodeElementType.FOR_STATEMENT) ||
innerNode.getLocationInfo().getCodeElementType().equals(CodeElementType.WHILE_STATEMENT)) {
boolean collectionNameMatched = false;
for(AbstractExpression expression : innerNode.getExpressions()) {
for(LeafExpression variable : expression.getVariables()) {
if(variable.getString().equals(collectionName)) {
collectionNameMatched = true;
break;
}
}
}
boolean currentElementNameMatched = false;
for(AbstractCodeFragment statement : innerNode.getLeaves()) {
VariableDeclaration variableDeclaration = statement.getVariableDeclaration(currentElementName);
if(variableDeclaration != null) {
for(LeafExpression variable : statement.getVariables()) {
if(variable.getString().equals(collectionName)) {
currentElementNameMatched = true;
break;
}
}
}
}
if(currentElementNameMatched && collectionNameMatched) {
return innerNode;
}
}
}
return null;
}
@Override
public List stringRepresentation() {
List stringRepresentation = new ArrayList();
stringRepresentation.add(this.toStringForStringRepresentation());
for(AbstractStatement statement : statementList) {
stringRepresentation.addAll(statement.stringRepresentation());
}
if(getLocationInfo().getCodeElementType().equals(CodeElementType.BLOCK)) {
stringRepresentation.add(JAVA.CLOSE_BLOCK);
}
return stringRepresentation;
}
public List bodyStringRepresentation() {
List stringRepresentation = new ArrayList();
for(AbstractStatement statement : statementList) {
stringRepresentation.addAll(statement.stringRepresentation());
}
if(getLocationInfo().getCodeElementType().equals(CodeElementType.BLOCK)) {
stringRepresentation.add(JAVA.CLOSE_BLOCK);
}
return stringRepresentation;
}
public String getSignature() {
String statementType = getLocationInfo().getCodeElementType().getName() != null ? getLocationInfo().getCodeElementType().getName() : toString();
CompositeStatementObject parent = getParent();
if (parent == null) {
return statementType;
}
List sameTypeSibling = parent.getStatements().stream().filter(st -> statementType.equals(st.getLocationInfo().getCodeElementType().getName())).collect(Collectors.toList());
int typeIndex = 1;
for (AbstractStatement abstractStatement : sameTypeSibling) {
if (abstractStatement.getIndex() == getIndex()) {
break;
}
typeIndex++;
}
return String.format("%s:%s%d", parent.getSignature(), statementType, typeIndex);
}
}