summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-08-13 07:33:55 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-08-13 07:33:55 +0000
commitf8c9b6c5dd536c5ad3b995be77f7189ca08ae345 (patch)
tree553b8ef9c52922f00decd60ff6fd253827f32c59
parente07cd326e1c454ababa75bb44d7b7f29322fc836 (diff)
parent8ea43aab82d66cb32138fcd659596ed140597023 (diff)
downloaddoclava-oreo-m6-s3-release.tar.gz
release-request-68cc9b2a-98ae-4fbf-8b56-3e535855f399-for-git_oc-mr1-release-4269864 snap-temp-L25700000092502312android-wear-8.1.0_r1android-vts-8.1_r9android-vts-8.1_r8android-vts-8.1_r7android-vts-8.1_r6android-vts-8.1_r5android-vts-8.1_r4android-vts-8.1_r3android-vts-8.1_r14android-vts-8.1_r13android-vts-8.1_r12android-vts-8.1_r11android-vts-8.1_r10android-security-8.1.0_r93android-security-8.1.0_r92android-security-8.1.0_r91android-security-8.1.0_r90android-security-8.1.0_r89android-security-8.1.0_r88android-security-8.1.0_r87android-security-8.1.0_r86android-security-8.1.0_r85android-security-8.1.0_r84android-security-8.1.0_r83android-security-8.1.0_r82android-cts-8.1_r9android-cts-8.1_r8android-cts-8.1_r7android-cts-8.1_r6android-cts-8.1_r5android-cts-8.1_r4android-cts-8.1_r3android-cts-8.1_r25android-cts-8.1_r24android-cts-8.1_r23android-cts-8.1_r22android-cts-8.1_r21android-cts-8.1_r20android-cts-8.1_r2android-cts-8.1_r19android-cts-8.1_r18android-cts-8.1_r17android-cts-8.1_r16android-cts-8.1_r15android-cts-8.1_r14android-cts-8.1_r13android-cts-8.1_r12android-cts-8.1_r11android-cts-8.1_r10android-cts-8.1_r1android-8.1.0_r9android-8.1.0_r81android-8.1.0_r80android-8.1.0_r8android-8.1.0_r79android-8.1.0_r78android-8.1.0_r77android-8.1.0_r76android-8.1.0_r75android-8.1.0_r74android-8.1.0_r73android-8.1.0_r72android-8.1.0_r71android-8.1.0_r70android-8.1.0_r7android-8.1.0_r69android-8.1.0_r68android-8.1.0_r67android-8.1.0_r66android-8.1.0_r65android-8.1.0_r64android-8.1.0_r63android-8.1.0_r62android-8.1.0_r61android-8.1.0_r60android-8.1.0_r6android-8.1.0_r53android-8.1.0_r52android-8.1.0_r51android-8.1.0_r50android-8.1.0_r5android-8.1.0_r48android-8.1.0_r47android-8.1.0_r46android-8.1.0_r45android-8.1.0_r43android-8.1.0_r42android-8.1.0_r41android-8.1.0_r40android-8.1.0_r4android-8.1.0_r39android-8.1.0_r38android-8.1.0_r37android-8.1.0_r36android-8.1.0_r35android-8.1.0_r33android-8.1.0_r32android-8.1.0_r31android-8.1.0_r30android-8.1.0_r3android-8.1.0_r29android-8.1.0_r28android-8.1.0_r27android-8.1.0_r26android-8.1.0_r25android-8.1.0_r23android-8.1.0_r22android-8.1.0_r21android-8.1.0_r20android-8.1.0_r2android-8.1.0_r19android-8.1.0_r18android-8.1.0_r17android-8.1.0_r16android-8.1.0_r15android-8.1.0_r14android-8.1.0_r13android-8.1.0_r12android-8.1.0_r11android-8.1.0_r10android-8.1.0_r1security-oc-mr1-releaseoreo-mr1-wear-releaseoreo-mr1-vts-releaseoreo-mr1-security-releaseoreo-mr1-s1-releaseoreo-mr1-releaseoreo-mr1-cuttlefish-testingoreo-mr1-cts-releaseoreo-m8-releaseoreo-m7-releaseoreo-m6-s4-releaseoreo-m6-s3-releaseoreo-m6-s2-releaseoreo-m5-releaseoreo-m4-s9-releaseoreo-m4-s8-releaseoreo-m4-s7-releaseoreo-m4-s6-releaseoreo-m4-s5-releaseoreo-m4-s4-releaseoreo-m4-s3-releaseoreo-m4-s2-releaseoreo-m4-s12-releaseoreo-m4-s11-releaseoreo-m4-s10-releaseoreo-m4-s1-releaseoreo-m3-releaseoreo-m2-s5-releaseoreo-m2-s4-releaseoreo-m2-s3-releaseoreo-m2-s2-releaseoreo-m2-s1-releaseoreo-m2-release
Change-Id: I396782341da824d0234f17222080aea5e1c3049a
-rw-r--r--res/assets/templates-sdk/page_info.cs14
-rw-r--r--res/assets/templates/macros.cs7
-rw-r--r--src/com/google/doclava/ArtifactTagger.java163
-rw-r--r--src/com/google/doclava/ClassInfo.java5
-rw-r--r--src/com/google/doclava/DocInfo.java21
-rw-r--r--src/com/google/doclava/Doclava.java10
-rw-r--r--src/com/google/doclava/Errors.java2
-rw-r--r--src/com/google/doclava/MemberInfo.java8
-rw-r--r--src/com/google/doclava/NavTree.java10
-rw-r--r--src/com/google/doclava/Stubs.java12
10 files changed, 231 insertions, 21 deletions
diff --git a/res/assets/templates-sdk/page_info.cs b/res/assets/templates-sdk/page_info.cs
index fad1274..4bdda67 100644
--- a/res/assets/templates-sdk/page_info.cs
+++ b/res/assets/templates-sdk/page_info.cs
@@ -23,11 +23,15 @@ elif:subcount(class)
?>
<div id="api-info-block">
<div class="api-level">
- <?cs call:since_tags(class) ?><?cs
- if:class.deprecatedsince
- ?><br>Deprecated since <a href="<?cs var:toroot ?>guide/topics/manifest/uses-sdk-element.html#ApiLevels"
- >API level <?cs var:class.deprecatedsince ?></a><?cs
- /if ?>
+ <?cs call:since_tags(class) ?>
+ <?cs if:class.artifact ?>
+ <br><?cs call:artifact_tags(class) ?>
+ <?cs /if ?>
+ <?cs if:class.deprecatedsince ?>
+ <br>Deprecated since
+ <a href="<?cs var:toroot ?>guide/topics/manifest/uses-sdk-element.html#ApiLevels">API level
+ <?cs var:class.deprecatedsince ?></a>
+ <?cs /if ?>
<?cs call:federated_refs(class) ?>
</div>
diff --git a/res/assets/templates/macros.cs b/res/assets/templates/macros.cs
index 3bf36e2..cf8c86e 100644
--- a/res/assets/templates/macros.cs
+++ b/res/assets/templates/macros.cs
@@ -274,6 +274,13 @@ if:reference.apilevels && obj.since ?><?cs
/if ?><?cs
/def ?><?cs
+# print the artifact ?><?cs
+def:artifact_tags(obj) ?><?cs
+if:reference.artifacts && obj.artifact ?>
+ belongs to Maven artifact <?cs var:obj.artifact ?></a><?cs
+/if ?><?cs
+/def ?><?cs
+
def:federated_refs(obj) ?>
<?cs if:subcount(obj.federated) ?>
<div>
diff --git a/src/com/google/doclava/ArtifactTagger.java b/src/com/google/doclava/ArtifactTagger.java
new file mode 100644
index 0000000..3c5ee06
--- /dev/null
+++ b/src/com/google/doclava/ArtifactTagger.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.doclava;
+
+import com.google.clearsilver.jsilver.data.Data;
+import com.google.doclava.apicheck.ApiCheck;
+import com.google.doclava.apicheck.ApiInfo;
+import com.google.doclava.apicheck.ApiParseException;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Applies version information to the Doclava class model from apicheck XML files.
+ * <p>
+ * Sample usage:
+ * <pre>
+ * ClassInfo[] classInfos = ...
+ *
+ * ArtifactTagger artifactTagger = new ArtifactTagger()
+ * artifactTagger.addArtifact("frameworks/support/core-ui/api/current.xml",
+ * "com.android.support:support-core-ui:26.0.0")
+ * artifactTagger.addArtifact("frameworks/support/design/api/current.xml",
+ * "com.android.support:support-design:26.0.0")
+ * artifactTagger.tagAll(...);
+ * </pre>
+ */
+public class ArtifactTagger {
+
+ private final Map<String, String> xmlToArtifact = new LinkedHashMap<>();
+
+ /**
+ * Specifies the apicheck XML file associated with an artifact.
+ * <p>
+ * This method should only be called once per artifact.
+ *
+ * @param file an apicheck XML file
+ * @param mavenSpec the Maven spec for the artifact to which the XML file belongs
+ */
+ public void addArtifact(String file, String mavenSpec) {
+ xmlToArtifact.put(file, mavenSpec);
+ }
+
+ /**
+ * Tags the specified docs with artifact information.
+ *
+ * @param classDocs the docs to tag
+ */
+ public void tagAll(ClassInfo[] classDocs) {
+ // Read through the XML files in order, applying their artifact information
+ // to the Javadoc models.
+ for (Map.Entry<String, String> artifactSpec : xmlToArtifact.entrySet()) {
+ String xmlFile = artifactSpec.getKey();
+ String artifactName = artifactSpec.getValue();
+
+ ApiInfo specApi;
+ try {
+ specApi = new ApiCheck().parseApi(xmlFile);
+ } catch (ApiParseException e) {
+ StringWriter stackTraceWriter = new StringWriter();
+ e.printStackTrace(new PrintWriter(stackTraceWriter));
+ Errors.error(Errors.BROKEN_ARTIFACT_FILE, (SourcePositionInfo) null,
+ "Failed to parse " + xmlFile + " for " + artifactName + " artifact data.\n"
+ + stackTraceWriter.toString());
+ continue;
+ }
+
+ applyArtifactsFromSpec(artifactName, specApi, classDocs);
+ }
+
+ if (!xmlToArtifact.isEmpty()) {
+ warnForMissingArtifacts(classDocs);
+ }
+ }
+
+ /**
+ * Returns {@code true} if any artifact mappings are specified.
+ */
+ public boolean hasArtifacts() {
+ return !xmlToArtifact.isEmpty();
+ }
+
+ /**
+ * Writes an index of the artifact names to {@code data}.
+ */
+ public void writeArtifactNames(Data data) {
+ int index = 1;
+ for (String artifact : xmlToArtifact.values()) {
+ data.setValue("artifact." + index + ".name", artifact);
+ index++;
+ }
+ }
+
+ /**
+ * Applies artifact information to {@code classDocs} where not already present.
+ *
+ * @param mavenSpec the Maven spec for the artifact
+ * @param specApi the spec for this artifact
+ * @param classDocs the docs to update
+ */
+ private void applyArtifactsFromSpec(String mavenSpec, ApiInfo specApi, ClassInfo[] classDocs) {
+ for (ClassInfo classDoc : classDocs) {
+ PackageInfo packageSpec = specApi.getPackages().get(classDoc.containingPackage().name());
+ if (packageSpec != null) {
+ ClassInfo classSpec = packageSpec.allClasses().get(classDoc.name());
+ if (classSpec != null) {
+ if (classDoc.getArtifact() == null) {
+ classDoc.setArtifact(mavenSpec);
+ } else {
+ Errors.error(Errors.BROKEN_ARTIFACT_FILE, (SourcePositionInfo) null, "Class "
+ + classDoc.name() + " belongs to multiple artifacts: " + classDoc.getArtifact()
+ + " and " + mavenSpec);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Warns if any symbols are missing artifact information. When configured properly, this will
+ * yield zero warnings because {@code apicheck} guarantees that all symbols are present in the
+ * most recent API.
+ *
+ * @param classDocs the docs to verify
+ */
+ private void warnForMissingArtifacts(ClassInfo[] classDocs) {
+ for (ClassInfo claz : classDocs) {
+ if (checkLevelRecursive(claz) && claz.getArtifact() == null) {
+ Errors.error(Errors.NO_ARTIFACT_DATA, claz.position(), "XML missing class "
+ + claz.qualifiedName());
+ }
+ }
+ }
+
+ /**
+ * Returns true if {@code claz} and all containing classes are documented. The result may be used
+ * to filter out members that exist in the API data structure but aren't a part of the API.
+ */
+ private boolean checkLevelRecursive(ClassInfo claz) {
+ for (ClassInfo c = claz; c != null; c = c.containingClass()) {
+ if (!c.checkLevel()) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/com/google/doclava/ClassInfo.java b/src/com/google/doclava/ClassInfo.java
index b152508..3a4090c 100644
--- a/src/com/google/doclava/ClassInfo.java
+++ b/src/com/google/doclava/ClassInfo.java
@@ -1123,6 +1123,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
if (isDeprecated()) {
data.setValue(base + ".deprecatedsince", getDeprecatedSince());
}
+ data.setValue(base + ".artifact", getArtifact());
ArrayList<AnnotationInstanceInfo> showAnnos = getShowAnnotationsIncludeOuters();
AnnotationInstanceInfo.makeLinkListHDF(
@@ -1193,6 +1194,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
if (isDeprecated()) {
data.setValue("class.deprecatedsince", getDeprecatedSince());
}
+ data.setValue("class.artifact", getArtifact());
setFederatedReferences(data, "class");
// the containing package -- note that this can be passed to type_link,
@@ -1510,9 +1512,6 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco
public boolean isRemovedImpl() {
ClassInfo cl = this;
while (cl != null) {
- if (cl.hasShowAnnotation()) {
- return false;
- }
PackageInfo pkg = cl.containingPackage();
if (pkg != null && pkg.hasRemovedComment()) {
return true;
diff --git a/src/com/google/doclava/DocInfo.java b/src/com/google/doclava/DocInfo.java
index d8a1961..650ce0d 100644
--- a/src/com/google/doclava/DocInfo.java
+++ b/src/com/google/doclava/DocInfo.java
@@ -104,6 +104,26 @@ public abstract class DocInfo {
return mSince;
}
+ /**
+ * Sets the artifact in which the class resides.
+ * <p>
+ * This property should be specified as a full Maven dependency spec. For example, a Support
+ * Library core utility class may use "com.android.support:support-core-utils:26.0.1".
+ *
+ * @param artifact the artifact in which the class resides
+ * @return
+ */
+ public void setArtifact(String artifact) {
+ mArtifact = artifact;
+ }
+
+ /**
+ * Returns the artifact in which the class resides.
+ */
+ public String getArtifact() {
+ return mArtifact;
+ }
+
public void setDeprecatedSince(String since) {
mDeprecatedSince = since;
}
@@ -137,6 +157,7 @@ public abstract class DocInfo {
Comment mComment;
SourcePositionInfo mPosition;
private String mSince;
+ private String mArtifact;
private String mDeprecatedSince;
private Set<FederatedSite> mFederatedReferences = new LinkedHashSet<FederatedSite>();
}
diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java
index 0327114..e1c92f1 100644
--- a/src/com/google/doclava/Doclava.java
+++ b/src/com/google/doclava/Doclava.java
@@ -101,6 +101,7 @@ public class Doclava {
public static Map<Character, String> escapeChars = new HashMap<Character, String>();
public static String title = "";
public static SinceTagger sinceTagger = new SinceTagger();
+ public static ArtifactTagger artifactTagger = new ArtifactTagger();
public static HashSet<String> knownTags = new HashSet<String>();
public static FederationTagger federationTagger = new FederationTagger();
public static Set<String> showAnnotations = new HashSet<String>();
@@ -309,6 +310,8 @@ public class Doclava {
parseComments = true;
} else if (a[0].equals("-since")) {
sinceTagger.addVersion(a[1], a[2]);
+ } else if (a[0].equals("-artifact")) {
+ artifactTagger.addArtifact(a[1], a[2]);
} else if (a[0].equals("-offlinemode")) {
offlineMode = true;
} else if (a[0].equals("-metadataDebug")) {
@@ -433,6 +436,9 @@ public class Doclava {
// Apply @since tags from the XML file
sinceTagger.tagAll(Converter.rootClasses());
+ // Apply @artifact tags from the XML file
+ artifactTagger.tagAll(Converter.rootClasses());
+
// Apply details of federated documentation
federationTagger.tagAll(Converter.rootClasses());
@@ -833,6 +839,9 @@ public class Doclava {
if (option.equals("-since")) {
return 3;
}
+ if (option.equals("-artifact")) {
+ return 3;
+ }
if (option.equals("-offlinemode")) {
return 1;
}
@@ -979,6 +988,7 @@ public class Doclava {
}
data.setValue("reference", "1");
data.setValue("reference.apilevels", sinceTagger.hasVersions() ? "1" : "0");
+ data.setValue("reference.artifacts", artifactTagger.hasArtifacts() ? "1" : "0");
data.setValue("docs.packages." + i + ".name", s);
data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
data.setValue("docs.packages." + i + ".since", pkg.getSince());
diff --git a/src/com/google/doclava/Errors.java b/src/com/google/doclava/Errors.java
index 48202a3..9edd239 100644
--- a/src/com/google/doclava/Errors.java
+++ b/src/com/google/doclava/Errors.java
@@ -311,6 +311,8 @@ public class Errors {
public static final Error BROADCAST_BEHAVIOR = new Error(126, LINT);
public static final Error SDK_CONSTANT = new Error(127, LINT);
public static final Error TODO = new Error(128, LINT);
+ public static final Error NO_ARTIFACT_DATA = new Error(129, HIDDEN);
+ public static final Error BROKEN_ARTIFACT_FILE = new Error(130, ERROR);
public static boolean setErrorLevel(int code, int level) {
for (Error e : sErrors) {
diff --git a/src/com/google/doclava/MemberInfo.java b/src/com/google/doclava/MemberInfo.java
index 8c88648..8e7863e 100644
--- a/src/com/google/doclava/MemberInfo.java
+++ b/src/com/google/doclava/MemberInfo.java
@@ -53,14 +53,6 @@ public abstract class MemberInfo extends DocInfo implements Comparable, Scoped {
}
@Override
- public boolean isRemoved() {
- if (mShowAnnotations.size() > 0) {
- return false;
- }
- return super.isRemoved();
- }
-
- @Override
public boolean isHiddenOrRemoved() {
return isHidden() || isRemoved();
}
diff --git a/src/com/google/doclava/NavTree.java b/src/com/google/doclava/NavTree.java
index 03926b2..5d055db 100644
--- a/src/com/google/doclava/NavTree.java
+++ b/src/com/google/doclava/NavTree.java
@@ -165,7 +165,7 @@ public class NavTree {
for (ClassInfo cl : classes) {
if (cl.checkLevel()) {
- children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince()));
+ children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince(), cl.getArtifact()));
}
}
@@ -179,12 +179,18 @@ public class NavTree {
private String mLink;
List<Node> mChildren;
private String mSince;
+ private String mArtifact;
Node(String label, String link, List<Node> children, String since) {
+ this(label, link, children, since, null);
+ }
+
+ Node(String label, String link, List<Node> children, String since, String artifact) {
mLabel = label;
mLink = link;
mChildren = children;
mSince = since;
+ mArtifact = artifact;
}
static void renderString(StringBuilder buf, String s) {
@@ -243,6 +249,8 @@ public class NavTree {
renderChildren(buf);
buf.append(", ");
renderString(buf, mSince);
+ buf.append(", ");
+ renderString(buf, mArtifact);
buf.append(" ]");
}
}
diff --git a/src/com/google/doclava/Stubs.java b/src/com/google/doclava/Stubs.java
index 479b5ae..4dc859d 100644
--- a/src/com/google/doclava/Stubs.java
+++ b/src/com/google/doclava/Stubs.java
@@ -1230,14 +1230,16 @@ public class Stubs {
ClassInfo clazz = member.containingClass();
boolean visible = member.isPublic() || member.isProtected();
+ boolean hidden = member.isHidden();
boolean removed = member.isRemoved();
while (clazz != null) {
visible &= clazz.isPublic() || clazz.isProtected();
+ hidden |= clazz.isHidden();
removed |= clazz.isRemoved();
clazz = clazz.containingClass();
}
- if (visible && removed) {
+ if (visible && !hidden && removed) {
if (member instanceof MethodInfo) {
final MethodInfo method = (MethodInfo) member;
return (method.findOverriddenMethod(method.name(), method.signature()) == null);
@@ -1257,15 +1259,17 @@ public class Stubs {
boolean visible = member.isPublic() || member.isProtected();
boolean hasShowAnnotation = member.hasShowAnnotation();
- boolean hiddenOrRemoved = member.isHiddenOrRemoved();
+ boolean hidden = member.isHidden();
+ boolean removed = member.isRemoved();
while (clazz != null) {
visible &= clazz.isPublic() || clazz.isProtected();
hasShowAnnotation |= clazz.hasShowAnnotation();
- hiddenOrRemoved |= clazz.isHiddenOrRemoved();
+ hidden |= clazz.isHidden();
+ removed |= clazz.isRemoved();
clazz = clazz.containingClass();
}
- if (visible && hasShowAnnotation && !hiddenOrRemoved) {
+ if (visible && hasShowAnnotation && !hidden && !removed) {
if (member instanceof MethodInfo) {
final MethodInfo method = (MethodInfo) member;
return (method.findOverriddenMethod(method.name(), method.signature()) == null);