diff --git a/src/main/java/org/codetracker/element/Attribute.java b/src/main/java/org/codetracker/element/Attribute.java index e542866848d..cb14e752358 100644 --- a/src/main/java/org/codetracker/element/Attribute.java +++ b/src/main/java/org/codetracker/element/Attribute.java @@ -3,6 +3,7 @@ import gr.uom.java.xmi.LocationInfo; import gr.uom.java.xmi.UMLAnonymousClass; import gr.uom.java.xmi.UMLAttribute; +import gr.uom.java.xmi.UMLComment; import gr.uom.java.xmi.UMLOperation; import gr.uom.java.xmi.LocationInfo.CodeElementType; import gr.uom.java.xmi.decomposition.AbstractCodeFragment; @@ -100,6 +101,34 @@ public Block findBlockWithoutName(Predicate equalOperator) { return null; } + public Comment findComment(Predicate equalOperator) { + for (UMLComment umlComment : umlAttribute.getComments()) { + Comment comment = Comment.of(umlComment, this); + if (comment != null && equalOperator.test(comment)) { + return comment; + } + } + for (UMLAnonymousClass anonymousClass : umlAttribute.getAnonymousClassList()) { + for (UMLOperation operation : anonymousClass.getOperations()) { + for (UMLComment umlComment : operation.getComments()) { + Comment comment = Comment.of(umlComment, this); + if (comment != null && equalOperator.test(comment)) { + return comment; + } + } + } + } + for (LambdaExpressionObject lambda : umlAttribute.getAllLambdas()) { + for (UMLComment umlComment : lambda.getComments()) { + Comment comment = Comment.of(umlComment, this); + if (comment != null && equalOperator.test(comment)) { + return comment; + } + } + } + return null; + } + private Block promotionStrategy(Map matches) { //promote catch over try if (matches.containsKey(CodeElementType.CATCH_CLAUSE)) { diff --git a/src/main/java/org/codetracker/element/Class.java b/src/main/java/org/codetracker/element/Class.java index f900571a0af..e020932c9f1 100644 --- a/src/main/java/org/codetracker/element/Class.java +++ b/src/main/java/org/codetracker/element/Class.java @@ -2,11 +2,15 @@ import gr.uom.java.xmi.LocationInfo; import gr.uom.java.xmi.UMLAbstractClass; +import gr.uom.java.xmi.UMLComment; + 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 Class extends BaseCodeElement { private final UMLAbstractClass umlClass; @@ -30,6 +34,16 @@ public static Class of(UMLAbstractClass umlClass, Version version) { return new Class(umlClass, identifierExcludeVersion, className, umlClass.getLocationInfo().getFilePath(), version); } + public Comment findComment(Predicate equalOperator) { + for (UMLComment umlComment : umlClass.getComments()) { + Comment comment = Comment.of(umlComment, this); + if (comment != null && equalOperator.test(comment)) { + return comment; + } + } + return null; + } + public UMLAbstractClass getUmlClass() { return umlClass; } diff --git a/src/main/java/org/codetracker/element/Comment.java b/src/main/java/org/codetracker/element/Comment.java new file mode 100644 index 00000000000..73184fb0c48 --- /dev/null +++ b/src/main/java/org/codetracker/element/Comment.java @@ -0,0 +1,109 @@ +package org.codetracker.element; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.codetracker.api.Version; +import org.codetracker.util.Util; + +import gr.uom.java.xmi.LocationInfo; +import gr.uom.java.xmi.UMLAbstractClass; +import gr.uom.java.xmi.UMLComment; +import gr.uom.java.xmi.VariableDeclarationContainer; + +public class Comment extends BaseCodeElement { + private final UMLComment comment; + private final VariableDeclarationContainer operation; + private final UMLAbstractClass clazz; + + public Comment(UMLComment comment, VariableDeclarationContainer operation, String identifierIgnoringVersion, String name, String filePath, Version version) { + super(identifierIgnoringVersion, name, filePath, version); + this.comment = comment; + this.operation = operation; + this.clazz = null; + } + + public Comment(UMLComment comment, UMLAbstractClass clazz, String identifierIgnoringVersion, String name, String filePath, Version version) { + super(identifierIgnoringVersion, name, filePath, version); + this.comment = comment; + this.clazz = clazz; + this.operation = null; + } + + public UMLComment getComment() { + return comment; + } + + public Optional getOperation() { + return operation != null ? Optional.of(operation) : Optional.empty(); + } + + public Optional getClazz() { + return clazz != null ? Optional.of(clazz) : Optional.empty(); + } + + public static Comment of(UMLComment comment, Class clazz) { + LocationInfo commentLocationInfo = comment.getLocationInfo(); + String statementType = commentLocationInfo.getCodeElementType().name(); + String name = String.format("%s$%s(%d-%d)", clazz.getName(), statementType, commentLocationInfo.getStartLine(), commentLocationInfo.getEndLine()); + String sha512 = Util.getSHA512(comment.getText()); + String identifierExcludeVersion = String.format( + "%s$%s:{%s,%s}", + clazz.getIdentifierIgnoringVersion(), + statementType, + sha512, + getSignature(comment, clazz.getUmlClass()) + ); + return new Comment(comment, clazz.getUmlClass(), identifierExcludeVersion, name, commentLocationInfo.getFilePath(), clazz.getVersion()); + } + + public static Comment of(UMLComment comment, Attribute attribute) { + LocationInfo commentLocationInfo = comment.getLocationInfo(); + String statementType = commentLocationInfo.getCodeElementType().name(); + String name = String.format("%s$%s(%d-%d)", attribute.getName(), statementType, commentLocationInfo.getStartLine(), commentLocationInfo.getEndLine()); + String sha512 = Util.getSHA512(comment.getText()); + String identifierExcludeVersion = String.format( + "%s$%s:{%s,%s}", + attribute.getIdentifierIgnoringVersion(), + statementType, + sha512, + getSignature(comment, attribute.getUmlAttribute()) + ); + return new Comment(comment, attribute.getUmlAttribute(), identifierExcludeVersion, name, commentLocationInfo.getFilePath(), attribute.getVersion()); + } + + public static Comment of(UMLComment comment, Method method) { + LocationInfo commentLocationInfo = comment.getLocationInfo(); + String statementType = commentLocationInfo.getCodeElementType().name(); + String name = String.format("%s$%s(%d-%d)", method.getName(), statementType, commentLocationInfo.getStartLine(), commentLocationInfo.getEndLine()); + String sha512 = Util.getSHA512(comment.getText()); + String identifierExcludeVersion = String.format( + "%s$%s:{%s,%s}", + method.getIdentifierIgnoringVersion(), + statementType, + sha512, + getSignature(comment, method.getUmlOperation()) + ); + return new Comment(comment, method.getUmlOperation(), identifierExcludeVersion, name, commentLocationInfo.getFilePath(), method.getVersion()); + } + + private static String getSignature(UMLComment comment, VariableDeclarationContainer operation) { + String statementType = comment.getLocationInfo().getCodeElementType().name(); + List sameTypeSibling = operation.getComments().stream().filter(st -> statementType.equals(st.getLocationInfo().getCodeElementType().name())).collect(Collectors.toList()); + int typeIndex = sameTypeSibling.indexOf(comment) + 1; + return String.format("%s%d", statementType, typeIndex); + } + + private static String getSignature(UMLComment comment, UMLAbstractClass clazz) { + String statementType = comment.getLocationInfo().getCodeElementType().name(); + List sameTypeSibling = clazz.getComments().stream().filter(st -> statementType.equals(st.getLocationInfo().getCodeElementType().name())).collect(Collectors.toList()); + int typeIndex = sameTypeSibling.indexOf(comment) + 1; + return String.format("%s%d", statementType, typeIndex); + } + + @Override + public LocationInfo getLocation() { + return comment.getLocationInfo(); + } +} diff --git a/src/main/java/org/codetracker/element/Method.java b/src/main/java/org/codetracker/element/Method.java index 1b1bd04953c..c05ccf12e69 100644 --- a/src/main/java/org/codetracker/element/Method.java +++ b/src/main/java/org/codetracker/element/Method.java @@ -200,6 +200,34 @@ private Block promotionStrategy(Map matches) { return null; } + public Comment findComment(Predicate equalOperator) { + for (UMLComment umlComment : umlOperation.getComments()) { + Comment comment = Comment.of(umlComment, this); + if (comment != null && equalOperator.test(comment)) { + return comment; + } + } + for (UMLAnonymousClass anonymousClass : umlOperation.getAnonymousClassList()) { + for (UMLOperation operation : anonymousClass.getOperations()) { + for (UMLComment umlComment : operation.getComments()) { + Comment comment = Comment.of(umlComment, this); + if (comment != null && equalOperator.test(comment)) { + return comment; + } + } + } + } + for (LambdaExpressionObject lambda : umlOperation.getAllLambdas()) { + for (UMLComment umlComment : lambda.getComments()) { + Comment comment = Comment.of(umlComment, this); + if (comment != null && equalOperator.test(comment)) { + return comment; + } + } + } + return null; + } + public VariableDeclarationContainer getUmlOperation() { return umlOperation; } diff --git a/src/main/java/org/codetracker/util/AbstractCodeElementLocator.java b/src/main/java/org/codetracker/util/AbstractCodeElementLocator.java index 50175704eb7..0eb82bfb09c 100644 --- a/src/main/java/org/codetracker/util/AbstractCodeElementLocator.java +++ b/src/main/java/org/codetracker/util/AbstractCodeElementLocator.java @@ -9,6 +9,7 @@ import org.codetracker.element.Attribute; import org.codetracker.element.Block; import org.codetracker.element.Class; +import org.codetracker.element.Comment; import org.codetracker.element.Method; import org.codetracker.element.Variable; @@ -91,6 +92,11 @@ protected boolean attributePredicateWithoutName(Attribute attribute) { attribute.getUmlAttribute().getLocationInfo().getEndLine() >= lineNumber; } + protected boolean commentPredicate(Comment comment) { + return comment.getComment().getLocationInfo().getStartLine() == lineNumber && + comment.getComment().getLocationInfo().getEndLine() >= lineNumber; + } + protected boolean blockPredicate(Block block) { return block.getComposite().getLocationInfo().getStartLine() == lineNumber && block.getComposite().getLocationInfo().getEndLine() >= lineNumber; @@ -208,6 +214,10 @@ protected CodeElement locateWithoutName(Version version, UMLModel umlModel) thro return block; } } + Comment comment = method.findComment(this::commentPredicate); + if (comment != null) { + return comment; + } Attribute attribute = getAttribute(umlModel, version, filePath, this::attributePredicateWithoutName); if (attribute != null) { return attribute; @@ -228,10 +238,18 @@ protected CodeElement locateWithoutName(Version version, UMLModel umlModel) thro return block; } } + Comment comment = attribute.findComment(this::commentPredicate); + if (comment != null) { + return comment; + } return attribute; } Class clazz = getClass(umlModel, version, filePath, this::classPredicateWithoutName); if (clazz != null) { + Comment comment = clazz.findComment(this::commentPredicate); + if (comment != null) { + return comment; + } clazz.checkClosingBracket(lineNumber); return clazz; }