Skip to content

Commit a6579eb

Browse files
committed
A few tweaks to the docs command
1 parent 24f9a47 commit a6579eb

File tree

7 files changed

+211
-11
lines changed

7 files changed

+211
-11
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ webhooks = "0.8.2"
3232
eventdispatcher = "1.7.1"
3333
asmutils = "0.4.0"
3434
typetools = "0.6.3"
35-
javadocapi = "21ad5c1759"
35+
javadocapi = "25c84a4"
3636
commons-io = "2.11.0"
3737
caffeine = "3.1.1"
3838
urldetector = "0.1.23"

src/commander/java/com/mcmoddev/mmdbot/commander/docs/ConfigBasedElementLoader.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import de.ialistannen.javadocapi.indexing.OnlineJavadocIndexer;
2626
import de.ialistannen.javadocapi.rendering.Java11PlusLinkResolver;
2727
import de.ialistannen.javadocapi.spoon.JavadocElementExtractor;
28+
import de.ialistannen.javadocapi.spoon.JavadocLauncher;
2829
import de.ialistannen.javadocapi.spoon.filtering.IndexerFilterChain;
2930
import de.ialistannen.javadocapi.spoon.filtering.ParallelProcessor;
3031
import de.ialistannen.javadocapi.storage.AggregatedElementLoader;
@@ -38,6 +39,7 @@
3839
import org.spongepowered.configurate.hocon.HoconConfigurationLoader;
3940
import spoon.Launcher;
4041
import spoon.OutputType;
42+
import spoon.support.compiler.ProgressLogger;
4143
import spoon.support.compiler.ZipFolder;
4244

4345
import java.io.FileOutputStream;
@@ -125,7 +127,7 @@ private void tryIndex(final String indexUrl, final SqliteStorage storage) throws
125127
Files.createDirectories(parent);
126128
}
127129
Files.createFile(storage.getFile());
128-
final var launcher = new Launcher();
130+
final var launcher = new JavadocLauncher();
129131
if (indexUrl.startsWith("https://") || indexUrl.startsWith("http://")) {
130132
log.info("Downloading {} for indexing...", indexUrl);
131133
try (final var readChannel = Channels.newChannel(new URL(indexUrl).openStream())) {
@@ -148,19 +150,20 @@ private void tryIndex(final String indexUrl, final SqliteStorage storage) throws
148150
index(launcher, storage);
149151
}
150152

151-
private void index(final Launcher launcher, final SqliteStorage storage) {
152-
log.warn("Started indexing JavaDocs...");
153+
static void index(final Launcher launcher, final SqliteStorage storage) {
154+
log.warn("Started indexing JavaDocs for {}...", storage.getFile());
153155
launcher.getEnvironment().setShouldCompile(false);
154156
launcher.getEnvironment().disableConsistencyChecks();
155157
launcher.getEnvironment().setOutputType(OutputType.NO_OUTPUT);
156158
launcher.getEnvironment().setCommentEnabled(true);
157159
launcher.getEnvironment().setComplianceLevel(16);
160+
launcher.getEnvironment().setSpoonProgress(new LoggingProcessLogger(launcher));
158161

159162
final var model = launcher.buildModel();
160163
final var extractor = new JavadocElementExtractor();
161164
final var processor = new ParallelProcessor(
162165
new IndexerFilterChain(Set.of("*")).asFilter(),
163-
Runtime.getRuntime().availableProcessors()
166+
1
164167
);
165168
model.getAllModules()
166169
.forEach(it -> processor.process(
@@ -196,4 +199,34 @@ private static List<ExternalJavadocReference> indexExternalJavadoc(List<String>
196199

197200
return references;
198201
}
202+
203+
public static class LoggingProcessLogger extends ProgressLogger {
204+
205+
public int touchedClasses;
206+
207+
public LoggingProcessLogger(Launcher launcher) {
208+
super(launcher.getEnvironment());
209+
touchedClasses = 0;
210+
}
211+
212+
@Override
213+
public void start(Process process) {
214+
log.warn("Stating phase {}", process);
215+
touchedClasses = 0;
216+
}
217+
218+
@Override
219+
public void step(Process process, String task, int taskId, int nbTask) {
220+
log.info("Working on {} as part of {}", task, process);
221+
touchedClasses++;
222+
if (touchedClasses % 1000 == 0) {
223+
log.warn("Phase {} has discovered {} classes so far. Currently working on {}", process, touchedClasses, task);
224+
}
225+
}
226+
227+
@Override
228+
public void end(Process process) {
229+
log.warn("Phase {} done! Discovered classes: {}", process, touchedClasses);
230+
}
231+
}
199232
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* MMDBot - https://github.com/MinecraftModDevelopment/MMDBot
3+
* Copyright (C) 2016-2022 <MMD - MinecraftModDevelopment>
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation;
8+
* Specifically version 2.1 of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18+
* USA
19+
* https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
20+
*/
21+
package com.mcmoddev.mmdbot.commander.docs;
22+
23+
import com.google.common.collect.Lists;
24+
import de.ialistannen.javadocapi.model.JavadocElement;
25+
import de.ialistannen.javadocapi.model.QualifiedName;
26+
import de.ialistannen.javadocapi.model.types.JavadocType;
27+
28+
import java.util.ArrayList;
29+
import java.util.List;
30+
import java.util.Optional;
31+
import java.util.stream.Collectors;
32+
33+
public class CustomDocFormatter implements DocsEmbed.DocFormatter {
34+
@Override
35+
public String format(final JavadocElement element, final JavadocElement.DeclarationStyle style) {
36+
if (element instanceof JavadocType type) {
37+
return formatType(type, style);
38+
}
39+
40+
return element.getDeclaration(style);
41+
}
42+
43+
public String formatType(final JavadocType type, final JavadocElement.DeclarationStyle style) {
44+
final var result = new StringBuilder();
45+
46+
if (!type.getAnnotations().isEmpty()) {
47+
result.append(type.getAnnotations().stream()
48+
.map(it -> it.getDeclaration(style))
49+
.collect(Collectors.joining("\n")));
50+
result.append("\n");
51+
}
52+
53+
result.append(String.join(" ", filterModifiers(type))).append(" ");
54+
result.append(type.getType().getKeyword()).append(" ");
55+
56+
result.append(type.getQualifiedName().formatted(style));
57+
58+
if (!type.getTypeParameters().isEmpty()) {
59+
result.append(type.getTypeParameters().stream()
60+
.map(it -> it.getDeclaration(style))
61+
.collect(Collectors.joining(", ", "<", ">")));
62+
}
63+
64+
if (type.getType() == JavadocType.Type.ANNOTATION) {
65+
final var members = type.getMembers().stream()
66+
.flatMap(it -> getMethodName(it).stream())
67+
.filter(QualifiedName::isMethod)
68+
.map(QualifiedName::asString)
69+
.toList();
70+
if (!members.isEmpty()) {
71+
final var partitioned = Lists.partition(members, 5);
72+
result.append("(\n");
73+
result.append(String.join("\n", partitioned.stream()
74+
.map(it -> " " + String.join(", ", it))
75+
.toList()));
76+
result.append("\n)");
77+
}
78+
}
79+
80+
if (type.getSuperClass() != null) {
81+
result.append(" extends ").append(type.getSuperClass().getDeclaration(style));
82+
}
83+
84+
if (!type.getSuperInterfaces().isEmpty()) {
85+
result.append(" implements ").append(type.getSuperInterfaces().stream()
86+
.map(it -> it.getDeclaration(style))
87+
.collect(Collectors.joining(", ")));
88+
}
89+
90+
return result.toString();
91+
}
92+
93+
private List<String> filterModifiers(final JavadocType type) {
94+
final var modifiers = new ArrayList<>(type.getModifiers());
95+
if (type.getType() == JavadocType.Type.INTERFACE || type.getType() == JavadocType.Type.ANNOTATION) {
96+
modifiers.remove("abstract");
97+
}
98+
return modifiers;
99+
}
100+
101+
public Optional<QualifiedName> getMethodName(QualifiedName qualifiedName) {
102+
if (qualifiedName.asString().contains("#")) {
103+
return Optional.of(new QualifiedName(
104+
qualifiedName.asString().substring(qualifiedName.asString().indexOf("#") + 1),
105+
qualifiedName.getModuleName().orElse(null)
106+
));
107+
}
108+
return Optional.empty();
109+
}
110+
}

src/commander/java/com/mcmoddev/mmdbot/commander/docs/DocsCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ protected void execute(final SlashCommandEvent event) {
139139
}
140140

141141
final var query = event.getOption("query", "", OptionMapping::getAsString);
142-
if (query.length() <= 2) {
142+
if (query.length() <= 1) {
143143
event.deferReply(true)
144144
.setContent("Expected at least 2 characters for the query!")
145145
.queue();
@@ -235,7 +235,7 @@ void replyResult(long userId, UUID buttonId, BiFunction<Message, Collection<Fuzz
235235
buttonId
236236
);
237237
} else {
238-
replier.apply(new MessageBuilder("Multiple results have been found for this qualified name.")
238+
replier.apply(new MessageBuilder("No results have been found for this qualified name.")
239239
.setActionRows(ActionRow.of(DismissListener.createDismissButton(userId)))
240240
.build(), List.of()).queue();
241241
}

src/commander/java/com/mcmoddev/mmdbot/commander/docs/DocsConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static final class Database {
6767
@Getter
6868
@Required
6969
@Setting("indexUrl")
70-
@Comment("An URL or a path relative to '/docs' which ")
70+
@Comment("An URL or a path relative to '/docs' from which to index the javadocs, from the sources")
7171
private String indexUrl = "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.9.0/gson-2.9.0-sources.jar";
7272
}
7373

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* MMDBot - https://github.com/MinecraftModDevelopment/MMDBot
3+
* Copyright (C) 2016-2022 <MMD - MinecraftModDevelopment>
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation;
8+
* Specifically version 2.1 of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18+
* USA
19+
* https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
20+
*/
21+
package com.mcmoddev.mmdbot.commander.docs;
22+
23+
import de.ialistannen.javadocapi.spoon.JavadocLauncher;
24+
import de.ialistannen.javadocapi.storage.ConfiguredGson;
25+
import de.ialistannen.javadocapi.storage.SqliteStorage;
26+
import spoon.support.compiler.ZipFolder;
27+
28+
import java.io.File;
29+
import java.io.IOException;
30+
import java.net.URL;
31+
import java.net.URLClassLoader;
32+
import java.nio.file.Files;
33+
import java.nio.file.Path;
34+
import java.util.ArrayList;
35+
36+
public class ManualIndexer {
37+
public static void main(String[] args) throws Exception {
38+
final var inPath = Path.of("run/thecommander/docs/input/groovy-4.0.4-sources.jar");
39+
final var outPath = Path.of("run/thecommander/docs/groovy_docs.db");
40+
Files.createFile(outPath);
41+
42+
final var launcher = new JavadocLauncher();
43+
launcher.addInputResource(new ZipFolder(inPath.toFile()));
44+
45+
final var inLibs = new ArrayList<URL>();
46+
47+
inLibs.add(get("\"C:\\Users\\rober\\.gradle\\caches\\modules-2\\files-2.1\\org.codehaus.gpars\\gpars\\1.2.1\\c3ea0fbcd67a163bd5e3a3efdaa3428262d0d437\\gpars-1.2.1.jar\""));
48+
49+
launcher.getEnvironment().setInputClassLoader(new URLClassLoader(inLibs.toArray(URL[]::new)));
50+
51+
ConfigBasedElementLoader.index(launcher, new SqliteStorage(
52+
ConfiguredGson.create(), outPath
53+
));
54+
}
55+
56+
private static URL get(@SuppressWarnings("SameParameterValue") String path) throws IOException {
57+
return new File(path.replace("\"", "")).toURI().toURL();
58+
}
59+
}

src/commander/java/com/mcmoddev/mmdbot/commander/docs/NormalDocsSender.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,7 @@
6060

6161
public class NormalDocsSender implements DocsSender {
6262

63-
// TODO maybe remove the `abstract` part from interfaces, and other similar cases
64-
// Maybe also add the parameters an annotation can have
65-
private final DocsEmbed.DocFormatter formatter = JavadocElement::getDeclaration;
63+
private final DocsEmbed.DocFormatter formatter = new CustomDocFormatter();
6664
private final NameShortener nameShortener = new NameShortener();
6765

6866
@Override

0 commit comments

Comments
 (0)