summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMathew Inwood <mathewi@google.com>2018-06-22 15:29:41 +0100
committerMathew Inwood <mathewi@google.com>2018-07-02 13:01:55 +0100
commit998f4e56f474d5355368b4485509cd97ecf6b0a4 (patch)
tree4e158b18fd568e06a328eef8e66ad75a21f56ad5 /src
parent0a8ebf780198fef6cab55589652e20c3be20f0ec (diff)
downloaddoclava-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.java12
-rw-r--r--src/com/google/doclava/Stubs.java57
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("->");