Skip to content

Commit

Permalink
Initial refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
abelsromero committed Apr 18, 2024
1 parent 144704b commit 0df76e0
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 115 deletions.
21 changes: 10 additions & 11 deletions src/main/java/org/asciidoctor/asciidoclet/AsciiDocTrees.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,11 @@ private Tokens.Comment convertToAsciidoctor(Tokens.Comment comment) {
AsciidocComment result = new AsciidocComment(asciidoc, comment);
return result;
}

private String convertJavadocStringToAsciidoctorString(String javadocString) {
return converter.convert(javadocString);
return converter.convert(javadocString);
}



@Override
public DocCommentTree getDocCommentTree(Element e) {
TreePath path = getPath(e);
Expand Down Expand Up @@ -154,19 +153,19 @@ public DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageE
public Element getElement(DocTreePath path) {
return docTrees.getElement(path);
}

// Not giving @Override in order to make this class compilable under all of JDK 11, 17, 21.
public TypeMirror getType(DocTreePath path) {
// In order to make this method compilable with JDK11, which doesn't define DocTrees#getType method,
// and make this method work with JDK 17 and later, invoke the DocTrees#getType(DocTreePath) method reflectively.
// Once we decide to stop supporting JDK 11, just call getType directly.
try {
return (TypeMirror) DocTrees.class.getMethod("getType", DocTreePath.class).invoke(docTrees, path);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
try {
return (TypeMirror) DocTrees.class.getMethod("getType", DocTreePath.class).invoke(docTrees, path);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}

@Override
public List<DocTree> getFirstSentence(List<? extends DocTree> list) {
return docTrees.getFirstSentence(list);
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/org/asciidoctor/asciidoclet/Asciidoclet.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import jdk.javadoc.doclet.StandardDoclet;

import javax.lang.model.SourceVersion;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
Expand Down Expand Up @@ -213,13 +211,11 @@ public SourceVersion getSupportedSourceVersion() {

@Override
public boolean run(DocletEnvironment environment) {
docletOptions.validateOptions();
docletOptions.validate();
AsciidoctorConverter converter = new AsciidoctorConverter(docletOptions, reporter);
boolean result;
try (AsciidoctorFilteredEnvironment env = new AsciidoctorFilteredEnvironment(environment, converter)) {
result = standardDoclet.run(env);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return result && postProcess(environment);
}
Expand Down
85 changes: 18 additions & 67 deletions src/main/java/org/asciidoctor/asciidoclet/AsciidoctorConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,9 @@

import jdk.javadoc.doclet.Reporter;
import org.asciidoctor.Asciidoctor;
import org.asciidoctor.Attributes;
import org.asciidoctor.AttributesBuilder;
import org.asciidoctor.Options;
import org.asciidoctor.OptionsBuilder;
import org.asciidoctor.SafeMode;
import org.asciidoctor.extension.RubyExtensionRegistry;
import org.asciidoctor.jruby.AsciidoctorJRuby;

import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand All @@ -40,74 +33,35 @@ class AsciidoctorConverter {

static final String MARKER = " \t \t";

private static AttributesBuilder defaultAttributes() {
return Attributes.builder()
.attribute("at", "&#64;")
.attribute("slash", "/")
.attribute("icons", null)
.attribute("idprefix", "")
.attribute("idseparator", "-")
.attribute("javadoc", "")
.attribute("showtitle", true)
.attribute("source-highlighter", "coderay")
.attribute("coderay-css", "class")
.attribute("env-asciidoclet")
.attribute("env", "asciidoclet");
}

private static OptionsBuilder defaultOptions() {
return Options.builder()
.safe(SafeMode.SAFE)
.backend("html5");
}

private static final Pattern TYPE_PARAM = Pattern.compile("\\s*<(\\w+)>(.*)");
private static final String INLINE_DOCTYPE = "inline";

private final Asciidoctor asciidoctor;
private final Optional<OutputTemplates> templates;
private final Options options;
// TODO ASR keep it because it copies templates and we don't want to do IO tasks every time we convert something.
private final OutputTemplates templates;
private final Reporter reporter;
private final DocletOptions docletOptions;

AsciidoctorConverter(DocletOptions docletOptions, Reporter reporter) {
// TODO ASR refactor templates to avoid doing stuff before time
this(docletOptions, reporter, OutputTemplates.create(reporter), createAsciidoctorInstance(docletOptions.gemPath()));
}

private static Asciidoctor createAsciidoctorInstance(String gemPath) {
if (gemPath != null) {
return AsciidoctorJRuby.Factory.create(gemPath);
}
return Asciidoctor.Factory.create();
}

/**
* Constructor used directly for testing purposes only.
*/
AsciidoctorConverter(DocletOptions docletOptions, Reporter errorReporter, Optional<OutputTemplates> templates, Asciidoctor asciidoctor) {
AsciidoctorConverter(DocletOptions docletOptions, Reporter reporter, OutputTemplates templates, Asciidoctor asciidoctor) {
this.asciidoctor = asciidoctor;
this.reporter = reporter;
this.templates = templates;
this.options = buildOptions(docletOptions, errorReporter);
this.docletOptions = docletOptions;
}

private Options buildOptions(DocletOptions docletOptions, Reporter errorReporter) {
final OptionsBuilder opts = defaultOptions();
if (docletOptions.baseDir().isPresent()) {
opts.baseDir(docletOptions.baseDir().get());
}
templates.ifPresent(outputTemplates -> opts.templateDir(outputTemplates.templateDir().toFile()));
opts.attributes(buildAttributes(docletOptions, errorReporter));
if (docletOptions.requires().size() > 0) {
RubyExtensionRegistry rubyExtensionRegistry = asciidoctor.rubyExtensionRegistry();
for (String require : docletOptions.requires()) {
rubyExtensionRegistry.requireLibrary(require);
}
private static Asciidoctor createAsciidoctorInstance(String gemPath) {
if (gemPath != null) {
return AsciidoctorJRuby.Factory.create(gemPath);
}
return opts.get();
}

private Attributes buildAttributes(DocletOptions docletOptions, Reporter errorReporter) {
return defaultAttributes()
.attributes(new AttributesLoader(asciidoctor, docletOptions, errorReporter).load())
.get();
return Asciidoctor.Factory.create();
}

/**
Expand All @@ -132,12 +86,6 @@ String convert(String doc) {
return buffer.toString();
}

void cleanup() throws IOException {
if (templates.isPresent()) {
templates.get().delete();
}
}

/**
* Renders a document tag in the standard way.
*
Expand Down Expand Up @@ -192,10 +140,13 @@ private String convert(String input, boolean inline) {
// "article");
// However, this fix breaks AsciidoctorConverterTest#testParameterWithoutTypeTag.
// For now, I simply set it to "article", always.
Options options = new AsciidoctorOptionsFactory(asciidoctor, reporter)
.create(docletOptions, templates);
// TODO ASR this should be in the factory ?
options.setDocType(inline ?
INLINE_DOCTYPE :
"article"); // upstream sets this to "".
INLINE_DOCTYPE :
"article"); // upstream sets this to "".

return asciidoctor.convert(cleanJavadocInput(input), options);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import javax.tools.JavaFileManager;
import javax.tools.StandardJavaFileManager;
import java.io.IOException;

/**
* An operating environment defined for AsciiDoclet.
Expand All @@ -30,13 +29,11 @@ public class AsciidoctorFilteredEnvironment
extends DocEnvImpl
implements DocletEnvironment, AutoCloseable {

private final AsciidoctorConverter converter;
private final StandardJavaFileManager fileManager;
private final AsciiDocTrees asciiDocTrees;

AsciidoctorFilteredEnvironment(DocletEnvironment environment, AsciidoctorConverter converter) {
super(((DocEnvImpl) environment).toolEnv, ((DocEnvImpl) environment).etable);
this.converter = converter;
this.fileManager = new AsciidoctorFileManager(converter, (StandardJavaFileManager) environment.getJavaFileManager());
this.asciiDocTrees = new AsciiDocTrees(converter, fileManager, environment.getDocTrees());
}
Expand All @@ -52,7 +49,6 @@ public DocTrees getDocTrees() {
}

@Override
public void close() throws IOException {
converter.cleanup();
public void close() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package org.asciidoctor.asciidoclet;

import jdk.javadoc.doclet.Reporter;
import org.asciidoctor.Asciidoctor;
import org.asciidoctor.Attributes;
import org.asciidoctor.AttributesBuilder;
import org.asciidoctor.Options;
import org.asciidoctor.OptionsBuilder;
import org.asciidoctor.SafeMode;
import org.asciidoctor.extension.RubyExtensionRegistry;

class AsciidoctorOptionsFactory {

private static final String DEFAULT_BACKEND = "html5";

private final Asciidoctor asciidoctor;
private final Reporter reporter;

AsciidoctorOptionsFactory(Asciidoctor asciidoctor, Reporter reporter) {
this.asciidoctor = asciidoctor;
this.reporter = reporter;
}

Options create(DocletOptions docletOptions, OutputTemplates templates) {
final OptionsBuilder opts = defaultOptions();
if (docletOptions.baseDir().isPresent()) {
opts.baseDir(docletOptions.baseDir().get());
}
if (templates != null) {
opts.templateDir(templates.templateDir().toFile());
}

opts.attributes(buildAttributes(docletOptions));
if (docletOptions.requires().size() > 0) {
RubyExtensionRegistry rubyExtensionRegistry = asciidoctor.rubyExtensionRegistry();
for (String require : docletOptions.requires()) {
rubyExtensionRegistry.requireLibrary(require);
}
}
return opts.get();
}

private Attributes buildAttributes(DocletOptions docletOptions) {
return defaultAttributes()
.attributes(new AttributesLoader(asciidoctor, docletOptions, reporter).load())
.get();
}

private static OptionsBuilder defaultOptions() {
return Options.builder()
.safe(SafeMode.SAFE)
.backend(DEFAULT_BACKEND);
}

private static AttributesBuilder defaultAttributes() {
return org.asciidoctor.Attributes.builder()
.attribute("at", "&#64;")
.attribute("slash", "/")
.attribute("icons", null)
.attribute("idprefix", "")
.attribute("idseparator", "-")
.attribute("javadoc", "")
.attribute("showtitle", true)
.attribute("source-highlighter", "coderay")
.attribute("coderay-css", "class")
.attribute("env-asciidoclet")
.attribute("env", "asciidoclet");
}

}
18 changes: 6 additions & 12 deletions src/main/java/org/asciidoctor/asciidoclet/AttributesLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,11 @@
import org.asciidoctor.Options;
import org.asciidoctor.OptionsBuilder;
import org.asciidoctor.SafeMode;
import org.asciidoctor.jruby.internal.IOUtils;

import javax.tools.Diagnostic;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
Expand All @@ -41,12 +37,12 @@ class AttributesLoader {

private final Asciidoctor asciidoctor;
private final DocletOptions docletOptions;
private final Reporter errorReporter;
private final Reporter reporter;

AttributesLoader(Asciidoctor asciidoctor, DocletOptions docletOptions, Reporter errorReporter) {
AttributesLoader(Asciidoctor asciidoctor, DocletOptions docletOptions, Reporter reporter) {
this.asciidoctor = asciidoctor;
this.docletOptions = docletOptions;
this.errorReporter = errorReporter;
this.reporter = reporter;
}

Map<String, Object> load() {
Expand Down Expand Up @@ -80,7 +76,7 @@ private Map<String, Object> parseAttributesFile(Optional<File> attrsFile, Map<St
try (Reader reader = Files.newBufferedReader(attrsFile.get().toPath(), docletOptions.encoding())) {
return parseAttributes(reader, cmdlineAttrs);
} catch (Exception e) {
errorReporter.print(Diagnostic.Kind.WARNING, "Cannot read attributes file: " + e);
reporter.print(Diagnostic.Kind.WARNING, "Cannot read attributes file: " + e);
}
}
return cmdlineAttrs;
Expand All @@ -95,13 +91,11 @@ private Map<String, Object> parseAttributes(Reader in, Map<String, Object> exist
options.baseDir(docletOptions.baseDir().get());
}

final String content = read(in);
final Map<String, Object> parsed = asciidoctor.load(content, options.build()).getAttributes();
return parsed;
return asciidoctor.load(read(in), options.build()).getAttributes();
}

public static String read(Reader reader) {
try (Scanner scanner = new Scanner(reader).useDelimiter("\\A")){
try (Scanner scanner = new Scanner(reader).useDelimiter("\\A")) {
return scanner.next();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private Stream<String> splitTrimStream(List<String> list) {
.filter(s -> !s.isEmpty());
}

void validateOptions() {
void validate() {
if (baseDir().isEmpty()) {
printWarning(AsciidocletOptions.BASEDIR + " must be present for includes or file reference features to work properly");
}
Expand Down
Loading

0 comments on commit 0df76e0

Please sign in to comment.