From c96dcc29a68942102d2ee7b5651b72927787455b Mon Sep 17 00:00:00 2001 From: Chris Vest Date: Tue, 4 Dec 2018 21:22:49 +0100 Subject: [PATCH 1/2] Update snapshot version to 2.0.0. Also update Java dependency to Java 11, and update all Maven plugins to the latest version. Also add a requirement that the Maven version must be at least 3.0.5 in order to support the latest plugins. Modularise and get things compiling on Java 11. The StandardAdapter was trashed in the process, though. License headers are not javadocs. First draft of getting the asciidoclet to run on the new Javadoc APIs under Java 11. Many things are broken. This is currently more of an exploratory prototype, than it is working but incomplete code. There are a lot of ugly hacks here, to work around the new restrictions of the javadoc APIs. Tell Travis CI to use Java 11. Bring back error reporting in AttributesLoader, and make sure to always close the attributes files we open. Make the stylesheet tests pass. Also update Stylesheets to use new Java APIs, and make sure that input and output streams are closed. Insert asciidoctor rendering into more places. Doclet option names begin with double-dashes. Also make sure that the output directory of the integration test is empty before rendering new doclet output. The old AsciidocletTest is not worth salvaging. Reduce reliance on Guava for IO stuff. Remove the remaining usages of Guava. Improve the javadoc parsing. Particularly around javadoc tags. Also avoid re-rendering asciidoctor javadoc comments that have already been rendered. Fix tests and remove debugging left overs. Keep everything grouped under the `org.asciidctor.asciidoclet` group and package. Fix the Maven javadoc plugin configuration, and a couple of other things, to almost make it possible for asciidoclet to render its own javadoc. Resource copying, including copying over our own style sheets, now works again. Make a `mvn javadoc:javadoc` build pass, by ignoring HTML5 doclint errors. Overview, and other files, are now processed correctly as well. Included in this is also a bunch of cleanup. Particularly, many inner classes have been extracted. Reported javadoc errors are now also _slightly_ closer to their cause in the code. Add callouts to explain the new options in the Maven plugin example. --- README.adoc | 20 +- pom.xml | 59 +- .../DocletRenderer.java => module-info.java} | 23 +- .../java/org/asciidoctor/Asciidoclet.java | 288 ----- .../asciidoclet/AsciiDocTrees.java | 275 +++++ .../asciidoclet/AsciidocComment.java | 55 + .../asciidoclet/AsciidocFileView.java | 159 +++ .../asciidoctor/asciidoclet/Asciidoclet.java | 241 ++++ .../asciidoclet/AsciidocletOptions.java | 77 ++ .../asciidoclet/AsciidoctorFileManager.java | 252 ++++ .../AsciidoctorFilteredEnvironment.java | 57 + .../asciidoclet/AsciidoctorRenderer.java | 113 +- .../asciidoclet/AttributesLoader.java | 33 +- .../asciidoclet/DocletOptions.java | 291 +++-- .../asciidoclet/JavadocParser.java | 172 +++ .../LazyDocCommentTableProcessor.java | 75 ++ .../asciidoclet/OptionProcessor.java | 69 ++ .../asciidoclet/OutputTemplates.java | 88 +- .../asciidoclet/StandardAdapter.java | 40 - .../asciidoctor/asciidoclet/Stylesheets.java | 110 +- .../{ => asciidoclet}/package-info.java | 12 +- src/main/resources/stylesheet11.css | 1049 +++++++++++++++++ .../java/org/asciidoctor/AsciidocletTest.java | 142 --- .../AsciidocletIntegrationTest.java | 93 ++ .../asciidoclet/AsciidoctorRendererTest.java | 113 +- .../asciidoclet/AttributesLoaderTest.java | 186 ++- .../asciidoclet/DocletOptionsTest.java | 107 +- .../asciidoclet/JavadocParserTest.java | 83 ++ .../asciidoclet/StandardAdapterTest.java | 84 -- .../asciidoctor/asciidoclet/StubReporter.java | 64 + .../asciidoclet/StylesheetsTest.java | 84 +- 31 files changed, 3359 insertions(+), 1155 deletions(-) rename src/main/java/{org/asciidoctor/asciidoclet/DocletRenderer.java => module-info.java} (69%) delete mode 100644 src/main/java/org/asciidoctor/Asciidoclet.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/AsciiDocTrees.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/AsciidocComment.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/AsciidocFileView.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/Asciidoclet.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/AsciidocletOptions.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/AsciidoctorFileManager.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/AsciidoctorFilteredEnvironment.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/JavadocParser.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/LazyDocCommentTableProcessor.java create mode 100644 src/main/java/org/asciidoctor/asciidoclet/OptionProcessor.java delete mode 100644 src/main/java/org/asciidoctor/asciidoclet/StandardAdapter.java rename src/main/java/org/asciidoctor/{ => asciidoclet}/package-info.java (93%) create mode 100644 src/main/resources/stylesheet11.css delete mode 100644 src/test/java/org/asciidoctor/AsciidocletTest.java create mode 100644 src/test/java/org/asciidoctor/asciidoclet/AsciidocletIntegrationTest.java create mode 100644 src/test/java/org/asciidoctor/asciidoclet/JavadocParserTest.java delete mode 100644 src/test/java/org/asciidoctor/asciidoclet/StandardAdapterTest.java create mode 100644 src/test/java/org/asciidoctor/asciidoclet/StubReporter.java diff --git a/README.adoc b/README.adoc index c93c9ef..e4db329 100644 --- a/README.adoc +++ b/README.adoc @@ -31,6 +31,8 @@ endif::[] ifdef::badges[] image:https://img.shields.io/badge/javadoc.io-{asciidoclet-version}-blue.svg[Javadoc, link={asciidoclet-javadoc-ref}] +image:http://img.shields.io/travis/asciidoctor/asciidoclet/master.svg["Build Status", link="https://travis-ci.org/asciidoctor/asciidoclet"] +image:https://img.shields.io/badge/javadoc.io-1.5.4-blue.svg[Javadoc, link=http://www.javadoc.io/doc/org.asciidoctor/asciidoclet/1.5.4] endif::[] {asciidoclet-src-ref}[Asciidoclet] is a Javadoc Doclet based on Asciidoctor that lets you write Javadoc in the AsciiDoc syntax. @@ -120,10 +122,14 @@ Asciidoclet may be used via a `maven-javadoc-plugin` doclet: org.apache.maven.plugins maven-javadoc-plugin - 2.9 + 3.6.3 - 1.7 - org.asciidoctor.Asciidoclet + 11 + + -J--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED // <1> + -Xdoclint:all,-html,-accessibility // <2> + + org.asciidoctor.asciidoclet.Asciidoclet org.asciidoctor asciidoclet @@ -139,6 +145,10 @@ Asciidoclet may be used via a `maven-javadoc-plugin` doclet: ---- +<1> For the asciidoclet to work, it needs access to the internals of the `javadoc` tool. +This incantation makes that access possible on moduler JDKs. +<2> Asciidoctor may generate HTML that produces doclint errors, which can cause the build to fail. +To work around that, we have to disable these doclint categories. === Gradle @@ -156,7 +166,7 @@ dependencies { javadoc { options.docletpath = configurations.asciidoclet.files.asType(List) - options.doclet = 'org.asciidoctor.Asciidoclet' + options.doclet = 'org.asciidoctor.asciidoclet.Asciidoclet' options.overview = "src/main/java/overview.adoc" options.addStringOption "-base-dir", "${projectDir}" // <1> options.addStringOption "-attribute", // <2> @@ -179,7 +189,7 @@ Asciidoclet may be used via a doclet element in Ant's `javadoc` task: - + diff --git a/pom.xml b/pom.xml index 7e949dc..d2b7806 100644 --- a/pom.xml +++ b/pom.xml @@ -46,27 +46,10 @@ asciidoctorj 1.5.8.1 - - com.sun.tools - tools - ${java.version} - system - ${java.home}/../lib/tools.jar - - - org.slf4j - slf4j-simple - 1.7.25 - - - com.google.guava - guava - 20.0 - junit junit - 4.13.1 + 4.12 test @@ -100,16 +83,19 @@ org.apache.maven.plugins maven-compiler-plugin - 3.1 + 3.8.0 - 1.6 - 1.6 + 11 + + org.apache.maven.plugins + maven-surefire-plugin + org.apache.maven.plugins maven-source-plugin - 2.2.1 + 3.0.1 attach-sources @@ -123,7 +109,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.9 + 3.0.1 attach-javadocs @@ -133,19 +119,19 @@ - 1.7 - org.asciidoctor.Asciidoclet + 11 + org.asciidoctor.asciidoclet.Asciidoclet - org.asciidoctor - asciidoclet + ${project.groupId} + ${project.artifactId} ${project.version} - - --base-dir ${project.basedir} - --attribute "project_name=${project.name}" - --attribute "project_version=${project.version}" - --attribute "project_desc=${project.description}" - + + --base-dir ${project.basedir} + --attribute "project_name=${project.name}" + --attribute "project_version=${project.version}" + --attribute "project_desc=${project.description}" + true src/main/java/overview.adoc @@ -154,7 +140,7 @@ com.mycila.maven-license-plugin maven-license-plugin - 1.9.0 + 1.10.b1
NOTICE
@@ -173,12 +159,15 @@ true true + + SLASHSTAR_STYLE +
org.apache.maven.plugins maven-shade-plugin - 3.1.1 + 3.2.1 true shaded diff --git a/src/main/java/org/asciidoctor/asciidoclet/DocletRenderer.java b/src/main/java/module-info.java similarity index 69% rename from src/main/java/org/asciidoctor/asciidoclet/DocletRenderer.java rename to src/main/java/module-info.java index 1dccf83..f0710ac 100644 --- a/src/main/java/org/asciidoctor/asciidoclet/DocletRenderer.java +++ b/src/main/java/module-info.java @@ -1,5 +1,5 @@ -/** - * Copyright 2013-2015 John Ericksen +/* + * Copyright 2013-2018 John Ericksen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,16 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.asciidoctor.asciidoclet; - -import com.sun.javadoc.Doc; - -/** - * Interface used to render a Javadoc Doc - * - * @author John Ericksen - */ -public interface DocletRenderer { - - void renderDoc(Doc doc); -} +module asciidoclet { + requires java.base; + requires jdk.javadoc; + requires asciidoctorj; + exports org.asciidoctor.asciidoclet; +} \ No newline at end of file diff --git a/src/main/java/org/asciidoctor/Asciidoclet.java b/src/main/java/org/asciidoctor/Asciidoclet.java deleted file mode 100644 index 513557f..0000000 --- a/src/main/java/org/asciidoctor/Asciidoclet.java +++ /dev/null @@ -1,288 +0,0 @@ -/** - * Copyright 2013-2015 John Ericksen - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.asciidoctor; - -import com.sun.javadoc.DocErrorReporter; -import com.sun.javadoc.Doclet; -import com.sun.javadoc.LanguageVersion; -import com.sun.javadoc.RootDoc; -import org.asciidoctor.asciidoclet.*; - -/** - * = Asciidoclet - * - * https://github.com/asciidoctor/asciidoclet[Asciidoclet] is a Javadoc Doclet - * that uses http://asciidoctor.org[Asciidoctor] (via the - * https://github.com/asciidoctor/asciidoctorj[Asciidoctor Java integration]) - * to interpet http://asciidoc.org[AsciiDoc] markup within Javadoc comments. - * - * include::README.adoc[tags=usage] - * - * == Examples - * - * Custom attributes:: - * `+{project_name}+`;; {project_name} - * `+{project_desc}+`;; {project_desc} - * `+{project_version}+`;; {project_version} - * - * Code block (with syntax highlighting added by CodeRay):: - * + - * [source,java] - * -- - * /** - * * = Asciidoclet - * * - * * A Javadoc Doclet that uses http://asciidoctor.org[Asciidoctor] - * * to render http://asciidoc.org[AsciiDoc] markup in Javadoc comments. - * * - * * @author https://github.com/johncarl81[John Ericksen] - * *\/ - * public class Asciidoclet extends Doclet { - * private final Asciidoctor asciidoctor = Asciidoctor.Factory.create(); // <1> - * - * @SuppressWarnings("UnusedDeclaration") - * public static boolean start(RootDoc rootDoc) { - * new Asciidoclet().render(rootDoc); // <2> - * return Standard.start(rootDoc); - * } - * } - * -- - * <1> Creates an instance of the Asciidoctor Java integration - * <2> Runs Javadoc comment strings through Asciidoctor - * - * Inline code:: `code()` - * - * Headings:: - * + - * -- - * [float] - * = Heading 1 - * - * [float] - * == Heading 2 - * - * [float] - * === Heading 3 - * - * [float] - * ==== Heading 4 - * - * [float] - * ===== Heading 5 - * -- - * - * Links:: - * Doc Writer + - * http://asciidoc.org[AsciiDoc] is a lightweight markup language. + - * Learn more about it at http://asciidoctor.org. + - * - * Bullets:: - * + - * -- - * .Unnumbered - * * bullet - * * bullet - * - bullet - * - bullet - * * bullet - * ** bullet - * ** bullet - * *** bullet - * *** bullet - * **** bullet - * **** bullet - * ***** bullet - * ***** bullet - * **** bullet - * *** bullet - * ** bullet - * * bullet - * -- - * + - * -- - * .Numbered - * . bullet - * . bullet - * .. bullet - * .. bullet - * . bullet - * .. bullet - * ... bullet - * ... bullet - * .... bullet - * .... bullet - * ... bullet - * ... bullet - * .. bullet - * .. bullet - * . bullet - * -- - * - * Tables:: - * + - * .An example table - * |=== - * |Column 1 |Column 2 |Column 3 - * - * |1 - * |Item 1 - * |a - * - * |2 - * |Item 2 - * |b - * - * |3 - * |Item 3 - * |c - * |=== - * - * Sidebar block:: - * + - * .Optional Title - * **** - * Usage: Notes in a sidebar, naturally. - * **** - * - * Admonitions:: - * + - * IMPORTANT: Check this out! - * - * @author https://github.com/johncarl81[John Ericksen] - * @version {project_version} - * @see org.asciidoctor.Asciidoclet - * @since 0.1.0 - * @serial (or @serialField or @serialData) - */ -public class Asciidoclet extends Doclet { - - private final RootDoc rootDoc; - private final DocletOptions docletOptions; - private final DocletIterator iterator; - private final Stylesheets stylesheets; - - public Asciidoclet(RootDoc rootDoc) { - this.rootDoc = rootDoc; - this.docletOptions = new DocletOptions(rootDoc); - this.iterator = new DocletIterator(docletOptions); - this.stylesheets = new Stylesheets(docletOptions, rootDoc); - } - - // test use - Asciidoclet(RootDoc rootDoc, DocletIterator iterator, Stylesheets stylesheets) { - this.rootDoc = rootDoc; - this.docletOptions = new DocletOptions(rootDoc); - this.iterator = iterator; - this.stylesheets = stylesheets; - } - - /** - * .Example usage - * [source,java] - * exampleDeprecated("do not use"); - * - * @deprecated for example purposes - * @exception Exception example - * @throws RuntimeException example - * @serialData something else - * @link Asciidoclet - */ - public static void exampleDeprecated(String field) throws Exception { - //noop - } - - /** - * Sets the language version to Java 5. - * - * _Javadoc spec requirement._ - * - * @return language version number - */ - @SuppressWarnings("UnusedDeclaration") - public static LanguageVersion languageVersion() { - return LanguageVersion.JAVA_1_5; - } - - /** - * Sets the option length to the standard Javadoc option length. - * - * _Javadoc spec requirement._ - * - * @param option input option - * @return length of required parameters - */ - @SuppressWarnings("UnusedDeclaration") - public static int optionLength(String option) { - return optionLength(option, new StandardAdapter()); - } - - /** - * The starting point of Javadoc render. - * - * _Javadoc spec requirement._ - * - * @param rootDoc input class documents - * @return success - */ - @SuppressWarnings("UnusedDeclaration") - public static boolean start(RootDoc rootDoc) { - return new Asciidoclet(rootDoc).start(new StandardAdapter()); - } - - /** - * Processes the input options by delegating to the standard handler. - * - * _Javadoc spec requirement._ - * - * @param options input option array - * @param errorReporter error handling - * @return success - */ - @SuppressWarnings("UnusedDeclaration") - public static boolean validOptions(String[][] options, DocErrorReporter errorReporter) { - return validOptions(options, errorReporter, new StandardAdapter()); - } - - static int optionLength(String option, StandardAdapter standardDoclet) { - return DocletOptions.optionLength(option, standardDoclet); - } - - static boolean validOptions(String[][] options, DocErrorReporter errorReporter, StandardAdapter standardDoclet) { - return DocletOptions.validOptions(options, errorReporter, standardDoclet); - } - - boolean start(StandardAdapter standardDoclet) { - return run(standardDoclet) - && postProcess(); - } - - private boolean run(StandardAdapter standardDoclet) { - AsciidoctorRenderer renderer = new AsciidoctorRenderer(docletOptions, rootDoc); - try { - return iterator.render(rootDoc, renderer) && - standardDoclet.start(rootDoc); - } finally { - renderer.cleanup(); - } - } - - private boolean postProcess() { - if (docletOptions.stylesheet().isPresent()) { - return true; - } - return stylesheets.copy(); - } -} diff --git a/src/main/java/org/asciidoctor/asciidoclet/AsciiDocTrees.java b/src/main/java/org/asciidoctor/asciidoclet/AsciiDocTrees.java new file mode 100644 index 0000000..2530d39 --- /dev/null +++ b/src/main/java/org/asciidoctor/asciidoclet/AsciiDocTrees.java @@ -0,0 +1,275 @@ +/* + * Copyright 2013-2018 John Ericksen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.asciidoctor.asciidoclet; + +import com.sun.source.doctree.DocCommentTree; +import com.sun.source.doctree.DocTree; +import com.sun.source.tree.CatchTree; +import com.sun.source.tree.ClassTree; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.MethodTree; +import com.sun.source.tree.Scope; +import com.sun.source.tree.Tree; +import com.sun.source.util.DocSourcePositions; +import com.sun.source.util.DocTreeFactory; +import com.sun.source.util.DocTreePath; +import com.sun.source.util.DocTrees; +import com.sun.source.util.TreePath; +import com.sun.tools.javac.model.JavacElements; +import com.sun.tools.javac.parser.Tokens; +import com.sun.tools.javac.tree.JCTree; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Field; +import java.text.BreakIterator; +import java.util.List; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.ErrorType; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic; +import javax.tools.FileObject; +import javax.tools.JavaFileManager; +import javax.tools.StandardJavaFileManager; + +import static javax.tools.StandardLocation.SOURCE_PATH; + +class AsciiDocTrees extends DocTrees +{ + private final AsciidoctorRenderer renderer; + private final StandardJavaFileManager fileManager; + private final DocTrees docTrees; + private final Field elementsField; + + AsciiDocTrees( AsciidoctorRenderer renderer, StandardJavaFileManager fileManager, DocTrees docTrees ) + { + this.renderer = renderer; + this.fileManager = fileManager; + this.docTrees = docTrees; + try + { + this.elementsField = docTrees.getClass().getDeclaredField( "elements" ); + this.elementsField.setAccessible( true ); + } + catch ( Exception e ) + { + throw new RuntimeException( e ); + } + } + + public BreakIterator getBreakIterator() + { + return docTrees.getBreakIterator(); + } + + public String getDocComment( TreePath path ) + { + return renderer.renderDoc( docTrees.getDocComment( path ) ); + } + + public DocCommentTree getDocCommentTree( TreePath path ) + { + // First we convert the asciidoctor to HTML inside the AST. + JCTree.JCCompilationUnit cu = (JCTree.JCCompilationUnit) path.getCompilationUnit(); + LazyDocCommentTableProcessor.processComments( cu.docComments, this::convertToAsciidoctor ); + + // Then we allow the normal javadoc parsing to continue on the asciidoctor result. + return docTrees.getDocCommentTree( path ); + } + + private Tokens.Comment convertToAsciidoctor( Tokens.Comment comment ) + { + String javadoc = comment.getText(); + String asciidoc = renderer.renderDoc( javadoc ); + AsciidocComment result = new AsciidocComment( asciidoc, comment );System.err.println( "" ); + return result; + } + + public DocCommentTree getDocCommentTree( Element e ) + { + TreePath path = getPath( e ); + if ( path == null ) + { + return null; + } + return getDocCommentTree( path ); + } + + public DocCommentTree getDocCommentTree( FileObject fileObject ) + { + // Empty names are used for built-in headers and footers, which need no asciidoctor processing anyway. + if ( !fileObject.getName().isEmpty() && !(fileObject instanceof AsciidocFileView)) + { + return docTrees.getDocCommentTree( new AsciidocFileView( renderer, fileObject ) ); + } + return docTrees.getDocCommentTree( fileObject ); + } + + public DocCommentTree getDocCommentTree( Element e, String relativePath ) throws IOException + { + PackageElement pkg = getElements().getPackageOf( e ); + JavaFileManager fileManager = getFileManager(); + FileObject input = fileManager.getFileForInput( SOURCE_PATH, pkg.getQualifiedName().toString(), relativePath ); + if ( input == null ) + { + throw new FileNotFoundException( relativePath ); + } + return getDocCommentTree( input ); + } + + private JavacElements getElements() + { + try + { + return (JavacElements) elementsField.get( docTrees ); + } + catch ( Exception e ) + { + throw new RuntimeException( e ); + } + } + + private JavaFileManager getFileManager() + { + return fileManager; + } + + public DocTreePath getDocTreePath( FileObject fileObject, PackageElement packageElement ) + { + return docTrees.getDocTreePath( fileObject, packageElement ); + } + + public Element getElement( DocTreePath path ) + { + return docTrees.getElement( path ); + } + + public List getFirstSentence( List list ) + { + return docTrees.getFirstSentence( list ); + } + + public DocSourcePositions getSourcePositions() + { + return docTrees.getSourcePositions(); + } + + public void printMessage( Diagnostic.Kind kind, CharSequence msg, DocTree t, DocCommentTree c, CompilationUnitTree root ) + { + docTrees.printMessage( kind, msg, t, c, root ); + } + + public void setBreakIterator( BreakIterator breakiterator ) + { + docTrees.setBreakIterator( breakiterator ); + } + + public DocTreeFactory getDocTreeFactory() + { + return docTrees.getDocTreeFactory(); + } + + public Tree getTree( Element element ) + { + return docTrees.getTree( element ); + } + + public ClassTree getTree( TypeElement element ) + { + return docTrees.getTree( element ); + } + + public MethodTree getTree( ExecutableElement method ) + { + return docTrees.getTree( method ); + } + + public Tree getTree( Element e, AnnotationMirror a ) + { + return docTrees.getTree( e, a ); + } + + public Tree getTree( Element e, AnnotationMirror a, AnnotationValue v ) + { + return docTrees.getTree( e, a, v ); + } + + public TreePath getPath( CompilationUnitTree unit, Tree node ) + { + return docTrees.getPath( unit, node ); + } + + public TreePath getPath( Element e ) + { + return docTrees.getPath( e ); + } + + public TreePath getPath( Element e, AnnotationMirror a ) + { + return docTrees.getPath( e, a ); + } + + public TreePath getPath( Element e, AnnotationMirror a, AnnotationValue v ) + { + return docTrees.getPath( e, a, v ); + } + + public Element getElement( TreePath path ) + { + return docTrees.getElement( path ); + } + + public TypeMirror getTypeMirror( TreePath path ) + { + return docTrees.getTypeMirror( path ); + } + + public Scope getScope( TreePath path ) + { + return docTrees.getScope( path ); + } + + public boolean isAccessible( Scope scope, TypeElement type ) + { + return docTrees.isAccessible( scope, type ); + } + + public boolean isAccessible( Scope scope, Element member, DeclaredType type ) + { + return docTrees.isAccessible( scope, member, type ); + } + + public TypeMirror getOriginalType( ErrorType errorType ) + { + return docTrees.getOriginalType( errorType ); + } + + public void printMessage( Diagnostic.Kind kind, CharSequence msg, Tree t, CompilationUnitTree root ) + { + docTrees.printMessage( kind, msg, t, root ); + } + + public TypeMirror getLub( CatchTree tree ) + { + return docTrees.getLub( tree ); + } +} diff --git a/src/main/java/org/asciidoctor/asciidoclet/AsciidocComment.java b/src/main/java/org/asciidoctor/asciidoclet/AsciidocComment.java new file mode 100644 index 0000000..fb09e4f --- /dev/null +++ b/src/main/java/org/asciidoctor/asciidoclet/AsciidocComment.java @@ -0,0 +1,55 @@ +/* + * Copyright 2013-2018 John Ericksen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.asciidoctor.asciidoclet; + +import com.sun.tools.javac.parser.Tokens; + +class AsciidocComment implements Tokens.Comment +{ + private final String asciidoc; + private final Tokens.Comment comment; + + AsciidocComment( String asciidoc, Tokens.Comment comment ) + { + this.asciidoc = asciidoc; + this.comment = comment; + } + + @Override + public String getText() + { + return asciidoc; + } + + @Override + public int getSourcePos( int index ) + { + // can we somehow map positions in the asciidoctor back to positions in the source javadoc? + return comment.getSourcePos( 0 ); + } + + @Override + public CommentStyle getStyle() + { + return comment.getStyle(); + } + + @Override + public boolean isDeprecated() + { + return comment.isDeprecated(); + } +} diff --git a/src/main/java/org/asciidoctor/asciidoclet/AsciidocFileView.java b/src/main/java/org/asciidoctor/asciidoclet/AsciidocFileView.java new file mode 100644 index 0000000..83e86df --- /dev/null +++ b/src/main/java/org/asciidoctor/asciidoclet/AsciidocFileView.java @@ -0,0 +1,159 @@ +/* + * Copyright 2013-2018 John Ericksen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.asciidoctor.asciidoclet; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.NestingKind; +import javax.tools.FileObject; +import javax.tools.JavaFileObject; + +class AsciidocFileView implements JavaFileObject +{ + private final AsciidoctorRenderer renderer; + private final FileObject fileObject; + private String renderedContents; + + AsciidocFileView( AsciidoctorRenderer renderer, FileObject fileObject ) + { + this.renderer = renderer; + this.fileObject = fileObject; + } + + @Override + public URI toUri() + { + try + { + URI uri = fileObject.toUri(); + uri = new URI( maskFileExtension( uri.toString() ) ); + return uri; + } + catch ( URISyntaxException e ) + { + throw new RuntimeException( e ); + } + } + + @Override + public String getName() + { + return maskFileExtension( fileObject.getName() ); + } + + private String maskFileExtension( String name ) + { + if ( isAsciidoctorFile( name ) ) + { + name = name.substring( 0, name.lastIndexOf( '.' ) ) + ".html"; + } + return name; + } + + private boolean isAsciidoctorFile( String name ) + { + return name.endsWith( ".adoc" ) || name.endsWith( ".ad" ) || name.endsWith( ".asciidoc" ) || name.endsWith( ".txt" ); + } + + @Override + public InputStream openInputStream() throws IOException + { + return new ByteArrayInputStream( getCharContent( true ).getBytes( Charset.defaultCharset() ) ); + } + + @Override + public OutputStream openOutputStream() throws IOException + { + return fileObject.openOutputStream(); + } + + @Override + public Reader openReader( boolean ignoreEncodingErrors ) throws IOException + { + return new StringReader( getCharContent( ignoreEncodingErrors ) ); + } + + @Override + public String getCharContent( boolean ignoreEncodingErrors ) throws IOException + { + if ( renderedContents == null ) + { + renderedContents = fileObject.getCharContent( ignoreEncodingErrors ).toString(); + if ( isAsciidoctorFile( fileObject.getName() ) ) + { + renderedContents = "" + renderer.renderDoc( renderedContents ) + ""; + } + } + return renderedContents; + } + + @Override + public Writer openWriter() throws IOException + { + return fileObject.openWriter(); + } + + @Override + public long getLastModified() + { + return fileObject.getLastModified(); + } + + @Override + public boolean delete() + { + return fileObject.delete(); + } + + @Override + public Kind getKind() + { + return ((JavaFileObject) fileObject).getKind(); + } + + @Override + public boolean isNameCompatible( String simpleName, Kind kind ) + { + return ((JavaFileObject) fileObject).isNameCompatible( simpleName, kind ); + } + + @Override + public NestingKind getNestingKind() + { + return ((JavaFileObject) fileObject).getNestingKind(); + } + + @Override + public Modifier getAccessLevel() + { + return ((JavaFileObject) fileObject).getAccessLevel(); + } + + @SuppressWarnings( "unchecked" ) + T unwrap() + { + return (T) fileObject; + } +} diff --git a/src/main/java/org/asciidoctor/asciidoclet/Asciidoclet.java b/src/main/java/org/asciidoctor/asciidoclet/Asciidoclet.java new file mode 100644 index 0000000..f9b7e76 --- /dev/null +++ b/src/main/java/org/asciidoctor/asciidoclet/Asciidoclet.java @@ -0,0 +1,241 @@ +/* + * Copyright 2013-2018 John Ericksen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.asciidoctor.asciidoclet; + +import jdk.javadoc.doclet.Doclet; +import jdk.javadoc.doclet.DocletEnvironment; +import jdk.javadoc.doclet.Reporter; +import jdk.javadoc.doclet.StandardDoclet; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import javax.lang.model.SourceVersion; + +/** + * = Asciidoclet + * + * https://github.com/asciidoctor/asciidoclet[Asciidoclet] is a Javadoc Doclet + * that uses http://asciidoctor.org[Asciidoctor] (via the + * https://github.com/asciidoctor/asciidoctorj[Asciidoctor Java integration]) + * to interpet http://asciidoc.org[AsciiDoc] markup within Javadoc comments. + * + * include::README.adoc[tags=usage] + * + * == Examples + * + * Custom attributes:: + * `+{project_name}+`;; {project_name} + * `+{project_desc}+`;; {project_desc} + * `+{project_version}+`;; {project_version} + * + * Code block (with syntax highlighting added by CodeRay):: + * + + * [source,java] + * -- + * /** + * * = Asciidoclet + * * + * * A Javadoc Doclet that uses http://asciidoctor.org[Asciidoctor] + * * to render http://asciidoc.org[AsciiDoc] markup in Javadoc comments. + * * + * * @author https://github.com/johncarl81[John Ericksen] + * *\/ + * public class Asciidoclet extends Doclet { + * private final Asciidoctor asciidoctor = Asciidoctor.Factory.create(); // <1> + * + * @SuppressWarnings("UnusedDeclaration") + * public static boolean start(RootDoc rootDoc) { + * new Asciidoclet().render(rootDoc); // <2> + * return Standard.start(rootDoc); + * } + * } + * -- + * <1> Creates an instance of the Asciidoctor Java integration + * <2> Runs Javadoc comment strings through Asciidoctor + * + * Inline code:: `code()` + * + * Headings:: + * + + * -- + * [float] + * = Heading 1 + * + * [float] + * == Heading 2 + * + * [float] + * === Heading 3 + * + * [float] + * ==== Heading 4 + * + * [float] + * ===== Heading 5 + * -- + * + * Links:: + * Doc Writer + + * http://asciidoc.org[AsciiDoc] is a lightweight markup language. + + * Learn more about it at http://asciidoctor.org. + + * + * Bullets:: + * + + * -- + * .Unnumbered + * * bullet + * * bullet + * - bullet + * - bullet + * * bullet + * ** bullet + * ** bullet + * *** bullet + * *** bullet + * **** bullet + * **** bullet + * ***** bullet + * ***** bullet + * **** bullet + * *** bullet + * ** bullet + * * bullet + * -- + * + + * -- + * .Numbered + * . bullet + * . bullet + * .. bullet + * .. bullet + * . bullet + * .. bullet + * ... bullet + * ... bullet + * .... bullet + * .... bullet + * ... bullet + * ... bullet + * .. bullet + * .. bullet + * . bullet + * -- + * + * Tables:: + * + + * .An example table + * |=== + * |Column 1 |Column 2 |Column 3 + * + * |1 + * |Item 1 + * |a + * + * |2 + * |Item 2 + * |b + * + * |3 + * |Item 3 + * |c + * |=== + * + * Sidebar block:: + * + + * .Optional Title + * **** + * Usage: Notes in a sidebar, naturally. + * **** + * + * Admonitions:: + * + + * IMPORTANT: Check this out! + * + * @author https://github.com/johncarl81[John Ericksen] + * @version {project_version} + * @see Asciidoclet + * @since 0.1.0 + * @serial (or @serialField or @serialData) + */ +public class Asciidoclet implements Doclet +{ + + private StandardDoclet standardDoclet; + private DocletOptions docletOptions; + private Stylesheets stylesheets; + private Reporter reporter; + + public Asciidoclet() { + standardDoclet = new StandardDoclet(); + } + + @Override + public void init( Locale locale, Reporter reporter ) + { + this.reporter = reporter; + standardDoclet.init( locale, reporter ); + this.docletOptions = new DocletOptions( reporter ); + this.stylesheets = new Stylesheets( reporter ); + } + + @Override + public String getName() + { + return "Asciidoclet"; + } + + @Override + public Set getSupportedOptions() + { + Set