|
1 | 1 | package edu.rit.se.satd.comment.model;
|
2 | 2 |
|
| 3 | +import com.github.javaparser.Position; |
3 | 4 | import com.github.javaparser.Range;
|
4 | 5 | import com.github.javaparser.ast.Node;
|
5 | 6 | import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
6 | 7 | import com.github.javaparser.ast.body.MethodDeclaration;
|
| 8 | +import com.github.javaparser.ast.body.VariableDeclarator; |
7 | 9 | import com.github.javaparser.ast.comments.Comment;
|
| 10 | +import com.github.javaparser.ast.expr.VariableDeclarationExpr; |
8 | 11 | import edu.rit.se.util.JavaParseUtil;
|
9 | 12 | import lombok.AccessLevel;
|
10 | 13 | import lombok.AllArgsConstructor;
|
11 | 14 | import lombok.Getter;
|
12 | 15 | import lombok.NoArgsConstructor;
|
13 | 16 |
|
14 | 17 | import java.util.Arrays;
|
| 18 | +import java.util.Comparator; |
| 19 | +import java.util.List; |
15 | 20 | import java.util.Optional;
|
16 | 21 | import java.util.stream.Collectors;
|
17 | 22 |
|
@@ -175,23 +180,50 @@ public static GroupedComment fromJavaParserComment(Comment oldComment) {
|
175 | 180 | newComment.containingClassDeclarationLineEnd = classRange.end.line;
|
176 | 181 |
|
177 | 182 | // Method Data
|
178 |
| - final Optional<MethodDeclaration> thisMethod = classRoot.get().findAll(MethodDeclaration.class).stream() |
| 183 | + // We need to check for all comments between the end of the last comment |
| 184 | + // and the end of the current comment. This is done to associate comments that |
| 185 | + // are not inside the contents of a method with the method that they pertain to. |
| 186 | + |
| 187 | + // Get all class variables |
| 188 | + // TODO fix issue where class variables are defined after a method |
| 189 | + final List<VariableDeclarator> variables = classRoot.get().findAll(VariableDeclarator.class).stream() |
| 190 | + .filter(varDec -> varDec.getParentNode().isPresent() && |
| 191 | + varDec.getParentNode().get().getParentNode().isPresent() && |
| 192 | + varDec.getParentNode().get().getParentNode().get() instanceof ClassOrInterfaceDeclaration) |
| 193 | + .collect(Collectors.toList()); |
| 194 | + final List<MethodDeclaration> allMethods = classRoot.get().findAll(MethodDeclaration.class).stream() |
179 | 195 | .filter(dec -> dec.getRange().isPresent())
|
180 |
| - .filter(dec -> JavaParseUtil.isRangeBetweenBounds( |
181 |
| - dec.getRange().get(), newComment.startLine, newComment.endLine)) |
182 |
| - .findFirst(); |
183 |
| - newComment.containingMethod = thisMethod |
184 |
| - .map(method -> method.getDeclarationAsString(false, false, false)) |
185 |
| - // Trim return type as it is not important for this study, and only causes problems |
186 |
| - // when detecting movement of SATD between files |
187 |
| - .map(methodDec -> methodDec.substring(methodDec.indexOf(" ")+1)) |
188 |
| - .orElse(UNKNOWN); |
189 |
| - final Range methodRange = thisMethod |
190 |
| - .map(Node::getRange) |
191 |
| - .orElse(Optional.of(NULL_RANGE)) |
192 |
| - .orElse(NULL_RANGE); |
193 |
| - newComment.containingMethodDeclarationLineStart = methodRange.begin.line; |
194 |
| - newComment.containingMethodDeclarationLineEnd = methodRange.end.line; |
| 196 | + .sorted(Comparator.comparingInt(x -> x.getRange().get().begin.line)) |
| 197 | + .collect(Collectors.toList()); |
| 198 | + |
| 199 | + // The first method in the class can be assumed to begin after all class variables have |
| 200 | + // been defined, so we start our bounds for the first method we search at the end of the |
| 201 | + // final variable declaration |
| 202 | + int lastMethodEnd = variables.stream() |
| 203 | + .filter(var -> var.getRange().isPresent()) |
| 204 | + .map(var -> var.getRange().get().end.line) |
| 205 | + .max(Comparator.comparingInt(x -> x)) |
| 206 | + .orElse(-1); |
| 207 | + for (final MethodDeclaration curMethod : allMethods) { |
| 208 | + final Range methodRangeIncludingProceeding = new Range( |
| 209 | + new Position(lastMethodEnd, 0), |
| 210 | + new Position(curMethod.getRange().get().end.line, 0)); |
| 211 | + // If the comment is within the bounds, then we can assume it related to this method |
| 212 | + if (JavaParseUtil.isRangeBetweenBounds( |
| 213 | + methodRangeIncludingProceeding, newComment.startLine, newComment.endLine)) { |
| 214 | + newComment.containingMethod = curMethod |
| 215 | + .getDeclarationAsString(false, false, false); |
| 216 | + newComment.containingMethod = newComment.containingMethod |
| 217 | + .substring(newComment.containingMethod.indexOf(" ") + 1); |
| 218 | + newComment.containingMethodDeclarationLineStart = curMethod.asMethodDeclaration() |
| 219 | + .getRange().get().begin.line; |
| 220 | + newComment.containingMethodDeclarationLineEnd = curMethod.asMethodDeclaration() |
| 221 | + .getRange().get().end.line; |
| 222 | + break; |
| 223 | + } |
| 224 | + lastMethodEnd = curMethod.getRange().get().end.line; |
| 225 | + } |
| 226 | + |
195 | 227 | }
|
196 | 228 | return newComment;
|
197 | 229 | }
|
|
0 commit comments