Skip to content

Commit

Permalink
CodeElementLocator without specifying name
Browse files Browse the repository at this point in the history
  • Loading branch information
tsantalis committed Jun 26, 2024
1 parent 603ed08 commit e30ade8
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 10 deletions.
53 changes: 53 additions & 0 deletions src/main/java/org/codetracker/element/Attribute.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package org.codetracker.element;

import gr.uom.java.xmi.LocationInfo;
import gr.uom.java.xmi.UMLAnonymousClass;
import gr.uom.java.xmi.UMLAttribute;
import gr.uom.java.xmi.UMLOperation;
import gr.uom.java.xmi.decomposition.AbstractCodeFragment;
import gr.uom.java.xmi.decomposition.CompositeStatementObject;
import gr.uom.java.xmi.decomposition.LambdaExpressionObject;
import gr.uom.java.xmi.decomposition.StatementObject;

import org.codetracker.api.Version;

import static org.codetracker.util.Util.annotationsToString;
import static org.codetracker.util.Util.getPath;

import java.util.function.Predicate;

public class Attribute extends BaseCodeElement {
private final UMLAttribute umlAttribute;

Expand Down Expand Up @@ -34,6 +43,50 @@ public static Attribute of(UMLAttribute umlAttribute, Version version) {
return new Attribute(umlAttribute, identifierExcludeVersion, String.format("%s%s@%s(%s)%s:%s(%d)", sourceFolder, className, modifiersString, visibility, name, type, startLine), umlAttribute.getLocationInfo().getFilePath(), version);
}

public Block findBlockWithoutName(Predicate<Block> equalOperator) {
for (UMLAnonymousClass anonymousClass : umlAttribute.getAnonymousClassList()) {
for (UMLOperation operation : anonymousClass.getOperations()) {
if (operation.getBody() != null) {
//first process leaves then composites
for (AbstractCodeFragment leaf : operation.getBody().getCompositeStatement().getLeaves()) {
if (leaf instanceof StatementObject) {
Block block = Block.of((StatementObject)leaf, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
for (CompositeStatementObject composite : operation.getBody().getCompositeStatement().getInnerNodes()) {
Block block = Block.of(composite, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
}
}
for (LambdaExpressionObject lambda : umlAttribute.getAllLambdas()) {
if (lambda.getBody() != null) {
//first process leaves then composites
for (AbstractCodeFragment leaf : lambda.getBody().getCompositeStatement().getLeaves()) {
if (leaf instanceof StatementObject) {
Block block = Block.of((StatementObject)leaf, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
for (CompositeStatementObject composite : lambda.getBody().getCompositeStatement().getInnerNodes()) {
Block block = Block.of(composite, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
}
return null;
}

public UMLAttribute getUmlAttribute() {
return umlAttribute;
}
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/org/codetracker/element/BaseCodeElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import org.codetracker.api.CodeElement;
import org.codetracker.api.Version;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.TreeSet;

Expand Down
45 changes: 44 additions & 1 deletion src/main/java/org/codetracker/element/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Block extends BaseCodeElement {
Expand Down Expand Up @@ -49,6 +48,21 @@ public static Block of(CompositeStatementObject composite, Method method) {
return new Block(composite, method.getUmlOperation(), identifierExcludeVersion, name, compositeLocationInfo.getFilePath(), method.getVersion());
}

public static Block of(CompositeStatementObject composite, Attribute attribute) {
LocationInfo compositeLocationInfo = composite.getLocationInfo();
String statementType = compositeLocationInfo.getCodeElementType().getName() != null ? compositeLocationInfo.getCodeElementType().getName() : composite.toString();
String name = String.format("%s$%s(%d-%d)", attribute.getName(), statementType, compositeLocationInfo.getStartLine(), compositeLocationInfo.getEndLine());
String sha512 = Util.getSHA512(composite.getAllStatements().stream().map(AbstractCodeFragment::toString).collect(Collectors.joining()));
String identifierExcludeVersion = String.format(
"%s$%s:{%s,%s}",
attribute.getIdentifierIgnoringVersion(),
statementType,
sha512,
composite.getSignature()
);
return new Block(composite, attribute.getUmlAttribute(), identifierExcludeVersion, name, compositeLocationInfo.getFilePath(), attribute.getVersion());
}

public static Block of(StatementObject statement, VariableDeclarationContainer operation, Version version) {
Method method = Method.of(operation, version);
return of(statement, method);
Expand Down Expand Up @@ -83,6 +97,35 @@ public static Block of(StatementObject statement, Method method) {
return new Block(statement, method.getUmlOperation(), identifierExcludeVersion, name, compositeLocationInfo.getFilePath(), method.getVersion());
}

public static Block of(StatementObject statement, Attribute attribute) {
LocationInfo compositeLocationInfo = statement.getLocationInfo();
List<AbstractCall> streamAPICalls = streamAPICalls(statement);
if(streamAPICalls.size() > 0) {
String statementType = streamAPICalls.get(0).getName();
String name = String.format("%s$%s(%d-%d)", attribute.getName(), statementType, compositeLocationInfo.getStartLine(), compositeLocationInfo.getEndLine());
String sha512 = Util.getSHA512(statement.toString());
String identifierExcludeVersion = String.format(
"%s$%s:{%s,%s}",
attribute.getIdentifierIgnoringVersion(),
statementType,
sha512,
signature(statement, statementType)
);
return new Block(statement, attribute.getUmlAttribute(), identifierExcludeVersion, name, compositeLocationInfo.getFilePath(), attribute.getVersion());
}
String statementType = statement.getLocationInfo().getCodeElementType().name();
String name = String.format("%s$%s(%d-%d)", attribute.getName(), statementType, compositeLocationInfo.getStartLine(), compositeLocationInfo.getEndLine());
String sha512 = Util.getSHA512(statement.toString());
String identifierExcludeVersion = String.format(
"%s$%s:{%s,%s}",
attribute.getIdentifierIgnoringVersion(),
statementType,
sha512,
signature(statement, statementType)
);
return new Block(statement, attribute.getUmlAttribute(), identifierExcludeVersion, name, compositeLocationInfo.getFilePath(), attribute.getVersion());
}

private static String signature(StatementObject statement, String statementType) {
CompositeStatementObject parent = statement.getParent();
if (parent == null) {
Expand Down
64 changes: 64 additions & 0 deletions src/main/java/org/codetracker/element/Method.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package org.codetracker.element;

import gr.uom.java.xmi.*;
import gr.uom.java.xmi.decomposition.AbstractCodeFragment;
import gr.uom.java.xmi.decomposition.AbstractStatement;
import gr.uom.java.xmi.decomposition.CompositeStatementObject;
import gr.uom.java.xmi.decomposition.LambdaExpressionObject;
import gr.uom.java.xmi.decomposition.StatementObject;
import gr.uom.java.xmi.decomposition.VariableDeclaration;
import org.codetracker.api.Version;
import org.codetracker.util.Util;
Expand Down Expand Up @@ -104,6 +107,67 @@ public Block findBlock(Predicate<Block> equalOperator) {
return null;
}

public Block findBlockWithoutName(Predicate<Block> equalOperator) {
if (umlOperation.getBody() != null) {
//first process leaves then composites
for (AbstractCodeFragment leaf : umlOperation.getBody().getCompositeStatement().getLeaves()) {
if (leaf instanceof StatementObject) {
Block block = Block.of((StatementObject)leaf, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
for (CompositeStatementObject composite : umlOperation.getBody().getCompositeStatement().getInnerNodes()) {
Block block = Block.of(composite, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
for (UMLAnonymousClass anonymousClass : umlOperation.getAnonymousClassList()) {
for (UMLOperation operation : anonymousClass.getOperations()) {
if (operation.getBody() != null) {
//first process leaves then composites
for (AbstractCodeFragment leaf : operation.getBody().getCompositeStatement().getLeaves()) {
if (leaf instanceof StatementObject) {
Block block = Block.of((StatementObject)leaf, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
for (CompositeStatementObject composite : operation.getBody().getCompositeStatement().getInnerNodes()) {
Block block = Block.of(composite, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
}
}
for (LambdaExpressionObject lambda : umlOperation.getAllLambdas()) {
if (lambda.getBody() != null) {
//first process leaves then composites
for (AbstractCodeFragment leaf : lambda.getBody().getCompositeStatement().getLeaves()) {
if (leaf instanceof StatementObject) {
Block block = Block.of((StatementObject)leaf, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
for (CompositeStatementObject composite : lambda.getBody().getCompositeStatement().getInnerNodes()) {
Block block = Block.of(composite, this);
if (block != null && equalOperator.test(block)) {
return block;
}
}
}
}
return null;
}

public VariableDeclarationContainer getUmlOperation() {
return umlOperation;
}
Expand Down
1 change: 0 additions & 1 deletion src/main/java/org/codetracker/element/Variable.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.codetracker.element;

import gr.uom.java.xmi.LocationInfo;
import gr.uom.java.xmi.UMLOperation;
import gr.uom.java.xmi.VariableDeclarationContainer;
import gr.uom.java.xmi.decomposition.AbstractCodeFragment;
import gr.uom.java.xmi.decomposition.VariableDeclaration;
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/org/codetracker/util/AbstractCodeElementLocator.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public AbstractCodeElementLocator(String commitId, String filePath, String name,
this.lineNumber = lineNumber;
}

public AbstractCodeElementLocator(String commitId, String filePath, int lineNumber) {
this(commitId, filePath, null, lineNumber);
}

public abstract CodeElement locate() throws Exception;

protected static Method getMethod(UMLModel umlModel, Version version, Predicate<Method> predicate) {
Expand All @@ -45,10 +49,15 @@ protected static Method getMethod(UMLModel umlModel, Version version, Predicate<
return null;
}

protected boolean classPredicate(Class clazz) {
protected boolean classPredicateWithName(Class clazz) {
return clazz.getUmlClass().getNonQualifiedName().equals(name);
}

protected boolean classPredicateWithoutName(Class clazz) {
return clazz.getUmlClass().getLocationInfo().getStartLine() <= lineNumber &&
clazz.getUmlClass().getLocationInfo().getEndLine() >= lineNumber;
}

protected boolean methodPredicateWithName(Method method) {
return method.getUmlOperation().getName().equals(name) &&
method.getUmlOperation().getLocationInfo().getStartLine() <= lineNumber &&
Expand All @@ -66,12 +75,17 @@ protected boolean variablePredicate(Variable variable) {
variable.getVariableDeclaration().getLocationInfo().getEndLine() >= lineNumber;
}

protected boolean attributePredicate(Attribute attribute) {
protected boolean attributePredicateWithName(Attribute attribute) {
return attribute.getUmlAttribute().getName().equals(name) &&
attribute.getUmlAttribute().getLocationInfo().getStartLine() <= lineNumber &&
attribute.getUmlAttribute().getLocationInfo().getEndLine() >= lineNumber;
}

protected boolean attributePredicateWithoutName(Attribute attribute) {
return attribute.getUmlAttribute().getLocationInfo().getStartLine() <= lineNumber &&
attribute.getUmlAttribute().getLocationInfo().getEndLine() >= lineNumber;
}

protected boolean blockPredicate(Block block) {
String blockCodeElementTypeName = block.getComposite().getLocationInfo().getCodeElementType().getName();
if(blockCodeElementTypeName != null) {
Expand Down
39 changes: 37 additions & 2 deletions src/main/java/org/codetracker/util/CodeElementLocator.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,24 @@ public CodeElementLocator(Repository repository, String commitId, String filePat
this.gitRepository = new GitRepository(repository);
}

public CodeElementLocator(Repository repository, String commitId, String filePath, int lineNumber) {
super(commitId, filePath, lineNumber);
this.repository = repository;
this.gitRepository = new GitRepository(repository);
}

@Override
public CodeElement locate() throws Exception {
if (name == null) {
return locateWithoutName();
}
Version version = gitRepository.getVersion(commitId);
UMLModel umlModel = getUMLModel(repository, commitId, Collections.singleton(filePath));
Class clazz = getClass(umlModel, version, this::classPredicate);
Class clazz = getClass(umlModel, version, this::classPredicateWithName);
if (clazz != null) {
return clazz;
}
Attribute attribute = getAttribute(umlModel, version, this::attributePredicate);
Attribute attribute = getAttribute(umlModel, version, this::attributePredicateWithName);
if (attribute != null) {
return attribute;
}
Expand All @@ -54,6 +63,32 @@ public CodeElement locate() throws Exception {
throw new CodeElementNotFoundException(filePath, name, lineNumber);
}

private CodeElement locateWithoutName() throws Exception {
Version version = gitRepository.getVersion(commitId);
UMLModel umlModel = getUMLModel(repository, commitId, Collections.singleton(filePath));
Method method = getMethod(umlModel, version, this::methodPredicateWithoutName);
if (method != null) {
Block block = method.findBlockWithoutName(this::blockPredicate);
if (block != null) {
return block;
}
return method;
}
Attribute attribute = getAttribute(umlModel, version, this::attributePredicateWithoutName);
if (attribute != null) {
Block block = attribute.findBlockWithoutName(this::blockPredicate);
if (block != null) {
return block;
}
return attribute;
}
Class clazz = getClass(umlModel, version, this::classPredicateWithoutName);
if (clazz != null) {
return clazz;
}
throw new CodeElementNotFoundException(filePath, name, lineNumber);
}

private static UMLModel getUMLModel(Repository repository, String commitId, Set<String> fileNames) throws Exception {
if (fileNames == null || fileNames.isEmpty())
return null;
Expand Down
Loading

0 comments on commit e30ade8

Please sign in to comment.