You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/12/11 13:45:15 UTC
[isis] 02/02: ISIS-2473: j2adoc: adds support for enum types
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
commit bd39f2bc186c0c5215a6c313a81f73570b417b56
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Dec 11 14:44:56 2020 +0100
ISIS-2473: j2adoc: adds support for enum types
---
.../apache/isis/tooling/j2adoc/J2AdocContext.java | 2 +-
.../org/apache/isis/tooling/j2adoc/J2AdocUnit.java | 46 +++----
.../tooling/javamodel/ast/AnyTypeDeclaration.java | 143 +++++++++++++++++++++
.../ast/ClassOrInterfaceDeclarations.java | 21 ---
.../tooling/javamodel/ast/CompilationUnits.java | 45 ++++++-
.../isis/tooling/javamodel/test/AnalyzerTest.java | 9 +-
6 files changed, 207 insertions(+), 59 deletions(-)
diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocContext.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocContext.java
index 031b663..d158ec1 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocContext.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocContext.java
@@ -88,7 +88,7 @@ public class J2AdocContext {
return J2AdocUnit.parse(sourceFile)
.peek(this::add)
// ensure the stream is consumed here,
- // current implementation does not expect more than 1 result per source file
+ // optimized for 1 result per source file, but can be more
.collect(Collectors.toCollection(()->new ArrayList<>(1)))
.stream();
}
diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocUnit.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocUnit.java
index 3983886..8ccff38 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocUnit.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocUnit.java
@@ -23,7 +23,6 @@ import java.util.Optional;
import java.util.stream.Stream;
import com.github.javaparser.StaticJavaParser;
-import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.javadoc.Javadoc;
@@ -32,10 +31,8 @@ import org.asciidoctor.ast.Document;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.tooling.j2adoc.util.AsciiDocIncludeTagFilter;
-import org.apache.isis.tooling.javamodel.ast.ClassOrInterfaceDeclarations;
+import org.apache.isis.tooling.javamodel.ast.AnyTypeDeclaration;
import org.apache.isis.tooling.javamodel.ast.CompilationUnits;
-import org.apache.isis.tooling.javamodel.ast.Javadocs;
-import org.apache.isis.tooling.javamodel.ast.TypeDeclarations;
import lombok.Getter;
import lombok.NonNull;
@@ -47,7 +44,7 @@ import lombok.extern.log4j.Log4j2;
@Log4j2
public final class J2AdocUnit {
- private final ClassOrInterfaceDeclaration td;
+ private final AnyTypeDeclaration atd;
public static Stream<J2AdocUnit> parse(final @NonNull File sourceFile) {
@@ -65,8 +62,8 @@ public final class J2AdocUnit {
val cu = StaticJavaParser.parse(source);
return Stream.of(cu)
- .flatMap(CompilationUnits::streamPublicTypeDeclarations)
- .filter(TypeDeclarations::hasIndexDirective)
+ .flatMap(CompilationUnits::streamTypeDeclarations)
+ .filter(AnyTypeDeclaration::hasIndexDirective)
.map(J2AdocUnit::new);
} catch (Exception e) {
@@ -80,31 +77,28 @@ public final class J2AdocUnit {
* Returns the recursively resolved (nested) type name.
* Same as {@link #getSimpleName()} if type is not nested.
*/
- @Getter(lazy = true)
- private final String name = ClassOrInterfaceDeclarations.name(td);
+ public String getName() {
+ return atd.getName();
+ }
- @Getter(lazy = true)
- private final String simpleName = td.getNameAsString();
+ public String getSimpleName() {
+ return atd.getSimpleName();
+ }
- @Getter(lazy = true)
- private final String declarationKeyword = td.isInterface()
- ? "interface"
- : "class";
+ public String getDeclarationKeyword() {
+ return atd.getKind().name().toLowerCase();
+ }
- @Getter(lazy = true)
- private final Can<ConstructorDeclaration> publicConstructorDeclarations =
- ClassOrInterfaceDeclarations.streamPublicConstructorDeclarations(td)
- .filter(Javadocs::presentAndNotHidden)
- .collect(Can.toCan());
+ public Can<ConstructorDeclaration> getPublicConstructorDeclarations() {
+ return atd.getPublicConstructorDeclarations();
+ }
- @Getter(lazy = true)
- private final Can<MethodDeclaration> publicMethodDeclarations =
- ClassOrInterfaceDeclarations.streamPublicMethodDeclarations(td)
- .filter(Javadocs::presentAndNotHidden)
- .collect(Can.toCan());
+ public Can<MethodDeclaration> getPublicMethodDeclarations() {
+ return atd.getPublicMethodDeclarations();
+ }
@Getter(lazy = true)
- private final Optional<Javadoc> javadoc = td.getJavadoc();
+ private final Optional<Javadoc> javadoc = atd.getJavadoc();
public String getAsciiDocXref(
final @NonNull J2AdocContext j2aContext) {
diff --git a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/AnyTypeDeclaration.java b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/AnyTypeDeclaration.java
new file mode 100644
index 0000000..1c8b190
--- /dev/null
+++ b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/AnyTypeDeclaration.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.isis.tooling.javamodel.ast;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.javadoc.Javadoc;
+
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public class AnyTypeDeclaration {
+
+ public static enum Kind {
+ CLASS,
+ ENUM,
+ INTERFACE
+ ;
+ public boolean isClass() { return this == CLASS; }
+ public boolean isEnum() { return this == ENUM; }
+ public boolean isInterface() { return this == INTERFACE; }
+ }
+
+ private final @NonNull Kind kind;
+ private final TypeDeclaration<?> td;
+ private final ClassOrInterfaceDeclaration classOrInterfaceDeclaration;
+ private final EnumDeclaration enumDeclaration;
+
+ private final Can<ConstructorDeclaration> publicConstructorDeclarations;
+ private final Can<MethodDeclaration> publicMethodDeclarations;
+
+ // -- FACTORIES
+
+ public static AnyTypeDeclaration of(
+ final @NonNull ClassOrInterfaceDeclaration classOrInterfaceDeclaration) {
+ return new AnyTypeDeclaration(
+ classOrInterfaceDeclaration.isInterface() ? Kind.INTERFACE : Kind.CLASS,
+ classOrInterfaceDeclaration,
+ classOrInterfaceDeclaration,
+ null,
+ ClassOrInterfaceDeclarations.streamPublicConstructorDeclarations(classOrInterfaceDeclaration)
+ .filter(Javadocs::presentAndNotHidden)
+ .collect(Can.toCan()),
+ ClassOrInterfaceDeclarations.streamPublicMethodDeclarations(classOrInterfaceDeclaration)
+ .filter(Javadocs::presentAndNotHidden)
+ .collect(Can.toCan())
+ );
+ }
+
+ public static AnyTypeDeclaration of(
+ final @NonNull EnumDeclaration enumDeclaration) {
+ return new AnyTypeDeclaration(
+ Kind.ENUM,
+ enumDeclaration,
+ null,
+ enumDeclaration,
+ Can.empty(),
+ Can.empty());
+ }
+
+ public static AnyTypeDeclaration auto(
+ final @NonNull TypeDeclaration<?> td) {
+
+ if(td instanceof ClassOrInterfaceDeclaration) {
+ return of((ClassOrInterfaceDeclaration)td);
+ }
+ if(td instanceof EnumDeclaration) {
+ return of((EnumDeclaration)td);
+ }
+ throw _Exceptions.unsupportedOperation("unsupported TypeDeclaration %s", td.getClass());
+ }
+
+ // -- UTILITY
+
+ public Stream<MethodDeclaration> streamMethodDeclarations() {
+ return td.getMethods().stream();
+ }
+
+ public Optional<Javadoc> getJavadoc() {
+ return td.getJavadoc();
+ }
+
+ public boolean hasIndexDirective() {
+ return TypeDeclarations.hasIndexDirective(td);
+ }
+
+ /**
+ * Returns the recursively resolved (nested) type name.
+ * Same as {@link #getSimpleName()} if type is not nested.
+ */
+ @Getter(lazy = true)
+ private final String name = createName();
+
+ public String getSimpleName() {
+ return td.getNameAsString();
+ }
+
+ // -- HELPER
+
+ private String createName() {
+ String name = td.getNameAsString();
+ Node walker = td;
+ while(walker.getParentNode().isPresent()) {
+ walker = walker.getParentNode().get();
+ if(walker instanceof NodeWithSimpleName) {
+ name = ((NodeWithSimpleName<?>)walker).getNameAsString() + "." + name;
+ } else break;
+ }
+ return name;
+ }
+
+}
diff --git a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/ClassOrInterfaceDeclarations.java b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/ClassOrInterfaceDeclarations.java
index 980448f..42c49e0 100644
--- a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/ClassOrInterfaceDeclarations.java
+++ b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/ClassOrInterfaceDeclarations.java
@@ -20,11 +20,9 @@ package org.apache.isis.tooling.javamodel.ast;
import java.util.stream.Stream;
-import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
-import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
import lombok.NonNull;
@@ -51,24 +49,5 @@ public final class ClassOrInterfaceDeclarations {
return streamMethodDeclarations(typeDeclaration)
.filter(md->MethodDeclarations.isEffectivePublic(md, typeDeclaration));
}
-
- /**
- * Returns the recursively resolved (nested) type name.
- * Same as {@link #getSimpleName()} if type is not nested.
- */
- public static String name(
- final @NonNull ClassOrInterfaceDeclaration td) {
- String name = td.getNameAsString();
- Node walker = td;
- while(walker.getParentNode().isPresent()) {
- walker = walker.getParentNode().get();
- if(walker instanceof NodeWithSimpleName) {
- name = ((NodeWithSimpleName<?>)walker).getNameAsString() + "." + name;
- } else break;
- }
- return name;
- }
-
-
}
diff --git a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/CompilationUnits.java b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/CompilationUnits.java
index 7eb846d..2447106 100644
--- a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/CompilationUnits.java
+++ b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/CompilationUnits.java
@@ -19,12 +19,15 @@
package org.apache.isis.tooling.javamodel.ast;
import java.io.File;
+import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
import lombok.NonNull;
import lombok.SneakyThrows;
@@ -43,7 +46,40 @@ public final class CompilationUnits {
.orElse(false);
}
- public static <T> Stream<ClassOrInterfaceDeclaration> streamPublicTypeDeclarations(
+ public static <T> Stream<AnyTypeDeclaration> streamTypeDeclarations(
+ final @NonNull CompilationUnit compilationUnit) {
+
+ return getPrimaryType(compilationUnit)
+ .map(type->type
+ .findAll(TypeDeclaration.class)
+ .stream()
+ .map(AnyTypeDeclaration::auto))
+ .orElseGet(Stream::empty);
+ }
+
+ public static <T> Stream<ClassOrInterfaceDeclaration> streamClassOrInterfaceDeclarations(
+ final @NonNull CompilationUnit compilationUnit) {
+
+ return getPrimaryType(compilationUnit)
+ .map(type->type
+ .findAll(ClassOrInterfaceDeclaration.class)
+ .stream())
+ .orElseGet(Stream::empty);
+ }
+
+ public static <T> Stream<EnumDeclaration> streamEnumDeclarations(
+ final @NonNull CompilationUnit compilationUnit) {
+
+ return getPrimaryType(compilationUnit)
+ .map(type->type
+ .findAll(EnumDeclaration.class)
+ .stream())
+ .orElseGet(Stream::empty);
+ }
+
+ // -- HELPER
+
+ private static Optional<TypeDeclaration<?>> getPrimaryType(
final @NonNull CompilationUnit compilationUnit) {
val type = compilationUnit.getPrimaryType()
@@ -55,13 +91,10 @@ public final class CompilationUnits {
if(type==null) {
System.err.println("could not find any type in CompilationUnit ...\n" +
compilationUnit);
- return Stream.empty();
+ return Optional.empty();
}
- //TODO not processing enums yet
- return type.findAll(ClassOrInterfaceDeclaration.class)
- .stream();
-
+ return Optional.of(type);
}
diff --git a/tooling/javamodel/src/test/java/org/apache/isis/tooling/javamodel/test/AnalyzerTest.java b/tooling/javamodel/src/test/java/org/apache/isis/tooling/javamodel/test/AnalyzerTest.java
index aca1d2f..5077b4f 100644
--- a/tooling/javamodel/src/test/java/org/apache/isis/tooling/javamodel/test/AnalyzerTest.java
+++ b/tooling/javamodel/src/test/java/org/apache/isis/tooling/javamodel/test/AnalyzerTest.java
@@ -26,7 +26,7 @@ import org.junit.jupiter.api.Test;
import org.apache.isis.commons.internal.base._Files;
import org.apache.isis.tooling.javamodel.AnalyzerConfigFactory;
-import org.apache.isis.tooling.javamodel.ast.ClassOrInterfaceDeclarations;
+import org.apache.isis.tooling.javamodel.ast.AnyTypeDeclaration;
import org.apache.isis.tooling.javamodel.ast.CompilationUnits;
import lombok.val;
@@ -65,11 +65,10 @@ class AnalyzerTest {
.filter(source->source.toString().contains("UserService"))
.peek(source->System.out.println("parsing source: " + source))
.map(CompilationUnits::parse)
- .flatMap(CompilationUnits::streamPublicTypeDeclarations)
+ .flatMap(CompilationUnits::streamTypeDeclarations)
.peek(td->{
- td.getJavadocComment().ifPresent(javadocComment->{
- val javadoc = javadocComment.parse();
+ td.getJavadoc().ifPresent(javadoc->{
javadoc.getBlockTags().stream()
.filter(tag->tag.getTagName().equals("since"))
@@ -78,7 +77,7 @@ class AnalyzerTest {
});
})
- .flatMap(ClassOrInterfaceDeclarations::streamMethodDeclarations)
+ .flatMap(AnyTypeDeclaration::streamMethodDeclarations)
.forEach(md->{
System.out.println("javadoc: " + md.getJavadocComment());