All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gr.uom.java.xmi.decomposition.CompositeStatementObject Maven / Gradle / Ivy

Go to download

RefactoringMiner is a library/API written in Java that can detect refactorings applied in the history of a Java project.

There is a newer version: 3.0.9
Show newest version
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 getTextBlocks() {
		List textBlocks = new ArrayList<>();
		for(AbstractExpression expression : expressionList) {
			textBlocks.addAll(expression.getTextBlocks());
		}
		return textBlocks;
	}

	@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 getAssignments() {
		List assignments = new ArrayList<>();
		for(AbstractExpression expression : expressionList) {
			assignments.addAll(expression.getAssignments());
		}
		return assignments;
	}

	@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 int statementCountIncludingBlocks() {
		int count = 0;
		count++;
		for(AbstractStatement statement : statementList) {
			count += statement.statementCountIncludingBlocks();
		}
		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;
	}

	public boolean isBlockReturningDefault() {
		if(locationInfo.getCodeElementType().equals(CodeElementType.BLOCK) && statementList.size() == 1) {
			AbstractStatement statement = statementList.get(0);
			String string = statement.getString();
			if(string.equals(JAVA.RETURN_STATEMENT) || string.equals(JAVA.RETURN_NULL) || string.equals(JAVA.RETURN_TRUE) ||
					string.equals(JAVA.RETURN_FALSE) || string.equals(JAVA.RETURN_THIS)) {
				return true;
			}
		}
		return false;
	}

	@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);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy