1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
package org.javacs;
import com.sun.source.tree.CompilationUnitTree;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.*;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.tools.*;
public class Docs {
/** File manager with source-path + platform sources, which we will use to look up individual source files */
private final SourceFileManager fileManager = new SourceFileManager();
private static Optional<Path> srcZip() {
if (!Lib.SRC_ZIP.isPresent()) {
return Optional.empty();
}
try {
var fs = FileSystems.newFileSystem(Lib.SRC_ZIP.get(), Docs.class.getClassLoader());
return Optional.of(fs.getPath("/"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Docs(Set<Path> docPath) {
// Path to source .jars + src.zip
var sourcePathFiles = docPath.stream().map(Path::toFile).collect(Collectors.toSet());
try {
fileManager.setLocation(StandardLocation.SOURCE_PATH, sourcePathFiles);
Optional<Path> srcZipPath = srcZip();
if (srcZipPath.isPresent()) {
fileManager.setLocationFromPaths(StandardLocation.MODULE_SOURCE_PATH, Set.of(srcZipPath.get()));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public Optional<JavaFileObject> find(Ptr ptr) {
LOG.info(String.format("...looking for file for `%s`...", ptr));
// Find the file el was declared in
var className = ptr.qualifiedClassName();
try {
var fromSourcePath =
fileManager.getJavaFileForInput(
StandardLocation.SOURCE_PATH, className, JavaFileObject.Kind.SOURCE);
if (fromSourcePath != null) {
LOG.info(String.format("...found %s on source path", fromSourcePath.toUri().getPath()));
return Optional.of(fromSourcePath);
}
for (var module : Classes.JDK_MODULES) {
var moduleLocation = fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, module);
if (moduleLocation == null) continue;
var fromModuleSourcePath =
fileManager.getJavaFileForInput(moduleLocation, className, JavaFileObject.Kind.SOURCE);
if (fromModuleSourcePath != null) {
LOG.info(String.format("...found %s in module %s of jdk", fromModuleSourcePath.toUri(), module));
return Optional.of(fromModuleSourcePath);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
LOG.info(String.format("...couldn't find file for top-level class `%s`", className));
return Optional.empty();
}
public ParseFile parse(JavaFileObject file) {
// Parse that file
var task = Parser.parseTask(file);
CompilationUnitTree root;
try {
root = task.parse().iterator().next();
} catch (IOException e) {
throw new RuntimeException(e);
}
return new ParseFile(task, root);
}
private static final Pattern HTML_TAG = Pattern.compile("<(\\w+)>");
private static boolean isHtml(String text) {
var tags = HTML_TAG.matcher(text);
while (tags.find()) {
var tag = tags.group(1);
var close = String.format("</%s>", tag);
var findClose = text.indexOf(close, tags.end());
if (findClose != -1) return true;
}
return false;
}
/** If `commentText` looks like HTML, convert it to markdown */
public static String htmlToMarkdown(String commentText) {
if (isHtml(commentText)) {
return TipFormatter.asMarkdown(commentText);
} else return commentText;
}
private static final Logger LOG = Logger.getLogger("main");
}
|