|
1 | 1 | package com.microsoft.android;
|
2 | 2 |
|
3 | 3 | import java.io.File;
|
| 4 | +import java.util.ArrayList; |
4 | 5 | import java.util.Collection;
|
5 | 6 | import java.util.List;
|
6 | 7 | import java.util.Optional;
|
|
35 | 36 |
|
36 | 37 | import com.microsoft.android.ast.*;
|
37 | 38 |
|
38 |
| -import javassist.compiler.ast.FieldDecl; |
39 |
| - |
40 | 39 | import static com.microsoft.android.util.Parameter.*;
|
41 | 40 |
|
42 | 41 | public final class JniPackagesInfoFactory {
|
@@ -90,6 +89,8 @@ private void parse(final JniPackagesInfo packages, final CompilationUnit unit) t
|
90 | 89 | : "";
|
91 | 90 | final JniPackageInfo packageInfo = packages.getPackage(packageName);
|
92 | 91 |
|
| 92 | + fixJavadocComments(unit, unit.getTypes()); |
| 93 | + |
93 | 94 | for (final TypeDeclaration<?> type : unit.getTypes()) {
|
94 | 95 | if (JavaSourceUtilsOptions.verboseOutput && type.getFullyQualifiedName().isPresent()) {
|
95 | 96 | System.out.println("Processing: " + type.getFullyQualifiedName().get());
|
@@ -171,6 +172,7 @@ static ClassOrInterfaceType getTypeParameterBound(TypeParameter typeParameter) {
|
171 | 172 | }
|
172 | 173 |
|
173 | 174 | private final void parseType(final JniPackageInfo packageInfo, final JniTypeInfo typeInfo, TypeDeclaration<?> typeDecl) {
|
| 175 | + fixJavadocComments(typeDecl, getUndocumentedBodyMembers(typeDecl.getMembers())); |
174 | 176 | for (final BodyDeclaration<?> body : typeDecl.getMembers()) {
|
175 | 177 | if (body.isAnnotationDeclaration()) {
|
176 | 178 | final AnnotationDeclaration annoDecl = body.asAnnotationDeclaration();
|
@@ -215,6 +217,68 @@ private final void parseType(final JniPackageInfo packageInfo, final JniTypeInfo
|
215 | 217 | }
|
216 | 218 | }
|
217 | 219 |
|
| 220 | + private final void fixJavadocComments(final Node decl, final Iterable<? extends BodyDeclaration<?>> bodyMembers) { |
| 221 | + final List<BodyDeclaration<?>> members = getUndocumentedBodyMembers(bodyMembers); |
| 222 | + final List<JavadocComment> orphanedComments = getOrphanComments(decl); |
| 223 | + |
| 224 | + if (members.size() == 0) |
| 225 | + return; |
| 226 | + |
| 227 | + final BodyDeclaration<?> firstMember = members.get(0); |
| 228 | + JavadocComment comment = orphanedComments.stream() |
| 229 | + .filter(c -> c.getBegin().get().isBefore(firstMember.getBegin().get())) |
| 230 | + .reduce((a, b) -> b) |
| 231 | + .orElse(null); |
| 232 | + if (comment != null) { |
| 233 | + ((NodeWithJavadoc<?>) firstMember).setJavadocComment(comment); |
| 234 | + } |
| 235 | + |
| 236 | + for (int i = 1; i < members.size(); ++i) { |
| 237 | + BodyDeclaration<?> prevMember = members.get(i-1); |
| 238 | + BodyDeclaration<?> member = members.get(i); |
| 239 | + |
| 240 | + Optional<JavadocComment> commentOpt = orphanedComments.stream() |
| 241 | + .filter(c -> c.getBegin().get().isAfter(prevMember.getEnd().get()) && |
| 242 | + c.getEnd().get().isBefore(member.getBegin().get())) |
| 243 | + .findFirst(); |
| 244 | + if (!commentOpt.isPresent()) |
| 245 | + continue; |
| 246 | + ((NodeWithJavadoc<?>)member).setJavadocComment(commentOpt.get()); |
| 247 | + } |
| 248 | + } |
| 249 | + |
| 250 | + private final List<BodyDeclaration<?>> getUndocumentedBodyMembers(Iterable<? extends BodyDeclaration<?>> bodyMembers) { |
| 251 | + final List<BodyDeclaration<?>> members = new ArrayList<BodyDeclaration<?>> (); |
| 252 | + for (BodyDeclaration<?> member : bodyMembers) { |
| 253 | + if (!(member instanceof NodeWithJavadoc<?>)) { |
| 254 | + continue; |
| 255 | + } |
| 256 | + final NodeWithJavadoc<?> memberJavadoc = (NodeWithJavadoc<?>) member; |
| 257 | + if (memberJavadoc.getJavadocComment().isPresent()) |
| 258 | + continue; |
| 259 | + final Optional<Position> memberBeginOpt = member.getBegin(); |
| 260 | + if (!memberBeginOpt.isPresent()) |
| 261 | + continue; |
| 262 | + members.add(member); |
| 263 | + } |
| 264 | + members.sort((a, b) -> a.getBegin().get().compareTo(b.getBegin().get())); |
| 265 | + return members; |
| 266 | + } |
| 267 | + |
| 268 | + private final List<JavadocComment> getOrphanComments(Node decl) { |
| 269 | + final List<JavadocComment> orphanedComments = new ArrayList<JavadocComment>(decl.getOrphanComments().size()); |
| 270 | + for (Comment c : decl.getOrphanComments()) { |
| 271 | + if (!c.isJavadocComment()) |
| 272 | + continue; |
| 273 | + final Optional<Position> commentBeginOpt = c.getBegin(); |
| 274 | + if (!commentBeginOpt.isPresent()) |
| 275 | + continue; |
| 276 | + orphanedComments.add(c.asJavadocComment()); |
| 277 | + } |
| 278 | + orphanedComments.sort((a, b) -> a.getBegin().get().compareTo(b.getBegin().get())); |
| 279 | + return orphanedComments; |
| 280 | + } |
| 281 | + |
218 | 282 | private final void parseAnnotationMemberDecl(final JniTypeInfo typeInfo, final AnnotationMemberDeclaration memberDecl) {
|
219 | 283 | final JniMethodInfo methodInfo = new JniMethodInfo(typeInfo, memberDecl.getNameAsString());
|
220 | 284 | typeInfo.add(methodInfo);
|
@@ -266,30 +330,8 @@ private static final void fillJavadoc(final HasJavadocComment member, NodeWithJa
|
266 | 330 | JavadocComment javadoc = null;
|
267 | 331 | if (nodeWithJavadoc.getJavadocComment().isPresent()) {
|
268 | 332 | javadoc = nodeWithJavadoc.getJavadocComment().get();
|
269 |
| - } else { |
270 |
| - Node node = (Node) nodeWithJavadoc; |
271 |
| - if (!node.getParentNode().isPresent()) |
272 |
| - return; |
273 |
| - |
274 |
| - /* |
275 |
| - * Sometimes `JavaParser` won't associate a Javadoc comment block with |
276 |
| - * the AST node we expect it to. In such circumstances the Javadoc |
277 |
| - * comment will become an "orphan" comment, unassociated with anything. |
278 |
| - * |
279 |
| - * If `nodeWithJavadoc` has no Javadoc comment, use the *first* |
280 |
| - * orphan Javadoc comment in the *parent* scope, then *remove* that |
281 |
| - * comment so that it doesn't "stick around" for the next member we |
282 |
| - * attempt to grab Javadoc comments for. |
283 |
| - */ |
284 |
| - Node parent = node.getParentNode().get(); |
285 |
| - for (Comment c : parent.getOrphanComments()) { |
286 |
| - if (c.isJavadocComment()) { |
287 |
| - javadoc = c.asJavadocComment(); |
288 |
| - c.remove(); |
289 |
| - break; |
290 |
| - } |
291 |
| - } |
292 | 333 | }
|
| 334 | + |
293 | 335 | if (javadoc != null) {
|
294 | 336 | member.setJavadocComment(javadoc.parse().toText());
|
295 | 337 | }
|
|
0 commit comments