From 82f3beff9a3cc9e1cd9534e772e8a91a54b49cab Mon Sep 17 00:00:00 2001 From: Juuz <6596629+Juuxel@users.noreply.github.com> Date: Sun, 14 May 2023 16:34:59 +0300 Subject: Move javadoc taglet classes to root project --- build.gradle | 17 +- javadoc/build.gradle | 7 - .../cottonmc/cotton/gui/jd/ExperimentalTaglet.java | 30 ---- .../cottonmc/cotton/gui/jd/PropertyTaglet.java | 196 --------------------- .../io/github/cottonmc/cotton/gui/jd/Util.java | 11 -- settings.gradle | 1 - .../cottonmc/cotton/gui/jd/ExperimentalTaglet.java | 30 ++++ .../cottonmc/cotton/gui/jd/PropertyTaglet.java | 196 +++++++++++++++++++++ .../io/github/cottonmc/cotton/gui/jd/Util.java | 11 ++ 9 files changed, 247 insertions(+), 252 deletions(-) delete mode 100644 javadoc/build.gradle delete mode 100644 javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/ExperimentalTaglet.java delete mode 100644 javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/PropertyTaglet.java delete mode 100644 javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/Util.java create mode 100644 src/javadoc/java/io/github/cottonmc/cotton/gui/jd/ExperimentalTaglet.java create mode 100644 src/javadoc/java/io/github/cottonmc/cotton/gui/jd/PropertyTaglet.java create mode 100644 src/javadoc/java/io/github/cottonmc/cotton/gui/jd/Util.java diff --git a/build.gradle b/build.gradle index 38d2974..3ebd1fe 100644 --- a/build.gradle +++ b/build.gradle @@ -13,8 +13,9 @@ archivesBaseName = project.archives_base_name version = "$project.mod_version+$project.minecraft_version" group = project.maven_group -configurations { - javadocClasspath +sourceSets { + javadoc { + } } repositories { @@ -62,8 +63,6 @@ dependencies { modCompileOnly("com.terraformersmc:modmenu:$project.modmenu_version") { exclude group: 'net.fabricmc.fabric-api' } - - javadocClasspath project(':javadoc') } processResources { @@ -117,17 +116,21 @@ allprojects { } } -evaluationDependsOn(':javadoc') +def javadocBuildJar = tasks.register('javadocBuildJar', Jar) { + destinationDirectory = file('build/devlibs') + archiveClassifier = 'javadoc-build' + from sourceSets.javadoc.output +} javadoc { - dependsOn project(':javadoc').tasks.jar + dependsOn javadocBuildJar options { links "https://maven.fabricmc.net/docs/yarn-$project.yarn_mappings" links 'https://javadoc.io/doc/org.jetbrains/annotations/19.0.0' taglets 'io.github.cottonmc.cotton.gui.jd.ExperimentalTaglet', 'io.github.cottonmc.cotton.gui.jd.PropertyTaglet' - tagletPath project(':javadoc').tasks.jar.outputs.files.singleFile + tagletPath javadocBuildJar.get().archiveFile.get().asFile } exclude("**/impl/**") diff --git a/javadoc/build.gradle b/javadoc/build.gradle deleted file mode 100644 index d263b57..0000000 --- a/javadoc/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -plugins { - id 'java' -} - -repositories { - mavenCentral() -} diff --git a/javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/ExperimentalTaglet.java b/javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/ExperimentalTaglet.java deleted file mode 100644 index dbd2391..0000000 --- a/javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/ExperimentalTaglet.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.github.cottonmc.cotton.gui.jd; - -import com.sun.source.doctree.DocTree; -import jdk.javadoc.doclet.Taglet; - -import java.util.List; -import java.util.Set; -import javax.lang.model.element.Element; - -public class ExperimentalTaglet implements Taglet { - @Override - public Set getAllowedLocations() { - return Set.of(Location.values()); - } - - @Override - public boolean isInlineTag() { - return false; - } - - @Override - public String getName() { - return "experimental"; - } - - @Override - public String toString(List tags, Element element) { - return "
Experimental API:
Might be modified or removed without prior notice until stabilised.
"; - } -} diff --git a/javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/PropertyTaglet.java b/javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/PropertyTaglet.java deleted file mode 100644 index 8b7b1ec..0000000 --- a/javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/PropertyTaglet.java +++ /dev/null @@ -1,196 +0,0 @@ -package io.github.cottonmc.cotton.gui.jd; - -import com.sun.source.doctree.DocTree; -import com.sun.source.doctree.TextTree; -import com.sun.source.util.DocTrees; -import com.sun.source.util.SimpleDocTreeVisitor; -import jdk.javadoc.doclet.Doclet; -import jdk.javadoc.doclet.DocletEnvironment; -import jdk.javadoc.doclet.Taglet; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeVisitor; -import javax.lang.model.util.ElementKindVisitor8; -import javax.lang.model.util.SimpleTypeVisitor8; - -public class PropertyTaglet implements Taglet { - private static final Pattern PROPERTY_METHOD = Pattern.compile("^(.+)Property$"); - private static final String OBSERVABLE_PROPERTY = "io.github.cottonmc.cotton.gui.widget.data.ObservableProperty"; - private static final Set VISIBILITY_MODIFIERS = Set.of(Modifier.PUBLIC, Modifier.PROTECTED); - private DocTrees docTrees; - - @Override - public void init(DocletEnvironment env, Doclet doclet) { - docTrees = env.getDocTrees(); - } - - @Override - public Set getAllowedLocations() { - return Set.of(Location.TYPE); - } - - @Override - public boolean isInlineTag() { - return false; - } - - @Override - public String getName() { - return "properties"; - } - - @Override - public String toString(List tags, Element element) { - if (!((element.getKind().isClass() || element.getKind().isInterface()) && element instanceof TypeElement type)) { - throw new IllegalArgumentException("Not a type: " + element); - } - - List myEntries = scan(type); - StringBuilder builder = new StringBuilder(); - - if (!myEntries.isEmpty()) { - builder.append("
  • "); - builder.append("

    Property Summary

    "); - builder.append("
    Properties
    "); - builder.append("
    "); - builder.append("
    Modifier and Type
    "); - builder.append("
    Property
    "); - builder.append("
    Description
    "); - - for (int i = 0; i < myEntries.size(); i++) { - PropertyEntry entry = myEntries.get(i); - String rowClass = (i % 2 == 0) ? "even-row-color" : "odd-row-color"; - builder.append("
    ").append(entry.visibility); - if (!entry.type.isEmpty()) { - builder.append(' ').append(entry.type); - } - builder.append("
    "); - builder.append("
    "); - builder.append("").append(entry.name).append(""); - builder.append("
    "); - builder.append("
    ").append(entry.doc).append("
    "); - } - - builder.append("
"); - } - - Map> inheritedProperties = new LinkedHashMap<>(); - scanParents(type, inheritedProperties); - - inheritedProperties.forEach((name, entries) -> { - if (!entries.isEmpty()) { - builder.append("
Properties from ").append(name).append("
"); - builder.append("
"); - builder.append(entries.stream().map(entry -> "" + entry.name + "").collect(Collectors.joining(", "))); - builder.append("
"); - } - }); - - return builder.toString(); - } - - private static String getClassName(TypeElement cl) { - return cl.getQualifiedName().toString(); - } - - private List scan(TypeElement cl) { - // Java classes don't have LibGui properties (yet? 😳) - if (getClassName(cl).startsWith("java.")) return List.of(); - - return cl.getEnclosedElements().stream() - .filter(el -> el.getKind() == ElementKind.METHOD) - .map(el -> (ExecutableElement) el) - .map(Util.zip(el -> el.getReturnType().accept(new ObservableTypeProbe(), null))) - .filter(pair -> pair.second().isPresent()) - .map(pair -> { - var el = pair.first(); - Modifier visibility = el.getModifiers().stream() - .filter(VISIBILITY_MODIFIERS::contains) - .findAny() - .orElse(null); - if (visibility == null) return null; // no privates or package-privates - Matcher matcher = PROPERTY_METHOD.matcher(el.getSimpleName()); - - if (matcher.matches()) { - String doc = docTrees.getDocCommentTree(el).getFirstSentence().stream() - .map(tree -> tree.accept(new SimpleDocTreeVisitor() { - @Override - public String visitText(TextTree node, Void o) { - return node.getBody(); - } - }, null)) - .filter(Objects::nonNull) - .findAny().orElse(""); - - return new PropertyEntry(visibility, pair.second().get(), matcher.group(1), doc); - } - - return null; - }) - .filter(Objects::nonNull) - .sorted() - .collect(Collectors.toList()); - } - - private void scanParents(TypeElement cl, Map> inheritedProperties) { - TypeVisitor typeVisitor = new SimpleTypeVisitor8<>() { - @Override - public Void visitDeclared(DeclaredType t, Void o) { - return t.asElement().accept(new ElementKindVisitor8<>() { - @Override - public Void visitType(TypeElement e, Object o) { - String fqn = e.getQualifiedName().toString(); - inheritedProperties.put(fqn, scan(e)); - scanParents(e, inheritedProperties); - return null; - } - }, null); - } - }; - - cl.getSuperclass().accept(typeVisitor, null); - cl.getInterfaces().forEach(itf -> itf.accept(typeVisitor, null)); - } - - private static final class ObservableTypeProbe extends SimpleTypeVisitor8, Void> { - ObservableTypeProbe() { - super(Optional.empty()); - } - - @Override - public Optional visitDeclared(DeclaredType t, Void v) { - Element type = t.asElement(); - - if (type.getKind() == ElementKind.CLASS && ((TypeElement) type).getQualifiedName().contentEquals(OBSERVABLE_PROPERTY)) { - if (!t.getTypeArguments().isEmpty()) { - return Optional.of(t.getTypeArguments().get(0).toString()); - } else { - return Optional.of(""); - } - } - - return Optional.empty(); - } - } - - private record PropertyEntry(Modifier visibility, String type, String name, String doc) implements Comparable { - @Override - public int compareTo(PropertyEntry o) { - return name.compareTo(o.name); - } - } -} diff --git a/javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/Util.java b/javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/Util.java deleted file mode 100644 index 775de4d..0000000 --- a/javadoc/src/main/java/io/github/cottonmc/cotton/gui/jd/Util.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.cottonmc.cotton.gui.jd; - -import java.util.function.Function; - -public final class Util { - public static Function> zip(Function transform) { - return a -> new Pair<>(a, transform.apply(a)); - } - - public record Pair(A first, B second) {} -} diff --git a/settings.gradle b/settings.gradle index d6015c6..ecd1298 100644 --- a/settings.gradle +++ b/settings.gradle @@ -11,4 +11,3 @@ pluginManagement { rootProject.name = 'LibGui' include ':GuiTest' -include 'javadoc' diff --git a/src/javadoc/java/io/github/cottonmc/cotton/gui/jd/ExperimentalTaglet.java b/src/javadoc/java/io/github/cottonmc/cotton/gui/jd/ExperimentalTaglet.java new file mode 100644 index 0000000..dbd2391 --- /dev/null +++ b/src/javadoc/java/io/github/cottonmc/cotton/gui/jd/ExperimentalTaglet.java @@ -0,0 +1,30 @@ +package io.github.cottonmc.cotton.gui.jd; + +import com.sun.source.doctree.DocTree; +import jdk.javadoc.doclet.Taglet; + +import java.util.List; +import java.util.Set; +import javax.lang.model.element.Element; + +public class ExperimentalTaglet implements Taglet { + @Override + public Set getAllowedLocations() { + return Set.of(Location.values()); + } + + @Override + public boolean isInlineTag() { + return false; + } + + @Override + public String getName() { + return "experimental"; + } + + @Override + public String toString(List tags, Element element) { + return "
Experimental API:
Might be modified or removed without prior notice until stabilised.
"; + } +} diff --git a/src/javadoc/java/io/github/cottonmc/cotton/gui/jd/PropertyTaglet.java b/src/javadoc/java/io/github/cottonmc/cotton/gui/jd/PropertyTaglet.java new file mode 100644 index 0000000..8b7b1ec --- /dev/null +++ b/src/javadoc/java/io/github/cottonmc/cotton/gui/jd/PropertyTaglet.java @@ -0,0 +1,196 @@ +package io.github.cottonmc.cotton.gui.jd; + +import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.TextTree; +import com.sun.source.util.DocTrees; +import com.sun.source.util.SimpleDocTreeVisitor; +import jdk.javadoc.doclet.Doclet; +import jdk.javadoc.doclet.DocletEnvironment; +import jdk.javadoc.doclet.Taglet; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeVisitor; +import javax.lang.model.util.ElementKindVisitor8; +import javax.lang.model.util.SimpleTypeVisitor8; + +public class PropertyTaglet implements Taglet { + private static final Pattern PROPERTY_METHOD = Pattern.compile("^(.+)Property$"); + private static final String OBSERVABLE_PROPERTY = "io.github.cottonmc.cotton.gui.widget.data.ObservableProperty"; + private static final Set VISIBILITY_MODIFIERS = Set.of(Modifier.PUBLIC, Modifier.PROTECTED); + private DocTrees docTrees; + + @Override + public void init(DocletEnvironment env, Doclet doclet) { + docTrees = env.getDocTrees(); + } + + @Override + public Set getAllowedLocations() { + return Set.of(Location.TYPE); + } + + @Override + public boolean isInlineTag() { + return false; + } + + @Override + public String getName() { + return "properties"; + } + + @Override + public String toString(List tags, Element element) { + if (!((element.getKind().isClass() || element.getKind().isInterface()) && element instanceof TypeElement type)) { + throw new IllegalArgumentException("Not a type: " + element); + } + + List myEntries = scan(type); + StringBuilder builder = new StringBuilder(); + + if (!myEntries.isEmpty()) { + builder.append("
  • "); + builder.append("

    Property Summary

    "); + builder.append("
    Properties
    "); + builder.append("
    "); + builder.append("
    Modifier and Type
    "); + builder.append("
    Property
    "); + builder.append("
    Description
    "); + + for (int i = 0; i < myEntries.size(); i++) { + PropertyEntry entry = myEntries.get(i); + String rowClass = (i % 2 == 0) ? "even-row-color" : "odd-row-color"; + builder.append("
    ").append(entry.visibility); + if (!entry.type.isEmpty()) { + builder.append(' ').append(entry.type); + } + builder.append("
    "); + builder.append("
    "); + builder.append("").append(entry.name).append(""); + builder.append("
    "); + builder.append("
    ").append(entry.doc).append("
    "); + } + + builder.append("
"); + } + + Map> inheritedProperties = new LinkedHashMap<>(); + scanParents(type, inheritedProperties); + + inheritedProperties.forEach((name, entries) -> { + if (!entries.isEmpty()) { + builder.append("
Properties from ").append(name).append("
"); + builder.append("
"); + builder.append(entries.stream().map(entry -> "" + entry.name + "").collect(Collectors.joining(", "))); + builder.append("
"); + } + }); + + return builder.toString(); + } + + private static String getClassName(TypeElement cl) { + return cl.getQualifiedName().toString(); + } + + private List scan(TypeElement cl) { + // Java classes don't have LibGui properties (yet? 😳) + if (getClassName(cl).startsWith("java.")) return List.of(); + + return cl.getEnclosedElements().stream() + .filter(el -> el.getKind() == ElementKind.METHOD) + .map(el -> (ExecutableElement) el) + .map(Util.zip(el -> el.getReturnType().accept(new ObservableTypeProbe(), null))) + .filter(pair -> pair.second().isPresent()) + .map(pair -> { + var el = pair.first(); + Modifier visibility = el.getModifiers().stream() + .filter(VISIBILITY_MODIFIERS::contains) + .findAny() + .orElse(null); + if (visibility == null) return null; // no privates or package-privates + Matcher matcher = PROPERTY_METHOD.matcher(el.getSimpleName()); + + if (matcher.matches()) { + String doc = docTrees.getDocCommentTree(el).getFirstSentence().stream() + .map(tree -> tree.accept(new SimpleDocTreeVisitor() { + @Override + public String visitText(TextTree node, Void o) { + return node.getBody(); + } + }, null)) + .filter(Objects::nonNull) + .findAny().orElse(""); + + return new PropertyEntry(visibility, pair.second().get(), matcher.group(1), doc); + } + + return null; + }) + .filter(Objects::nonNull) + .sorted() + .collect(Collectors.toList()); + } + + private void scanParents(TypeElement cl, Map> inheritedProperties) { + TypeVisitor typeVisitor = new SimpleTypeVisitor8<>() { + @Override + public Void visitDeclared(DeclaredType t, Void o) { + return t.asElement().accept(new ElementKindVisitor8<>() { + @Override + public Void visitType(TypeElement e, Object o) { + String fqn = e.getQualifiedName().toString(); + inheritedProperties.put(fqn, scan(e)); + scanParents(e, inheritedProperties); + return null; + } + }, null); + } + }; + + cl.getSuperclass().accept(typeVisitor, null); + cl.getInterfaces().forEach(itf -> itf.accept(typeVisitor, null)); + } + + private static final class ObservableTypeProbe extends SimpleTypeVisitor8, Void> { + ObservableTypeProbe() { + super(Optional.empty()); + } + + @Override + public Optional visitDeclared(DeclaredType t, Void v) { + Element type = t.asElement(); + + if (type.getKind() == ElementKind.CLASS && ((TypeElement) type).getQualifiedName().contentEquals(OBSERVABLE_PROPERTY)) { + if (!t.getTypeArguments().isEmpty()) { + return Optional.of(t.getTypeArguments().get(0).toString()); + } else { + return Optional.of(""); + } + } + + return Optional.empty(); + } + } + + private record PropertyEntry(Modifier visibility, String type, String name, String doc) implements Comparable { + @Override + public int compareTo(PropertyEntry o) { + return name.compareTo(o.name); + } + } +} diff --git a/src/javadoc/java/io/github/cottonmc/cotton/gui/jd/Util.java b/src/javadoc/java/io/github/cottonmc/cotton/gui/jd/Util.java new file mode 100644 index 0000000..775de4d --- /dev/null +++ b/src/javadoc/java/io/github/cottonmc/cotton/gui/jd/Util.java @@ -0,0 +1,11 @@ +package io.github.cottonmc.cotton.gui.jd; + +import java.util.function.Function; + +public final class Util { + public static Function> zip(Function transform) { + return a -> new Pair<>(a, transform.apply(a)); + } + + public record Pair(A first, B second) {} +} -- cgit