From 8549fd8600f70cffc374ea89983c0ca5ad69f74e Mon Sep 17 00:00:00 2001 From: ZZZank <3410764033@qq.com> Date: Wed, 29 May 2024 11:39:00 +0800 Subject: [PATCH] DocDocument++ --- .../com/probejs/document/DocumentComment.java | 5 +- .../document/comment/CommentHandler.java | 8 +++ .../comment/special/CommentModify.java | 3 + .../java/com/probejs/rewrite/ClazzPath.java | 9 +-- .../com/probejs/rewrite/doc/DocClazz.java | 3 +- .../com/probejs/rewrite/doc/DocComment.java | 49 ++++++++++++++- .../com/probejs/rewrite/doc/DocField.java | 3 +- .../com/probejs/rewrite/doc/DocMethod.java | 61 +++++++++++++++++-- .../rewrite/doc/type/DocTypeArray.java | 15 +++++ .../rewrite/doc/type/DocTypeClazz.java | 6 ++ .../rewrite/doc/type/DocTypeResolver.java | 24 ++++++++ 11 files changed, 168 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/probejs/rewrite/doc/type/DocTypeArray.java create mode 100644 src/main/java/com/probejs/rewrite/doc/type/DocTypeResolver.java diff --git a/src/main/java/com/probejs/document/DocumentComment.java b/src/main/java/com/probejs/document/DocumentComment.java index d0890b02..d51fe11a 100644 --- a/src/main/java/com/probejs/document/DocumentComment.java +++ b/src/main/java/com/probejs/document/DocumentComment.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; public class DocumentComment implements IDecorative, MultiFormatter { @@ -48,8 +49,8 @@ public DocumentComment(List lines) { .map(String::trim) .collect(Collectors.toList()); this.rawLines.stream() - .filter(CommentHandler::isCommentLineSpecial) - .map(t -> CommentHandler.specialCommentHandler.get(t.split(" ", 2)[0]).apply(t)) + .map(CommentHandler::tryParseSpecialComment) + .filter(Objects::nonNull) .forEach(c -> specials.put(c.getClass(), c)); } diff --git a/src/main/java/com/probejs/document/comment/CommentHandler.java b/src/main/java/com/probejs/document/comment/CommentHandler.java index 2b631b62..0f27838c 100644 --- a/src/main/java/com/probejs/document/comment/CommentHandler.java +++ b/src/main/java/com/probejs/document/comment/CommentHandler.java @@ -27,6 +27,14 @@ public static boolean isCommentLineSpecial(String line) { return specialCommentHandler.containsKey(line.split(" ", 2)[0]); } + public static SpecialComment tryParseSpecialComment(String line) { + line = line.trim(); + if (!line.startsWith("@")) { + return null; + } + return specialCommentHandler.get(line.split(" ")[0]).apply(line); + } + public static void init() { specialCommentHandler.put("@hidden", CommentHidden::new); specialCommentHandler.put("@modify", CommentModify::new); diff --git a/src/main/java/com/probejs/document/comment/special/CommentModify.java b/src/main/java/com/probejs/document/comment/special/CommentModify.java index c85e6dfc..daa78599 100644 --- a/src/main/java/com/probejs/document/comment/special/CommentModify.java +++ b/src/main/java/com/probejs/document/comment/special/CommentModify.java @@ -5,6 +5,9 @@ import com.probejs.document.type.DocTypeResolver; import lombok.Getter; +/** + * type modify + */ @Getter public class CommentModify extends SpecialComment { diff --git a/src/main/java/com/probejs/rewrite/ClazzPath.java b/src/main/java/com/probejs/rewrite/ClazzPath.java index 2772f794..a7a7b68b 100644 --- a/src/main/java/com/probejs/rewrite/ClazzPath.java +++ b/src/main/java/com/probejs/rewrite/ClazzPath.java @@ -13,8 +13,9 @@ @AllArgsConstructor public class ClazzPath { public static final List NAMESPACE_INTERNAL = Collections.singletonList("Internal"); + public static final List NAMESPACE_NONE = Collections.emptyList(); public static final String NAME_UNRESOLVED = "Unresolved"; - public static final ClazzPath UNRESOLVED = new ClazzPath(Collections.emptyList(), NAME_UNRESOLVED, false); + public static final ClazzPath UNRESOLVED = new ClazzPath(NAMESPACE_NONE, NAME_UNRESOLVED, false); private final List namespace; private final String name; @@ -30,12 +31,6 @@ public class ClazzPath { this.isInternal = false; } - public List getNamespace() { - return this.isInternal && !this.namespace.isEmpty() - ? ClazzPath.NAMESPACE_INTERNAL - : this.namespace; - } - public String asStrPath(String delimiter) { return String.join(delimiter, this.asStrNamespace(delimiter), this.name); } diff --git a/src/main/java/com/probejs/rewrite/doc/DocClazz.java b/src/main/java/com/probejs/rewrite/doc/DocClazz.java index 548ef0c8..4a7769e6 100644 --- a/src/main/java/com/probejs/rewrite/doc/DocClazz.java +++ b/src/main/java/com/probejs/rewrite/doc/DocClazz.java @@ -26,12 +26,13 @@ public class DocClazz implements CommentHolder { private final List assignables; private DocClazz(Class clazz) { + //doc properties val cInfo = ClassInfo.ofCache(clazz); this.path = PathResolver.resolve(cInfo.getRaw()); REGISTRIES.put(clazz, this); this.assignables = new ArrayList<>(); this.comment = new DocComment(); - + //properties from ClassInfo this.fields = cInfo.getFields().stream().map(DocField::new).collect(Collectors.toList()); this.methods = cInfo.getMethods().stream().map(DocMethod::new).collect(Collectors.toList()); } diff --git a/src/main/java/com/probejs/rewrite/doc/DocComment.java b/src/main/java/com/probejs/rewrite/doc/DocComment.java index a4aa8567..101f46b2 100644 --- a/src/main/java/com/probejs/rewrite/doc/DocComment.java +++ b/src/main/java/com/probejs/rewrite/doc/DocComment.java @@ -1,23 +1,31 @@ package com.probejs.rewrite.doc; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import com.probejs.document.comment.CommentHandler; import com.probejs.document.comment.SpecialComment; +import com.probejs.util.Pair; +import lombok.Getter; +import lombok.val; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** * only java doc comment, regular line comment / block comment are not supported by this */ +@Getter public class DocComment { - private final List specials; + private final ListMultimap, SpecialComment> specials; private final List normals; /** * construct a new, empty DocComment */ DocComment() { - this.specials = new ArrayList<>(0); + this.specials = ArrayListMultimap.create(3,1); this.normals = new ArrayList<>(0); } @@ -25,4 +33,41 @@ public class DocComment { this(); //TODO: parse } + + /** + * @return {trimmed line, special comment} + */ + private static Pair parseFirstLine(String line) { + line = line.trim(); + if (!line.startsWith("/**")) { + throw new IllegalArgumentException("arg not first line of a javadoc comment"); + } + line = line.substring(3); + return new Pair<>(line, CommentHandler.tryParseSpecialComment(line)); + } + + private static Pair parseLastLine(String line) { + line = line.trim(); + if (!line.endsWith("*/")) { + throw new IllegalArgumentException("arg not last line of a javadoc comment"); + } + //TODO + return null; + } + + public void acceptSpecials(Collection specials) { + for (T special : specials) { + this.specials.put(special.getClass(), special); + } + } + + @SuppressWarnings("unchecked") + public List getSpecialComment(Class type) { + val comments = this.specials.get(type); + val special = new ArrayList(comments.size()); + for (val comment : comments) { + special.add((T) comment); + } + return special; + } } diff --git a/src/main/java/com/probejs/rewrite/doc/DocField.java b/src/main/java/com/probejs/rewrite/doc/DocField.java index 6e7073f2..6893d568 100644 --- a/src/main/java/com/probejs/rewrite/doc/DocField.java +++ b/src/main/java/com/probejs/rewrite/doc/DocField.java @@ -4,6 +4,7 @@ import com.probejs.info.type.IType; import com.probejs.rewrite.doc.comments.CommentHolder; import lombok.Getter; +import lombok.val; @Getter public class DocField implements CommentHolder { @@ -21,6 +22,6 @@ public class DocField implements CommentHolder { @Override public void applyComment() { - + val specials = this.comment.getSpecials(); } } diff --git a/src/main/java/com/probejs/rewrite/doc/DocMethod.java b/src/main/java/com/probejs/rewrite/doc/DocMethod.java index 82d9bdb6..7fbc8575 100644 --- a/src/main/java/com/probejs/rewrite/doc/DocMethod.java +++ b/src/main/java/com/probejs/rewrite/doc/DocMethod.java @@ -1,28 +1,79 @@ package com.probejs.rewrite.doc; +import com.probejs.document.comment.SpecialComment; +import com.probejs.document.comment.special.CommentModify; +import com.probejs.document.comment.special.CommentRename; +import com.probejs.document.type.IDocType; import com.probejs.info.clazz.MethodInfo; -import com.probejs.info.type.IType; import com.probejs.rewrite.doc.comments.CommentHolder; import lombok.Getter; +import lombok.Setter; +import lombok.val; import java.util.List; +import java.util.stream.Collectors; @Getter public class DocMethod implements CommentHolder { private final DocComment comment; - private final List params; - private IType returnType; + private final List params; + private IDocType returnType; DocMethod(MethodInfo mInfo) { this.comment = new DocComment(); + this.params = mInfo.getParams().stream().map(DocParam::new).collect(Collectors.toList()); //TODO: doc type - this.params = mInfo.getParams(); - this.returnType = mInfo.getType(); + this.returnType = (IDocType) mInfo.getType(); } @Override public void applyComment() { + //rename + for (val rename : this.comment.getSpecialComment(CommentRename.class)) { + for (val param : this.params) { + if (param.applyComment(rename)) { + break; + } + } + } + //type modify + val modifys = this.comment.getSpecialComment(CommentModify.class); + if (!modifys.isEmpty()) { + val modify = modifys.get(0); + if (modify.getName().equals(this.returnType.getTypeName())) { + this.returnType = modify.getType(); + } + } + } + + @Getter + @Setter + public static class DocParam { + + private String name; + private IDocType type; + + DocParam(MethodInfo.ParamInfo pInfo) { + this.name = pInfo.getName(); + //TODO: doc type + this.type = (IDocType) pInfo.getType(); + } + public boolean applyComment(SpecialComment comment) { + //TODO: totally mess + if (comment instanceof CommentRename rename) { + if (rename.getName().equals(this.name)) { + this.name = rename.getTo(); + } + } else if (comment instanceof CommentModify modify) { + if (modify.getName().equals(this.type.getTypeName())) { + this.type = modify.getType(); + } + } else { + return false; + } + return true; + } } } diff --git a/src/main/java/com/probejs/rewrite/doc/type/DocTypeArray.java b/src/main/java/com/probejs/rewrite/doc/type/DocTypeArray.java new file mode 100644 index 00000000..f23a57d3 --- /dev/null +++ b/src/main/java/com/probejs/rewrite/doc/type/DocTypeArray.java @@ -0,0 +1,15 @@ +package com.probejs.rewrite.doc.type; + +import com.probejs.info.type.IType; +import com.probejs.info.type.TypeArray; +import lombok.Getter; + +@Getter +public class DocTypeArray implements DocType { + + private final DocType base; + + DocTypeArray(IType type) { + this.base = DocTypeResolver.of(((TypeArray)type).getBase()); + } +} diff --git a/src/main/java/com/probejs/rewrite/doc/type/DocTypeClazz.java b/src/main/java/com/probejs/rewrite/doc/type/DocTypeClazz.java index 1d0a852e..7c7858b1 100644 --- a/src/main/java/com/probejs/rewrite/doc/type/DocTypeClazz.java +++ b/src/main/java/com/probejs/rewrite/doc/type/DocTypeClazz.java @@ -1,6 +1,8 @@ package com.probejs.rewrite.doc.type; import com.probejs.info.clazz.ClassInfo; +import com.probejs.info.type.IType; +import com.probejs.info.type.TypeClass; import com.probejs.rewrite.ClazzPath; import com.probejs.rewrite.doc.DocClazz; import lombok.Getter; @@ -21,4 +23,8 @@ public class DocTypeClazz implements DocType { DocTypeClazz(ClassInfo clazz) { this(clazz.getRaw()); } + + public DocTypeClazz(IType iType) { + this(((TypeClass) iType).getRaw()); + } } diff --git a/src/main/java/com/probejs/rewrite/doc/type/DocTypeResolver.java b/src/main/java/com/probejs/rewrite/doc/type/DocTypeResolver.java new file mode 100644 index 00000000..de2f717c --- /dev/null +++ b/src/main/java/com/probejs/rewrite/doc/type/DocTypeResolver.java @@ -0,0 +1,24 @@ +package com.probejs.rewrite.doc.type; + +import com.probejs.info.type.IType; +import com.probejs.info.type.TypeArray; +import com.probejs.info.type.TypeClass; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +public abstract class DocTypeResolver { + + private static final Map, Function> REGISTRIES; + + static { + REGISTRIES = new HashMap<>(); + REGISTRIES.put(TypeClass.class, DocTypeClazz::new); + REGISTRIES.put(TypeArray.class, DocTypeClazz::new); + } + + public static DocType of(IType type) { + return REGISTRIES.get(type.getClass()).apply(type); + } +}