diff --git a/src/java/apiview-java-processor/pom.xml b/src/java/apiview-java-processor/pom.xml
index c2b42637b99..9c8e17abe78 100644
--- a/src/java/apiview-java-processor/pom.xml
+++ b/src/java/apiview-java-processor/pom.xml
@@ -20,13 +20,13 @@
com.fasterxml.jackson.core
jackson-databind
- 2.13.4.2
+ 2.17.0
com.github.javaparser
javaparser-symbol-solver-core
- 3.24.2
+ 3.25.9
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/Main.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/Main.java
index dc7b7a53bbb..babec810213 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/Main.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/Main.java
@@ -8,6 +8,7 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import java.io.File;
import java.io.FileInputStream;
@@ -164,8 +165,6 @@ private static void processJavaSourcesJar(File inputFile, APIListing apiListing)
}
System.out.println(" Using '" + apiListing.getLanguageVariant() + "' for the language variant");
- final Analyser analyser = new JavaASTAnalyser(apiListing);
-
// Read all files within the jar file so that we can create a list of files to analyse
final List allFiles = new ArrayList<>();
try (FileSystem fs = FileSystems.newFileSystem(inputFile.toPath(), Main.class.getClassLoader())) {
@@ -179,6 +178,9 @@ private static void processJavaSourcesJar(File inputFile, APIListing apiListing)
apiListing.setApiViewProperties(properties);
System.out.println(" Found apiview_properties.json file in jar file");
System.out.println(" - Found " + properties.getCrossLanguageDefinitionIds().size() + " cross-language definition IDs");
+ } catch (InvalidFormatException e) {
+ System.out.println(" ERROR: Unable to parse apiview_properties.json file in jar file");
+ e.printStackTrace();
} catch (Exception e) {
// this is fine, we just won't have any APIView properties to read in
System.out.println(" No apiview_properties.json file found in jar file - continuing...");
@@ -194,6 +196,7 @@ private static void processJavaSourcesJar(File inputFile, APIListing apiListing)
});
// Do the analysis while the filesystem is still represented in memory
+ final Analyser analyser = new JavaASTAnalyser(apiListing);
analyser.analyse(allFiles);
} catch (Exception e) {
e.printStackTrace();
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/JavaASTAnalyser.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/JavaASTAnalyser.java
index 58415428da8..9ae94e720de 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/JavaASTAnalyser.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/JavaASTAnalyser.java
@@ -1,5 +1,7 @@
package com.azure.tools.apiview.processor.analysers;
+import com.azure.tools.apiview.processor.analysers.models.AnnotationRendererModel;
+import com.azure.tools.apiview.processor.analysers.models.AnnotationRule;
import com.azure.tools.apiview.processor.analysers.util.MiscUtils;
import com.azure.tools.apiview.processor.analysers.util.TokenModifier;
import com.azure.tools.apiview.processor.diagnostics.Diagnostics;
@@ -51,19 +53,10 @@
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
-import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.TreeMap;
+import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.regex.Matcher;
@@ -75,6 +68,7 @@
import org.apache.commons.lang.StringEscapeUtils;
import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.*;
+import static com.azure.tools.apiview.processor.analysers.util.MiscUtils.*;
import static com.azure.tools.apiview.processor.analysers.util.TokenModifier.INDENT;
import static com.azure.tools.apiview.processor.analysers.util.TokenModifier.NEWLINE;
import static com.azure.tools.apiview.processor.analysers.util.TokenModifier.NOTHING;
@@ -101,8 +95,22 @@ public class JavaASTAnalyser implements Analyser {
public static final String MODULE_INFO_KEY = "module-info";
private static final boolean SHOW_JAVADOC = true;
- private static final Set BLOCKED_ANNOTATIONS =
- new HashSet<>(Arrays.asList("ServiceMethod", "SuppressWarnings"));
+
+ private static final Map ANNOTATION_RULE_MAP;
+ static {
+ /*
+ For some annotations, we want to customise how they are displayed. Sometimes, we don't show them in any
+ circumstance. Other times, we want to show them but not their attributes. This map is used to define these
+ customisations. These rules override the default output that APIView will do, based on the location
+ annotation in the code.
+ */
+ ANNOTATION_RULE_MAP = new HashMap<>();
+ ANNOTATION_RULE_MAP.put("ServiceMethod", new AnnotationRule().setHidden(true));
+ ANNOTATION_RULE_MAP.put("SuppressWarnings", new AnnotationRule().setHidden(true));
+
+ // we always want @Metadata annotations to be fully expanded, but in a condensed form
+ ANNOTATION_RULE_MAP.put("Metadata", new AnnotationRule().setShowProperties(true).setCondensed(true));
+ }
private static final Pattern SPLIT_NEWLINE = Pattern.compile(MiscUtils.LINEBREAK);
@@ -112,12 +120,13 @@ public class JavaASTAnalyser implements Analyser {
private final Map packageNameToPackageInfoJavaDoc = new HashMap<>();
- private final Diagnostics diagnostic = new Diagnostics();
+ private final Diagnostics diagnostic;
private int indent = 0;
public JavaASTAnalyser(APIListing apiListing) {
this.apiListing = apiListing;
+ diagnostic = new Diagnostics(apiListing);
}
@Override
@@ -1032,34 +1041,24 @@ private void getAnnotations(final NodeWithAnnotations> nodeWithAnnotations,
final boolean showAnnotationProperties,
final boolean addNewline) {
Consumer consumer = annotation -> {
- if (addNewline) {
- addToken(makeWhitespace());
- }
-
- addToken(new Token(TYPE_NAME, "@" + annotation.getName().toString(), makeId(annotation, nodeWithAnnotations)));
- if (showAnnotationProperties) {
- if (annotation instanceof NormalAnnotationExpr) {
- addToken(new Token(PUNCTUATION, "("));
- NodeList pairs = ((NormalAnnotationExpr) annotation).getPairs();
- for (int i = 0; i < pairs.size(); i++) {
- MemberValuePair pair = pairs.get(i);
-
- addToken(new Token(TEXT, pair.getNameAsString()));
- addToken(new Token(PUNCTUATION, " = "));
+ // Check the annotation rules map for any overrides
+ final String annotationName = annotation.getName().toString();
+ AnnotationRule annotationRule = ANNOTATION_RULE_MAP.get(annotationName);
- Expression valueExpr = pair.getValue();
- processAnnotationValueExpression(valueExpr);
+ AnnotationRendererModel model = new AnnotationRendererModel(
+ annotation, nodeWithAnnotations, annotationRule, showAnnotationProperties, addNewline);
- if (i < pairs.size() - 1) {
- addToken(new Token(PUNCTUATION, ", "));
- }
- }
+ if (model.isHidden()) {
+ return;
+ }
- addToken(new Token(PUNCTUATION, ")"));
- }
+ if (model.isAddNewline()) {
+ addToken(makeWhitespace());
}
- if (addNewline) {
+ renderAnnotation(model).forEach(JavaASTAnalyser.this::addToken);
+
+ if (model.isAddNewline()) {
addNewLine();
} else {
addToken(new Token(WHITESPACE, " "));
@@ -1070,43 +1069,96 @@ private void getAnnotations(final NodeWithAnnotations> nodeWithAnnotations,
.stream()
.filter(annotationExpr -> {
String id = annotationExpr.getName().getIdentifier();
- return !BLOCKED_ANNOTATIONS.contains(id) && !id.startsWith("Json");
+ return !id.startsWith("Json");
})
.sorted(Comparator.comparing(a -> a.getName().getIdentifier())) // we sort the annotations alphabetically
.forEach(consumer);
}
- private void processAnnotationValueExpression(Expression valueExpr) {
+ private List renderAnnotation(AnnotationRendererModel m) {
+ final AnnotationExpr a = m.getAnnotation();
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(TYPE_NAME, "@" + a.getNameAsString(), makeId(a, m.getAnnotationParent())));
+ if (m.isShowProperties()) {
+ if (a instanceof NormalAnnotationExpr) {
+ tokens.add(new Token(PUNCTUATION, "("));
+ NodeList pairs = ((NormalAnnotationExpr) a).getPairs();
+ for (int i = 0; i < pairs.size(); i++) {
+ MemberValuePair pair = pairs.get(i);
+
+ // If the pair is a boolean expression, and we are condensed, we only take the name.
+ // If we are not a boolean expression, and we are condensed, we only take the value.
+ // If we are not condensed, we take both.
+ final Expression valueExpr = pair.getValue();
+ if (m.isCondensed()) {
+ if (valueExpr.isBooleanLiteralExpr()) {
+ tokens.add(new Token(MEMBER_NAME, upperCase(pair.getNameAsString())));
+ } else {
+ processAnnotationValueExpression(valueExpr, m.isCondensed(), tokens);
+ }
+ } else {
+ tokens.add(new Token(MEMBER_NAME, pair.getNameAsString()));
+ tokens.add(new Token(PUNCTUATION, " = "));
+
+ processAnnotationValueExpression(valueExpr, m.isCondensed(), tokens);
+ }
+
+ if (i < pairs.size() - 1) {
+ tokens.add(new Token(PUNCTUATION, ", "));
+ }
+ }
+
+ tokens.add(new Token(PUNCTUATION, ")"));
+ }
+ }
+ return tokens;
+ }
+
+ private void processAnnotationValueExpression(final Expression valueExpr, final boolean condensed, final List tokens) {
if (valueExpr.isClassExpr()) {
// lookup to see if the type is known about, if so, make it a link, otherwise leave it as text
String typeName = valueExpr.getChildNodes().get(0).toString();
if (apiListing.getKnownTypes().containsKey(typeName)) {
final Token token = new Token(TYPE_NAME, typeName);
token.setNavigateToId(apiListing.getKnownTypes().get(typeName));
- addToken(token);
+ tokens.add(token);
return;
}
} else if (valueExpr.isArrayInitializerExpr()) {
- addToken(new Token(PUNCTUATION, "{ "));
+ if (!condensed) {
+ tokens.add(new Token(PUNCTUATION, "{ "));
+ }
for (int i = 0; i < valueExpr.getChildNodes().size(); i++) {
Node n = valueExpr.getChildNodes().get(i);
if (n instanceof Expression) {
- processAnnotationValueExpression((Expression) n);
+ processAnnotationValueExpression((Expression) n, condensed, tokens);
} else {
- addToken(new Token(TEXT, valueExpr.toString()));
+ tokens.add(new Token(TEXT, valueExpr.toString()));
}
if (i < valueExpr.getChildNodes().size() - 1) {
- addToken(new Token(PUNCTUATION, ", "));
+ tokens.add(new Token(PUNCTUATION, ", "));
}
}
- addToken(new Token(PUNCTUATION, " }"));
+ if (!condensed) {
+ tokens.add(new Token(PUNCTUATION, " }"));
+ }
return;
}
- // if we fall through to here, just treat it as a string
- addToken(new Token(TEXT, valueExpr.toString()));
+ // if we fall through to here, just treat it as a string.
+ // If we are in condensed mode, we strip off everything before the last period
+ String value = valueExpr.toString();
+ if (condensed) {
+ int lastPeriod = value.lastIndexOf('.');
+ if (lastPeriod != -1) {
+ value = value.substring(lastPeriod + 1);
+ }
+ tokens.add(new Token(TEXT, upperCase(value)));
+ } else {
+ tokens.add(new Token(TEXT, value));
+ }
}
private void getModifiers(NodeList modifiers) {
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/models/AnnotationRendererModel.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/models/AnnotationRendererModel.java
new file mode 100644
index 00000000000..0119cc9493c
--- /dev/null
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/models/AnnotationRendererModel.java
@@ -0,0 +1,54 @@
+package com.azure.tools.apiview.processor.analysers.models;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+
+public class AnnotationRendererModel {
+ private final AnnotationExpr annotation;
+
+ private final NodeWithAnnotations> annotationParent;
+
+ private final AnnotationRule rule;
+
+ private final boolean showProperties;
+
+ private final boolean addNewline;
+
+ public AnnotationRendererModel(AnnotationExpr annotation,
+ NodeWithAnnotations> nodeWithAnnotations,
+ AnnotationRule rule,
+ boolean showAnnotationProperties,
+ boolean addNewline) {
+ this.annotation = annotation;
+ this.annotationParent = nodeWithAnnotations;
+ this.rule = rule;
+
+ // we override the showAnnotationProperties flag if the annotation rule specifies it
+ this.showProperties = rule == null ? showAnnotationProperties : rule.isShowProperties().orElse(showAnnotationProperties);
+ this.addNewline = rule == null ? addNewline : rule.isShowOnNewline().orElse(addNewline);
+ }
+
+ public boolean isAddNewline() {
+ return addNewline;
+ }
+
+ public boolean isShowProperties() {
+ return showProperties;
+ }
+
+ public AnnotationExpr getAnnotation() {
+ return annotation;
+ }
+
+ public NodeWithAnnotations> getAnnotationParent() {
+ return annotationParent;
+ }
+
+ public boolean isHidden() {
+ return rule != null && rule.isHidden().orElse(false);
+ }
+
+ public boolean isCondensed() {
+ return rule != null && rule.isCondensed().orElse(false);
+ }
+}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/models/AnnotationRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/models/AnnotationRule.java
new file mode 100644
index 00000000000..b3adb001a6c
--- /dev/null
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/models/AnnotationRule.java
@@ -0,0 +1,50 @@
+package com.azure.tools.apiview.processor.analysers.models;
+
+import java.util.Optional;
+
+public class AnnotationRule {
+
+ private Optional hideAnnotation = Optional.empty();
+
+ private Optional showProperties = Optional.empty();
+
+ private Optional showOnNewline = Optional.empty();
+
+ private Optional condensed = Optional.empty();
+
+ public AnnotationRule setHidden(boolean hidden) {
+ this.hideAnnotation = Optional.of(hidden);
+ return this;
+ }
+
+ public Optional isHidden() {
+ return hideAnnotation;
+ }
+
+ public AnnotationRule setShowProperties(boolean showProperties) {
+ this.showProperties = Optional.of(showProperties);
+ return this;
+ }
+
+ public Optional isShowProperties() {
+ return showProperties;
+ }
+
+ public AnnotationRule setShowOnNewline(boolean showOnNewline) {
+ this.showOnNewline = Optional.of(showOnNewline);
+ return this;
+ }
+
+ public Optional isShowOnNewline() {
+ return showOnNewline;
+ }
+
+ public AnnotationRule setCondensed(boolean condensed) {
+ this.condensed = Optional.of(condensed);
+ return this;
+ }
+
+ public Optional isCondensed() {
+ return condensed;
+ }
+}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/util/ASTUtils.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/util/ASTUtils.java
index bcc6eb24214..aea307a1fd4 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/util/ASTUtils.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/util/ASTUtils.java
@@ -181,7 +181,7 @@ public static boolean isPublicOrProtected(AccessSpecifier accessSpecifier) {
* @return Whether the access specifier is package-private or private.
*/
public static boolean isPrivateOrPackagePrivate(AccessSpecifier accessSpecifier) {
- return (accessSpecifier == AccessSpecifier.PRIVATE) || (accessSpecifier == AccessSpecifier.PACKAGE_PRIVATE);
+ return (accessSpecifier == AccessSpecifier.PRIVATE) || (accessSpecifier == AccessSpecifier.NONE);
}
public static String makeId(CompilationUnit cu) {
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/util/MiscUtils.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/util/MiscUtils.java
index 649c380e267..85ba4a865e2 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/util/MiscUtils.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/analysers/util/MiscUtils.java
@@ -87,6 +87,22 @@ private static String wrapLine(final String line, final int lineLength) {
return allLines.toString();
}
+ /**
+ * Makes all characters in the string lowercase, other than the first character.
+ */
+ public static String upperCase(String s) {
+ return upperCase(s, 0);
+ }
+
+ /**
+ * Makes all characters in the string lowercase, other than the given index.
+ */
+ public static String upperCase(String s, int index) {
+ return s.substring(0, index).toLowerCase()
+ + Character.toUpperCase(s.charAt(index))
+ + s.substring(index + 1).toLowerCase();
+ }
+
private MiscUtils() {
}
}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/Diagnostics.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/Diagnostics.java
index a5d787fc033..3a047b3ea49 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/Diagnostics.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/Diagnostics.java
@@ -1,73 +1,107 @@
package com.azure.tools.apiview.processor.diagnostics;
import com.azure.tools.apiview.processor.diagnostics.rules.*;
+import com.azure.tools.apiview.processor.diagnostics.rules.azure.*;
+import com.azure.tools.apiview.processor.diagnostics.rules.clientcore.ClientCoreBuilderTraitsDiagnosticRule;
+import com.azure.tools.apiview.processor.diagnostics.rules.clientcore.ClientCoreFluentSetterReturnTypeDiagnosticRule;
+import com.azure.tools.apiview.processor.diagnostics.rules.clientcore.ExpandableEnumDiagnosticRule;
+import com.azure.tools.apiview.processor.diagnostics.rules.general.*;
+import com.azure.tools.apiview.processor.diagnostics.rules.utils.MiscUtils;
import com.azure.tools.apiview.processor.model.APIListing;
-import com.azure.tools.apiview.processor.model.Diagnostic;
+import com.azure.tools.apiview.processor.model.Flavor;
import com.github.javaparser.ast.CompilationUnit;
-import com.github.javaparser.ast.body.MethodDeclaration;
-import com.github.javaparser.ast.type.ClassOrInterfaceType;
-import com.github.javaparser.ast.type.Type;
import java.util.ArrayList;
import java.util.List;
-import java.util.Optional;
+import java.util.regex.Pattern;
-import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.makeId;
-import static com.azure.tools.apiview.processor.diagnostics.rules.IllegalMethodNamesDiagnosticRule.Rule;
+import static com.azure.tools.apiview.processor.model.Flavor.*;
+
+import static com.azure.tools.apiview.processor.diagnostics.rules.general.IllegalMethodNamesDiagnosticRule.Rule;
import static com.azure.tools.apiview.processor.diagnostics.rules.RequiredBuilderMethodsDiagnosticRule.DirectSubclassCheckFunction;
import static com.azure.tools.apiview.processor.diagnostics.rules.RequiredBuilderMethodsDiagnosticRule.ExactTypeNameCheckFunction;
import static com.azure.tools.apiview.processor.diagnostics.rules.RequiredBuilderMethodsDiagnosticRule.ParameterAllowedTypes;
-import static com.azure.tools.apiview.processor.diagnostics.rules.BadAnnotationDiagnosticRule.BadAnnotation;
-import static com.azure.tools.apiview.processor.model.DiagnosticKind.WARNING;
+import static com.azure.tools.apiview.processor.diagnostics.rules.general.BadAnnotationDiagnosticRule.BadAnnotation;
public class Diagnostics {
- private final List diagnostics = new ArrayList<>();
-
- public Diagnostics() {
- diagnostics.add(new PackageNameDiagnosticRule());
- diagnostics.add(new ImportsDiagnosticRule("com.sun"));
- diagnostics.add(new IllegalPackageAPIExportsDiagnosticRule("implementation", "netty"));
- diagnostics.add(new NoPublicFieldsDiagnosticRule());
- diagnostics.add(new UpperCaseNamingDiagnosticRule("URL", "HTTP", "XML", "JSON", "SAS", "CPK", "API"));
- diagnostics.add(new MissingAnnotationsDiagnosticRule());
- diagnostics.add(new FluentSetterReturnTypeDiagnosticRule());
- diagnostics.add(new ConsiderFinalClassDiagnosticRule());
- diagnostics.add(new IllegalMethodNamesDiagnosticRule(
- new Rule("Builder$", "tokenCredential"), // it should just be 'credential'
- new Rule("Builder$", "^set"), // we shouldn't have setters in the builder
- new Rule("^isHas"),
- new Rule("^setHas")
+ final List rules;
+
+ public Diagnostics(APIListing apiListing) {
+ rules = new ArrayList<>();
+
+ System.out.println(" Setting up diagnostics...");
+
+ Flavor flavor = Flavor.getFlavor(apiListing);
+
+ // Special rules for com.azure or io.clientcore libraries only
+ switch (flavor) {
+ case AZURE: {
+ System.out.println(" Applying com.azure specific diagnostics...");
+ addAzureCoreDiagnostics();
+ break;
+ }
+ case GENERIC: {
+ System.out.println(" Applying io.clientcore specific diagnostics...");
+ addClientCoreDiagnostics();
+ break;
+ }
+ case UNKNOWN:
+ default: {
+ System.out.println(" Unknown library flavor...");
+ break;
+ }
+ }
+
+ System.out.println(" Applying general-purpose diagnostics...");
+
+ // general rules applicable in all cases
+ rules.add(new UpperCaseEnumValuesDiagnosticRule());
+ rules.add(new ImportsDiagnosticRule("com.sun"));
+ rules.add(new IllegalPackageAPIExportsDiagnosticRule("implementation", "netty"));
+ rules.add(new NoPublicFieldsDiagnosticRule());
+ rules.add(new UpperCaseNamingDiagnosticRule("URL", "HTTP", "XML", "JSON", "SAS", "CPK", "API"));
+ rules.add(new ConsiderFinalClassDiagnosticRule());
+ rules.add(new IllegalMethodNamesDiagnosticRule(
+ new Rule("Builder$", "tokenCredential"), // it should just be 'credential'
+ new Rule("Builder$", "^set"), // we shouldn't have setters in the builder
+ new Rule("^isHas"),
+ new Rule("^setHas")
));
- diagnostics.add(new MissingJavaDocDiagnosticRule());
- diagnostics.add(new MissingJavadocCodeSnippetsRule());
- diagnostics.add(new NoLocalesInJavadocUrlDiagnosticRule());
- diagnostics.add(new ModuleInfoDiagnosticRule());
- diagnostics.add(new ServiceVersionDiagnosticRule());
- diagnostics.add(new BadAnnotationDiagnosticRule(
- new BadAnnotation("JacksonXmlRootElement",
- "From the Jackson JavaDoc: \"NOTE! Since 2.4 this annotation is usually not necessary and " +
- "you should use JsonRootName instead. About the only expected usage may be to have different " +
- "root name for XML content than other formats.\"")
+ rules.add(new MissingJavaDocDiagnosticRule());
+ rules.add(new MissingJavadocCodeSnippetsRule());
+ rules.add(new NoLocalesInJavadocUrlDiagnosticRule());
+ rules.add(new ModuleInfoDiagnosticRule());
+ rules.add(new BadAnnotationDiagnosticRule(
+ new BadAnnotation("JacksonXmlRootElement",
+ "From the Jackson JavaDoc: \"NOTE! Since 2.4 this annotation is usually not necessary and " +
+ "you should use JsonRootName instead. About the only expected usage may be to have different " +
+ "root name for XML content than other formats.\"")
));
- diagnostics.add(new BuilderTraitsDiagnosticRule());
- diagnostics.add(new MavenPackageAndDescriptionDiagnosticRule());
- diagnostics.add(new ExpandableStringEnumDiagnosticRule());
- diagnostics.add(new UpperCaseEnumValuesDiagnosticRule());
+ }
+
+ private void addAzureCoreDiagnostics() {
+ rules.add(new PackageNameDiagnosticRule(Pattern.compile("^" + AZURE.getPackagePrefix() + "(\\.[a-z0-9]+)+$")));
+ rules.add(new AzureCoreBuilderTraitsDiagnosticRule());
+ rules.add(new MissingAnnotationsDiagnosticRule(AZURE.getPackagePrefix()));
+ rules.add(new AzureCoreFluentSetterReturnTypeDiagnosticRule());
+ rules.add(new ServiceVersionDiagnosticRule());
+ rules.add(new ExpandableEnumDiagnosticRule("ExpandableStringEnum"));
+ rules.add(new MavenPackageAndDescriptionDiagnosticRule());
// common APIs for all builders (below we will do rules for http or amqp builders)
- diagnostics.add(new RequiredBuilderMethodsDiagnosticRule(null)
+ rules.add(new RequiredBuilderMethodsDiagnosticRule(null)
.add("configuration", new ExactTypeNameCheckFunction("Configuration"))
.add("clientOptions", new ExactTypeNameCheckFunction("ClientOptions"))
.add("connectionString", new ExactTypeNameCheckFunction("String"))
.add("credential", new ExactTypeNameCheckFunction(new ParameterAllowedTypes("TokenCredential",
- "AzureKeyCredential", "AzureSasCredential", "AzureNamedKeyCredential", "KeyCredential")))
+ "AzureKeyCredential", "AzureSasCredential", "AzureNamedKeyCredential", "KeyCredential")))
.add("endpoint", new ExactTypeNameCheckFunction("String"))
- .add("serviceVersion", this::checkServiceVersionType));
- diagnostics.add(new RequiredBuilderMethodsDiagnosticRule("amqp")
+ .add("serviceVersion", m -> MiscUtils.checkMethodParameterTypeSuffix(m, "ServiceVersion")));
+ rules.add(new RequiredBuilderMethodsDiagnosticRule("amqp")
.add("proxyOptions", new ExactTypeNameCheckFunction("ProxyOptions"))
.add("retry", new ExactTypeNameCheckFunction("AmqpRetryOptions"))
.add("transportType", new DirectSubclassCheckFunction("AmqpTransportType")));
- diagnostics.add(new RequiredBuilderMethodsDiagnosticRule("http")
+ rules.add(new RequiredBuilderMethodsDiagnosticRule("http")
.add("addPolicy", new ExactTypeNameCheckFunction("HttpPipelinePolicy"))
.add("httpClient", new ExactTypeNameCheckFunction("HttpClient"))
.add("httpLogOptions", new ExactTypeNameCheckFunction("HttpLogOptions"))
@@ -75,16 +109,28 @@ public Diagnostics() {
.add("retryPolicy", new ExactTypeNameCheckFunction("RetryPolicy")));
}
- private Optional checkServiceVersionType(MethodDeclaration methodDeclaration) {
- Type parameterType = methodDeclaration.getParameter(0).getType();
- ClassOrInterfaceType classOrInterfaceType = parameterType.asClassOrInterfaceType();
- if (!classOrInterfaceType.getNameAsString().endsWith("ServiceVersion")) {
- return Optional.of(
- new Diagnostic(WARNING, makeId(methodDeclaration),
- "Incorrect type being supplied to this builder method. Expected an enum "
- + "implementing ServiceVersion but was " + classOrInterfaceType.getNameAsString() + "."));
- }
- return Optional.empty();
+ private void addClientCoreDiagnostics() {
+ rules.add(new ClientCoreBuilderTraitsDiagnosticRule());
+ rules.add(new MissingAnnotationsDiagnosticRule(GENERIC.getPackagePrefix()));
+ rules.add(new ClientCoreFluentSetterReturnTypeDiagnosticRule());
+ rules.add(new ExpandableEnumDiagnosticRule("ExpandableEnum"));
+
+ // common APIs for all builders (below we will do rules for http or amqp builders)
+ rules.add(new RequiredBuilderMethodsDiagnosticRule(null)
+ .add("endpoint", new ExactTypeNameCheckFunction("String"))
+ .add("configuration", new ExactTypeNameCheckFunction("Configuration"))
+ .add("credential", new ExactTypeNameCheckFunction(new ParameterAllowedTypes("KeyCredential")))
+ .add("addHttpPipelinePolicy", new ExactTypeNameCheckFunction("HttpPipelinePolicy"))
+ .add("httpClient", new ExactTypeNameCheckFunction("HttpClient"))
+ .add("httpLogOptions", new ExactTypeNameCheckFunction("HttpLogOptions"))
+ .add("httpPipeline", new ExactTypeNameCheckFunction("HttpPipeline"))
+ .add("httpRetryOptions", new ExactTypeNameCheckFunction("HttpRetryOptions"))
+ .add("httpRedirectOptions", new ExactTypeNameCheckFunction("HttpRedirectOptions"))
+ .add("proxyOptions", new ExactTypeNameCheckFunction("ProxyOptions")));
+ }
+
+ private void add(DiagnosticRule rule) {
+ rules.add(rule);
}
/**
@@ -95,13 +141,13 @@ public void scanIndividual(CompilationUnit cu, APIListing listing) {
if (!cu.getPrimaryType().isPresent()) {
return;
}
- diagnostics.forEach(rule -> rule.scanIndividual(cu, listing));
+ rules.forEach(rule -> rule.scanIndividual(cu, listing));
}
/**
* Called once to allow for any full analysis to be performed after all individual scans have been completed.
*/
public void scanFinal(APIListing listing) {
- diagnostics.forEach(rule -> rule.scanFinal(listing));
+ rules.forEach(rule -> rule.scanFinal(listing));
}
}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/AzureCoreBuilderTraitsDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/AzureCoreBuilderTraitsDiagnosticRule.java
new file mode 100644
index 00000000000..d9befaa4b3d
--- /dev/null
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/AzureCoreBuilderTraitsDiagnosticRule.java
@@ -0,0 +1,59 @@
+package com.azure.tools.apiview.processor.diagnostics.rules.azure;
+
+import com.azure.tools.apiview.processor.diagnostics.rules.utils.BuilderTraitsDiagnosticRule;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This diagnostic ensures that builder traits are applied correctly against client builders.
+ */
+public class AzureCoreBuilderTraitsDiagnosticRule extends BuilderTraitsDiagnosticRule {
+ private static final Map traits;
+ static {
+ traits = new HashMap<>();
+ traits.put("KeyCredentialTrait", new TraitClass(
+ new TraitMethod("credential", "KeyCredential")
+ ));
+ traits.put("AzureKeyCredentialTrait", new TraitClass(
+ new TraitMethod("credential", "AzureKeyCredential")
+ ));
+ traits.put("AzureNamedKeyCredentialTrait", new TraitClass(
+ new TraitMethod("credential", "AzureNamedKeyCredential")
+ ));
+ traits.put("AzureSasCredentialTrait", new TraitClass(
+ new TraitMethod("credential", "AzureSasCredential")
+ ));
+ traits.put("TokenCredentialTrait", new TraitClass(
+ new TraitMethod("credential", "TokenCredential")
+ ));
+ traits.put("ConfigurationTrait", new TraitClass(
+ new TraitMethod("configuration", "Configuration")
+ ));
+ traits.put("ConnectionStringTrait", new TraitClass(
+ new TraitMethod("connectionString", "String")
+ ));
+ traits.put("EndpointTrait", new TraitClass(
+ new TraitMethod("endpoint", "String")
+ ));
+ traits.put("HttpTrait", new TraitClass(TraitClass.BUILDER_PROTOCOL_HTTP,
+ new TraitMethod("httpClient", "HttpClient"),
+ new TraitMethod("pipeline", "HttpPipeline"),
+ new TraitMethod("addPolicy", "HttpPipelinePolicy"),
+ new TraitMethod("retryOptions", "RetryOptions"),
+ new TraitMethod("httpLogOptions", "HttpLogOptions"),
+ new TraitMethod("clientOptions", "ClientOptions")
+ ));
+ traits.put("AmqpTrait", new TraitClass(TraitClass.BUILDER_PROTOCOL_AMQP,
+ new TraitMethod("retryOptions", "AmqpRetryOptions"),
+ new TraitMethod("transportType", "AmqpTransportType"),
+ new TraitMethod("proxyOptions", "ProxyOptions"),
+ new TraitMethod("clientOptions", "ClientOptions")
+ ));
+ }
+
+ public AzureCoreBuilderTraitsDiagnosticRule() {
+ super(traits);
+ }
+}
+
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/AzureCoreFluentSetterReturnTypeDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/AzureCoreFluentSetterReturnTypeDiagnosticRule.java
new file mode 100644
index 00000000000..491608adf78
--- /dev/null
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/AzureCoreFluentSetterReturnTypeDiagnosticRule.java
@@ -0,0 +1,10 @@
+package com.azure.tools.apiview.processor.diagnostics.rules.azure;
+
+import com.azure.tools.apiview.processor.diagnostics.rules.utils.FluentSetterReturnTypeDiagnosticRule;
+
+public class AzureCoreFluentSetterReturnTypeDiagnosticRule extends FluentSetterReturnTypeDiagnosticRule {
+
+ public AzureCoreFluentSetterReturnTypeDiagnosticRule() {
+ super(type -> type.getAnnotationByName("Fluent").isPresent());
+ }
+}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MavenPackageAndDescriptionDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/MavenPackageAndDescriptionDiagnosticRule.java
similarity index 98%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MavenPackageAndDescriptionDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/MavenPackageAndDescriptionDiagnosticRule.java
index 93e65df4651..d3940783ff8 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MavenPackageAndDescriptionDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/MavenPackageAndDescriptionDiagnosticRule.java
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.azure;
import com.azure.tools.apiview.processor.analysers.util.MiscUtils;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ServiceVersionDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/ServiceVersionDiagnosticRule.java
similarity index 98%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ServiceVersionDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/ServiceVersionDiagnosticRule.java
index 8682c664dd0..5f233d3617d 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ServiceVersionDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/ServiceVersionDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.azure;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/clientcore/ClientCoreBuilderTraitsDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/clientcore/ClientCoreBuilderTraitsDiagnosticRule.java
new file mode 100644
index 00000000000..6becaf74160
--- /dev/null
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/clientcore/ClientCoreBuilderTraitsDiagnosticRule.java
@@ -0,0 +1,39 @@
+package com.azure.tools.apiview.processor.diagnostics.rules.clientcore;
+
+import com.azure.tools.apiview.processor.diagnostics.rules.utils.BuilderTraitsDiagnosticRule;
+
+import java.util.*;
+
+/**
+ * This diagnostic ensures that builder traits are applied correctly against client builders.
+ */
+public class ClientCoreBuilderTraitsDiagnosticRule extends BuilderTraitsDiagnosticRule {
+ private static final Map traits;
+ static {
+ traits = new HashMap<>();
+ traits.put("KeyCredentialTrait", new TraitClass(
+ new TraitMethod("credential", "KeyCredential")
+ ));
+ traits.put("ConfigurationTrait", new TraitClass(
+ new TraitMethod("configuration", "Configuration")
+ ));
+ traits.put("ProxyTrait", new TraitClass(
+ new TraitMethod("proxyOptions", "ProxyOptions")
+ ));
+ traits.put("EndpointTrait", new TraitClass(
+ new TraitMethod("endpoint", "String")
+ ));
+ traits.put("HttpTrait", new TraitClass(TraitClass.BUILDER_PROTOCOL_HTTP,
+ new TraitMethod("httpClient", "HttpClient"),
+ new TraitMethod("httpPipeline", "HttpPipeline"),
+ new TraitMethod("addHttpPipelinePolicy", "HttpPipelinePolicy"),
+ new TraitMethod("httpRetryOptions", "HttpRetryOptions"),
+ new TraitMethod("httpLogOptions", "HttpLogOptions"),
+ new TraitMethod("httpRedirectOptions", "HttpRedirectOptions")
+ ));
+ }
+
+ public ClientCoreBuilderTraitsDiagnosticRule() {
+ super(traits);
+ }
+}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/clientcore/ClientCoreFluentSetterReturnTypeDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/clientcore/ClientCoreFluentSetterReturnTypeDiagnosticRule.java
new file mode 100644
index 00000000000..90766aca608
--- /dev/null
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/clientcore/ClientCoreFluentSetterReturnTypeDiagnosticRule.java
@@ -0,0 +1,13 @@
+package com.azure.tools.apiview.processor.diagnostics.rules.clientcore;
+
+import com.azure.tools.apiview.processor.diagnostics.rules.utils.FluentSetterReturnTypeDiagnosticRule;
+
+public class ClientCoreFluentSetterReturnTypeDiagnosticRule extends FluentSetterReturnTypeDiagnosticRule {
+
+ public ClientCoreFluentSetterReturnTypeDiagnosticRule() {
+ super(type -> type.getAnnotationByName("Metadata")
+ .map(annotationExpr -> annotationExpr.asNormalAnnotationExpr().getPairs().stream()
+ .filter(pair -> pair.getName().asString().equals("conditions"))
+ .anyMatch(pair -> pair.getValue().toString().contains("FLUENT"))).orElse(false));
+ }
+}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ExpandableStringEnumDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/clientcore/ExpandableEnumDiagnosticRule.java
similarity index 80%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ExpandableStringEnumDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/clientcore/ExpandableEnumDiagnosticRule.java
index 608fe69f3e6..f82bff5aad1 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ExpandableStringEnumDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/clientcore/ExpandableEnumDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.clientcore;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
@@ -18,25 +18,29 @@
* Diagnostic rule to validate if types extending from ExpandableStringEnum include
* fromString() and values() methods.
*/
-public class ExpandableStringEnumDiagnosticRule implements DiagnosticRule {
+public class ExpandableEnumDiagnosticRule implements DiagnosticRule {
+ private final String parentTypeName;
+
+ public ExpandableEnumDiagnosticRule(String parentTypeName) {
+ this.parentTypeName = parentTypeName;
+ }
@Override
public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
-
cu.getPrimaryType().ifPresent(typeDeclaration -> {
if (typeDeclaration instanceof ClassOrInterfaceDeclaration) {
ClassOrInterfaceDeclaration classDeclaration = (ClassOrInterfaceDeclaration) typeDeclaration;
// check if the type extends ExpandableStringEnum
if (classDeclaration.getExtendedTypes() != null
&& classDeclaration.getExtendedTypes().stream()
- .anyMatch(extendedType -> extendedType.getNameAsString().equals("ExpandableStringEnum"))) {
+ .anyMatch(extendedType -> extendedType.getNameAsString().equals(parentTypeName))) {
checkRequiredMethodsExist(cu, listing);
}
}
});
}
- private static void checkRequiredMethodsExist(CompilationUnit cu, APIListing listing) {
+ private void checkRequiredMethodsExist(CompilationUnit cu, APIListing listing) {
getClassName(cu).ifPresent(className -> {
AtomicBoolean hasFromStringMethod = new AtomicBoolean(false);
AtomicBoolean hasValuesMethod = new AtomicBoolean(false);
@@ -55,14 +59,14 @@ private static void checkRequiredMethodsExist(CompilationUnit cu, APIListing lis
listing.addDiagnostic(new Diagnostic(
ERROR,
makeId(cu),
- "Types extending ExpandableStringEnum should include public static fromString() method."));
+ "Types extending " + parentTypeName + " should include public static fromString() method."));
}
if (!hasValuesMethod.get()) {
// Missing values method can be logged at warning level.
listing.addDiagnostic(new Diagnostic(
WARNING,
makeId(cu),
- "Types extending ExpandableStringEnum should include public static values() method."));
+ "Types extending " + parentTypeName + " should include public static values() method."));
}
});
}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/BadAnnotationDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/BadAnnotationDiagnosticRule.java
similarity index 97%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/BadAnnotationDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/BadAnnotationDiagnosticRule.java
index 420644a26b5..dab54d42c79 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/BadAnnotationDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/BadAnnotationDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
@@ -26,7 +26,6 @@ public BadAnnotationDiagnosticRule(BadAnnotation... badAnnotations) {
@Override
public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
-
getClasses(cu).forEach(typeDeclaration -> {
// check annotations on the type itself
typeDeclaration.getAnnotations()
@@ -41,6 +40,7 @@ public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
getPublicOrProtectedConstructors(typeDeclaration)
.forEach(constructor -> constructor.getAnnotations()
.forEach(annotation -> checkForBadAnnotations(listing, constructor, annotation)));
+
// check annotations on methods
getPublicOrProtectedMethods(typeDeclaration)
.forEach(method -> method.getAnnotations()
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ConsiderFinalClassDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/ConsiderFinalClassDiagnosticRule.java
similarity index 97%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ConsiderFinalClassDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/ConsiderFinalClassDiagnosticRule.java
index fc8b00e5e68..c81c533e5a0 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ConsiderFinalClassDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/ConsiderFinalClassDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/IllegalMethodNamesDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/IllegalMethodNamesDiagnosticRule.java
similarity index 98%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/IllegalMethodNamesDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/IllegalMethodNamesDiagnosticRule.java
index 5dcf4c967b3..114f3aa04d8 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/IllegalMethodNamesDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/IllegalMethodNamesDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/IllegalPackageAPIExportsDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/IllegalPackageAPIExportsDiagnosticRule.java
similarity index 98%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/IllegalPackageAPIExportsDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/IllegalPackageAPIExportsDiagnosticRule.java
index e4c3d01d64a..abf93ea2ec5 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/IllegalPackageAPIExportsDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/IllegalPackageAPIExportsDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ImportsDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/ImportsDiagnosticRule.java
similarity index 96%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ImportsDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/ImportsDiagnosticRule.java
index 470ecc2a613..8504a069867 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ImportsDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/ImportsDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.analysers.util.ASTUtils;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MissingAnnotationsDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/MissingAnnotationsDiagnosticRule.java
similarity index 86%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MissingAnnotationsDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/MissingAnnotationsDiagnosticRule.java
index ae5751e897e..d5322df2d30 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MissingAnnotationsDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/MissingAnnotationsDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
@@ -10,12 +10,22 @@
import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.*;
import static com.azure.tools.apiview.processor.model.DiagnosticKind.*;
+/**
+ * This diagnostic, whilst being in the 'general' package, is still very heavily skewed towards azure and client core
+ * libraries, so it isn't enabled for all libraries.
+ */
public class MissingAnnotationsDiagnosticRule implements DiagnosticRule {
+ private final String packagePrefix;
+
+ public MissingAnnotationsDiagnosticRule(String packagePrefix) {
+ this.packagePrefix = packagePrefix;
+ }
+
@Override
public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
getClasses(cu)
- .filter(type -> getPackageName(type).startsWith("com.azure")) // we only want to give this guidance to Azure SDK developers
+ .filter(type -> getPackageName(type).startsWith(packagePrefix)) // we only want to give this guidance to Azure SDK developers
.forEach(typeDeclaration -> {
String className = typeDeclaration.getNameAsString();
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MissingJavaDocDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/MissingJavaDocDiagnosticRule.java
similarity index 97%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MissingJavaDocDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/MissingJavaDocDiagnosticRule.java
index dd4daa8ae46..a0f5b14bacd 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MissingJavaDocDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/MissingJavaDocDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MissingJavadocCodeSnippetsRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/MissingJavadocCodeSnippetsRule.java
similarity index 98%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MissingJavadocCodeSnippetsRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/MissingJavadocCodeSnippetsRule.java
index 111a9fc9e0d..4d602bcd588 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/MissingJavadocCodeSnippetsRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/MissingJavadocCodeSnippetsRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ModuleInfoDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/ModuleInfoDiagnosticRule.java
similarity index 98%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ModuleInfoDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/ModuleInfoDiagnosticRule.java
index ce53e74f129..653b8effa90 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/ModuleInfoDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/ModuleInfoDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.analysers.JavaASTAnalyser;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/NoLocalesInJavadocUrlDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/NoLocalesInJavadocUrlDiagnosticRule.java
similarity index 97%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/NoLocalesInJavadocUrlDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/NoLocalesInJavadocUrlDiagnosticRule.java
index 0719bea5da4..1a2c0b380b5 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/NoLocalesInJavadocUrlDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/NoLocalesInJavadocUrlDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/NoPublicFieldsDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/NoPublicFieldsDiagnosticRule.java
similarity index 93%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/NoPublicFieldsDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/NoPublicFieldsDiagnosticRule.java
index b4d37abbfdc..c8e97ee216d 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/NoPublicFieldsDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/NoPublicFieldsDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/PackageNameDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/PackageNameDiagnosticRule.java
similarity index 79%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/PackageNameDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/PackageNameDiagnosticRule.java
index 7b5a731ebc7..16cc9c91dce 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/PackageNameDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/PackageNameDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
@@ -11,7 +11,11 @@
import static com.azure.tools.apiview.processor.model.DiagnosticKind.*;
public class PackageNameDiagnosticRule implements DiagnosticRule {
- final static Pattern regex = Pattern.compile("^com.azure(\\.[a-z0-9]+)+$");
+ private final Pattern regex;
+
+ public PackageNameDiagnosticRule(Pattern regex) {
+ this.regex = regex;
+ }
@Override
public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
@@ -22,7 +26,7 @@ public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
listing.addDiagnostic(new Diagnostic(
ERROR,
typeId,
- "Package name must start with 'com.azure..', and it must be lower-case, with no underscores or hyphens."));
+ "Package name match the following regex: " + regex.pattern()));
}
});
});
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/UpperCaseEnumValuesDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/UpperCaseEnumValuesDiagnosticRule.java
similarity index 60%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/UpperCaseEnumValuesDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/UpperCaseEnumValuesDiagnosticRule.java
index c84d516beaf..b0d09f20a90 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/UpperCaseEnumValuesDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/UpperCaseEnumValuesDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
@@ -21,16 +21,14 @@ public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
getClasses(cu)
.filter(TypeDeclaration::isEnumDeclaration)
.map(TypeDeclaration::asEnumDeclaration)
- .forEach(enumDeclaration -> {
- enumDeclaration.getEntries().forEach(enumConstantDeclaration -> {
- String name = enumConstantDeclaration.getName().asString();
- if (!name.equals(name.toUpperCase())) {
- listing.addDiagnostic(new Diagnostic(
- WARNING,
- makeId(enumConstantDeclaration),
- "All enum constants should be upper case, using underscores as necessary between words."));
- }
- });
- });
+ .forEach(enumDeclaration -> enumDeclaration.getEntries().forEach(enumConstantDeclaration -> {
+ String name = enumConstantDeclaration.getName().asString();
+ if (!name.equals(name.toUpperCase())) {
+ listing.addDiagnostic(new Diagnostic(
+ WARNING,
+ makeId(enumConstantDeclaration),
+ "All enum constants should be upper case, using underscores as necessary between words."));
+ }
+ }));
}
}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/UpperCaseNamingDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/UpperCaseNamingDiagnosticRule.java
similarity index 95%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/UpperCaseNamingDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/UpperCaseNamingDiagnosticRule.java
index d2b226536f8..4abad29a776 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/UpperCaseNamingDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/general/UpperCaseNamingDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/BuilderTraitsDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/utils/BuilderTraitsDiagnosticRule.java
similarity index 70%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/BuilderTraitsDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/utils/BuilderTraitsDiagnosticRule.java
index bdbbea304e9..05f80478853 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/BuilderTraitsDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/utils/BuilderTraitsDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.utils;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
@@ -8,64 +8,20 @@
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.expr.AnnotationExpr;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
-import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.*;
+import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.isTypeImplementingInterface;
+import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.makeId;
import static com.azure.tools.apiview.processor.model.DiagnosticKind.ERROR;
import static com.azure.tools.apiview.processor.model.DiagnosticKind.WARNING;
-/**
- * This diagnostic ensures that builder traits are applied correctly against client builders.
- */
-public class BuilderTraitsDiagnosticRule implements DiagnosticRule {
+public abstract class BuilderTraitsDiagnosticRule implements DiagnosticRule {
private static final String ANNOTATION_SERVICE_CLIENT_BUILDER = "ServiceClientBuilder";
private final Map traits;
- public BuilderTraitsDiagnosticRule() {
- traits = new HashMap<>();
- traits.put("KeyCredentialTrait", new TraitClass(
- new TraitMethod("credential", "KeyCredential")
- ));
- traits.put("AzureKeyCredentialTrait", new TraitClass(
- new TraitMethod("credential", "AzureKeyCredential")
- ));
- traits.put("AzureNamedKeyCredentialTrait", new TraitClass(
- new TraitMethod("credential", "AzureNamedKeyCredential")
- ));
- traits.put("AzureSasCredentialTrait", new TraitClass(
- new TraitMethod("credential", "AzureSasCredential")
- ));
- traits.put("TokenCredentialTrait", new TraitClass(
- new TraitMethod("credential", "TokenCredential")
- ));
- traits.put("ConfigurationTrait", new TraitClass(
- new TraitMethod("configuration", "Configuration")
- ));
- traits.put("ConnectionStringTrait", new TraitClass(
- new TraitMethod("connectionString", "String")
- ));
- traits.put("EndpointTrait", new TraitClass(
- new TraitMethod("endpoint", "String")
- ));
- traits.put("HttpTrait", new TraitClass(TraitClass.BUILDER_PROTOCOL_HTTP,
- new TraitMethod("httpClient", "HttpClient"),
- new TraitMethod("pipeline", "HttpPipeline"),
- new TraitMethod("addPolicy", "HttpPipelinePolicy"),
- new TraitMethod("retryOptions", "RetryOptions"),
- new TraitMethod("httpLogOptions", "HttpLogOptions"),
- new TraitMethod("clientOptions", "ClientOptions")
- ));
- traits.put("AmqpTrait", new TraitClass(TraitClass.BUILDER_PROTOCOL_AMQP,
- new TraitMethod("retryOptions", "AmqpRetryOptions"),
- new TraitMethod("transportType", "AmqpTransportType"),
- new TraitMethod("proxyOptions", "ProxyOptions"),
- new TraitMethod("clientOptions", "ClientOptions")
- ));
+ protected BuilderTraitsDiagnosticRule(Map traits) {
+ this.traits = traits;
}
@Override
@@ -146,10 +102,10 @@ public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
// that mean this method is non-standard and not part of the trait.
String message = isTypeImplementingInterface(type, traitName) ?
"This builder implements the " + traitName + " trait, but offers duplicate " +
- "functionality. Consider whether this impacts consistency with other builders." :
+ "functionality. Consider whether this impacts consistency with other builders." :
"This builder does not implement the " + traitName + " trait, but offers " +
- "similar functionality. Consider implementing the trait and aligning the parameters " +
- "in this builder method.";
+ "similar functionality. Consider implementing the trait and aligning the parameters " +
+ "in this builder method.";
listing.addDiagnostic(new Diagnostic(WARNING, makeId(matchingNameMethod), message));
}
}
@@ -158,10 +114,10 @@ public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
});
}
- private static class TraitClass {
- static final String BUILDER_PROTOCOL_NOT_APPLICABLE = "N/A";
- static final String BUILDER_PROTOCOL_HTTP = "ServiceClientProtocol.HTTP";
- static final String BUILDER_PROTOCOL_AMQP = "ServiceClientProtocol.AMQP";
+ public static class TraitClass {
+ public static final String BUILDER_PROTOCOL_NOT_APPLICABLE = "N/A";
+ public static final String BUILDER_PROTOCOL_HTTP = "ServiceClientProtocol.HTTP";
+ public static final String BUILDER_PROTOCOL_AMQP = "ServiceClientProtocol.AMQP";
private final String builderProtocol;
private final List methods;
@@ -176,7 +132,7 @@ public TraitClass(String builderProtocol, TraitMethod... methods) {
}
}
- private static class TraitMethod {
+ public static class TraitMethod {
private final String methodName;
private final String[] methodParamTypes;
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/FluentSetterReturnTypeDiagnosticRule.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/utils/FluentSetterReturnTypeDiagnosticRule.java
similarity index 66%
rename from src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/FluentSetterReturnTypeDiagnosticRule.java
rename to src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/utils/FluentSetterReturnTypeDiagnosticRule.java
index c4bc4b98646..cdf9950f49c 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/FluentSetterReturnTypeDiagnosticRule.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/utils/FluentSetterReturnTypeDiagnosticRule.java
@@ -1,4 +1,4 @@
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.utils;
import com.azure.tools.apiview.processor.diagnostics.DiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
@@ -6,20 +6,25 @@
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.TypeDeclaration;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.getPublicOrProtectedMethods;
import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.makeId;
-import static com.azure.tools.apiview.processor.model.DiagnosticKind.*;
+import static com.azure.tools.apiview.processor.model.DiagnosticKind.ERROR;
-public class FluentSetterReturnTypeDiagnosticRule implements DiagnosticRule {
+public abstract class FluentSetterReturnTypeDiagnosticRule implements DiagnosticRule {
+ private Predicate> isFluentType;
- public FluentSetterReturnTypeDiagnosticRule() {
- // no-op
+ public FluentSetterReturnTypeDiagnosticRule(Predicate> isFluentType) {
+ this.isFluentType = isFluentType;
}
@Override
public void scanIndividual(final CompilationUnit cu, final APIListing listing) {
- cu.getTypes().forEach(type ->
- type.getAnnotationByName("Fluent").ifPresent(a -> processFluentType(type, listing)));
+ cu.getTypes().stream()
+ .filter(isFluentType)
+ .forEach(type -> processFluentType(type, listing));
}
private void processFluentType(final TypeDeclaration> type, final APIListing listing) {
@@ -33,7 +38,7 @@ private void processFluentType(final TypeDeclaration> type, final APIListing l
listing.addDiagnostic(new Diagnostic(
ERROR,
makeId(method),
- "Setter methods in a @Fluent class must return the same type as the fluent type."));
+ "Setter methods in a fluent class must return the same type as the fluent type."));
}
});
}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/utils/MiscUtils.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/utils/MiscUtils.java
new file mode 100644
index 00000000000..a173601a969
--- /dev/null
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/diagnostics/rules/utils/MiscUtils.java
@@ -0,0 +1,44 @@
+package com.azure.tools.apiview.processor.diagnostics.rules.utils;
+
+import com.azure.tools.apiview.processor.model.Diagnostic;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+
+import java.util.Optional;
+
+import static com.azure.tools.apiview.processor.analysers.util.ASTUtils.makeId;
+import static com.azure.tools.apiview.processor.model.DiagnosticKind.WARNING;
+
+public class MiscUtils {
+
+ /**
+ * Checks that a given method declaration accepts a type whose name ends with the given suffix.
+ */
+ public static Optional checkMethodParameterTypeSuffix(MethodDeclaration methodDeclaration, String suffix) {
+ return checkMethodParameterTypeSuffix(methodDeclaration, 0, suffix);
+ }
+
+ /**
+ * Checks that a given method declaration accepts a type whose name ends with the given suffix.
+ */
+ public static Optional checkMethodParameterTypeSuffix(MethodDeclaration methodDeclaration,
+ int paramIndex,
+ String suffix) {
+ if (paramIndex >= methodDeclaration.getParameters().size()) {
+ // The method does not have the expected number of parameters.
+ return Optional.of(new Diagnostic(WARNING, makeId(methodDeclaration),
+ "Incorrect number of parameters for this builder method. Expected " + paramIndex + " but was "
+ + methodDeclaration.getParameters().size() + "."));
+ }
+
+ Type parameterType = methodDeclaration.getParameter(paramIndex).getType();
+ ClassOrInterfaceType classOrInterfaceType = parameterType.asClassOrInterfaceType();
+ if (!classOrInterfaceType.getNameAsString().endsWith(suffix)) {
+ return Optional.of(new Diagnostic(WARNING, makeId(methodDeclaration),
+ "Incorrect type being supplied to this builder method. Expected a type ending with '"
+ + suffix + "' but was " + classOrInterfaceType.getNameAsString() + "."));
+ }
+ return Optional.empty();
+ }
+}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/model/ApiViewProperties.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/model/ApiViewProperties.java
index e71027c5966..2781c90adda 100644
--- a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/model/ApiViewProperties.java
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/model/ApiViewProperties.java
@@ -13,6 +13,9 @@
*/
public class ApiViewProperties {
+ @JsonProperty("flavor")
+ private Flavor flavor;
+
// This is a map of model names and methods to their TypeSpec definition IDs.
@JsonProperty("CrossLanguageDefinitionId")
private final Map crossLanguageDefinitionIds = new HashMap<>();
@@ -32,4 +35,8 @@ public Optional getCrossLanguageDefinitionId(String fullyQualifiedName)
public Map getCrossLanguageDefinitionIds() {
return Collections.unmodifiableMap(crossLanguageDefinitionIds);
}
+
+ public Flavor getFlavor() {
+ return flavor;
+ }
}
diff --git a/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/model/Flavor.java b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/model/Flavor.java
new file mode 100644
index 00000000000..9563c4c5e8d
--- /dev/null
+++ b/src/java/apiview-java-processor/src/main/java/com/azure/tools/apiview/processor/model/Flavor.java
@@ -0,0 +1,66 @@
+package com.azure.tools.apiview.processor.model;
+
+import com.azure.tools.apiview.processor.model.maven.Dependency;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public enum Flavor {
+ @JsonProperty("azure")
+ AZURE("com.azure"),
+
+ @JsonProperty("generic")
+ GENERIC("io.clientcore"),
+
+ UNKNOWN(null);
+
+ private final String packagePrefix;
+
+ private Flavor(String packagePrefix) {
+ this.packagePrefix = packagePrefix;
+ }
+
+ public String getPackagePrefix() {
+ return packagePrefix;
+ }
+
+ public static Flavor getFlavor(APIListing apiListing) {
+ Flavor flavor = apiListing.getApiViewProperties().getFlavor();
+ if (flavor != null) {
+ return flavor;
+ }
+
+ // we are reviewing a library that does not have a flavor metadata in its apiview_properties.json file,
+ // so we will use alternate means to determine the flavor.
+
+ // Firstly, check the package name - does it start with one of the known package prefixes?
+ if (apiListing.getPackageName().startsWith(AZURE.getPackagePrefix())) {
+ return AZURE;
+ } else if (apiListing.getPackageName().startsWith(GENERIC.getPackagePrefix())) {
+ return GENERIC;
+ }
+
+ // we still don't know the flavor, so the next thing we can do is look at the dependencies of the library
+ // to see if it brings in com.azure or io.clientcore libraries.
+ int azureCount = 0;
+ int genericCount = 0;
+ for (Dependency dependency : apiListing.getMavenPom().getDependencies()) {
+ if (dependency.getGroupId().equals(AZURE.getPackagePrefix())) {
+ // if we have azure-core, then we are an azure library and we bail
+ if (dependency.getArtifactId().equals("azure-core")) {
+ return AZURE;
+ }
+ azureCount++;
+ } else if (dependency.getGroupId().equals(GENERIC.getPackagePrefix())) {
+ // if we have 'core', then we are a clientcore library and we bail
+ if (dependency.getArtifactId().equals("core")) {
+ return GENERIC;
+ }
+ genericCount++;
+ }
+ }
+
+ // see which count is greatest (and non-zero), and return that flavour. If equal, return unknown
+ return azureCount > genericCount ? AZURE : genericCount > azureCount ? GENERIC : UNKNOWN;
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/MavenPackageAndDescriptionDiagnosticRuleTests.java b/src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/MavenPackageAndDescriptionDiagnosticRuleTests.java
similarity index 94%
rename from src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/MavenPackageAndDescriptionDiagnosticRuleTests.java
rename to src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/MavenPackageAndDescriptionDiagnosticRuleTests.java
index 3d66aaeb483..5e437741102 100644
--- a/src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/MavenPackageAndDescriptionDiagnosticRuleTests.java
+++ b/src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/azure/MavenPackageAndDescriptionDiagnosticRuleTests.java
@@ -1,18 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.azure;
+import com.azure.tools.apiview.processor.diagnostics.rules.azure.MavenPackageAndDescriptionDiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
import com.azure.tools.apiview.processor.model.maven.Pom;
import org.junit.jupiter.api.Test;
import java.util.regex.Pattern;
-import static com.azure.tools.apiview.processor.diagnostics.rules.MavenPackageAndDescriptionDiagnosticRule.DEFAULT_MAVEN_DESCRIPTION;
-import static com.azure.tools.apiview.processor.diagnostics.rules.MavenPackageAndDescriptionDiagnosticRule.DEFAULT_MAVEN_DESCRIPTION_GUIDELINE_LINK;
-import static com.azure.tools.apiview.processor.diagnostics.rules.MavenPackageAndDescriptionDiagnosticRule.DEFAULT_MAVEN_NAME;
-import static com.azure.tools.apiview.processor.diagnostics.rules.MavenPackageAndDescriptionDiagnosticRule.DEFAULT_MAVEN_NAME_GUIDELINE_LINK;
+import static com.azure.tools.apiview.processor.diagnostics.rules.azure.MavenPackageAndDescriptionDiagnosticRule.DEFAULT_MAVEN_DESCRIPTION;
+import static com.azure.tools.apiview.processor.diagnostics.rules.azure.MavenPackageAndDescriptionDiagnosticRule.DEFAULT_MAVEN_DESCRIPTION_GUIDELINE_LINK;
+import static com.azure.tools.apiview.processor.diagnostics.rules.azure.MavenPackageAndDescriptionDiagnosticRule.DEFAULT_MAVEN_NAME;
+import static com.azure.tools.apiview.processor.diagnostics.rules.azure.MavenPackageAndDescriptionDiagnosticRule.DEFAULT_MAVEN_NAME_GUIDELINE_LINK;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
diff --git a/src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/NoLocalesInJavadocUrlDiagnosticRuleTests.java b/src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/general/NoLocalesInJavadocUrlDiagnosticRuleTests.java
similarity index 94%
rename from src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/NoLocalesInJavadocUrlDiagnosticRuleTests.java
rename to src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/general/NoLocalesInJavadocUrlDiagnosticRuleTests.java
index 04ef51d1a1b..17125ce2325 100644
--- a/src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/NoLocalesInJavadocUrlDiagnosticRuleTests.java
+++ b/src/java/apiview-java-processor/src/test/java/com/azure/tools/apiview/processor/diagnostics/rules/general/NoLocalesInJavadocUrlDiagnosticRuleTests.java
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.tools.apiview.processor.diagnostics.rules;
+package com.azure.tools.apiview.processor.diagnostics.rules.general;
+import com.azure.tools.apiview.processor.diagnostics.rules.general.NoLocalesInJavadocUrlDiagnosticRule;
import com.azure.tools.apiview.processor.model.APIListing;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.comments.Comment;