Skip to content

Commit

Permalink
fix: ImportScanner javadoc link scanning
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel Vojtěchovský authored and pvojtechovsky committed Sep 20, 2018
1 parent f03dd06 commit da81492
Showing 1 changed file with 59 additions and 3 deletions.
62 changes: 59 additions & 3 deletions src/main/java/spoon/reflect/visitor/ImportScannerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* A scanner that calculates the imports for a given model.
Expand Down Expand Up @@ -153,20 +155,74 @@ public void visitCtJavaDoc(CtJavaDoc ctJavaDoc) {
stringBuilder.append(ctJavaDoc.getContent());

for (CtJavaDocTag ctJavaDocTag : ctJavaDoc.getTags()) {
stringBuilder.append(ctJavaDocTag.getContent());
stringBuilder.append("\n").append(ctJavaDocTag.getType()).append(" ").append(ctJavaDocTag.getContent());
}

String javadoc = stringBuilder.toString();
if (targetType.getQualifiedName().equals("spoon.reflect.visitor.TokenWriter") && javadoc.indexOf("@link CtCodeSnippetExpression") >= 0) {
this.getClass();
}
for (CtImport ctImport : this.usedImport.keySet()) {
switch (ctImport.getImportKind()) {
case TYPE:
if (javadoc.contains(ctImport.getReference().getSimpleName())) {
this.setImportUsed(ctImport);
if (javadoc.contains(ctImport.getReference().getSimpleName()) && ctImport.getReference() instanceof CtTypeReference) {
//assure that it is not just any occurrence of same substring, but it is real javadoc link to the same type
if (matchesTypeName(javadoc, (CtTypeReference<?>) ctImport.getReference())) {
this.setImportUsed(ctImport);
}
}
break;
}
}
}

private static Set<String> mainTags = new HashSet<>(Arrays.asList("see", "throws", "exception"));
private static Set<String> inlineTags = new HashSet<>(Arrays.asList("link", "linkplain", "value"));
private static Pattern tagRE = Pattern.compile("(\\{)?@(\\w+)\\s+([\\w\\.\\$]+)(?:#(\\w+)(?:\\(([^\\)]*)\\)))?");

private boolean matchesTypeName(String javadoc, CtTypeReference<?> typeRef) {
Matcher m = tagRE.matcher(javadoc);
while (m.find()) {
String bracket = m.group(1);
String tag = m.group(2);
if ("{".equals(bracket)) {
if (inlineTags.contains(tag) == false) {
continue;
}
} else {
if (mainTags.contains(tag) == false) {
continue;
}
}
String type = m.group(3);
// String methodName = m.group(4);
String params = m.group(5);

if (isTypeMatching(type, typeRef)) {
return true;
}
if (params != null) {
String[] paramTypes = params.split("\\s*,\\s*");
for (String paramType : paramTypes) {
if (isTypeMatching(paramType, typeRef)) {
return true;
}
}
}
}
return false;
}

private boolean isTypeMatching(String typeName, CtTypeReference<?> typeRef) {
if (typeName != null) {
if (typeName.equals(typeRef.getQualifiedName())) {
return true;
}
if (typeName.equals(typeRef.getSimpleName())) {
return true;
}
}
return false;
}

@Override
Expand Down

0 comments on commit da81492

Please sign in to comment.