diff options
author | Mathew Inwood <mathewi@google.com> | 2018-06-22 15:29:41 +0100 |
---|---|---|
committer | Mathew Inwood <mathewi@google.com> | 2018-07-02 13:01:55 +0100 |
commit | 998f4e56f474d5355368b4485509cd97ecf6b0a4 (patch) | |
tree | 4e158b18fd568e06a328eef8e66ad75a21f56ad5 /src | |
parent | 0a8ebf780198fef6cab55589652e20c3be20f0ec (diff) | |
download | doclava-998f4e56f474d5355368b4485509cd97ecf6b0a4.tar.gz |
Support for dex signature -> source position map.
For every class processed by doclava, output the dex signature and
source position of the corresponding API definition. This can then be
read by other tools to perform automated changes to the source file.
A new parameter -apiMapping is added to control this functionality. The
mapping file is in the format of:
dex-signature
source/file.java:123
with two lines for every dex signature.
Test: m
Bug: 110868826
Change-Id: I12e01419e10efb7f38706f1a24d8bdf44f5bf55e
Diffstat (limited to 'src')
-rw-r--r-- | src/com/google/doclava/Doclava.java | 12 | ||||
-rw-r--r-- | src/com/google/doclava/Stubs.java | 57 |
2 files changed, 63 insertions, 6 deletions
diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java index 9aaf577..57a4b5a 100644 --- a/src/com/google/doclava/Doclava.java +++ b/src/com/google/doclava/Doclava.java @@ -189,6 +189,7 @@ public class Doclava { String privateApiFile = null; String privateDexApiFile = null; String debugStubsFile = ""; + String apiMappingFile = null; HashSet<String> stubPackages = null; HashSet<String> stubImportPackages = null; boolean stubSourceOnly = false; @@ -316,6 +317,8 @@ public class Doclava { privateApiFile = a[1]; } else if (a[0].equals("-privateDexApi")) { privateDexApiFile = a[1]; + } else if (a[0].equals("-apiMapping")) { + apiMappingFile = a[1]; } else if (a[0].equals("-nodocs")) { generateDocs = false; } else if (a[0].equals("-noassets")) { @@ -554,10 +557,10 @@ public class Doclava { // Stubs if (stubsDir != null || apiFile != null || dexApiFile != null || proguardFile != null || removedApiFile != null || removedDexApiFile != null || exactApiFile != null - || privateApiFile != null || privateDexApiFile != null) { + || privateApiFile != null || privateDexApiFile != null || apiMappingFile != null) { Stubs.writeStubsAndApi(stubsDir, apiFile, dexApiFile, proguardFile, removedApiFile, - removedDexApiFile, exactApiFile, privateApiFile, privateDexApiFile, stubPackages, - stubImportPackages, stubSourceOnly); + removedDexApiFile, exactApiFile, privateApiFile, privateDexApiFile, apiMappingFile, + stubPackages, stubImportPackages, stubSourceOnly); } Errors.printErrors(); @@ -864,6 +867,9 @@ public class Doclava { if (option.equals("-privateDexApi")) { return 2; } + if (option.equals("-apiMapping")) { + return 2; + } if (option.equals("-nodocs")) { return 1; } diff --git a/src/com/google/doclava/Stubs.java b/src/com/google/doclava/Stubs.java index 343a020..3c9138a 100644 --- a/src/com/google/doclava/Stubs.java +++ b/src/com/google/doclava/Stubs.java @@ -48,8 +48,8 @@ import java.util.stream.Collectors; public class Stubs { public static void writeStubsAndApi(String stubsDir, String apiFile, String dexApiFile, String keepListFile, String removedApiFile, String removedDexApiFile, String exactApiFile, - String privateApiFile, String privateDexApiFile, HashSet<String> stubPackages, - HashSet<String> stubImportPackages, boolean stubSourceOnly) { + String privateApiFile, String privateDexApiFile, String apiMappingFile, + HashSet<String> stubPackages, HashSet<String> stubImportPackages, boolean stubSourceOnly) { // figure out which classes we need final HashSet<ClassInfo> notStrippable = new HashSet<ClassInfo>(); Collection<ClassInfo> all = Converter.allClasses(); @@ -62,6 +62,7 @@ public class Stubs { PrintStream exactApiWriter = null; PrintStream privateApiWriter = null; PrintStream privateDexApiWriter = null; + PrintStream apiMappingWriter = null; if (apiFile != null) { try { @@ -148,6 +149,17 @@ public class Stubs { "Cannot open file for write"); } } + if (apiMappingFile != null) { + try { + File apiMapping = new File(apiMappingFile); + apiMapping.getParentFile().mkdirs(); + apiMappingWriter = new PrintStream( + new BufferedOutputStream(new FileOutputStream(apiMapping))); + } catch (FileNotFoundException e) { + Errors.error(Errors.IO_ERROR, new SourcePositionInfo(apiMappingFile, 0, 0), + "Cannot open file for write"); + } + } // 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) { @@ -264,7 +276,7 @@ public class Stubs { } if (privateApiWriter != null || privateDexApiWriter != null || removedApiWriter != null - || removedDexApiWriter != null) { + || removedDexApiWriter != null || apiMappingWriter != null) { allClassesByPackage = Converter.allClasses().stream() // Make sure that the files only contains information from the required packages. .filter(ci -> stubPackages == null @@ -320,6 +332,12 @@ public class Stubs { privateDexApiWriter.close(); } + // Write out the API mapping + if (apiMappingWriter != null) { + writeApiMapping(apiMappingWriter, allClassesByPackage); + apiMappingWriter.close(); + } + // Write out the removed API if (removedApiWriter != null) { writeApi(removedApiWriter, allClassesByPackage, removedEmit, removedReference); @@ -1459,6 +1477,34 @@ public class Stubs { } } + static void writeApiMapping(PrintStream mappingWriter, + Map<PackageInfo, List<ClassInfo>> classesByPackage) { + + for (PackageInfo pkg : classesByPackage.keySet().stream().sorted(PackageInfo.comparator) + .collect(Collectors.toList())) { + if (pkg.name().equals(PackageInfo.DEFAULT_PACKAGE)) continue; + for (ClassInfo cl : classesByPackage.get(pkg).stream().sorted(ClassInfo.comparator) + .collect(Collectors.toList())) { + cl.getExhaustiveConstructors().stream().sorted(MethodInfo.comparator).forEach(method -> { + writeMethodDexApi(mappingWriter, cl, method); + writeSourcePositionInfo(mappingWriter, method); + }); + cl.getExhaustiveMethods().stream().sorted(MethodInfo.comparator).forEach(method -> { + writeMethodDexApi(mappingWriter, cl, method); + writeSourcePositionInfo(mappingWriter, method); + }); + cl.getExhaustiveEnumConstants().stream().sorted(FieldInfo.comparator).forEach(enumInfo -> { + writeFieldDexApi(mappingWriter, cl, enumInfo); + writeSourcePositionInfo(mappingWriter, enumInfo); + }); + cl.getExhaustiveFields().stream().sorted(FieldInfo.comparator).forEach(field -> { + writeFieldDexApi(mappingWriter, cl, field); + writeSourcePositionInfo(mappingWriter, field); + }); + } + } + } + /** * Write the removed members of the class to removed.txt */ @@ -1765,6 +1811,11 @@ public class Stubs { apiWriter.print(";\n"); } + static void writeSourcePositionInfo(PrintStream writer, DocInfo docInfo) { + SourcePositionInfo pos = docInfo.position(); + writer.println(pos); + } + static void writeMethodDexApi(PrintStream apiWriter, ClassInfo cl, MethodInfo mi) { apiWriter.print(toSlashFormat(cl.qualifiedName())); apiWriter.print("->"); |