diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-07-02 07:37:55 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-07-02 07:37:55 +0000 |
commit | df1078da8f2040a8914935a99cb4ddfaa241ae4e (patch) | |
tree | 841278a1572e46b942cf3c8cfc91666fc2b17bf1 | |
parent | 4246128398070c1953bf500e12242713cf83ee6a (diff) | |
parent | ef998e0b87c045318de63b42951cec1522d3b502 (diff) | |
download | platform_external_doclava-df1078da8f2040a8914935a99cb4ddfaa241ae4e.tar.gz platform_external_doclava-df1078da8f2040a8914935a99cb4ddfaa241ae4e.tar.bz2 platform_external_doclava-df1078da8f2040a8914935a99cb4ddfaa241ae4e.zip |
release-request-d9dc98f7-19b2-484c-b4d1-f35dc43e9c05-for-git_oc-mr1-release-4152006 snap-temp-L91700000079405440
Change-Id: I0e9ab16163540a387214a04f47c55aa1a8b823b0
-rw-r--r-- | src/com/google/doclava/Doclava.java | 20 | ||||
-rw-r--r-- | src/com/google/doclava/Stubs.java | 88 |
2 files changed, 85 insertions, 23 deletions
diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index 9d3f1b6..15789e5 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -183,6 +183,8 @@ public class Doclava { String exactApiFile = null; String debugStubsFile = ""; HashSet<String> stubPackages = null; + HashSet<String> stubImportPackages = null; + boolean stubSourceOnly = false; ArrayList<String> knownTagsFiles = new ArrayList<String>(); root = r; @@ -281,6 +283,14 @@ public class Doclava { for (String pkg : a[1].split(":")) { stubPackages.add(pkg); } + } else if (a[0].equals("-stubimportpackages")) { + stubImportPackages = new HashSet<String>(); + for (String pkg : a[1].split(":")) { + stubImportPackages.add(pkg); + hiddenPackages.add(pkg); + } + } else if (a[0].equals("-stubsourceonly")) { + stubSourceOnly = true; } else if (a[0].equals("-sdkvalues")) { sdkValuePath = a[1]; } else if (a[0].equals("-api")) { @@ -517,7 +527,9 @@ public class Doclava { if (stubsDir != null || apiFile != null || proguardFile != null || removedApiFile != null || exactApiFile != null) { Stubs.writeStubsAndApi(stubsDir, apiFile, proguardFile, removedApiFile, exactApiFile, - stubPackages); + stubPackages, + stubImportPackages, + stubSourceOnly); } Errors.printErrors(); @@ -788,6 +800,12 @@ public class Doclava { if (option.equals("-stubpackages")) { return 2; } + if (option.equals("-stubimportpackages")) { + return 2; + } + if (option.equals("-stubsourceonly")) { + return 1; + } if (option.equals("-sdkvalues")) { return 2; } diff --git a/src/com/google/doclava/Stubs.java b/src/com/google/doclava/Stubs.java index fdd9d0d..59ca505 100644 --- a/src/com/google/doclava/Stubs.java +++ b/src/com/google/doclava/Stubs.java @@ -28,6 +28,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -44,7 +46,9 @@ import java.util.stream.Collectors; public class Stubs { public static void writeStubsAndApi(String stubsDir, String apiFile, String keepListFile, - String removedApiFile, String exactApiFile, HashSet<String> stubPackages) { + String removedApiFile, String exactApiFile, HashSet<String> stubPackages, + HashSet<String> stubImportPackages, + boolean stubSourceOnly) { // figure out which classes we need final HashSet<ClassInfo> notStrippable = new HashSet<ClassInfo>(); ClassInfo[] all = Converter.allClasses(); @@ -95,11 +99,11 @@ public class Stubs { "Cannot open file for write"); } } - // If a class is public or protected, not hidden, and marked as included, + // If a class is public or protected, not hidden, not imported and marked as included, // then we can't strip it for (ClassInfo cl : all) { if (cl.checkLevel() && cl.isIncluded()) { - cantStripThis(cl, notStrippable, "0:0"); + cantStripThis(cl, notStrippable, "0:0", stubImportPackages); } } @@ -118,7 +122,7 @@ public class Stubs { + m.name() + " is deprecated"); } - ClassInfo hiddenClass = findHiddenClasses(m.returnType()); + ClassInfo hiddenClass = findHiddenClasses(m.returnType(), stubImportPackages); if (null != hiddenClass) { if (hiddenClass.qualifiedName() == m.returnType().asClassInfo().qualifiedName()) { // Return type is hidden @@ -135,7 +139,7 @@ public class Stubs { for (ParameterInfo p : m.parameters()) { TypeInfo t = p.type(); if (!t.isPrimitive()) { - hiddenClass = findHiddenClasses(t); + hiddenClass = findHiddenClasses(t, stubImportPackages); if (null != hiddenClass) { if (hiddenClass.qualifiedName() == t.asClassInfo().qualifiedName()) { // Parameter type is hidden @@ -188,6 +192,9 @@ public class Stubs { final HashSet<Pattern> stubPackageWildcards = extractWildcards(stubPackages); for (ClassInfo cl : notStrippable) { if (!cl.isDocOnly()) { + if (stubSourceOnly && !Files.exists(Paths.get(cl.position().file))) { + continue; + } if (shouldWriteStub(cl.containingPackage().name(), stubPackages, stubPackageWildcards)) { // write out the stubs if (stubsDir != null) { @@ -283,15 +290,34 @@ public class Stubs { return wildcards; } - private static ClassInfo findHiddenClasses(TypeInfo ti) { + /** + * Find references to hidden classes. + * + * <p>This finds hidden classes that are used by public parts of the API in order to ensure the + * API is self consistent and does not reference classes that are not included in + * the stubs. Any such references cause an error to be reported. + * + * <p>A reference to an imported class is not treated as an error, even though imported classes + * are hidden from the stub generation. That is because imported classes are, by definition, + * excluded from the set of classes for which stubs are required. + * + * @param ti the type information to examine for references to hidden classes. + * @param stubImportPackages the possibly null set of imported package names. + * @return a reference to a hidden class or null if there are none + */ + private static ClassInfo findHiddenClasses(TypeInfo ti, HashSet<String> stubImportPackages) { ClassInfo ci = ti.asClassInfo(); if (ci == null) return null; + if (stubImportPackages != null + && stubImportPackages.contains(ci.containingPackage().qualifiedName())) { + return null; + } if (ci.isHiddenOrRemoved()) return ci; if (ti.typeArguments() != null) { for (TypeInfo tii : ti.typeArguments()) { // Avoid infinite recursion in the case of Foo<T extends Foo> if (tii.qualifiedTypeName() != ti.qualifiedTypeName()) { - ClassInfo hiddenClass = findHiddenClasses(tii); + ClassInfo hiddenClass = findHiddenClasses(tii, stubImportPackages); if (hiddenClass != null) return hiddenClass; } } @@ -299,7 +325,14 @@ public class Stubs { return null; } - public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable, String why) { + public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable, String why, + HashSet<String> stubImportPackages) { + + if (stubImportPackages != null + && stubImportPackages.contains(cl.containingPackage().qualifiedName())) { + // if the package is imported then it does not need stubbing. + return; + } if (!notStrippable.add(cl)) { // slight optimization: if it already contains cl, it already contains @@ -319,12 +352,14 @@ public class Stubs { for (FieldInfo fInfo : cl.selfFields()) { if (fInfo.type() != null) { if (fInfo.type().asClassInfo() != null) { - cantStripThis(fInfo.type().asClassInfo(), notStrippable, "2:" + cl.qualifiedName()); + cantStripThis(fInfo.type().asClassInfo(), notStrippable, "2:" + cl.qualifiedName(), + stubImportPackages); } if (fInfo.type().typeArguments() != null) { for (TypeInfo tTypeInfo : fInfo.type().typeArguments()) { if (tTypeInfo.asClassInfo() != null) { - cantStripThis(tTypeInfo.asClassInfo(), notStrippable, "3:" + cl.qualifiedName()); + cantStripThis(tTypeInfo.asClassInfo(), notStrippable, "3:" + cl.qualifiedName(), + stubImportPackages); } } } @@ -336,7 +371,8 @@ public class Stubs { if (cl.asTypeInfo().typeArguments() != null) { for (TypeInfo tInfo : cl.asTypeInfo().typeArguments()) { if (tInfo.asClassInfo() != null) { - cantStripThis(tInfo.asClassInfo(), notStrippable, "4:" + cl.qualifiedName()); + cantStripThis(tInfo.asClassInfo(), notStrippable, "4:" + cl.qualifiedName(), + stubImportPackages); } } } @@ -344,11 +380,12 @@ public class Stubs { // cant strip any of the annotation elements // cantStripThis(cl.annotationElements(), notStrippable); // take care of methods - cantStripThis(cl.allSelfMethods(), notStrippable); - cantStripThis(cl.allConstructors(), notStrippable); + cantStripThis(cl.allSelfMethods(), notStrippable, stubImportPackages); + cantStripThis(cl.allConstructors(), notStrippable, stubImportPackages); // blow the outer class open if this is an inner class if (cl.containingClass() != null) { - cantStripThis(cl.containingClass(), notStrippable, "5:" + cl.qualifiedName()); + cantStripThis(cl.containingClass(), notStrippable, "5:" + cl.qualifiedName(), + stubImportPackages); } // blow open super class and interfaces ClassInfo supr = cl.realSuperclass(); @@ -366,7 +403,8 @@ public class Stubs { Errors.error(Errors.HIDDEN_SUPERCLASS, cl.position(), "Public class " + cl.qualifiedName() + " stripped of unavailable superclass " + supr.qualifiedName()); } else { - cantStripThis(supr, notStrippable, "6:" + cl.realSuperclass().name() + cl.qualifiedName()); + cantStripThis(supr, notStrippable, "6:" + cl.realSuperclass().name() + cl.qualifiedName(), + stubImportPackages); if (supr.isPrivate()) { Errors.error(Errors.PRIVATE_SUPERCLASS, cl.position(), "Public class " + cl.qualifiedName() + " extends private class " + supr.qualifiedName()); @@ -375,7 +413,8 @@ public class Stubs { } } - private static void cantStripThis(ArrayList<MethodInfo> mInfos, HashSet<ClassInfo> notStrippable) { + private static void cantStripThis(ArrayList<MethodInfo> mInfos, HashSet<ClassInfo> notStrippable, + HashSet<String> stubImportPackages) { // for each method, blow open the parameters, throws and return types. also blow open their // generics if (mInfos != null) { @@ -384,7 +423,8 @@ public class Stubs { for (TypeInfo tInfo : mInfo.getTypeParameters()) { if (tInfo.asClassInfo() != null) { cantStripThis(tInfo.asClassInfo(), notStrippable, "8:" - + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); + + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name(), + stubImportPackages); } } } @@ -392,7 +432,8 @@ public class Stubs { for (ParameterInfo pInfo : mInfo.parameters()) { if (pInfo.type() != null && pInfo.type().asClassInfo() != null) { cantStripThis(pInfo.type().asClassInfo(), notStrippable, "9:" - + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); + + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name(), + stubImportPackages); if (pInfo.type().typeArguments() != null) { for (TypeInfo tInfoType : pInfo.type().typeArguments()) { if (tInfoType.asClassInfo() != null) { @@ -405,7 +446,8 @@ public class Stubs { + "()"); } else { cantStripThis(tcl, notStrippable, "10:" - + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); + + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name(), + stubImportPackages); } } } @@ -415,16 +457,18 @@ public class Stubs { } for (ClassInfo thrown : mInfo.thrownExceptions()) { cantStripThis(thrown, notStrippable, "11:" + mInfo.realContainingClass().qualifiedName() - + ":" + mInfo.name()); + + ":" + mInfo.name(), stubImportPackages); } if (mInfo.returnType() != null && mInfo.returnType().asClassInfo() != null) { cantStripThis(mInfo.returnType().asClassInfo(), notStrippable, "12:" - + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); + + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name(), + stubImportPackages); if (mInfo.returnType().typeArguments() != null) { for (TypeInfo tyInfo : mInfo.returnType().typeArguments()) { if (tyInfo.asClassInfo() != null) { cantStripThis(tyInfo.asClassInfo(), notStrippable, "13:" - + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); + + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name(), + stubImportPackages); } } } |