aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelisa CZ <melisacz@google.com>2024-05-13 14:46:22 +0000
committerMelisa CZ <melisacz@google.com>2024-05-13 15:52:34 +0000
commitacc63236ae9d85530467d2175cae4d3ca0f0b9b5 (patch)
tree53f5b9e88d4f310c86870bd56ff055ef9289e847
parent7abe78fe73fb94c384f149016ae329586e39c28d (diff)
parent878d37fe960945e1b2eec430f1649d43910a4fd0 (diff)
downloadgoogle-smali-master.tar.gz
Upgrade google-smali to 3.0.7HEADmastermain
This project was upgraded with external_updater. Usage: tools/external_updater/updater.sh update external/google-smali For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md Test: TreeHugger Change-Id: I9150aa0e64f80c0f248e5c56e796058f45bf2298
-rw-r--r--METADATA6
-rw-r--r--baksmali/Android.bp7
-rw-r--r--baksmali/src/test/java/com/android/tools/smali/baksmali/InstructionMethodItemTest.java3
-rw-r--r--baksmali/src/test/java/com/android/tools/smali/baksmali/formatter/BaksmaliWriterTest.java12
-rw-r--r--build.gradle2
-rw-r--r--dexlib2/Android.bp23
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/DexFileFactory.java3
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/MethodHandleType.java25
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcode.java34
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcodes.java10
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/AnalyzedInstruction.java16
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ArrayProto.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPath.java36
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPathResolver.java33
-rwxr-xr-xdexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassProto.java109
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/CustomInlineMethodResolver.java7
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/DexClassProvider.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/InlineMethodResolver.java9
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/MethodAnalyzer.java19
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/PathEntryLoader.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionClassDef.java90
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionConstructor.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionField.java6
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionMethod.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/util/ReflectionUtils.java46
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/util/LruCache.java400
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/util/MemoizingSupplier.java72
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/BuilderTryBlock.java5
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/LocatedItems.java5
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/MutableMethodImplementation.java43
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderArrayPayload.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderPackedSwitchPayload.java9
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderSparseSwitchPayload.java12
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/DexBackedMethod.java2
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/OatFile.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/instruction/DexBackedArrayPayload.java2
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotation.java10
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotationElement.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableClassDef.java99
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableDexFile.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableExceptionHandler.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableField.java40
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethod.java36
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodImplementation.java19
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodParameter.java16
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMultiDexContainer.java18
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableTryBlock.java16
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/README.md4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/debug/ImmutableDebugItem.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableArrayPayload.java23
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableInstruction.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutablePackedSwitchPayload.java10
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSparseSwitchPayload.java10
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSwitchElement.java3
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableCallSiteReference.java5
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodProtoReference.java5
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodReference.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableTypeReference.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/util/CharSequenceConverter.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableAnnotationEncodedValue.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableArrayEncodedValue.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableEncodedValueFactory.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/CallSiteReferenceRewriter.java15
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/ClassDefRewriter.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/MethodReferenceRewriter.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterUtils.java9
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/AnnotatedBytes.java12
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/FieldUtil.java6
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/MethodUtil.java6
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/SyntheticAccessorResolver.java19
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/DebugInfoCache.java30
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/DexWriter.java101
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/EncodedValueWriter.java9
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/InstructionWriter.java12
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationPool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSet.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSetPool.java18
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSitePool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSiteReference.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassDef.java43
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassPool.java39
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderEncodedArrayPool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderFieldPool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodHandlePool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodPool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderProtoPool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderStringPool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeList.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeListPool.java18
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypePool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/DexBuilder.java67
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/FileDeferredOutputStream.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/MemoryDeferredOutputStream.java5
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/BasePool.java5
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/ClassPool.java28
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolClassDef.java53
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolMethod.java3
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/TypeListPool.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/CallSiteUtil.java4
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/StaticInitializerUtil.java13
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/TryListBuilder.java9
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/AbstractIterator.java108
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/ArraySortedSet.java35
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/ChainedIterator.java8
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/CharSequenceUtils.java18
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/CollectionUtils.java17
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/ImmutableConverter.java85
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/ImmutableUtils.java28
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/InputStreamUtil.java27
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/IteratorUtils.java72
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/Range.java297
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/StringUtils.java76
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/TransformedIterator.java16
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/UnmodifiableRangeMap.java205
-rw-r--r--dexlib2/src/main/java/com/android/tools/smali/util/WrappedIndentingWriter.java5
-rw-r--r--dexlib2/src/test/java/com/android/tools/smali/dexlib2/util/RangeTest.java499
-rw-r--r--dexlib2/src/test/java/com/android/tools/smali/dexlib2/util/UnmodifiableRangeMapTest.java166
-rw-r--r--dexlib2/src/test/java/com/android/tools/smali/util/ArraySortedSetTest.java179
-rw-r--r--smali/Android.bp3
119 files changed, 3004 insertions, 900 deletions
diff --git a/METADATA b/METADATA
index 2d0a8a92..d3c83fc7 100644
--- a/METADATA
+++ b/METADATA
@@ -8,12 +8,12 @@ third_party {
license_type: NOTICE
last_upgrade_date {
year: 2024
- month: 2
- day: 7
+ month: 5
+ day: 13
}
identifier {
type: "Git"
value: "https://github.com/google/smali"
- version: "3.0.4"
+ version: "3.0.7"
}
}
diff --git a/baksmali/Android.bp b/baksmali/Android.bp
index 6fc3f7ea..347be56b 100644
--- a/baksmali/Android.bp
+++ b/baksmali/Android.bp
@@ -14,10 +14,10 @@
* limitations under the License.
*/
- // Create a new baksmali.properties file using the correct version
+// Create a new baksmali.properties file using the correct version
genrule {
name: "android-baksmali_version",
- defaults : ["android-smali_version_defaults"],
+ defaults: ["android-smali_version_defaults"],
out: ["android-baksmali.properties"],
}
@@ -35,6 +35,7 @@ java_binary_host {
manifest: "manifest.txt",
static_libs: [
+ "guava",
"smali-dexlib2",
"android-smali-util",
"jcommander",
@@ -43,4 +44,4 @@ java_binary_host {
java_resources: [":android-baksmali_version"],
wrapper: ":android-baksmali_script",
-} \ No newline at end of file
+}
diff --git a/baksmali/src/test/java/com/android/tools/smali/baksmali/InstructionMethodItemTest.java b/baksmali/src/test/java/com/android/tools/smali/baksmali/InstructionMethodItemTest.java
index 492b3c7c..10ffccf6 100644
--- a/baksmali/src/test/java/com/android/tools/smali/baksmali/InstructionMethodItemTest.java
+++ b/baksmali/src/test/java/com/android/tools/smali/baksmali/InstructionMethodItemTest.java
@@ -151,7 +151,8 @@ public class InstructionMethodItemTest {
BaksmaliWriter writer = new BaksmaliWriter(stringWriter);
methodItem.writeTo(writer);
- Assert.assertEquals("#Invalid reference\n#const-string v0, blahblahblah\nnop", stringWriter.toString());
+ Assert.assertEquals("#Invalid reference" + System.lineSeparator()
+ + "#const-string v0, blahblahblah" + System.lineSeparator() + "nop", stringWriter.toString());
}
private static class TestMethod extends BaseMethodReference implements Method {
diff --git a/baksmali/src/test/java/com/android/tools/smali/baksmali/formatter/BaksmaliWriterTest.java b/baksmali/src/test/java/com/android/tools/smali/baksmali/formatter/BaksmaliWriterTest.java
index be621620..963c8e80 100644
--- a/baksmali/src/test/java/com/android/tools/smali/baksmali/formatter/BaksmaliWriterTest.java
+++ b/baksmali/src/test/java/com/android/tools/smali/baksmali/formatter/BaksmaliWriterTest.java
@@ -179,10 +179,10 @@ public class BaksmaliWriterTest {
)));
Assert.assertEquals(
- ".subannotation Lannotation/`type with spaces`;\n" +
- " `element with spaces 1` = Ldefining/class/`with spaces`;->`fieldName with spaces`:Lfield/`type with spaces`;\n" +
+ ".subannotation Lannotation/`type with spaces`;" + System.lineSeparator() +
+ " `element with spaces 1` = Ldefining/class/`with spaces`;->`fieldName with spaces`:Lfield/`type with spaces`;" + System.lineSeparator() +
" `element with spaces 2` = Ldefining/class/`with spaces`;->`methodName with spaces`(" +
- "L`param with spaces 1`;L`param with spaces 2`;)Lreturn/type/`with spaces`;\n" +
+ "L`param with spaces 1`;L`param with spaces 2`;)Lreturn/type/`with spaces`;" + System.lineSeparator() +
".end subannotation",
output.toString());
}
@@ -196,9 +196,9 @@ public class BaksmaliWriterTest {
new ImmutableMethodEncodedValue(getMethodReferenceWithSpaces()))));
Assert.assertEquals(
- "{\n" +
- " Ldefining/class/`with spaces`;->`fieldName with spaces`:Lfield/`type with spaces`;,\n" +
- " Ldefining/class/`with spaces`;->`methodName with spaces`(L`param with spaces 1`;L`param with spaces 2`;)Lreturn/type/`with spaces`;\n" +
+ "{" + System.lineSeparator() +
+ " Ldefining/class/`with spaces`;->`fieldName with spaces`:Lfield/`type with spaces`;," + System.lineSeparator() +
+ " Ldefining/class/`with spaces`;->`methodName with spaces`(L`param with spaces 1`;L`param with spaces 2`;)Lreturn/type/`with spaces`;" + System.lineSeparator() +
"}",
output.toString());
}
diff --git a/build.gradle b/build.gradle
index ecc1f848..148abf70 100644
--- a/build.gradle
+++ b/build.gradle
@@ -30,7 +30,7 @@
apply plugin: 'idea'
-version = '3.0.4'
+version = '3.0.7'
def jcommanderVersion = ''
if (!('release' in gradle.startParameter.taskNames)) {
diff --git a/dexlib2/Android.bp b/dexlib2/Android.bp
index 1e9d6e42..0c69645b 100644
--- a/dexlib2/Android.bp
+++ b/dexlib2/Android.bp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
- java_library_host {
+java_library_host {
name: "smali-dexlib2",
srcs: [
@@ -23,9 +23,7 @@
],
static_libs: [
- "guava",
"jsr305",
- "auto_android_annotation_stubs",
],
errorprone: {
@@ -43,13 +41,8 @@ java_library_host {
":third_party-smali-dexlib2",
],
- libs: [
- "guava",
- ],
-
static_libs: [
"jsr305",
- "auto_android_annotation_stubs",
],
errorprone: {
@@ -59,7 +52,6 @@ java_library_host {
},
}
-
java_library {
name: "smali-dexlib2-device",
@@ -68,19 +60,12 @@ java_library {
":third_party-smali-dexlib2",
],
- libs: [
- "guava",
- ],
-
static_libs: [
"jsr305",
],
sdk_version: "system_server_current",
min_sdk_version: "33",
- apex_available: [
- "com.android.adservices"
- ],
optimize: {
enabled: true,
@@ -92,4 +77,8 @@ java_library {
"-Xep:ComparableType:WARN",
],
},
-} \ No newline at end of file
+
+ apex_available: [
+ "//apex_available:anyapex",
+ ],
+}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/DexFileFactory.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/DexFileFactory.java
index c464c474..eb5675a1 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/DexFileFactory.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/DexFileFactory.java
@@ -55,6 +55,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Collections;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -460,7 +461,7 @@ public final class DexFileFactory {
}
@Nonnull @Override public List<String> getDexEntryNames() {
- return unmodifiableList(List.of(entryName));
+ return Collections.singletonList(entryName);
}
@Nullable @Override public DexEntry<DexBackedDexFile> getEntry(@Nonnull String entryName) {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/MethodHandleType.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/MethodHandleType.java
index 6ba1726b..c0003dec 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/MethodHandleType.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/MethodHandleType.java
@@ -50,16 +50,21 @@ public class MethodHandleType {
public static final int INVOKE_DIRECT = 7;
public static final int INVOKE_INTERFACE = 8;
- private static final Map<Integer, String> methodHandleTypeNames = unmodifiableMap(Map.of(
- STATIC_PUT, "static-put",
- STATIC_GET, "static-get",
- INSTANCE_PUT, "instance-put",
- INSTANCE_GET, "instance-get",
- INVOKE_STATIC, "invoke-static",
- INVOKE_INSTANCE, "invoke-instance",
- INVOKE_CONSTRUCTOR, "invoke-constructor",
- INVOKE_DIRECT, "invoke-direct",
- INVOKE_INTERFACE, "invoke-interface"));
+ private static final Map<Integer, String> methodHandleTypeNames;
+
+ static {
+ Map<Integer, String> temp = new HashMap<>();
+ temp.put(STATIC_PUT, "static-put");
+ temp.put(STATIC_GET, "static-get");
+ temp.put(INSTANCE_PUT, "instance-put");
+ temp.put(INSTANCE_GET, "instance-get");
+ temp.put(INVOKE_STATIC, "invoke-static");
+ temp.put(INVOKE_INSTANCE, "invoke-instance");
+ temp.put(INVOKE_CONSTRUCTOR, "invoke-constructor");
+ temp.put(INVOKE_DIRECT, "invoke-direct");
+ temp.put(INVOKE_INTERFACE, "invoke-interface");
+ methodHandleTypeNames = unmodifiableMap(temp);
+ }
private static final Map<String, Integer> inverse = getInverse();
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcode.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcode.java
index d0ca08d7..bd8dc5f2 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcode.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcode.java
@@ -30,12 +30,12 @@
package com.android.tools.smali.dexlib2;
-import com.google.common.collect.ImmutableRangeMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Range;
-import com.google.common.collect.RangeMap;
+import com.android.tools.smali.util.UnmodifiableRangeMap;
+import com.android.tools.smali.util.Range;
import javax.annotation.Nonnull;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
public enum Opcode
@@ -348,8 +348,8 @@ public enum Opcode
// values and minApis provide a mapping of api -> bytecode value.
// the apis in minApis are guaranteed to be
- public final RangeMap<Integer, Short> apiToValueMap;
- public final RangeMap<Integer, Short> artVersionToValueMap;
+ public final UnmodifiableRangeMap<Integer, Short> apiToValueMap;
+ public final UnmodifiableRangeMap<Integer, Short> artVersionToValueMap;
public final String name;
public final int referenceType;
@@ -371,8 +371,8 @@ public enum Opcode
Opcode(List<VersionConstraint> versionConstraints, String opcodeName, int referenceType, int referenceType2,
Format format, int flags) {
- ImmutableRangeMap.Builder<Integer, Short> apiToValueBuilder = ImmutableRangeMap.builder();
- ImmutableRangeMap.Builder<Integer, Short> artVersionToValueBuilder = ImmutableRangeMap.builder();
+ UnmodifiableRangeMap.Builder<Integer, Short> apiToValueBuilder = UnmodifiableRangeMap.builder();
+ UnmodifiableRangeMap.Builder<Integer, Short> artVersionToValueBuilder = UnmodifiableRangeMap.builder();
for (VersionConstraint versionConstraint : versionConstraints) {
if (!versionConstraint.apiRange.isEmpty()) {
@@ -393,41 +393,41 @@ public enum Opcode
}
private static List<VersionConstraint> firstApi(int opcodeValue, int api) {
- return Lists.newArrayList(new VersionConstraint(Range.atLeast(api), Range.openClosed(0, 0), opcodeValue));
+ return Arrays.asList(new VersionConstraint(Range.atLeast(api), Range.openClosed(0, 0), opcodeValue));
}
private static List<VersionConstraint> lastApi(int opcodeValue, int api) {
- return Lists.newArrayList(new VersionConstraint(Range.atMost(api), Range.openClosed(0, 0), opcodeValue));
+ return Arrays.asList(new VersionConstraint(Range.atMost(api), Range.openClosed(0, 0), opcodeValue));
}
private static List<VersionConstraint> betweenApi(int opcodeValue, int minApi, int maxApi) {
- return Lists.newArrayList(new VersionConstraint(Range.closed(minApi, maxApi), Range.openClosed(0, 0),
+ return Arrays.asList(new VersionConstraint(Range.closed(minApi, maxApi), Range.openClosed(0, 0),
opcodeValue));
}
private static List<VersionConstraint> firstArtVersion(int opcodeValue, int artVersion) {
- return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.atLeast(artVersion), opcodeValue));
+ return Arrays.asList(new VersionConstraint(Range.openClosed(0, 0), Range.atLeast(artVersion), opcodeValue));
}
private static List<VersionConstraint> lastArtVersion(int opcodeValue, int artVersion) {
- return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.atMost(artVersion), opcodeValue));
+ return Arrays.asList(new VersionConstraint(Range.openClosed(0, 0), Range.atMost(artVersion), opcodeValue));
}
private static List<VersionConstraint> allVersions(int opcodeValue) {
- return Lists.newArrayList(new VersionConstraint(Range.<Integer>all(), Range.<Integer>all(), opcodeValue));
+ return Arrays.asList(new VersionConstraint(Range.allValues(), Range.allValues(), opcodeValue));
}
private static List<VersionConstraint> allApis(int opcodeValue) {
- return Lists.newArrayList(new VersionConstraint(Range.<Integer>all(), Range.openClosed(0, 0), opcodeValue));
+ return Arrays.asList(new VersionConstraint(Range.allValues(), Range.openClosed(0, 0), opcodeValue));
}
private static List<VersionConstraint> allArtVersions(int opcodeValue) {
- return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.<Integer>all(), opcodeValue));
+ return Arrays.asList(new VersionConstraint(Range.openClosed(0, 0), Range.allValues(), opcodeValue));
}
@SuppressWarnings("unchecked")
private static List<VersionConstraint> combine(List<VersionConstraint>... versionConstraints) {
- List<VersionConstraint> combinedList = Lists.newArrayList();
+ List<VersionConstraint> combinedList = new ArrayList<>();
for (List<VersionConstraint> versionConstraintList: versionConstraints) {
combinedList.addAll(versionConstraintList);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcodes.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcodes.java
index 176c5175..4c5b597e 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcodes.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/Opcodes.java
@@ -30,16 +30,16 @@
package com.android.tools.smali.dexlib2;
-import com.google.common.collect.RangeMap;
+import static com.android.tools.smali.dexlib2.VersionMap.NO_VERSION;
+import static com.android.tools.smali.dexlib2.VersionMap.mapApiToArtVersion;
+import static com.android.tools.smali.dexlib2.VersionMap.mapArtVersionToApi;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.EnumMap;
import java.util.HashMap;
-import static com.android.tools.smali.dexlib2.VersionMap.NO_VERSION;
-import static com.android.tools.smali.dexlib2.VersionMap.mapApiToArtVersion;
-import static com.android.tools.smali.dexlib2.VersionMap.mapArtVersionToApi;
+import com.android.tools.smali.util.UnmodifiableRangeMap;
public class Opcodes {
@@ -103,7 +103,7 @@ public class Opcodes {
}
for (Opcode opcode: Opcode.values()) {
- RangeMap<Integer, Short> versionToValueMap;
+ UnmodifiableRangeMap<Integer, Short> versionToValueMap;
if (isArt()) {
versionToValueMap = opcode.artVersionToValueMap;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/AnalyzedInstruction.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/AnalyzedInstruction.java
index b67fee76..adc18485 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/AnalyzedInstruction.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/AnalyzedInstruction.java
@@ -42,15 +42,15 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
import com.android.tools.smali.dexlib2.iface.reference.Reference;
import com.android.tools.smali.dexlib2.iface.reference.TypeReference;
import com.android.tools.smali.util.ExceptionWithContext;
-import com.google.common.base.Objects;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.annotation.Nonnull;
@@ -301,7 +301,7 @@ public class AnalyzedInstruction implements Comparable<AnalyzedInstruction> {
protected boolean overridePredecessorRegisterType(@Nonnull AnalyzedInstruction predecessor, int registerNumber,
@Nonnull RegisterType registerType, BitSet verifiedInstructions) {
if (predecessorRegisterOverrides == null) {
- predecessorRegisterOverrides = Maps.newHashMap();
+ predecessorRegisterOverrides = new HashMap<>();
}
predecessorRegisterOverrides.put(new PredecessorOverrideKey(predecessor, registerNumber), registerType);
@@ -482,7 +482,7 @@ public class AnalyzedInstruction implements Comparable<AnalyzedInstruction> {
}
public List<Integer> getSetRegisters() {
- List<Integer> setRegisters = Lists.newArrayList();
+ List<Integer> setRegisters = new ArrayList<>();
if (instruction.getOpcode().setsRegister()) {
setRegisters.add(getDestinationRegister());
@@ -667,12 +667,12 @@ public class AnalyzedInstruction implements Comparable<AnalyzedInstruction> {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PredecessorOverrideKey that = (PredecessorOverrideKey)o;
- return com.google.common.base.Objects.equal(registerNumber, that.registerNumber) &&
- Objects.equal(analyzedInstruction, that.analyzedInstruction);
+ return Objects.equals(registerNumber, that.registerNumber) &&
+ Objects.equals(analyzedInstruction, that.analyzedInstruction);
}
@Override public int hashCode() {
- return Objects.hashCode(analyzedInstruction, registerNumber);
+ return Objects.hash(analyzedInstruction, registerNumber);
}
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ArrayProto.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ArrayProto.java
index 740dbc8c..699b4237 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ArrayProto.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ArrayProto.java
@@ -36,7 +36,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableFieldReference;
import com.android.tools.smali.dexlib2.util.TypeUtils;
import com.android.tools.smali.util.ExceptionWithContext;
-import com.google.common.base.Strings;
+import com.android.tools.smali.util.StringUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -141,7 +141,7 @@ public class ArrayProto implements TypeProto {
return other.getCommonSuperclass(this);
}
- private static final String BRACKETS = Strings.repeat("[", 256);
+ private static final String BRACKETS = StringUtils.repeat("[", 256);
@Nonnull
private static String makeArrayType(@Nonnull String elementType, int dimensions) {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPath.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPath.java
index 1b6f0a00..e2aadc64 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPath.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPath.java
@@ -32,21 +32,20 @@ package com.android.tools.smali.dexlib2.analysis;
import com.android.tools.smali.dexlib2.Opcodes;
import com.android.tools.smali.dexlib2.analysis.reflection.ReflectionClassDef;
+import com.android.tools.smali.dexlib2.analysis.util.LruCache;
+import com.android.tools.smali.dexlib2.analysis.util.MemoizingSupplier;
import com.android.tools.smali.dexlib2.iface.ClassDef;
import com.android.tools.smali.dexlib2.immutable.ImmutableDexFile;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
+import com.android.tools.smali.util.IteratorUtils;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.function.Supplier;
public class ClassPath {
@Nonnull private final TypeProto unknownClass;
@@ -104,7 +103,7 @@ public class ClassPath {
loadPrimitiveType("D");
loadPrimitiveType("L");
- this.classProviders = Lists.newArrayList(classProviders);
+ this.classProviders = (List<ClassProvider>)IteratorUtils.toList(classProviders);
this.classProviders.add(getBasicClasses());
}
@@ -114,13 +113,14 @@ public class ClassPath {
private static ClassProvider getBasicClasses() {
// fallbacks for some special classes that we assume are present
- return new DexClassProvider(new ImmutableDexFile(Opcodes.getDefault(), ImmutableSet.of(
+ return new DexClassProvider(new ImmutableDexFile(Opcodes.getDefault(),
+ Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
new ReflectionClassDef(Class.class),
new ReflectionClassDef(Cloneable.class),
new ReflectionClassDef(Object.class),
new ReflectionClassDef(Serializable.class),
new ReflectionClassDef(String.class),
- new ReflectionClassDef(Throwable.class))));
+ new ReflectionClassDef(Throwable.class))))));
}
public boolean isArt() {
@@ -129,21 +129,19 @@ public class ClassPath {
@Nonnull
public TypeProto getClass(@Nonnull CharSequence type) {
- return loadedClasses.getUnchecked(type.toString());
+ return loadedClasses.get(type.toString());
}
- private final CacheLoader<String, TypeProto> classLoader = new CacheLoader<String, TypeProto>() {
- @Override public TypeProto load(String type) throws Exception {
- if (type.charAt(0) == '[') {
- return new ArrayProto(ClassPath.this, type);
+ @Nonnull private LruCache<String, TypeProto> loadedClasses = new LruCache<String, TypeProto>(30000) {
+ @Override protected TypeProto create(String key) {
+ if (key.charAt(0) == '[') {
+ return new ArrayProto(ClassPath.this, key);
} else {
- return new ClassProto(ClassPath.this, type);
+ return new ClassProto(ClassPath.this, key);
}
}
};
- @Nonnull private LoadingCache<String, TypeProto> loadedClasses = CacheBuilder.newBuilder().build(classLoader);
-
@Nonnull
public ClassDef getClassDef(String type) {
for (ClassProvider provider: classProviders) {
@@ -164,7 +162,7 @@ public class ClassPath {
return checkPackagePrivateAccess;
}
- private final Supplier<OdexedFieldInstructionMapper> fieldInstructionMapperSupplier = Suppliers.memoize(
+ private final Supplier<OdexedFieldInstructionMapper> fieldInstructionMapperSupplier = MemoizingSupplier.memoize(
new Supplier<OdexedFieldInstructionMapper>() {
@Override public OdexedFieldInstructionMapper get() {
return new OdexedFieldInstructionMapper(isArt());
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPathResolver.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPathResolver.java
index e5d92dad..6057b144 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPathResolver.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassPathResolver.java
@@ -36,14 +36,13 @@ import com.android.tools.smali.dexlib2.dexbacked.OatFile;
import com.android.tools.smali.dexlib2.iface.DexFile;
import com.android.tools.smali.dexlib2.iface.MultiDexContainer;
import com.android.tools.smali.dexlib2.iface.MultiDexContainer.DexEntry;
-import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Lists;
+import com.android.tools.smali.util.StringUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
+import java.util.Arrays;
import java.util.List;
public class ClassPathResolver {
@@ -182,7 +181,6 @@ public class ClassPathResolver {
// It's not a local path, so let's try to resolve it as a device path, relative to one of the provided
// directories
List<String> pathComponents = splitDevicePath(entry);
- Joiner pathJoiner = Joiner.on(File.separatorChar);
for (String directory: classPathDirs) {
File directoryFile = new File(directory);
@@ -191,7 +189,8 @@ public class ClassPathResolver {
}
for (int i=0; i<pathComponents.size(); i++) {
- String partialPath = pathJoiner.join(pathComponents.subList(i, pathComponents.size()));
+ String partialPath = StringUtils.join(
+ pathComponents.subList(i, pathComponents.size()), File.separator);
File entryFile = new File(directoryFile, partialPath);
if (entryFile.exists() && entryFile.isFile()) {
pathEntryLoader.loadEntry(entryFile, true);
@@ -205,7 +204,7 @@ public class ClassPathResolver {
@Nonnull
private static List<String> splitDevicePath(@Nonnull String path) {
- return Lists.newArrayList(Splitter.on('/').split(path));
+ return Arrays.asList(path.split("/"));
}
static class NotFoundException extends Exception {
@@ -250,14 +249,14 @@ public class ClassPathResolver {
}
if (apiLevel <= 8) {
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core.jar",
"/system/framework/ext.jar",
"/system/framework/framework.jar",
"/system/framework/android.policy.jar",
"/system/framework/services.jar");
} else if (apiLevel <= 11) {
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core.jar",
"/system/framework/bouncycastle.jar",
"/system/framework/ext.jar",
@@ -266,7 +265,7 @@ public class ClassPathResolver {
"/system/framework/services.jar",
"/system/framework/core-junit.jar");
} else if (apiLevel <= 13) {
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core.jar",
"/system/framework/apache-xml.jar",
"/system/framework/bouncycastle.jar",
@@ -276,7 +275,7 @@ public class ClassPathResolver {
"/system/framework/services.jar",
"/system/framework/core-junit.jar");
} else if (apiLevel <= 15) {
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core.jar",
"/system/framework/core-junit.jar",
"/system/framework/bouncycastle.jar",
@@ -288,7 +287,7 @@ public class ClassPathResolver {
"/system/framework/filterfw.jar");
} else if (apiLevel <= 17) {
// this is correct as of api 17/4.2.2
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core.jar",
"/system/framework/core-junit.jar",
"/system/framework/bouncycastle.jar",
@@ -300,7 +299,7 @@ public class ClassPathResolver {
"/system/framework/services.jar",
"/system/framework/apache-xml.jar");
} else if (apiLevel <= 18) {
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core.jar",
"/system/framework/core-junit.jar",
"/system/framework/bouncycastle.jar",
@@ -313,7 +312,7 @@ public class ClassPathResolver {
"/system/framework/services.jar",
"/system/framework/apache-xml.jar");
} else if (apiLevel <= 19) {
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core.jar",
"/system/framework/conscrypt.jar",
"/system/framework/core-junit.jar",
@@ -329,7 +328,7 @@ public class ClassPathResolver {
"/system/framework/apache-xml.jar",
"/system/framework/webviewchromium.jar");
} else if (apiLevel <= 22) {
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core-libart.jar",
"/system/framework/conscrypt.jar",
"/system/framework/okhttp.jar",
@@ -344,7 +343,7 @@ public class ClassPathResolver {
"/system/framework/android.policy.jar",
"/system/framework/apache-xml.jar");
} else if (apiLevel <= 23) {
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core-libart.jar",
"/system/framework/conscrypt.jar",
"/system/framework/okhttp.jar",
@@ -358,7 +357,7 @@ public class ClassPathResolver {
"/system/framework/apache-xml.jar",
"/system/framework/org.apache.http.legacy.boot.jar");
} else /*if (apiLevel <= 24)*/ {
- return Lists.newArrayList(
+ return Arrays.asList(
"/system/framework/core-oj.jar",
"/system/framework/core-libart.jar",
"/system/framework/conscrypt.jar",
@@ -378,7 +377,7 @@ public class ClassPathResolver {
private static List<String> bootClassPathForOat(@Nonnull OatFile oatFile) {
List<String> bcp = oatFile.getBootClassPath();
if(bcp.isEmpty()) {
- return Lists.newArrayList("boot.oat");
+ return Arrays.asList("boot.oat");
} else {
return replaceElementsSuffix(bcp, ".art", ".oat");
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassProto.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassProto.java
index 34743ec8..368eda95 100755
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassProto.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/ClassProto.java
@@ -32,6 +32,7 @@ package com.android.tools.smali.dexlib2.analysis;
import com.android.tools.smali.dexlib2.AccessFlags;
import com.android.tools.smali.dexlib2.HiddenApiRestriction;
+import com.android.tools.smali.dexlib2.analysis.util.MemoizingSupplier;
import com.android.tools.smali.dexlib2.analysis.util.TypeProtoUtils;
import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference;
import com.android.tools.smali.dexlib2.iface.Annotation;
@@ -45,17 +46,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
import com.android.tools.smali.dexlib2.util.AlignmentUtils;
import com.android.tools.smali.dexlib2.util.MethodUtil;
import com.android.tools.smali.util.ExceptionWithContext;
+import com.android.tools.smali.util.IteratorUtils;
import com.android.tools.smali.util.SparseArray;
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.primitives.Ints;
+import com.android.tools.smali.util.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
@@ -66,9 +59,11 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;
+import java.util.function.Supplier;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map.Entry;
+import java.util.function.Predicate;
/**
* A class "prototype". This contains things like the interfaces, the superclass, the vtable and the instance fields
@@ -105,7 +100,7 @@ public class ClassProto implements TypeProto {
}
- @Nonnull private final Supplier<ClassDef> classDefSupplier = Suppliers.memoize(new Supplier<ClassDef>() {
+ @Nonnull private final Supplier<ClassDef> classDefSupplier = MemoizingSupplier.memoize(new Supplier<ClassDef>() {
@Override public ClassDef get() {
return classPath.getClassDef(type);
}
@@ -151,10 +146,10 @@ public class ClassProto implements TypeProto {
*/
@Nonnull
private final Supplier<LinkedHashMap<String, ClassDef>> preDefaultMethodInterfaceSupplier =
- Suppliers.memoize(new Supplier<LinkedHashMap<String, ClassDef>>() {
+ MemoizingSupplier.memoize(new Supplier<LinkedHashMap<String, ClassDef>>() {
@Override public LinkedHashMap<String, ClassDef> get() {
Set<String> unresolvedInterfaces = new HashSet<>(0);
- LinkedHashMap<String, ClassDef> interfaces = Maps.newLinkedHashMap();
+ LinkedHashMap<String, ClassDef> interfaces = new LinkedHashMap<>();
try {
for (String interfaceType: getClassDef().getInterfaces()) {
@@ -227,10 +222,10 @@ public class ClassProto implements TypeProto {
*/
@Nonnull
private final Supplier<LinkedHashMap<String, ClassDef>> postDefaultMethodInterfaceSupplier =
- Suppliers.memoize(new Supplier<LinkedHashMap<String, ClassDef>>() {
+ MemoizingSupplier.memoize(new Supplier<LinkedHashMap<String, ClassDef>>() {
@Override public LinkedHashMap<String, ClassDef> get() {
Set<String> unresolvedInterfaces = new HashSet<String>(0);
- LinkedHashMap<String, ClassDef> interfaces = Maps.newLinkedHashMap();
+ LinkedHashMap<String, ClassDef> interfaces = new LinkedHashMap<>();
String superclass = getSuperclass();
if (superclass != null) {
@@ -290,7 +285,7 @@ public class ClassProto implements TypeProto {
@Nonnull
protected Set<String> getUnresolvedInterfaces() {
if (unresolvedInterfaces == null) {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
return unresolvedInterfaces;
}
@@ -305,12 +300,15 @@ public class ClassProto implements TypeProto {
*/
@Nonnull
protected Iterable<ClassDef> getDirectInterfaces() {
- Iterable<ClassDef> directInterfaces =
- FluentIterable.from(getInterfaces().values()).filter(Predicates.notNull());
+ Iterable<ClassDef> directInterfaces = IteratorUtils.filter(getInterfaces().values(), new Predicate<ClassDef>() {
+ @Override public boolean test(@Nullable ClassDef input) {
+ return input != null;
+ }
+ });
if (!interfacesFullyResolved) {
throw new UnresolvedClassException("Interfaces for class %s not fully resolved: %s", getType(),
- Joiner.on(',').join(getUnresolvedInterfaces()));
+ StringUtils.join(getUnresolvedInterfaces(), ","));
}
return directInterfaces;
@@ -428,15 +426,17 @@ public class ClassProto implements TypeProto {
return classPath.getUnknownClass();
}
- List<TypeProto> thisChain = Lists.<TypeProto>newArrayList(this);
- Iterables.addAll(thisChain, TypeProtoUtils.getSuperclassChain(this));
+ List<TypeProto> thisChain = new ArrayList<>();
+ thisChain.add(this);
+ IteratorUtils.addAll(thisChain, TypeProtoUtils.getSuperclassChain(this).iterator());
- List<TypeProto> otherChain = Lists.newArrayList(other);
- Iterables.addAll(otherChain, TypeProtoUtils.getSuperclassChain(other));
+ List<TypeProto> otherChain = new ArrayList<>();
+ otherChain.add(other);
+ IteratorUtils.addAll(otherChain, TypeProtoUtils.getSuperclassChain(other).iterator());
// reverse them, so that the first entry is either Ljava/lang/Object; or Ujava/lang/Object;
- thisChain = Lists.reverse(thisChain);
- otherChain = Lists.reverse(otherChain);
+ Collections.reverse(thisChain);
+ Collections.reverse(otherChain);
for (int i=Math.min(thisChain.size(), otherChain.size())-1; i>=0; i--) {
TypeProto typeProto = thisChain.get(i);
@@ -507,7 +507,7 @@ public class ClassProto implements TypeProto {
}
@Nonnull private final Supplier<SparseArray<FieldReference>> dalvikInstanceFieldsSupplier =
- Suppliers.memoize(new Supplier<SparseArray<FieldReference>>() {
+ MemoizingSupplier.memoize(new Supplier<SparseArray<FieldReference>>() {
@Override public SparseArray<FieldReference> get() {
//This is a bit of an "involved" operation. We need to follow the same algorithm that dalvik uses to
//arrange fields, so that we end up with the same field offsets (which is needed for deodexing).
@@ -654,7 +654,7 @@ public class ClassProto implements TypeProto {
@Nonnull
private ArrayList<Field> getSortedInstanceFields(@Nonnull ClassDef classDef) {
- ArrayList<Field> fields = Lists.newArrayList(classDef.getInstanceFields());
+ ArrayList<Field> fields = (ArrayList<Field>)IteratorUtils.toList(classDef.getInstanceFields());
Collections.sort(fields);
return fields;
}
@@ -677,21 +677,21 @@ public class ClassProto implements TypeProto {
if (oatVersion >= 67) {
return new FieldGap(offset, size) {
@Override public int compareTo(@Nonnull FieldGap o) {
- int result = Ints.compare(o.size, size);
+ int result = Integer.compare(o.size, size);
if (result != 0) {
return result;
}
- return Ints.compare(offset, o.offset);
+ return Integer.compare(offset, o.offset);
}
};
} else {
return new FieldGap(offset, size) {
@Override public int compareTo(@Nonnull FieldGap o) {
- int result = Ints.compare(size, o.size);
+ int result = Integer.compare(size, o.size);
if (result != 0) {
return result;
}
- return Ints.compare(o.offset, offset);
+ return Integer.compare(o.offset, offset);
}
};
}
@@ -704,7 +704,7 @@ public class ClassProto implements TypeProto {
}
@Nonnull private final Supplier<SparseArray<FieldReference>> artInstanceFieldsSupplier =
- Suppliers.memoize(new Supplier<SparseArray<FieldReference>>() {
+ MemoizingSupplier.memoize(new Supplier<SparseArray<FieldReference>>() {
@Override public SparseArray<FieldReference> get() {
// We need to follow the same algorithm that art uses to arrange fields, so that we end up with the
@@ -781,10 +781,10 @@ public class ClassProto implements TypeProto {
@Nonnull
private ArrayList<Field> getSortedInstanceFields(@Nonnull ClassDef classDef) {
- ArrayList<Field> fields = Lists.newArrayList(classDef.getInstanceFields());
+ ArrayList<Field> fields = (ArrayList<Field>)IteratorUtils.toList(classDef.getInstanceFields());
Collections.sort(fields, new Comparator<Field>() {
@Override public int compare(Field field1, Field field2) {
- int result = Ints.compare(getFieldSortOrder(field1), getFieldSortOrder(field2));
+ int result = Integer.compare(getFieldSortOrder(field1), getFieldSortOrder(field2));
if (result != 0) {
return result;
}
@@ -891,9 +891,9 @@ public class ClassProto implements TypeProto {
}
//TODO: check the case when we have a package private method that overrides an interface method
- @Nonnull private final Supplier<List<Method>> preDefaultMethodVtableSupplier = Suppliers.memoize(new Supplier<List<Method>>() {
+ @Nonnull private final Supplier<List<Method>> preDefaultMethodVtableSupplier = MemoizingSupplier.memoize(new Supplier<List<Method>>() {
@Override public List<Method> get() {
- List<Method> vtable = Lists.newArrayList();
+ List<Method> vtable = new ArrayList<>();
//copy the virtual methods from the superclass
String superclassType;
@@ -926,7 +926,7 @@ public class ClassProto implements TypeProto {
// we don't end up trying to call invoke-virtual using an interface, which will fail verification
Iterable<ClassDef> interfaces = getDirectInterfaces();
for (ClassDef interfaceDef: interfaces) {
- List<Method> interfaceMethods = Lists.newArrayList();
+ List<Method> interfaceMethods = new ArrayList<>();
for (Method interfaceMethod: interfaceDef.getVirtualMethods()) {
interfaceMethods.add(new ReparentedMethod(interfaceMethod, type));
}
@@ -942,9 +942,9 @@ public class ClassProto implements TypeProto {
* produce multiple vtable entries for a given virtual method. This supplier duplicates this buggy logic in order to
* generate an identical vtable
*/
- @Nonnull private final Supplier<List<Method>> buggyPostDefaultMethodVtableSupplier = Suppliers.memoize(new Supplier<List<Method>>() {
+ @Nonnull private final Supplier<List<Method>> buggyPostDefaultMethodVtableSupplier = MemoizingSupplier.memoize(new Supplier<List<Method>>() {
@Override public List<Method> get() {
- List<Method> vtable = Lists.newArrayList();
+ List<Method> vtable = new ArrayList<>();
//copy the virtual methods from the superclass
String superclassType;
@@ -973,13 +973,13 @@ public class ClassProto implements TypeProto {
if (!isInterface()) {
addToVtable(getClassDef().getVirtualMethods(), vtable, true, true);
- List<String> interfaces = Lists.newArrayList(getInterfaces().keySet());
+ List<String> interfaces = new ArrayList<>(getInterfaces().keySet());
- List<Method> defaultMethods = Lists.newArrayList();
- List<Method> defaultConflictMethods = Lists.newArrayList();
- List<Method> mirandaMethods = Lists.newArrayList();
+ List<Method> defaultMethods = new ArrayList<>();
+ List<Method> defaultConflictMethods = new ArrayList<>();
+ List<Method> mirandaMethods = new ArrayList<>();
- final HashMap<MethodReference, Integer> methodOrder = Maps.newHashMap();
+ final HashMap<MethodReference, Integer> methodOrder = new HashMap<>();
for (int i=interfaces.size()-1; i>=0; i--) {
String interfaceType = interfaces.get(i);
@@ -1070,7 +1070,7 @@ public class ClassProto implements TypeProto {
Comparator<MethodReference> comparator = new Comparator<MethodReference>() {
@Override public int compare(MethodReference o1, MethodReference o2) {
- return Ints.compare(methodOrder.get(o1), methodOrder.get(o2));
+ return Integer.compare(methodOrder.get(o1), methodOrder.get(o2));
}
};
@@ -1089,9 +1089,9 @@ public class ClassProto implements TypeProto {
}
});
- @Nonnull private final Supplier<List<Method>> postDefaultMethodVtableSupplier = Suppliers.memoize(new Supplier<List<Method>>() {
+ @Nonnull private final Supplier<List<Method>> postDefaultMethodVtableSupplier = MemoizingSupplier.memoize(new Supplier<List<Method>>() {
@Override public List<Method> get() {
- List<Method> vtable = Lists.newArrayList();
+ List<Method> vtable = new ArrayList<>();
//copy the virtual methods from the superclass
String superclassType;
@@ -1120,13 +1120,14 @@ public class ClassProto implements TypeProto {
if (!isInterface()) {
addToVtable(getClassDef().getVirtualMethods(), vtable, true, true);
- Iterable<ClassDef> interfaces = Lists.reverse(Lists.newArrayList(getDirectInterfaces()));
+ List<ClassDef> interfaces = IteratorUtils.toList(getDirectInterfaces());
+ Collections.reverse(interfaces);
- List<Method> defaultMethods = Lists.newArrayList();
- List<Method> defaultConflictMethods = Lists.newArrayList();
- List<Method> mirandaMethods = Lists.newArrayList();
+ List<Method> defaultMethods = new ArrayList<>();
+ List<Method> defaultConflictMethods = new ArrayList<>();
+ List<Method> mirandaMethods = new ArrayList<>();
- final HashMap<MethodReference, Integer> methodOrder = Maps.newHashMap();
+ final HashMap<MethodReference, Integer> methodOrder = new HashMap<>();
for (ClassDef interfaceDef: interfaces) {
for (Method interfaceMethod : interfaceDef.getVirtualMethods()) {
@@ -1190,7 +1191,7 @@ public class ClassProto implements TypeProto {
Comparator<MethodReference> comparator = new Comparator<MethodReference>() {
@Override public int compare(MethodReference o1, MethodReference o2) {
- return Ints.compare(methodOrder.get(o1), methodOrder.get(o2));
+ return Integer.compare(methodOrder.get(o1), methodOrder.get(o2));
}
};
@@ -1211,7 +1212,7 @@ public class ClassProto implements TypeProto {
private void addToVtable(@Nonnull Iterable<? extends Method> localMethods, @Nonnull List<Method> vtable,
boolean replaceExisting, boolean sort) {
if (sort) {
- ArrayList<Method> methods = Lists.newArrayList(localMethods);
+ ArrayList<Method> methods = (ArrayList<Method>)IteratorUtils.toList(localMethods);
Collections.sort(methods);
localMethods = methods;
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/CustomInlineMethodResolver.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/CustomInlineMethodResolver.java
index 7c59c4b2..a78b092c 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/CustomInlineMethodResolver.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/CustomInlineMethodResolver.java
@@ -37,14 +37,14 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod;
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter;
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference;
import com.android.tools.smali.dexlib2.immutable.util.ParamUtil;
-import com.google.common.io.Files;
+import com.android.tools.smali.util.InputStreamUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
+import java.io.FileInputStream;
import java.io.StringReader;
import javax.annotation.Nonnull;
-import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@@ -85,7 +85,8 @@ public class CustomInlineMethodResolver extends InlineMethodResolver {
}
public CustomInlineMethodResolver(@Nonnull ClassPath classPath, @Nonnull File inlineTable) throws IOException {
- this(classPath, Files.asCharSource(inlineTable, StandardCharsets.UTF_8).read());
+ this(classPath, new String(
+ InputStreamUtil.toByteArray(new FileInputStream(inlineTable)), StandardCharsets.UTF_8));
}
@Override
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/DexClassProvider.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/DexClassProvider.java
index db9fb99c..f0eb027a 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/DexClassProvider.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/DexClassProvider.java
@@ -32,14 +32,14 @@ package com.android.tools.smali.dexlib2.analysis;
import com.android.tools.smali.dexlib2.iface.ClassDef;
import com.android.tools.smali.dexlib2.iface.DexFile;
-import com.google.common.collect.Maps;
import javax.annotation.Nullable;
+import java.util.HashMap;
import java.util.Map;
public class DexClassProvider implements ClassProvider {
private final DexFile dexFile;
- private Map<String, ClassDef> classMap = Maps.newHashMap();
+ private Map<String, ClassDef> classMap = new HashMap<>();
public DexClassProvider(DexFile dexFile) {
this.dexFile = dexFile;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/InlineMethodResolver.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/InlineMethodResolver.java
index 5e7322a2..fbf5bce1 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/InlineMethodResolver.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/InlineMethodResolver.java
@@ -30,15 +30,19 @@
package com.android.tools.smali.dexlib2.analysis;
+import static java.util.Collections.unmodifiableList;
+
import com.android.tools.smali.dexlib2.iface.Method;
import com.android.tools.smali.dexlib2.iface.instruction.InlineIndexInstruction;
import com.android.tools.smali.dexlib2.iface.instruction.VariableRegisterInstruction;
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod;
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter;
import com.android.tools.smali.dexlib2.immutable.util.ParamUtil;
-import com.google.common.collect.ImmutableList;
+import com.android.tools.smali.util.IteratorUtils;
import javax.annotation.Nonnull;
+import java.util.ArrayList;
+import java.util.List;
public abstract class InlineMethodResolver {
// These are the possible values for the accessFlag field on a resolved inline method
@@ -65,7 +69,8 @@ public abstract class InlineMethodResolver {
@Nonnull
private static Method inlineMethod(int accessFlags, @Nonnull String cls, @Nonnull String name,
@Nonnull String params, @Nonnull String returnType) {
- ImmutableList<ImmutableMethodParameter> paramList = ImmutableList.copyOf(ParamUtil.parseParamString(params));
+ List<ImmutableMethodParameter> paramList = unmodifiableList(
+ IteratorUtils.toList(ParamUtil.parseParamString(params)));
return new ImmutableMethod(cls, name, paramList, returnType, accessFlags, null, null, null);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/MethodAnalyzer.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/MethodAnalyzer.java
index b6174a26..3af6cb97 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/MethodAnalyzer.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/MethodAnalyzer.java
@@ -76,15 +76,15 @@ import com.android.tools.smali.dexlib2.util.TypeUtils;
import com.android.tools.smali.dexlib2.writer.util.TryListBuilder;
import com.android.tools.smali.util.BitSetUtils;
import com.android.tools.smali.util.ExceptionWithContext;
+import com.android.tools.smali.util.IteratorUtils;
import com.android.tools.smali.util.SparseArray;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.BitSet;
+import java.util.Collections;
import java.util.List;
+import java.util.stream.Collectors;
/**
* The MethodAnalyzer performs several functions. It "analyzes" the instructions and infers the register types
@@ -329,14 +329,8 @@ public class MethodAnalyzer {
}
public List<Instruction> getInstructions() {
- return Lists.transform(analyzedInstructions.getValues(), new Function<AnalyzedInstruction, Instruction>() {
- @Nullable @Override public Instruction apply(@Nullable AnalyzedInstruction input) {
- if (input == null) {
- return null;
- }
- return input.instruction;
- }
- });
+ return analyzedInstructions.getValues().stream().map(
+ input -> input == null ? null : input.instruction).collect(Collectors.toList());
}
@Nullable
@@ -458,7 +452,8 @@ public class MethodAnalyzer {
private void buildInstructionList() {
int registerCount = methodImpl.getRegisterCount();
- ImmutableList<Instruction> instructions = ImmutableList.copyOf(methodImpl.getInstructions());
+ List<Instruction> instructions = Collections.unmodifiableList(
+ IteratorUtils.toList(methodImpl.getInstructions()));
analyzedInstructions.ensureCapacity(instructions.size());
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/PathEntryLoader.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/PathEntryLoader.java
index 3f65298b..698eb1f5 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/PathEntryLoader.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/PathEntryLoader.java
@@ -35,12 +35,12 @@ import com.android.tools.smali.dexlib2.Opcodes;
import com.android.tools.smali.dexlib2.dexbacked.DexBackedDexFile;
import com.android.tools.smali.dexlib2.dexbacked.OatFile;
import com.android.tools.smali.dexlib2.iface.MultiDexContainer;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -51,8 +51,8 @@ public class PathEntryLoader {
return opcodes;
}
- final Set<File> loadedFiles = Sets.newHashSet();
- final List<ClassProvider> classProviders = Lists.newArrayList();
+ final Set<File> loadedFiles = new HashSet<>();
+ final List<ClassProvider> classProviders = new ArrayList<>();
public List<ClassProvider> getClassProviders() {
return classProviders;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionClassDef.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionClassDef.java
index b1404509..1451a269 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionClassDef.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionClassDef.java
@@ -35,11 +35,10 @@ import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.ClassDef;
import com.android.tools.smali.dexlib2.iface.Field;
import com.android.tools.smali.dexlib2.iface.Method;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterators;
+import com.android.tools.smali.util.ChainedIterator;
+import com.android.tools.smali.util.IteratorUtils;
+import com.android.tools.smali.util.TransformedIterator;
+
import com.android.tools.smali.dexlib2.base.reference.BaseTypeReference;
import javax.annotation.Nonnull;
@@ -48,8 +47,13 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.AbstractSet;
import java.util.Iterator;
+import java.util.function.Function;
+import java.util.function.Predicate;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.Arrays;
+import java.util.Collections;
/**
* Wraps a ClassDef around a class loaded in the current VM
@@ -79,17 +83,10 @@ public class ReflectionClassDef extends BaseTypeReference implements ClassDef {
return ReflectionUtils.javaToDexName(superClass.getName());
}
- @Nonnull @Override public List<String> getInterfaces() {
- return ImmutableList.copyOf(Iterators.transform(Iterators.forArray(cls.getInterfaces()), new Function<Class, String>() {
- @Nullable
- @Override
- public String apply(@Nullable Class input) {
- if (input == null) {
- return null;
- }
- return ReflectionUtils.javaToDexName(input.getName());
- }
- }));
+ @Nonnull @Override public List<String> getInterfaces() {
+ return Arrays.asList(cls.getInterfaces()).stream().map(
+ i -> i == null ? null : ReflectionUtils.javaToDexName(i.getName()))
+ .collect(Collectors.toList());
}
@Nullable @Override public String getSourceFile() {
@@ -97,27 +94,25 @@ public class ReflectionClassDef extends BaseTypeReference implements ClassDef {
}
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
@Nonnull @Override public Iterable<? extends Field> getStaticFields() {
return new Iterable<Field>() {
@Nonnull @Override public Iterator<Field> iterator() {
- Iterator<java.lang.reflect.Field> staticFields = Iterators.filter(
- Iterators.forArray(cls.getDeclaredFields()),
+ Iterator<java.lang.reflect.Field> staticFields = IteratorUtils.filter(
+ Arrays.asList(cls.getDeclaredFields()),
new Predicate<java.lang.reflect.Field>() {
- @Override public boolean apply(@Nullable java.lang.reflect.Field input) {
+ @Override public boolean test(@Nullable java.lang.reflect.Field input) {
return input!=null && Modifier.isStatic(input.getModifiers());
}
});
- return Iterators.transform(staticFields,
- new Function<java.lang.reflect.Field, Field>() {
- @Nullable @Override public Field apply(@Nullable java.lang.reflect.Field input) {
- return new ReflectionField(input);
- }
- }
- );
+ return new TransformedIterator<java.lang.reflect.Field, Field>(staticFields, new Function<java.lang.reflect.Field, Field>() {
+ @Nullable @Override public Field apply(@Nullable java.lang.reflect.Field input) {
+ return new ReflectionField(input);
+ }
+ });
}
};
}
@@ -125,15 +120,15 @@ public class ReflectionClassDef extends BaseTypeReference implements ClassDef {
@Nonnull @Override public Iterable<? extends Field> getInstanceFields() {
return new Iterable<Field>() {
@Nonnull @Override public Iterator<Field> iterator() {
- Iterator<java.lang.reflect.Field> staticFields = Iterators.filter(
- Iterators.forArray(cls.getDeclaredFields()),
+ Iterator<java.lang.reflect.Field> staticFields = IteratorUtils.filter(
+ Arrays.asList(cls.getDeclaredFields()),
new Predicate<java.lang.reflect.Field>() {
- @Override public boolean apply(@Nullable java.lang.reflect.Field input) {
+ @Override public boolean test(@Nullable java.lang.reflect.Field input) {
return input!=null && !Modifier.isStatic(input.getModifiers());
}
});
- return Iterators.transform(staticFields,
+ return new TransformedIterator<java.lang.reflect.Field, Field>(staticFields,
new Function<java.lang.reflect.Field, Field>() {
@Nullable @Override public Field apply(@Nullable java.lang.reflect.Field input) {
return new ReflectionField(input);
@@ -147,7 +142,8 @@ public class ReflectionClassDef extends BaseTypeReference implements ClassDef {
@Nonnull @Override public Set<? extends Field> getFields() {
return new AbstractSet<Field>() {
@Nonnull @Override public Iterator<Field> iterator() {
- return Iterators.transform(Iterators.forArray(cls.getDeclaredFields()),
+ return new TransformedIterator<java.lang.reflect.Field, Field>(
+ Arrays.asList(cls.getDeclaredFields()),
new Function<java.lang.reflect.Field, Field>() {
@Nullable @Override public Field apply(@Nullable java.lang.reflect.Field input) {
return new ReflectionField(input);
@@ -166,28 +162,30 @@ public class ReflectionClassDef extends BaseTypeReference implements ClassDef {
return new Iterable<Method>() {
@Nonnull @Override public Iterator<Method> iterator() {
Iterator<Method> constructorIterator =
- Iterators.transform(Iterators.forArray(cls.getDeclaredConstructors()),
+ new TransformedIterator<Constructor, Method>(
+ Arrays.asList(cls.getDeclaredConstructors()).iterator(),
new Function<Constructor, Method>() {
@Nullable @Override public Method apply(@Nullable Constructor input) {
return new ReflectionConstructor(input);
}
});
- Iterator<java.lang.reflect.Method> directMethods = Iterators.filter(
- Iterators.forArray(cls.getDeclaredMethods()),
+ Iterator<java.lang.reflect.Method> directMethods = IteratorUtils.filter(
+ Arrays.asList(cls.getDeclaredMethods()),
new Predicate<java.lang.reflect.Method>() {
- @Override public boolean apply(@Nullable java.lang.reflect.Method input) {
+ @Override public boolean test(@Nullable java.lang.reflect.Method input) {
return input != null && (input.getModifiers() & DIRECT_MODIFIERS) != 0;
}
});
- Iterator<Method> methodIterator = Iterators.transform(directMethods,
+ Iterator<Method> methodIterator = new TransformedIterator<java.lang.reflect.Method, Method>(
+ directMethods,
new Function<java.lang.reflect.Method, Method>() {
@Nullable @Override public Method apply(@Nullable java.lang.reflect.Method input) {
return new ReflectionMethod(input);
}
});
- return Iterators.concat(constructorIterator, methodIterator);
+ return new ChainedIterator<Method>(constructorIterator, methodIterator);
}
};
}
@@ -195,15 +193,15 @@ public class ReflectionClassDef extends BaseTypeReference implements ClassDef {
@Nonnull @Override public Iterable<? extends Method> getVirtualMethods() {
return new Iterable<Method>() {
@Nonnull @Override public Iterator<Method> iterator() {
- Iterator<java.lang.reflect.Method> directMethods = Iterators.filter(
- Iterators.forArray(cls.getDeclaredMethods()),
+ Iterator<java.lang.reflect.Method> directMethods = IteratorUtils.filter(
+ Arrays.asList(cls.getDeclaredMethods()),
new Predicate<java.lang.reflect.Method>() {
- @Override public boolean apply(@Nullable java.lang.reflect.Method input) {
+ @Override public boolean test(@Nullable java.lang.reflect.Method input) {
return input != null && (input.getModifiers() & DIRECT_MODIFIERS) == 0;
}
});
- return Iterators.transform(directMethods,
+ return new TransformedIterator<java.lang.reflect.Method, Method>(directMethods,
new Function<java.lang.reflect.Method, Method>() {
@Nullable @Override public Method apply(@Nullable java.lang.reflect.Method input) {
return new ReflectionMethod(input);
@@ -217,7 +215,8 @@ public class ReflectionClassDef extends BaseTypeReference implements ClassDef {
return new AbstractSet<Method>() {
@Nonnull @Override public Iterator<Method> iterator() {
Iterator<Method> constructorIterator =
- Iterators.transform(Iterators.forArray(cls.getDeclaredConstructors()),
+ new TransformedIterator<Constructor, Method>(
+ Arrays.asList(cls.getDeclaredConstructors()),
new Function<Constructor, Method>() {
@Nullable @Override public Method apply(@Nullable Constructor input) {
return new ReflectionConstructor(input);
@@ -225,13 +224,14 @@ public class ReflectionClassDef extends BaseTypeReference implements ClassDef {
});
Iterator<Method> methodIterator =
- Iterators.transform(Iterators.forArray(cls.getDeclaredMethods()),
+ new TransformedIterator<java.lang.reflect.Method, Method>(
+ Arrays.asList(cls.getDeclaredMethods()),
new Function<java.lang.reflect.Method, Method>() {
@Nullable @Override public Method apply(@Nullable java.lang.reflect.Method input) {
return new ReflectionMethod(input);
}
});
- return Iterators.concat(constructorIterator, methodIterator);
+ return new ChainedIterator<Method>(constructorIterator, methodIterator);
}
@Override public int size() {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionConstructor.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionConstructor.java
index 80ba4bee..ff112391 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionConstructor.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionConstructor.java
@@ -37,13 +37,13 @@ import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.Method;
import com.android.tools.smali.dexlib2.iface.MethodImplementation;
import com.android.tools.smali.dexlib2.iface.MethodParameter;
-import com.google.common.collect.ImmutableSet;
import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Constructor;
import java.util.AbstractList;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -62,7 +62,7 @@ public class ReflectionConstructor extends BaseMethodReference implements Method
@Override public MethodParameter get(final int index) {
return new BaseMethodParameter() {
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
@Nullable @Override public String getName() {
@@ -86,7 +86,7 @@ public class ReflectionConstructor extends BaseMethodReference implements Method
}
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
@Nullable @Override public MethodImplementation getImplementation() {
@@ -120,6 +120,6 @@ public class ReflectionConstructor extends BaseMethodReference implements Method
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionField.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionField.java
index d35f90d4..5205ea01 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionField.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionField.java
@@ -34,12 +34,12 @@ import com.android.tools.smali.dexlib2.HiddenApiRestriction;
import com.android.tools.smali.dexlib2.analysis.reflection.util.ReflectionUtils;
import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.Field;
-import com.google.common.collect.ImmutableSet;
import com.android.tools.smali.dexlib2.base.reference.BaseFieldReference;
import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.Collections;
import java.util.Set;
public class ReflectionField extends BaseFieldReference implements Field {
@@ -58,7 +58,7 @@ public class ReflectionField extends BaseFieldReference implements Field {
}
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
@Nonnull @Override public String getDefiningClass() {
@@ -74,6 +74,6 @@ public class ReflectionField extends BaseFieldReference implements Field {
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionMethod.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionMethod.java
index 24396b13..40f5d4aa 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionMethod.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/ReflectionMethod.java
@@ -37,12 +37,12 @@ import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.Method;
import com.android.tools.smali.dexlib2.iface.MethodImplementation;
import com.android.tools.smali.dexlib2.iface.MethodParameter;
-import com.google.common.collect.ImmutableSet;
import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.AbstractList;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -61,7 +61,7 @@ public class ReflectionMethod extends BaseMethodReference implements Method {
@Override public MethodParameter get(final int index) {
return new BaseMethodParameter() {
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
@Nullable @Override public String getName() {
@@ -85,7 +85,7 @@ public class ReflectionMethod extends BaseMethodReference implements Method {
}
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
@Nullable @Override public MethodImplementation getImplementation() {
@@ -119,6 +119,6 @@ public class ReflectionMethod extends BaseMethodReference implements Method {
}
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/util/ReflectionUtils.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/util/ReflectionUtils.java
index 2fb8bdcd..ab4a2897 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/util/ReflectionUtils.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/reflection/util/ReflectionUtils.java
@@ -30,21 +30,39 @@
package com.android.tools.smali.dexlib2.analysis.reflection.util;
-import com.google.common.collect.ImmutableBiMap;
+import static java.util.Collections.unmodifiableMap;
+
+import java.util.Map;
+import java.util.HashMap;
public class ReflectionUtils {
- private static ImmutableBiMap<String, String> primitiveMap = ImmutableBiMap.<String, String>builder()
- .put("boolean", "Z")
- .put("int", "I")
- .put("long", "J")
- .put("double", "D")
- .put("void", "V")
- .put("float", "F")
- .put("char", "C")
- .put("short", "S")
- .put("byte", "B")
- .build();
+ private static Map<String, String> primitiveMap;
+
+ static {
+ Map<String, String> temp = new HashMap<>();
+ temp.put("boolean", "Z");
+ temp.put("int", "I");
+ temp.put("long", "J");
+ temp.put("double", "D");
+ temp.put("void", "V");
+ temp.put("float", "F");
+ temp.put("char", "C");
+ temp.put("short", "S");
+ temp.put("byte", "B");
+ primitiveMap = unmodifiableMap(temp);
+ }
+
+ private static Map<String, String> primitiveMapInverse = getInverse();
+
+ private static Map<String, String> getInverse() {
+ Map<String, String> temp = new HashMap<>();
+ for (Map.Entry<String, String> entry : primitiveMap.entrySet()) {
+ temp.put(entry.getValue(), entry.getKey());
+ }
+ return unmodifiableMap(temp);
+ }
+
public static String javaToDexName(String javaName) {
if (javaName.charAt(0) == '[') {
@@ -63,8 +81,8 @@ public class ReflectionUtils {
return dexName.replace('/', '.');
}
- if (primitiveMap.inverse().containsKey(dexName)) {
- return primitiveMap.inverse().get(dexName);
+ if (primitiveMapInverse.containsKey(dexName)) {
+ return primitiveMapInverse.get(dexName);
}
return dexName.replace('/', '.').substring(1, dexName.length()-1);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/util/LruCache.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/util/LruCache.java
new file mode 100644
index 00000000..5c971893
--- /dev/null
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/util/LruCache.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2024, Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.tools.smali.dexlib2.analysis.util;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+/**
+ * Based on android.util.LruCache.
+ * A cache that holds strong references to a limited number of values. Each time
+ * a value is accessed, it is moved to the head of a queue. When a value is
+ * added to a full cache, the value at the end of that queue is evicted and may
+ * become eligible for garbage collection.
+ *
+ * <p>If your cached values hold resources that need to be explicitly released,
+ * override {@link #entryRemoved}.
+ *
+ * <p>If a cache miss should be computed on demand for the corresponding keys,
+ * override {@link #create}. This simplifies the calling code, allowing it to
+ * assume a value will always be returned, even when there's a cache miss.
+ *
+ * <p>By default, the cache size is measured in the number of entries. Override
+ * {@link #sizeOf} to size the cache in different units. For example, this cache
+ * is limited to 4MiB of bitmaps:
+ * <pre> {@code
+ * int cacheSize = 4 * 1024 * 1024; // 4MiB
+ * LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
+ * protected int sizeOf(String key, Bitmap value) {
+ * return value.getByteCount();
+ * }
+ * }}</pre>
+ *
+ * <p>This class is thread-safe. Perform multiple cache operations atomically by
+ * synchronizing on the cache: <pre> {@code
+ * synchronized (cache) {
+ * if (cache.get(key) == null) {
+ * cache.put(key, value);
+ * }
+ * }}</pre>
+ *
+ * <p>This class does not allow null to be used as a key or value. A return
+ * value of null from {@link #get}, {@link #put} or {@link #remove} is
+ * unambiguous: the key was not in the cache.
+ */
+
+public class LruCache<K, V> {
+ private final LinkedHashMap<K, V> map;
+
+ /** Size of this cache in units. Not necessarily the number of elements. */
+ private int size;
+ private int maxSize;
+
+ private int putCount;
+ private int createCount;
+ private int evictionCount;
+ private int hitCount;
+ private int missCount;
+
+ /**
+ * @param maxSize for caches that do not override {@link #sizeOf}, this is
+ * the maximum number of entries in the cache. For all other caches,
+ * this is the maximum sum of the sizes of the entries in this cache.
+ */
+ public LruCache(int maxSize) {
+ if (maxSize <= 0) {
+ throw new IllegalArgumentException("maxSize <= 0");
+ }
+ this.maxSize = maxSize;
+ this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
+ }
+
+ /**
+ * Sets the size of the cache.
+ *
+ * @param maxSize The new maximum size.
+ */
+ public void resize(int maxSize) {
+ if (maxSize <= 0) {
+ throw new IllegalArgumentException("maxSize <= 0");
+ }
+
+ synchronized (this) {
+ this.maxSize = maxSize;
+ }
+ trimToSize(maxSize);
+ }
+
+ /**
+ * Returns the value for {@code key} if it exists in the cache or can be
+ * created by {@code #create}. If a value was returned, it is moved to the
+ * head of the queue. This returns null if a value is not cached and cannot
+ * be created.
+ */
+ public final V get(K key) {
+ if (key == null) {
+ throw new NullPointerException("key == null");
+ }
+
+ V mapValue;
+ synchronized (this) {
+ mapValue = map.get(key);
+ if (mapValue != null) {
+ hitCount++;
+ return mapValue;
+ }
+ missCount++;
+ }
+
+ /*
+ * Attempt to create a value. This may take a long time, and the map
+ * may be different when create() returns. If a conflicting value was
+ * added to the map while create() was working, we leave that value in
+ * the map and release the created value.
+ */
+
+ V createdValue = create(key);
+ if (createdValue == null) {
+ return null;
+ }
+
+ synchronized (this) {
+ createCount++;
+ mapValue = map.put(key, createdValue);
+
+ if (mapValue != null) {
+ // There was a conflict so undo that last put
+ map.put(key, mapValue);
+ } else {
+ size += safeSizeOf(key, createdValue);
+ }
+ }
+
+ if (mapValue != null) {
+ entryRemoved(false, key, createdValue, mapValue);
+ return mapValue;
+ } else {
+ trimToSize(maxSize);
+ return createdValue;
+ }
+ }
+
+ /**
+ * Caches {@code value} for {@code key}. The value is moved to the head of
+ * the queue.
+ *
+ * @return the previous value mapped by {@code key}.
+ */
+ public final V put(K key, V value) {
+ if (key == null || value == null) {
+ throw new NullPointerException("key == null || value == null");
+ }
+
+ V previous;
+ synchronized (this) {
+ putCount++;
+ size += safeSizeOf(key, value);
+ previous = map.put(key, value);
+ if (previous != null) {
+ size -= safeSizeOf(key, previous);
+ }
+ }
+
+ if (previous != null) {
+ entryRemoved(false, key, previous, value);
+ }
+
+ trimToSize(maxSize);
+ return previous;
+ }
+
+ /**
+ * Remove the eldest entries until the total of remaining entries is at or
+ * below the requested size.
+ *
+ * @param maxSize the maximum size of the cache before returning. May be -1
+ * to evict even 0-sized elements.
+ */
+ public void trimToSize(int maxSize) {
+ while (true) {
+ K key;
+ V value;
+ synchronized (this) {
+ if (size < 0 || (map.isEmpty() && size != 0)) {
+ throw new IllegalStateException(getClass().getName()
+ + ".sizeOf() is reporting inconsistent results!");
+ }
+
+ if (size <= maxSize) {
+ break;
+ }
+
+ Map.Entry<K, V> toEvict = eldest();
+ if (toEvict == null) {
+ break;
+ }
+
+ key = toEvict.getKey();
+ value = toEvict.getValue();
+ map.remove(key);
+ size -= safeSizeOf(key, value);
+ evictionCount++;
+ }
+
+ entryRemoved(true, key, value, null);
+ }
+ }
+
+
+ private Map.Entry<K, V> eldest() {
+ final Iterator<Map.Entry<K, V>> it = map.entrySet().iterator();
+ return it.hasNext() ? it.next() : null;
+ }
+
+ /**
+ * Removes the entry for {@code key} if it exists.
+ *
+ * @return the previous value mapped by {@code key}.
+ */
+ public final V remove(K key) {
+ if (key == null) {
+ throw new NullPointerException("key == null");
+ }
+
+ V previous;
+ synchronized (this) {
+ previous = map.remove(key);
+ if (previous != null) {
+ size -= safeSizeOf(key, previous);
+ }
+ }
+
+ if (previous != null) {
+ entryRemoved(false, key, previous, null);
+ }
+
+ return previous;
+ }
+
+ /**
+ * Called for entries that have been evicted or removed. This method is
+ * invoked when a value is evicted to make space, removed by a call to
+ * {@link #remove}, or replaced by a call to {@link #put}. The default
+ * implementation does nothing.
+ *
+ * <p>The method is called without synchronization: other threads may
+ * access the cache while this method is executing.
+ *
+ * @param evicted true if the entry is being removed to make space, false
+ * if the removal was caused by a {@link #put} or {@link #remove}.
+ * @param newValue the new value for {@code key}, if it exists. If non-null,
+ * this removal was caused by a {@link #put} or a {@link #get}. Otherwise it was caused by
+ * an eviction or a {@link #remove}.
+ */
+ protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}
+
+ /**
+ * Called after a cache miss to compute a value for the corresponding key.
+ * Returns the computed value or null if no value can be computed. The
+ * default implementation returns null.
+ *
+ * <p>The method is called without synchronization: other threads may
+ * access the cache while this method is executing.
+ *
+ * <p>If a value for {@code key} exists in the cache when this method
+ * returns, the created value will be released with {@link #entryRemoved}
+ * and discarded. This can occur when multiple threads request the same key
+ * at the same time (causing multiple values to be created), or when one
+ * thread calls {@link #put} while another is creating a value for the same
+ * key.
+ */
+ protected V create(K key) {
+ return null;
+ }
+
+ private int safeSizeOf(K key, V value) {
+ int result = sizeOf(key, value);
+ if (result < 0) {
+ throw new IllegalStateException("Negative size: " + key + "=" + value);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the size of the entry for {@code key} and {@code value} in
+ * user-defined units. The default implementation returns 1 so that size
+ * is the number of entries and max size is the maximum number of entries.
+ *
+ * <p>An entry's size must not change while it is in the cache.
+ */
+ protected int sizeOf(K key, V value) {
+ return 1;
+ }
+
+ /**
+ * Clear the cache, calling {@link #entryRemoved} on each removed entry.
+ */
+ public final void evictAll() {
+ trimToSize(-1); // -1 will evict 0-sized elements
+ }
+
+ /**
+ * For caches that do not override {@link #sizeOf}, this returns the number
+ * of entries in the cache. For all other caches, this returns the sum of
+ * the sizes of the entries in this cache.
+ */
+ public synchronized final int size() {
+ return size;
+ }
+
+ /**
+ * For caches that do not override {@link #sizeOf}, this returns the maximum
+ * number of entries in the cache. For all other caches, this returns the
+ * maximum sum of the sizes of the entries in this cache.
+ */
+ public synchronized final int maxSize() {
+ return maxSize;
+ }
+
+ /**
+ * Returns the number of times {@link #get} returned a value that was
+ * already present in the cache.
+ */
+ public synchronized final int hitCount() {
+ return hitCount;
+ }
+
+ /**
+ * Returns the number of times {@link #get} returned null or required a new
+ * value to be created.
+ */
+ public synchronized final int missCount() {
+ return missCount;
+ }
+
+ /**
+ * Returns the number of times {@link #create(Object)} returned a value.
+ */
+ public synchronized final int createCount() {
+ return createCount;
+ }
+
+ /**
+ * Returns the number of times {@link #put} was called.
+ */
+ public synchronized final int putCount() {
+ return putCount;
+ }
+
+ /**
+ * Returns the number of values that have been evicted.
+ */
+ public synchronized final int evictionCount() {
+ return evictionCount;
+ }
+
+ /**
+ * Returns a copy of the current contents of the cache, ordered from least
+ * recently accessed to most recently accessed.
+ */
+ public synchronized final Map<K, V> snapshot() {
+ return new LinkedHashMap<K, V>(map);
+ }
+
+ @Override public synchronized final String toString() {
+ int accesses = hitCount + missCount;
+ int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0;
+ return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",
+ maxSize, hitCount, missCount, hitPercent);
+ }
+}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/util/MemoizingSupplier.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/util/MemoizingSupplier.java
new file mode 100644
index 00000000..c9622f1a
--- /dev/null
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/analysis/util/MemoizingSupplier.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2024, Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.tools.smali.dexlib2.analysis.util;
+
+import java.util.function.Supplier;
+
+/**
+ * Based on Guava's NonSerializableMemoizing Supplier. This implementation is thread safe.
+ */
+public class MemoizingSupplier<T> implements Supplier<T> {
+ // Delegate will only be null when the value was successfuly computed
+ private volatile Supplier<T> delegate;
+ private T value;
+
+ private MemoizingSupplier(Supplier<T> delegate) {
+ if (delegate == null) {
+ throw new NullPointerException("delegate == null");
+ }
+ this.delegate = delegate;
+ }
+
+ @Override
+ public T get() {
+ // Because Supplier is read-heavy, we use the "double-checked locking" pattern.
+ if (delegate != null) {
+ synchronized (this) {
+ if (delegate != null) {
+ T t = delegate.get();
+ value = t;
+ delegate = null;
+ }
+ }
+ }
+ // This is safe because we checked `delegate.`
+ return value;
+ }
+
+ public static <T extends Object> MemoizingSupplier<T> memoize(Supplier<T> delegate) {
+ if (delegate instanceof MemoizingSupplier) {
+ return (MemoizingSupplier<T>) delegate;
+ }
+ return new MemoizingSupplier<>(delegate);
+ }
+}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/BuilderTryBlock.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/BuilderTryBlock.java
index 25c079d3..19c05b10 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/BuilderTryBlock.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/BuilderTryBlock.java
@@ -30,12 +30,13 @@
package com.android.tools.smali.dexlib2.builder;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.base.BaseTryBlock;
import com.android.tools.smali.dexlib2.iface.reference.TypeReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
public class BuilderTryBlock extends BaseTryBlock<BuilderExceptionHandler> {
@@ -75,6 +76,6 @@ public class BuilderTryBlock extends BaseTryBlock<BuilderExceptionHandler> {
}
@Nonnull @Override public List<? extends BuilderExceptionHandler> getExceptionHandlers() {
- return ImmutableList.of(exceptionHandler);
+ return Collections.unmodifiableList(Arrays.asList(exceptionHandler));
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/LocatedItems.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/LocatedItems.java
index 6adf69ec..9060713b 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/LocatedItems.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/LocatedItems.java
@@ -30,10 +30,9 @@
package com.android.tools.smali.dexlib2.builder;
-import com.google.common.collect.ImmutableList;
-
import java.util.AbstractSet;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -50,7 +49,7 @@ public abstract class LocatedItems<T extends ItemWithLocation> {
@Nonnull
private List<T> getItems() {
if (items == null) {
- return ImmutableList.of();
+ return Collections.emptyList();
}
return items;
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/MutableMethodImplementation.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/MutableMethodImplementation.java
index 2be0f22a..40f9dd77 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/MutableMethodImplementation.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/MutableMethodImplementation.java
@@ -122,11 +122,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.PackedSwitchPay
import com.android.tools.smali.dexlib2.iface.instruction.formats.SparseSwitchPayload;
import com.android.tools.smali.dexlib2.iface.reference.TypeReference;
import com.android.tools.smali.util.ExceptionWithContext;
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
@@ -138,8 +133,9 @@ import javax.annotation.Nullable;
public class MutableMethodImplementation implements MethodImplementation {
private final int registerCount;
- final ArrayList<MethodLocation> instructionList = Lists.newArrayList(new MethodLocation(null, 0, 0));
- private final ArrayList<BuilderTryBlock> tryBlocks = Lists.newArrayList();
+ final ArrayList<MethodLocation> instructionList = new ArrayList<>(
+ Arrays.asList(new MethodLocation(null, 0, 0)));
+ private final ArrayList<BuilderTryBlock> tryBlocks = new ArrayList<>();
private boolean fixInstructions = true;
public MutableMethodImplementation(@Nonnull MethodImplementation methodImplementation) {
@@ -162,7 +158,7 @@ public class MutableMethodImplementation implements MethodImplementation {
codeAddressToIndex[instructionList.get(i).codeAddress] = i;
}
- List<Task> switchPayloadTasks = Lists.newArrayList();
+ List<Task> switchPayloadTasks = new ArrayList<>();
index = 0;
for (final Instruction instruction: methodImplementation.getInstructions()) {
final MethodLocation location = instructionList.get(index);
@@ -256,17 +252,20 @@ public class MutableMethodImplementation implements MethodImplementation {
if (fixInstructions) {
fixInstructions();
}
- return Iterables.concat(
- Iterables.transform(instructionList, new Function<MethodLocation, Iterable<? extends DebugItem>>() {
- @Nullable @Override public Iterable<? extends DebugItem> apply(@Nullable MethodLocation input) {
- assert input != null;
- if (fixInstructions) {
- throw new IllegalStateException("This iterator was invalidated by a change to" +
- " this MutableMethodImplementation.");
- }
- return input.getDebugItems();
- }
- }));
+
+ ArrayList<DebugItem> debugItems = new ArrayList<>();
+
+ for (MethodLocation methodLocation: instructionList) {
+ assert methodLocation != null;
+
+ if (fixInstructions) {
+ throw new IllegalStateException("This iterator was invalidated by a change to" +
+ " this MutableMethodImplementation.");
+ }
+ debugItems.addAll(methodLocation.getDebugItems());
+ }
+
+ return Collections.unmodifiableList(debugItems);
}
public void addCatch(@Nullable TypeReference type, @Nonnull Label from,
@@ -438,7 +437,7 @@ public class MutableMethodImplementation implements MethodImplementation {
}
private void fixInstructions() {
- HashSet<MethodLocation> payloadLocations = Sets.newHashSet();
+ HashSet<MethodLocation> payloadLocations = new HashSet<>();
for (MethodLocation location: instructionList) {
BuilderInstruction instruction = location.instruction;
@@ -1104,7 +1103,7 @@ public class MutableMethodImplementation implements MethodImplementation {
baseAddress = switchLocation.codeAddress;
}
- List<Label> labels = Lists.newArrayList();
+ List<Label> labels = new ArrayList<>();
for (SwitchElement element: switchElements) {
labels.add(newLabel(codeAddressToIndex, element.getOffset() + baseAddress));
}
@@ -1129,7 +1128,7 @@ public class MutableMethodImplementation implements MethodImplementation {
baseAddress = switchLocation.codeAddress;
}
- List<SwitchLabelElement> labelElements = Lists.newArrayList();
+ List<SwitchLabelElement> labelElements = new ArrayList<>();
for (SwitchElement element: switchElements) {
labelElements.add(new SwitchLabelElement(element.getKey(),
newLabel(codeAddressToIndex, element.getOffset() + baseAddress)));
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderArrayPayload.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderArrayPayload.java
index a42ee87b..d3cc40cf 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderArrayPayload.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderArrayPayload.java
@@ -34,10 +34,10 @@ import com.android.tools.smali.dexlib2.Format;
import com.android.tools.smali.dexlib2.Opcode;
import com.android.tools.smali.dexlib2.builder.BuilderInstruction;
import com.android.tools.smali.dexlib2.iface.instruction.formats.ArrayPayload;
-import com.google.common.collect.ImmutableList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.Collections;
import java.util.List;
public class BuilderArrayPayload extends BuilderInstruction implements ArrayPayload {
@@ -50,7 +50,7 @@ public class BuilderArrayPayload extends BuilderInstruction implements ArrayPayl
@Nullable List<Number> arrayElements) {
super(OPCODE);
this.elementWidth = elementWidth;
- this.arrayElements = arrayElements==null?ImmutableList.<Number>of():arrayElements;
+ this.arrayElements = arrayElements == null ? Collections.emptyList() : arrayElements;
}
@Override public int getElementWidth() { return elementWidth; }
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderPackedSwitchPayload.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderPackedSwitchPayload.java
index cac33505..fd872d15 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderPackedSwitchPayload.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderPackedSwitchPayload.java
@@ -35,11 +35,12 @@ import com.android.tools.smali.dexlib2.Opcode;
import com.android.tools.smali.dexlib2.builder.BuilderSwitchPayload;
import com.android.tools.smali.dexlib2.builder.Label;
import com.android.tools.smali.dexlib2.iface.instruction.formats.PackedSwitchPayload;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
public class BuilderPackedSwitchPayload extends BuilderSwitchPayload implements
@@ -52,9 +53,9 @@ public class BuilderPackedSwitchPayload extends BuilderSwitchPayload implements
@Nullable List<? extends Label> switchElements) {
super(OPCODE);
if (switchElements == null) {
- this.switchElements = ImmutableList.of();
+ this.switchElements = Collections.emptyList();
} else {
- this.switchElements = Lists.newArrayList();
+ this.switchElements = new ArrayList<>();
int key = startKey;
for (Label target: switchElements) {
this.switchElements.add(new BuilderSwitchElement(this, key++, target));
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderSparseSwitchPayload.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderSparseSwitchPayload.java
index 6b4c021b..b1e935cc 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderSparseSwitchPayload.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/builder/instruction/BuilderSparseSwitchPayload.java
@@ -35,13 +35,13 @@ import com.android.tools.smali.dexlib2.Opcode;
import com.android.tools.smali.dexlib2.builder.BuilderSwitchPayload;
import com.android.tools.smali.dexlib2.builder.SwitchLabelElement;
import com.android.tools.smali.dexlib2.iface.instruction.formats.SparseSwitchPayload;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.Collections;
import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
public class BuilderSparseSwitchPayload extends BuilderSwitchPayload implements
SparseSwitchPayload {
@@ -52,14 +52,14 @@ public class BuilderSparseSwitchPayload extends BuilderSwitchPayload implements
public BuilderSparseSwitchPayload(@Nullable List<? extends SwitchLabelElement> switchElements) {
super(OPCODE);
if (switchElements == null) {
- this.switchElements = ImmutableList.of();
+ this.switchElements = Collections.emptyList();
} else {
- this.switchElements = Lists.transform(switchElements, new Function<SwitchLabelElement, BuilderSwitchElement>() {
+ this.switchElements = switchElements.stream().map(new Function<SwitchLabelElement, BuilderSwitchElement>() {
@Nullable @Override public BuilderSwitchElement apply(@Nullable SwitchLabelElement element) {
assert element != null;
return new BuilderSwitchElement(BuilderSparseSwitchPayload.this, element.key, element.target);
}
- });
+ }).collect(Collectors.toList());
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/DexBackedMethod.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/DexBackedMethod.java
index 84e6e831..3e0327ee 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/DexBackedMethod.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/DexBackedMethod.java
@@ -155,7 +155,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
}
};
}
- return unmodifiableList(List.of());
+ return Collections.emptyList();
}
@Nonnull
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/OatFile.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/OatFile.java
index a6011b42..8b41ab8b 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/OatFile.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/OatFile.java
@@ -170,11 +170,11 @@ public class OatFile extends DexBuffer implements MultiDexContainer<DexBackedDex
@Nonnull
public List<String> getBootClassPath() {
if (getOatVersion() < 75) {
- return Collections.unmodifiableList(List.of());
+ return Collections.emptyList();
}
String bcp = oatHeader.getKeyValue("bootclasspath");
if (bcp == null) {
- return Collections.unmodifiableList(List.of());
+ return Collections.emptyList();
}
return Arrays.asList(bcp.split(":"));
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/instruction/DexBackedArrayPayload.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/instruction/DexBackedArrayPayload.java
index ec93d9a3..da4996b0 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/instruction/DexBackedArrayPayload.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/instruction/DexBackedArrayPayload.java
@@ -81,7 +81,7 @@ public class DexBackedArrayPayload extends DexBackedInstruction implements Array
}
if (elementCount == 0) {
- return Collections.unmodifiableList(List.of());
+ return Collections.emptyList();
}
switch (elementWidth) {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotation.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotation.java
index 7168c397..ca55368b 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotation.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotation.java
@@ -35,16 +35,16 @@ import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.AnnotationElement;
import com.android.tools.smali.util.ImmutableConverter;
import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableSet;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
+import java.util.Set;
public class ImmutableAnnotation extends BaseAnnotation {
protected final int visibility;
@Nonnull protected final String type;
- @Nonnull protected final ImmutableSet<? extends ImmutableAnnotationElement> elements;
+ @Nonnull protected final Set<? extends ImmutableAnnotationElement> elements;
public ImmutableAnnotation(int visibility,
@Nonnull String type,
@@ -56,7 +56,7 @@ public class ImmutableAnnotation extends BaseAnnotation {
public ImmutableAnnotation(int visibility,
@Nonnull String type,
- @Nullable ImmutableSet<? extends ImmutableAnnotationElement> elements) {
+ @Nullable Set<? extends ImmutableAnnotationElement> elements) {
this.visibility = visibility;
this.type = type;
this.elements = ImmutableUtils.nullToEmptySet(elements);
@@ -74,10 +74,10 @@ public class ImmutableAnnotation extends BaseAnnotation {
@Override public int getVisibility() { return visibility; }
@Nonnull @Override public String getType() { return type; }
- @Nonnull @Override public ImmutableSet<? extends ImmutableAnnotationElement> getElements() { return elements; }
+ @Nonnull @Override public Set<? extends ImmutableAnnotationElement> getElements() { return elements; }
@Nonnull
- public static ImmutableSet<ImmutableAnnotation> immutableSetOf(@Nullable Iterable<? extends Annotation> list) {
+ public static Set<ImmutableAnnotation> immutableSetOf(@Nullable Iterable<? extends Annotation> list) {
return CONVERTER.toSet(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotationElement.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotationElement.java
index b589b1a7..bb2731e1 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotationElement.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableAnnotationElement.java
@@ -36,10 +36,10 @@ import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
import com.android.tools.smali.dexlib2.immutable.value.ImmutableEncodedValue;
import com.android.tools.smali.dexlib2.immutable.value.ImmutableEncodedValueFactory;
import com.android.tools.smali.util.ImmutableConverter;
-import com.google.common.collect.ImmutableSet;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.Set;
public class ImmutableAnnotationElement extends BaseAnnotationElement {
@Nonnull protected final String name;
@@ -70,7 +70,7 @@ public class ImmutableAnnotationElement extends BaseAnnotationElement {
@Nonnull @Override public EncodedValue getValue() { return value; }
@Nonnull
- public static ImmutableSet<ImmutableAnnotationElement> immutableSetOf(
+ public static Set<ImmutableAnnotationElement> immutableSetOf(
@Nullable Iterable<? extends AnnotationElement> list) {
return CONVERTER.toSet(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableClassDef.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableClassDef.java
index 7f70a4ad..34298cd8 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableClassDef.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableClassDef.java
@@ -30,6 +30,8 @@
package com.android.tools.smali.dexlib2.immutable;
+import static java.util.Collections.unmodifiableList;
+
import com.android.tools.smali.dexlib2.base.reference.BaseTypeReference;
import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.ClassDef;
@@ -37,31 +39,32 @@ import com.android.tools.smali.dexlib2.iface.Field;
import com.android.tools.smali.dexlib2.iface.Method;
import com.android.tools.smali.dexlib2.util.FieldUtil;
import com.android.tools.smali.dexlib2.util.MethodUtil;
+import com.android.tools.smali.util.ChainedIterator;
import com.android.tools.smali.util.ImmutableConverter;
import com.android.tools.smali.util.ImmutableUtils;
+import com.android.tools.smali.util.IteratorUtils;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Iterators;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import java.util.AbstractCollection;
+import java.util.ArrayList;
import java.util.Collection;
-import java.util.Iterator;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+
public class ImmutableClassDef extends BaseTypeReference implements ClassDef {
@Nonnull protected final String type;
protected final int accessFlags;
@Nullable protected final String superclass;
- @Nonnull protected final ImmutableList<String> interfaces;
+ @Nonnull protected final List<String> interfaces;
@Nullable protected final String sourceFile;
- @Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
- @Nonnull protected final ImmutableSortedSet<? extends ImmutableField> staticFields;
- @Nonnull protected final ImmutableSortedSet<? extends ImmutableField> instanceFields;
- @Nonnull protected final ImmutableSortedSet<? extends ImmutableMethod> directMethods;
- @Nonnull protected final ImmutableSortedSet<? extends ImmutableMethod> virtualMethods;
+ @Nonnull protected final Set<? extends ImmutableAnnotation> annotations;
+ @Nonnull protected final SortedSet<? extends ImmutableField> staticFields;
+ @Nonnull protected final SortedSet<? extends ImmutableField> instanceFields;
+ @Nonnull protected final SortedSet<? extends ImmutableMethod> directMethods;
+ @Nonnull protected final SortedSet<? extends ImmutableMethod> virtualMethods;
public ImmutableClassDef(@Nonnull String type,
int accessFlags,
@@ -72,22 +75,22 @@ public class ImmutableClassDef extends BaseTypeReference implements ClassDef {
@Nullable Iterable<? extends Field> fields,
@Nullable Iterable<? extends Method> methods) {
if (fields == null) {
- fields = ImmutableList.of();
+ fields = Collections.emptyList();
}
if (methods == null) {
- methods = ImmutableList.of();
+ methods = Collections.emptyList();
}
this.type = type;
this.accessFlags = accessFlags;
this.superclass = superclass;
- this.interfaces = interfaces==null ? ImmutableList.<String>of() : ImmutableList.copyOf(interfaces);
+ this.interfaces = interfaces == null ? Collections.emptyList() : unmodifiableList(new ArrayList<>(interfaces));
this.sourceFile = sourceFile;
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
- this.staticFields = ImmutableField.immutableSetOf(Iterables.filter(fields, FieldUtil.FIELD_IS_STATIC));
- this.instanceFields = ImmutableField.immutableSetOf(Iterables.filter(fields, FieldUtil.FIELD_IS_INSTANCE));
- this.directMethods = ImmutableMethod.immutableSetOf(Iterables.filter(methods, MethodUtil.METHOD_IS_DIRECT));
- this.virtualMethods = ImmutableMethod.immutableSetOf(Iterables.filter(methods, MethodUtil.METHOD_IS_VIRTUAL));
+ this.staticFields = ImmutableField.immutableSetOf(IteratorUtils.filter(fields, FieldUtil.FIELD_IS_STATIC));
+ this.instanceFields = ImmutableField.immutableSetOf(IteratorUtils.filter(fields, FieldUtil.FIELD_IS_INSTANCE));
+ this.directMethods = ImmutableMethod.immutableSetOf(IteratorUtils.filter(methods, MethodUtil.METHOD_IS_DIRECT));
+ this.virtualMethods = ImmutableMethod.immutableSetOf(IteratorUtils.filter(methods, MethodUtil.METHOD_IS_VIRTUAL));
}
public ImmutableClassDef(@Nonnull String type,
@@ -103,7 +106,7 @@ public class ImmutableClassDef extends BaseTypeReference implements ClassDef {
this.type = type;
this.accessFlags = accessFlags;
this.superclass = superclass;
- this.interfaces = interfaces==null ? ImmutableList.<String>of() : ImmutableList.copyOf(interfaces);
+ this.interfaces = interfaces == null ? Collections.emptyList() : unmodifiableList(new ArrayList<>(interfaces));
this.sourceFile = sourceFile;
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
this.staticFields = ImmutableField.immutableSetOf(staticFields);
@@ -115,13 +118,13 @@ public class ImmutableClassDef extends BaseTypeReference implements ClassDef {
public ImmutableClassDef(@Nonnull String type,
int accessFlags,
@Nullable String superclass,
- @Nullable ImmutableList<String> interfaces,
+ @Nullable List<String> interfaces,
@Nullable String sourceFile,
- @Nullable ImmutableSet<? extends ImmutableAnnotation> annotations,
- @Nullable ImmutableSortedSet<? extends ImmutableField> staticFields,
- @Nullable ImmutableSortedSet<? extends ImmutableField> instanceFields,
- @Nullable ImmutableSortedSet<? extends ImmutableMethod> directMethods,
- @Nullable ImmutableSortedSet<? extends ImmutableMethod> virtualMethods) {
+ @Nullable Set<? extends ImmutableAnnotation> annotations,
+ @Nullable SortedSet<? extends ImmutableField> staticFields,
+ @Nullable SortedSet<? extends ImmutableField> instanceFields,
+ @Nullable SortedSet<? extends ImmutableMethod> directMethods,
+ @Nullable SortedSet<? extends ImmutableMethod> virtualMethods) {
this.type = type;
this.accessFlags = accessFlags;
this.superclass = superclass;
@@ -154,48 +157,28 @@ public class ImmutableClassDef extends BaseTypeReference implements ClassDef {
@Nonnull @Override public String getType() { return type; }
@Override public int getAccessFlags() { return accessFlags; }
@Nullable @Override public String getSuperclass() { return superclass; }
- @Nonnull @Override public ImmutableList<String> getInterfaces() { return interfaces; }
+ @Nonnull @Override public List<String> getInterfaces() { return interfaces; }
@Nullable @Override public String getSourceFile() { return sourceFile; }
- @Nonnull @Override public ImmutableSet<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
- @Nonnull @Override public ImmutableSet<? extends ImmutableField> getStaticFields() { return staticFields; }
- @Nonnull @Override public ImmutableSet<? extends ImmutableField> getInstanceFields() { return instanceFields; }
- @Nonnull @Override public ImmutableSet<? extends ImmutableMethod> getDirectMethods() { return directMethods; }
- @Nonnull @Override public ImmutableSet<? extends ImmutableMethod> getVirtualMethods() { return virtualMethods; }
+ @Nonnull @Override public Set<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
+ @Nonnull @Override public Set<? extends ImmutableField> getStaticFields() { return staticFields; }
+ @Nonnull @Override public Set<? extends ImmutableField> getInstanceFields() { return instanceFields; }
+ @Nonnull @Override public Set<? extends ImmutableMethod> getDirectMethods() { return directMethods; }
+ @Nonnull @Override public Set<? extends ImmutableMethod> getVirtualMethods() { return virtualMethods; }
@Nonnull
@Override
- public Collection<? extends ImmutableField> getFields() {
- return new AbstractCollection<ImmutableField>() {
- @Nonnull
- @Override
- public Iterator<ImmutableField> iterator() {
- return Iterators.concat(staticFields.iterator(), instanceFields.iterator());
- }
-
- @Override public int size() {
- return staticFields.size() + instanceFields.size();
- }
- };
+ public Iterable<? extends ImmutableField> getFields() {
+ return new ChainedIterator(staticFields, instanceFields);
}
@Nonnull
@Override
- public Collection<? extends ImmutableMethod> getMethods() {
- return new AbstractCollection<ImmutableMethod>() {
- @Nonnull
- @Override
- public Iterator<ImmutableMethod> iterator() {
- return Iterators.concat(directMethods.iterator(), virtualMethods.iterator());
- }
-
- @Override public int size() {
- return directMethods.size() + virtualMethods.size();
- }
- };
+ public Iterable<? extends ImmutableMethod> getMethods() {
+ return new ChainedIterator(directMethods, virtualMethods);
}
@Nonnull
- public static ImmutableSet<ImmutableClassDef> immutableSetOf(@Nullable Iterable<? extends ClassDef> iterable) {
+ public static Set<ImmutableClassDef> immutableSetOf(@Nullable Iterable<? extends ClassDef> iterable) {
return CONVERTER.toSet(iterable);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableDexFile.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableDexFile.java
index 5c9a40c0..d27fdec0 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableDexFile.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableDexFile.java
@@ -34,14 +34,14 @@ import com.android.tools.smali.dexlib2.Opcodes;
import com.android.tools.smali.dexlib2.iface.ClassDef;
import com.android.tools.smali.dexlib2.iface.DexFile;
import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableSet;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
+import java.util.Set;
public class ImmutableDexFile implements DexFile {
- @Nonnull protected final ImmutableSet<? extends ImmutableClassDef> classes;
+ @Nonnull protected final Set<? extends ImmutableClassDef> classes;
@Nonnull private final Opcodes opcodes;
public ImmutableDexFile(@Nonnull Opcodes opcodes, @Nullable Collection<? extends ClassDef> classes) {
@@ -49,7 +49,7 @@ public class ImmutableDexFile implements DexFile {
this.opcodes = opcodes;
}
- public ImmutableDexFile(@Nonnull Opcodes opcodes, @Nullable ImmutableSet<? extends ImmutableClassDef> classes) {
+ public ImmutableDexFile(@Nonnull Opcodes opcodes, @Nullable Set<? extends ImmutableClassDef> classes) {
this.classes = ImmutableUtils.nullToEmptySet(classes);
this.opcodes = opcodes;
}
@@ -61,6 +61,6 @@ public class ImmutableDexFile implements DexFile {
return new ImmutableDexFile(dexFile.getOpcodes(), dexFile.getClasses());
}
- @Nonnull @Override public ImmutableSet<? extends ImmutableClassDef> getClasses() { return classes; }
+ @Nonnull @Override public Set<? extends ImmutableClassDef> getClasses() { return classes; }
@Nonnull @Override public Opcodes getOpcodes() { return opcodes; }
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableExceptionHandler.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableExceptionHandler.java
index e8cd7fa7..ab8f08cf 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableExceptionHandler.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableExceptionHandler.java
@@ -33,10 +33,10 @@ package com.android.tools.smali.dexlib2.immutable;
import com.android.tools.smali.dexlib2.base.BaseExceptionHandler;
import com.android.tools.smali.dexlib2.iface.ExceptionHandler;
import com.android.tools.smali.util.ImmutableConverter;
-import com.google.common.collect.ImmutableList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.List;
public class ImmutableExceptionHandler extends BaseExceptionHandler implements ExceptionHandler {
@Nullable protected final String exceptionType;
@@ -61,7 +61,7 @@ public class ImmutableExceptionHandler extends BaseExceptionHandler implements E
@Override public int getHandlerCodeAddress() { return handlerCodeAddress; }
@Nonnull
- public static ImmutableList<ImmutableExceptionHandler> immutableListOf(
+ public static List<ImmutableExceptionHandler> immutableListOf(
@Nullable Iterable<? extends ExceptionHandler> list) {
return CONVERTER.toList(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableField.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableField.java
index d5cb7fc6..3e32aff3 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableField.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableField.java
@@ -30,6 +30,8 @@
package com.android.tools.smali.dexlib2.immutable;
+import static java.util.Collections.unmodifiableSet;
+
import com.android.tools.smali.dexlib2.HiddenApiRestriction;
import com.android.tools.smali.dexlib2.base.reference.BaseFieldReference;
import com.android.tools.smali.dexlib2.iface.Annotation;
@@ -37,16 +39,16 @@ import com.android.tools.smali.dexlib2.iface.Field;
import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
import com.android.tools.smali.dexlib2.immutable.value.ImmutableEncodedValue;
import com.android.tools.smali.dexlib2.immutable.value.ImmutableEncodedValueFactory;
+import com.android.tools.smali.util.CollectionUtils;
import com.android.tools.smali.util.ImmutableConverter;
-import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Ordering;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
+import java.util.SortedSet;
public class ImmutableField extends BaseFieldReference implements Field {
@Nonnull protected final String definingClass;
@@ -54,8 +56,8 @@ public class ImmutableField extends BaseFieldReference implements Field {
@Nonnull protected final String type;
protected final int accessFlags;
@Nullable protected final ImmutableEncodedValue initialValue;
- @Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
- @Nonnull protected final ImmutableSet<HiddenApiRestriction> hiddenApiRestrictions;
+ @Nonnull protected final Set<? extends ImmutableAnnotation> annotations;
+ @Nonnull protected final Set<HiddenApiRestriction> hiddenApiRestrictions;
public ImmutableField(@Nonnull String definingClass,
@Nonnull String name,
@@ -70,24 +72,8 @@ public class ImmutableField extends BaseFieldReference implements Field {
this.accessFlags = accessFlags;
this.initialValue = ImmutableEncodedValueFactory.ofNullable(initialValue);
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
- this.hiddenApiRestrictions =
- hiddenApiRestrictions == null ? ImmutableSet.of() : ImmutableSet.copyOf(hiddenApiRestrictions);
- }
-
- public ImmutableField(@Nonnull String definingClass,
- @Nonnull String name,
- @Nonnull String type,
- int accessFlags,
- @Nullable ImmutableEncodedValue initialValue,
- @Nullable ImmutableSet<? extends ImmutableAnnotation> annotations,
- @Nullable ImmutableSet<HiddenApiRestriction> hiddenApiRestrictions) {
- this.definingClass = definingClass;
- this.name = name;
- this.type = type;
- this.accessFlags = accessFlags;
- this.initialValue = initialValue;
- this.annotations = ImmutableUtils.nullToEmptySet(annotations);
- this.hiddenApiRestrictions = ImmutableUtils.nullToEmptySet(hiddenApiRestrictions);
+ this.hiddenApiRestrictions = hiddenApiRestrictions == null ? Collections.emptySet()
+ : unmodifiableSet(new HashSet<>(hiddenApiRestrictions));
}
public static ImmutableField of(Field field) {
@@ -109,12 +95,12 @@ public class ImmutableField extends BaseFieldReference implements Field {
@Nonnull @Override public String getType() { return type; }
@Override public int getAccessFlags() { return accessFlags; }
@Override public EncodedValue getInitialValue() { return initialValue;}
- @Nonnull @Override public ImmutableSet<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
+ @Nonnull @Override public Set<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() { return hiddenApiRestrictions; }
@Nonnull
- public static ImmutableSortedSet<ImmutableField> immutableSetOf(@Nullable Iterable<? extends Field> list) {
- return CONVERTER.toSortedSet(Ordering.natural(), list);
+ public static SortedSet<ImmutableField> immutableSetOf(@Nullable Iterable<? extends Field> list) {
+ return CONVERTER.toSortedSet(CollectionUtils.naturalOrdering(), list);
}
private static final ImmutableConverter<ImmutableField, Field> CONVERTER =
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethod.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethod.java
index 09aa81bc..e38da3aa 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethod.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethod.java
@@ -30,31 +30,34 @@
package com.android.tools.smali.dexlib2.immutable;
+import static java.util.Collections.unmodifiableSet;
+
import com.android.tools.smali.dexlib2.HiddenApiRestriction;
import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference;
import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.Method;
import com.android.tools.smali.dexlib2.iface.MethodImplementation;
import com.android.tools.smali.dexlib2.iface.MethodParameter;
+import com.android.tools.smali.util.CollectionUtils;
import com.android.tools.smali.util.ImmutableConverter;
import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Ordering;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import java.util.SortedSet;
public class ImmutableMethod extends BaseMethodReference implements Method {
@Nonnull protected final String definingClass;
@Nonnull protected final String name;
- @Nonnull protected final ImmutableList<? extends ImmutableMethodParameter> parameters;
+ @Nonnull protected final List<? extends ImmutableMethodParameter> parameters;
@Nonnull protected final String returnType;
protected final int accessFlags;
- @Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
- @Nonnull protected final ImmutableSet<HiddenApiRestriction> hiddenApiRestrictions;
+ @Nonnull protected final Set<? extends ImmutableAnnotation> annotations;
+ @Nonnull protected final Set<HiddenApiRestriction> hiddenApiRestrictions;
@Nullable protected final ImmutableMethodImplementation methodImplementation;
public ImmutableMethod(@Nonnull String definingClass,
@@ -72,17 +75,18 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
this.accessFlags = accessFlags;
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
this.hiddenApiRestrictions =
- hiddenApiRestrictions == null ? ImmutableSet.of() : ImmutableSet.copyOf(hiddenApiRestrictions);
+ hiddenApiRestrictions == null ? Collections.emptySet() :
+ unmodifiableSet(new HashSet<>(hiddenApiRestrictions));
this.methodImplementation = ImmutableMethodImplementation.of(methodImplementation);
}
public ImmutableMethod(@Nonnull String definingClass,
@Nonnull String name,
- @Nullable ImmutableList<? extends ImmutableMethodParameter> parameters,
+ @Nullable List<? extends ImmutableMethodParameter> parameters,
@Nonnull String returnType,
int accessFlags,
- @Nullable ImmutableSet<? extends ImmutableAnnotation> annotations,
- @Nullable ImmutableSet<HiddenApiRestriction> hiddenApiRestrictions,
+ @Nullable Set<? extends ImmutableAnnotation> annotations,
+ @Nullable Set<HiddenApiRestriction> hiddenApiRestrictions,
@Nullable ImmutableMethodImplementation methodImplementation) {
this.definingClass = definingClass;
this.name = name;
@@ -111,17 +115,17 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
@Override @Nonnull public String getDefiningClass() { return definingClass; }
@Override @Nonnull public String getName() { return name; }
- @Override @Nonnull public ImmutableList<? extends CharSequence> getParameterTypes() { return parameters; }
- @Override @Nonnull public ImmutableList<? extends ImmutableMethodParameter> getParameters() { return parameters; }
+ @Override @Nonnull public List<? extends CharSequence> getParameterTypes() { return parameters; }
+ @Override @Nonnull public List<? extends ImmutableMethodParameter> getParameters() { return parameters; }
@Override @Nonnull public String getReturnType() { return returnType; }
@Override public int getAccessFlags() { return accessFlags; }
- @Override @Nonnull public ImmutableSet<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
+ @Override @Nonnull public Set<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nonnull @Override public Set<HiddenApiRestriction> getHiddenApiRestrictions() { return hiddenApiRestrictions; }
@Override @Nullable public ImmutableMethodImplementation getImplementation() { return methodImplementation; }
@Nonnull
- public static ImmutableSortedSet<ImmutableMethod> immutableSetOf(@Nullable Iterable<? extends Method> list) {
- return CONVERTER.toSortedSet(Ordering.natural(), list);
+ public static SortedSet<ImmutableMethod> immutableSetOf(@Nullable Iterable<? extends Method> list) {
+ return CONVERTER.toSortedSet(CollectionUtils.naturalOrdering(), list);
}
private static final ImmutableConverter<ImmutableMethod, Method> CONVERTER =
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodImplementation.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodImplementation.java
index 10bc8333..2fdeba99 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodImplementation.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodImplementation.java
@@ -38,7 +38,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction;
import com.android.tools.smali.dexlib2.immutable.debug.ImmutableDebugItem;
import com.android.tools.smali.dexlib2.immutable.instruction.ImmutableInstruction;
import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -46,9 +45,9 @@ import java.util.List;
public class ImmutableMethodImplementation implements MethodImplementation {
protected final int registerCount;
- @Nonnull protected final ImmutableList<? extends ImmutableInstruction> instructions;
- @Nonnull protected final ImmutableList<? extends ImmutableTryBlock> tryBlocks;
- @Nonnull protected final ImmutableList<? extends ImmutableDebugItem> debugItems;
+ @Nonnull protected final List<? extends ImmutableInstruction> instructions;
+ @Nonnull protected final List<? extends ImmutableTryBlock> tryBlocks;
+ @Nonnull protected final List<? extends ImmutableDebugItem> debugItems;
public ImmutableMethodImplementation(int registerCount,
@Nullable Iterable<? extends Instruction> instructions,
@@ -61,9 +60,9 @@ public class ImmutableMethodImplementation implements MethodImplementation {
}
public ImmutableMethodImplementation(int registerCount,
- @Nullable ImmutableList<? extends ImmutableInstruction> instructions,
- @Nullable ImmutableList<? extends ImmutableTryBlock> tryBlocks,
- @Nullable ImmutableList<? extends ImmutableDebugItem> debugItems) {
+ @Nullable List<? extends ImmutableInstruction> instructions,
+ @Nullable List<? extends ImmutableTryBlock> tryBlocks,
+ @Nullable List<? extends ImmutableDebugItem> debugItems) {
this.registerCount = registerCount;
this.instructions = ImmutableUtils.nullToEmptyList(instructions);
this.tryBlocks = ImmutableUtils.nullToEmptyList(tryBlocks);
@@ -86,7 +85,7 @@ public class ImmutableMethodImplementation implements MethodImplementation {
}
@Override public int getRegisterCount() { return registerCount; }
- @Nonnull @Override public ImmutableList<? extends ImmutableInstruction> getInstructions() { return instructions; }
- @Nonnull @Override public ImmutableList<? extends ImmutableTryBlock> getTryBlocks() { return tryBlocks; }
- @Nonnull @Override public ImmutableList<? extends ImmutableDebugItem> getDebugItems() { return debugItems; }
+ @Nonnull @Override public List<? extends ImmutableInstruction> getInstructions() { return instructions; }
+ @Nonnull @Override public List<? extends ImmutableTryBlock> getTryBlocks() { return tryBlocks; }
+ @Nonnull @Override public List<? extends ImmutableDebugItem> getDebugItems() { return debugItems; }
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodParameter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodParameter.java
index 37d815dd..8dc0a412 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodParameter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMethodParameter.java
@@ -34,17 +34,15 @@ import com.android.tools.smali.dexlib2.base.BaseMethodParameter;
import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.MethodParameter;
import com.android.tools.smali.util.ImmutableConverter;
-import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.List;
import java.util.Set;
public class ImmutableMethodParameter extends BaseMethodParameter {
@Nonnull protected final String type;
- @Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
+ @Nonnull protected final Set<? extends ImmutableAnnotation> annotations;
@Nullable protected final String name;
public ImmutableMethodParameter(@Nonnull String type,
@@ -55,14 +53,6 @@ public class ImmutableMethodParameter extends BaseMethodParameter {
this.name = name;
}
- public ImmutableMethodParameter(@Nonnull String type,
- @Nullable ImmutableSet<? extends ImmutableAnnotation> annotations,
- @Nullable String name) {
- this.type = type;
- this.annotations = ImmutableUtils.nullToEmptySet(annotations);
- this.name = name;
- }
-
public static ImmutableMethodParameter of(MethodParameter methodParameter) {
if (methodParameter instanceof ImmutableMethodParameter) {
return (ImmutableMethodParameter)methodParameter;
@@ -81,7 +71,7 @@ public class ImmutableMethodParameter extends BaseMethodParameter {
@Nullable @Override public String getSignature() { return null; }
@Nonnull
- public static ImmutableList<ImmutableMethodParameter> immutableListOf(
+ public static List<ImmutableMethodParameter> immutableListOf(
@Nullable Iterable<? extends MethodParameter> list) {
return CONVERTER.toList(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMultiDexContainer.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMultiDexContainer.java
index 2077bffe..317ab455 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMultiDexContainer.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableMultiDexContainer.java
@@ -30,35 +30,37 @@
package com.android.tools.smali.dexlib2.immutable;
+import static java.util.Collections.unmodifiableMap;
+import static java.util.Collections.unmodifiableList;
+
import com.android.tools.smali.dexlib2.iface.MultiDexContainer;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ImmutableMultiDexContainer implements MultiDexContainer<ImmutableDexFile> {
- private final ImmutableMap<String, ImmutableDexEntry> entries;
+ private final Map<String, ImmutableDexEntry> entries;
public ImmutableMultiDexContainer(Map<String, ImmutableDexFile> entries) {
- ImmutableMap.Builder<String, ImmutableDexEntry> builder = ImmutableMap.builder();
+ HashMap<String, ImmutableDexEntry> map = new HashMap<>();
for (Map.Entry<String, ImmutableDexFile> entry : entries.entrySet()) {
ImmutableDexEntry dexEntry = new ImmutableDexEntry(entry.getKey(), entry.getValue());
- builder.put(dexEntry.getEntryName(), dexEntry);
+ map.put(dexEntry.getEntryName(), dexEntry);
}
- this.entries = builder.build();
+ this.entries = unmodifiableMap(map);
}
-
@Nonnull
@Override
public List<String> getDexEntryNames() {
- return ImmutableList.copyOf(entries.keySet());
+ return unmodifiableList(new ArrayList<>(entries.keySet()));
}
@Nullable
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableTryBlock.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableTryBlock.java
index 9b7ca4aa..cc60b814 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableTryBlock.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/ImmutableTryBlock.java
@@ -34,8 +34,6 @@ import com.android.tools.smali.dexlib2.base.BaseTryBlock;
import com.android.tools.smali.dexlib2.iface.ExceptionHandler;
import com.android.tools.smali.dexlib2.iface.TryBlock;
import com.android.tools.smali.util.ImmutableConverter;
-import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -44,7 +42,7 @@ import java.util.List;
public class ImmutableTryBlock extends BaseTryBlock<ImmutableExceptionHandler> {
protected final int startCodeAddress;
protected final int codeUnitCount;
- @Nonnull protected final ImmutableList<? extends ImmutableExceptionHandler> exceptionHandlers;
+ @Nonnull protected final List<? extends ImmutableExceptionHandler> exceptionHandlers;
public ImmutableTryBlock(int startCodeAddress,
int codeUnitCount,
@@ -54,14 +52,6 @@ public class ImmutableTryBlock extends BaseTryBlock<ImmutableExceptionHandler> {
this.exceptionHandlers = ImmutableExceptionHandler.immutableListOf(exceptionHandlers);
}
- public ImmutableTryBlock(int startCodeAddress,
- int codeUnitCount,
- @Nullable ImmutableList<? extends ImmutableExceptionHandler> exceptionHandlers) {
- this.startCodeAddress = startCodeAddress;
- this.codeUnitCount = codeUnitCount;
- this.exceptionHandlers = ImmutableUtils.nullToEmptyList(exceptionHandlers);
- }
-
public static ImmutableTryBlock of(TryBlock<? extends ExceptionHandler> tryBlock) {
if (tryBlock instanceof ImmutableTryBlock) {
return (ImmutableTryBlock)tryBlock;
@@ -75,12 +65,12 @@ public class ImmutableTryBlock extends BaseTryBlock<ImmutableExceptionHandler> {
@Override public int getStartCodeAddress() { return startCodeAddress; }
@Override public int getCodeUnitCount() { return codeUnitCount; }
- @Nonnull @Override public ImmutableList<? extends ImmutableExceptionHandler> getExceptionHandlers() {
+ @Nonnull @Override public List<? extends ImmutableExceptionHandler> getExceptionHandlers() {
return exceptionHandlers;
}
@Nonnull
- public static ImmutableList<ImmutableTryBlock> immutableListOf(
+ public static List<ImmutableTryBlock> immutableListOf(
@Nullable List<? extends TryBlock<? extends ExceptionHandler>> list) {
return CONVERTER.toList(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/README.md b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/README.md
new file mode 100644
index 00000000..892ac519
--- /dev/null
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/README.md
@@ -0,0 +1,4 @@
+## About
+This folder contains classes that originally relied on Guava based Immutable collections, thus the
+naming. The current implementations rely on the Java unmodifiable collections or on constructor
+helpers that produce immutable collections from Java Collections. \ No newline at end of file
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/debug/ImmutableDebugItem.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/debug/ImmutableDebugItem.java
index 6e7c706d..b119b145 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/debug/ImmutableDebugItem.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/debug/ImmutableDebugItem.java
@@ -41,10 +41,10 @@ import com.android.tools.smali.dexlib2.iface.debug.SetSourceFile;
import com.android.tools.smali.dexlib2.iface.debug.StartLocal;
import com.android.tools.smali.util.ExceptionWithContext;
import com.android.tools.smali.util.ImmutableConverter;
-import com.google.common.collect.ImmutableList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.List;
public abstract class ImmutableDebugItem implements DebugItem {
protected final int codeAddress;
@@ -81,7 +81,7 @@ public abstract class ImmutableDebugItem implements DebugItem {
@Override public int getCodeAddress() { return codeAddress; }
@Nonnull
- public static ImmutableList<ImmutableDebugItem> immutableListOf(@Nullable Iterable<? extends DebugItem> list) {
+ public static List<ImmutableDebugItem> immutableListOf(@Nullable Iterable<? extends DebugItem> list) {
return CONVERTER.toList(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableArrayPayload.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableArrayPayload.java
index c359a6cf..4f815b24 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableArrayPayload.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableArrayPayload.java
@@ -30,36 +30,33 @@
package com.android.tools.smali.dexlib2.immutable.instruction;
+import static java.util.Collections.unmodifiableList;
+
import com.android.tools.smali.dexlib2.Format;
import com.android.tools.smali.dexlib2.Opcode;
import com.android.tools.smali.dexlib2.util.Preconditions;
-import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
+
import com.android.tools.smali.dexlib2.iface.instruction.formats.ArrayPayload;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+
public class ImmutableArrayPayload extends ImmutableInstruction implements ArrayPayload {
public static final Opcode OPCODE = Opcode.ARRAY_PAYLOAD;
protected final int elementWidth;
- @Nonnull protected final ImmutableList<Number> arrayElements;
+ @Nonnull protected final List<Number> arrayElements;
- public ImmutableArrayPayload(int elementWidth,
- @Nullable List<Number> arrayElements) {
+ public ImmutableArrayPayload(int elementWidth, @Nullable List<Number> arrayElements) {
super(OPCODE);
this.elementWidth = Preconditions.checkArrayPayloadElementWidth(elementWidth);
this.arrayElements = Preconditions.checkArrayPayloadElements(elementWidth,
- arrayElements==null ? ImmutableList.<Number>of() : ImmutableList.copyOf(arrayElements));
- }
-
- public ImmutableArrayPayload(int elementWidth,
- @Nullable ImmutableList<Number> arrayElements) {
- super(OPCODE);
- this.elementWidth = Preconditions.checkArrayPayloadElementWidth(elementWidth);
- this.arrayElements = Preconditions.checkArrayPayloadElements(elementWidth, ImmutableUtils.nullToEmptyList(arrayElements));
+ arrayElements == null ? Collections.emptyList()
+ : unmodifiableList(new ArrayList<>(arrayElements)));
}
@Nonnull
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableInstruction.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableInstruction.java
index fda86fa3..f70dcee1 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableInstruction.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableInstruction.java
@@ -71,10 +71,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.SparseSwitchPay
import com.android.tools.smali.dexlib2.iface.instruction.formats.UnknownInstruction;
import com.android.tools.smali.dexlib2.util.Preconditions;
import com.android.tools.smali.util.ImmutableConverter;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.iface.instruction.Instruction;
import javax.annotation.Nonnull;
+import java.util.List;
public abstract class ImmutableInstruction implements Instruction {
@Nonnull protected final Opcode opcode;
@@ -182,7 +182,7 @@ public abstract class ImmutableInstruction implements Instruction {
}
@Nonnull
- public static ImmutableList<ImmutableInstruction> immutableListOf(Iterable<? extends Instruction> list) {
+ public static List<ImmutableInstruction> immutableListOf(Iterable<? extends Instruction> list) {
return CONVERTER.toList(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutablePackedSwitchPayload.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutablePackedSwitchPayload.java
index 5ed73e07..6d68f4b2 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutablePackedSwitchPayload.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutablePackedSwitchPayload.java
@@ -34,8 +34,6 @@ import com.android.tools.smali.dexlib2.Format;
import com.android.tools.smali.dexlib2.Opcode;
import com.android.tools.smali.dexlib2.iface.instruction.formats.PackedSwitchPayload;
import com.android.tools.smali.dexlib2.util.Preconditions;
-import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.iface.instruction.SwitchElement;
import javax.annotation.Nonnull;
@@ -46,19 +44,13 @@ public class ImmutablePackedSwitchPayload extends ImmutableInstruction implement
PackedSwitchPayload {
public static final Opcode OPCODE = Opcode.PACKED_SWITCH_PAYLOAD;
- @Nonnull protected final ImmutableList<? extends ImmutableSwitchElement> switchElements;
+ @Nonnull protected final List<? extends ImmutableSwitchElement> switchElements;
public ImmutablePackedSwitchPayload(@Nullable List<? extends SwitchElement> switchElements) {
super(OPCODE);
this.switchElements = Preconditions.checkSequentialOrderedKeys(ImmutableSwitchElement.immutableListOf(switchElements));
}
- public ImmutablePackedSwitchPayload(
- @Nullable ImmutableList<? extends ImmutableSwitchElement> switchElements) {
- super(OPCODE);
- this.switchElements = Preconditions.checkSequentialOrderedKeys(ImmutableUtils.nullToEmptyList(switchElements));
- }
-
@Nonnull
public static ImmutablePackedSwitchPayload of(PackedSwitchPayload instruction) {
if (instruction instanceof ImmutablePackedSwitchPayload) {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSparseSwitchPayload.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSparseSwitchPayload.java
index 43e76ac7..d563f6d0 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSparseSwitchPayload.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSparseSwitchPayload.java
@@ -33,8 +33,6 @@ package com.android.tools.smali.dexlib2.immutable.instruction;
import com.android.tools.smali.dexlib2.Format;
import com.android.tools.smali.dexlib2.Opcode;
import com.android.tools.smali.dexlib2.iface.instruction.formats.SparseSwitchPayload;
-import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.iface.instruction.SwitchElement;
import javax.annotation.Nonnull;
@@ -45,19 +43,13 @@ public class ImmutableSparseSwitchPayload extends ImmutableInstruction implement
SparseSwitchPayload {
public static final Opcode OPCODE = Opcode.SPARSE_SWITCH_PAYLOAD;
- @Nonnull protected final ImmutableList<? extends ImmutableSwitchElement> switchElements;
+ @Nonnull protected final List<? extends ImmutableSwitchElement> switchElements;
public ImmutableSparseSwitchPayload(@Nullable List<? extends SwitchElement> switchElements) {
super(OPCODE);
this.switchElements = ImmutableSwitchElement.immutableListOf(switchElements);
}
- public ImmutableSparseSwitchPayload(
- @Nullable ImmutableList<? extends ImmutableSwitchElement> switchElements) {
- super(OPCODE);
- this.switchElements = ImmutableUtils.nullToEmptyList(switchElements);
- }
-
@Nonnull
public static ImmutableSparseSwitchPayload of(SparseSwitchPayload instruction) {
if (instruction instanceof ImmutableSparseSwitchPayload) {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSwitchElement.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSwitchElement.java
index 79e10272..e5a2be46 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSwitchElement.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/instruction/ImmutableSwitchElement.java
@@ -31,7 +31,6 @@
package com.android.tools.smali.dexlib2.immutable.instruction;
import com.android.tools.smali.util.ImmutableConverter;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.iface.instruction.SwitchElement;
import javax.annotation.Nonnull;
@@ -62,7 +61,7 @@ public class ImmutableSwitchElement implements SwitchElement {
@Override public int getOffset() { return offset; }
@Nonnull
- public static ImmutableList<ImmutableSwitchElement> immutableListOf(@Nullable List<? extends SwitchElement> list) {
+ public static List<ImmutableSwitchElement> immutableListOf(@Nullable List<? extends SwitchElement> list) {
return CONVERTER.toList(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableCallSiteReference.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableCallSiteReference.java
index 62d969b9..67bcf03a 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableCallSiteReference.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableCallSiteReference.java
@@ -31,7 +31,6 @@
package com.android.tools.smali.dexlib2.immutable.reference;
import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.base.reference.BaseCallSiteReference;
import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference;
@@ -49,7 +48,7 @@ public class ImmutableCallSiteReference extends BaseCallSiteReference implements
@Nonnull protected final ImmutableMethodHandleReference methodHandle;
@Nonnull protected final String methodName;
@Nonnull protected final ImmutableMethodProtoReference methodProto;
- @Nonnull protected final ImmutableList<? extends ImmutableEncodedValue> extraArguments;
+ @Nonnull protected final List<? extends ImmutableEncodedValue> extraArguments;
public ImmutableCallSiteReference(@Nonnull String name, @Nonnull MethodHandleReference methodHandle,
@Nonnull String methodName, @Nonnull MethodProtoReference methodProto,
@@ -63,7 +62,7 @@ public class ImmutableCallSiteReference extends BaseCallSiteReference implements
public ImmutableCallSiteReference(@Nonnull String name, @Nonnull ImmutableMethodHandleReference methodHandle,
@Nonnull String methodName, @Nonnull ImmutableMethodProtoReference methodProto,
- @Nullable ImmutableList<? extends ImmutableEncodedValue> extraArguments) {
+ @Nullable List<? extends ImmutableEncodedValue> extraArguments) {
this.name = name;
this.methodHandle = methodHandle;
this.methodName = methodName;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodProtoReference.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodProtoReference.java
index 5fe4f0f3..bec5c37f 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodProtoReference.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodProtoReference.java
@@ -31,7 +31,6 @@
package com.android.tools.smali.dexlib2.immutable.reference;
import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.base.reference.BaseMethodProtoReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference;
import com.android.tools.smali.dexlib2.immutable.util.CharSequenceConverter;
@@ -41,10 +40,10 @@ import javax.annotation.Nullable;
import java.util.List;
public class ImmutableMethodProtoReference extends BaseMethodProtoReference implements ImmutableReference {
- @Nonnull protected final ImmutableList<String> parameters;
+ @Nonnull protected final List<String> parameters;
@Nonnull protected final String returnType;
- public ImmutableMethodProtoReference(@Nullable ImmutableList<String> parameters,
+ public ImmutableMethodProtoReference(@Nullable List<String> parameters,
@Nonnull String returnType) {
this.parameters = ImmutableUtils.nullToEmptyList(parameters);
this.returnType = returnType;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodReference.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodReference.java
index 842d838d..b81337d9 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodReference.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableMethodReference.java
@@ -31,18 +31,18 @@
package com.android.tools.smali.dexlib2.immutable.reference;
import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
import com.android.tools.smali.dexlib2.immutable.util.CharSequenceConverter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.List;
public class ImmutableMethodReference extends BaseMethodReference implements ImmutableReference {
@Nonnull protected final String definingClass;
@Nonnull protected final String name;
- @Nonnull protected final ImmutableList<String> parameters;
+ @Nonnull protected final List<String> parameters;
@Nonnull protected final String returnType;
public ImmutableMethodReference(@Nonnull String definingClass,
@@ -57,7 +57,7 @@ public class ImmutableMethodReference extends BaseMethodReference implements Imm
public ImmutableMethodReference(@Nonnull String definingClass,
@Nonnull String name,
- @Nullable ImmutableList<String> parameters,
+ @Nullable List<String> parameters,
@Nonnull String returnType) {
this.definingClass = definingClass;
this.name = name;
@@ -79,7 +79,7 @@ public class ImmutableMethodReference extends BaseMethodReference implements Imm
@Nonnull @Override public String getDefiningClass() { return definingClass; }
@Nonnull @Override public String getName() { return name; }
- @Nonnull @Override public ImmutableList<String> getParameterTypes() { return parameters; }
+ @Nonnull @Override public List<String> getParameterTypes() { return parameters; }
@Nonnull @Override public String getReturnType() { return returnType; }
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableTypeReference.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableTypeReference.java
index 5560bc1d..f2980f58 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableTypeReference.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/reference/ImmutableTypeReference.java
@@ -31,7 +31,7 @@
package com.android.tools.smali.dexlib2.immutable.reference;
import com.android.tools.smali.util.ImmutableConverter;
-import com.google.common.collect.ImmutableList;
+
import com.android.tools.smali.dexlib2.base.reference.BaseTypeReference;
import com.android.tools.smali.dexlib2.iface.reference.TypeReference;
@@ -57,7 +57,7 @@ public class ImmutableTypeReference extends BaseTypeReference implements Immutab
@Nonnull @Override public String getType() { return type; }
@Nonnull
- public static ImmutableList<ImmutableTypeReference> immutableListOf(@Nullable List<? extends TypeReference> list) {
+ public static List<ImmutableTypeReference> immutableListOf(@Nullable List<? extends TypeReference> list) {
return CONVERTER.toList(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/util/CharSequenceConverter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/util/CharSequenceConverter.java
index 09020d01..4f2a27ae 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/util/CharSequenceConverter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/util/CharSequenceConverter.java
@@ -31,17 +31,17 @@
package com.android.tools.smali.dexlib2.immutable.util;
import com.android.tools.smali.util.ImmutableConverter;
-import com.google.common.collect.ImmutableList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.List;
public final class CharSequenceConverter {
private CharSequenceConverter() {
}
@Nonnull
- public static ImmutableList<String> immutableStringList(@Nullable Iterable<? extends CharSequence> iterable) {
+ public static List<String> immutableStringList(@Nullable Iterable<? extends CharSequence> iterable) {
return CONVERTER.toList(iterable);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableAnnotationEncodedValue.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableAnnotationEncodedValue.java
index b42e73d0..10e83cbd 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableAnnotationEncodedValue.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableAnnotationEncodedValue.java
@@ -32,7 +32,6 @@ package com.android.tools.smali.dexlib2.immutable.value;
import com.android.tools.smali.dexlib2.iface.AnnotationElement;
import com.android.tools.smali.util.ImmutableUtils;
-import com.google.common.collect.ImmutableSet;
import com.android.tools.smali.dexlib2.base.value.BaseAnnotationEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.AnnotationEncodedValue;
import com.android.tools.smali.dexlib2.immutable.ImmutableAnnotationElement;
@@ -40,10 +39,11 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableAnnotationElement;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
+import java.util.Set;
public class ImmutableAnnotationEncodedValue extends BaseAnnotationEncodedValue implements ImmutableEncodedValue {
@Nonnull protected final String type;
- @Nonnull protected final ImmutableSet<? extends ImmutableAnnotationElement> elements;
+ @Nonnull protected final Set<? extends ImmutableAnnotationElement> elements;
public ImmutableAnnotationEncodedValue(@Nonnull String type,
@Nullable Collection<? extends AnnotationElement> elements) {
@@ -52,7 +52,7 @@ public class ImmutableAnnotationEncodedValue extends BaseAnnotationEncodedValue
}
public ImmutableAnnotationEncodedValue(@Nonnull String type,
- @Nullable ImmutableSet<? extends ImmutableAnnotationElement> elements) {
+ @Nullable Set<? extends ImmutableAnnotationElement> elements) {
this.type = type;
this.elements = ImmutableUtils.nullToEmptySet(elements);
}
@@ -67,5 +67,5 @@ public class ImmutableAnnotationEncodedValue extends BaseAnnotationEncodedValue
}
@Nonnull @Override public String getType() { return type; }
- @Nonnull @Override public ImmutableSet<? extends ImmutableAnnotationElement> getElements() { return elements; }
+ @Nonnull @Override public Set<? extends ImmutableAnnotationElement> getElements() { return elements; }
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableArrayEncodedValue.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableArrayEncodedValue.java
index d9025930..cf27be16 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableArrayEncodedValue.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableArrayEncodedValue.java
@@ -30,22 +30,22 @@
package com.android.tools.smali.dexlib2.immutable.value;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.base.value.BaseArrayEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.ArrayEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import java.util.Collection;
+import java.util.List;
public class ImmutableArrayEncodedValue extends BaseArrayEncodedValue implements ImmutableEncodedValue {
- @Nonnull protected final ImmutableList<? extends ImmutableEncodedValue> value;
+ @Nonnull protected final List<? extends ImmutableEncodedValue> value;
public ImmutableArrayEncodedValue(@Nonnull Collection<? extends EncodedValue> value) {
this.value = ImmutableEncodedValueFactory.immutableListOf(value);
}
- public ImmutableArrayEncodedValue(@Nonnull ImmutableList<ImmutableEncodedValue> value) {
+ public ImmutableArrayEncodedValue(@Nonnull List<ImmutableEncodedValue> value) {
this.value = value;
}
@@ -56,5 +56,5 @@ public class ImmutableArrayEncodedValue extends BaseArrayEncodedValue implements
return new ImmutableArrayEncodedValue(arrayEncodedValue.getValue());
}
- @Nonnull public ImmutableList<? extends ImmutableEncodedValue> getValue() { return value; }
+ @Nonnull public List<? extends ImmutableEncodedValue> getValue() { return value; }
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableEncodedValueFactory.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableEncodedValueFactory.java
index e458a1e1..1159b60b 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableEncodedValueFactory.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/immutable/value/ImmutableEncodedValueFactory.java
@@ -51,11 +51,10 @@ import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.TypeEncodedValue;
import com.android.tools.smali.util.ExceptionWithContext;
import com.android.tools.smali.util.ImmutableConverter;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.List;
public class ImmutableEncodedValueFactory {
@Nonnull
@@ -98,8 +97,7 @@ public class ImmutableEncodedValueFactory {
case ValueType.METHOD_TYPE:
return ImmutableMethodTypeEncodedValue.of((MethodTypeEncodedValue) encodedValue);
default:
- Preconditions.checkArgument(false);
- return null;
+ throw new IllegalArgumentException("Invalid value type.");
}
}
@@ -139,7 +137,7 @@ public class ImmutableEncodedValueFactory {
}
@Nonnull
- public static ImmutableList<ImmutableEncodedValue> immutableListOf
+ public static List<ImmutableEncodedValue> immutableListOf
(@Nullable Iterable<? extends EncodedValue> list) {
return CONVERTER.toList(list);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/CallSiteReferenceRewriter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/CallSiteReferenceRewriter.java
index d19cebfa..439ff769 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/CallSiteReferenceRewriter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/CallSiteReferenceRewriter.java
@@ -30,8 +30,6 @@
package com.android.tools.smali.dexlib2.rewriter;
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
import com.android.tools.smali.dexlib2.base.reference.BaseCallSiteReference;
import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference;
@@ -40,6 +38,8 @@ import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import java.util.List;
+import java.util.stream.Collectors;
+import java.util.function.Function;
public class CallSiteReferenceRewriter implements Rewriter<CallSiteReference> {
@Nonnull protected final Rewriters rewriters;
@@ -79,12 +79,11 @@ public class CallSiteReferenceRewriter implements Rewriter<CallSiteReference> {
}
@Override @Nonnull public List<? extends EncodedValue> getExtraArguments() {
- return Lists.transform(callSiteReference.getExtraArguments(),
- new Function<EncodedValue, EncodedValue>() {
- @Nonnull @Override public EncodedValue apply(EncodedValue encodedValue) {
- return RewriterUtils.rewriteValue(rewriters, encodedValue);
- }
- });
+ return callSiteReference.getExtraArguments().stream().map(new Function<EncodedValue, EncodedValue>() {
+ @Nonnull @Override public EncodedValue apply(EncodedValue encodedValue) {
+ return RewriterUtils.rewriteValue(rewriters, encodedValue);
+ }
+ }).collect(Collectors.toList());
}
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/ClassDefRewriter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/ClassDefRewriter.java
index 6117d348..27d2c873 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/ClassDefRewriter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/ClassDefRewriter.java
@@ -35,7 +35,7 @@ import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.ClassDef;
import com.android.tools.smali.dexlib2.iface.Field;
import com.android.tools.smali.dexlib2.iface.Method;
-import com.google.common.collect.Iterators;
+import com.android.tools.smali.util.ChainedIterator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -100,7 +100,8 @@ public class ClassDefRewriter implements Rewriter<ClassDef> {
@Nonnull
@Override
public Iterator<Field> iterator() {
- return Iterators.concat(getStaticFields().iterator(), getInstanceFields().iterator());
+ return new ChainedIterator(
+ getStaticFields().iterator(), getInstanceFields().iterator());
}
};
}
@@ -120,7 +121,8 @@ public class ClassDefRewriter implements Rewriter<ClassDef> {
@Nonnull
@Override
public Iterator<Method> iterator() {
- return Iterators.concat(getDirectMethods().iterator(), getVirtualMethods().iterator());
+ return new ChainedIterator(
+ getDirectMethods().iterator(), getVirtualMethods().iterator());
}
};
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/MethodReferenceRewriter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/MethodReferenceRewriter.java
index c7b1d8cc..b4209d85 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/MethodReferenceRewriter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/MethodReferenceRewriter.java
@@ -32,11 +32,11 @@ package com.android.tools.smali.dexlib2.rewriter;
import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
import javax.annotation.Nonnull;
import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
public class MethodReferenceRewriter implements Rewriter<MethodReference> {
@Nonnull protected final Rewriters rewriters;
@@ -66,12 +66,12 @@ public class MethodReferenceRewriter implements Rewriter<MethodReference> {
@Override @Nonnull public List<? extends CharSequence> getParameterTypes() {
return RewriterUtils.rewriteList(rewriters.getTypeRewriter(),
- Lists.transform(methodReference.getParameterTypes(),
+ methodReference.getParameterTypes().stream().map(
new Function<CharSequence, String>() {
@Nonnull @Override public String apply(CharSequence input) {
return input.toString();
}
- }));
+ }).collect(Collectors.toList()));
}
@Override @Nonnull public String getReturnType() {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterUtils.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterUtils.java
index 652eb46e..a9978b6d 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterUtils.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterUtils.java
@@ -53,14 +53,14 @@ import com.android.tools.smali.dexlib2.iface.value.MethodEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.MethodHandleEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.MethodTypeEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.TypeEncodedValue;
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
import java.util.AbstractList;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -183,12 +183,11 @@ public class RewriterUtils {
return new BaseMethodProtoReference() {
@Nonnull @Override public List<? extends CharSequence> getParameterTypes() {
return rewriteList(typeRewriter,
- Lists.transform(methodProtoReference.getParameterTypes(),
+ methodProtoReference.getParameterTypes().stream().map(
new Function<CharSequence, String>() {
@Nonnull @Override public String apply(CharSequence input) {
return input.toString();
- }
- }));
+ }}).collect(Collectors.toList()));
}
@Nonnull @Override public String getReturnType() {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/AnnotatedBytes.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/AnnotatedBytes.java
index 9b8e7f62..7fd0c4f6 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/AnnotatedBytes.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/AnnotatedBytes.java
@@ -30,18 +30,16 @@
package com.android.tools.smali.dexlib2.util;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
import com.android.tools.smali.util.ExceptionWithContext;
import com.android.tools.smali.util.Hex;
+import com.android.tools.smali.util.StringUtils;
import com.android.tools.smali.util.TwoColumnOutput;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.Writer;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -65,7 +63,7 @@ public class AnnotatedBytes {
* is the exclusive end point. The range annotation for a range is associated with the first key for that range.
* The point annotations for a point are associated with the key at that point.
*/
- @Nonnull private TreeMap<Integer, AnnotationEndpoint> annotatations = Maps.newTreeMap();
+ @Nonnull private TreeMap<Integer, AnnotationEndpoint> annotatations = new TreeMap<>();
private int cursor;
private int indentLevel;
@@ -250,7 +248,7 @@ public class AnnotatedBytes {
private static class AnnotationEndpoint {
/** Annotations that are associated with a specific point between bytes */
@Nonnull
- public final List<AnnotationItem> pointAnnotations = Lists.newArrayList();
+ public final List<AnnotationItem> pointAnnotations = new ArrayList<>();
/** Annotations that are associated with a range of bytes */
@Nullable
public AnnotationItem rangeAnnotation = null;
@@ -284,7 +282,7 @@ public class AnnotatedBytes {
int rightWidth = getAnnotationWidth();
int leftWidth = outputWidth - rightWidth - 1;
- String padding = Strings.repeat(" ", 1000);
+ String padding = StringUtils.repeat(" ", 1000);
TwoColumnOutput twoc = new TwoColumnOutput(out, leftWidth, rightWidth, "|");
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/FieldUtil.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/FieldUtil.java
index a543b695..835d8a7f 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/FieldUtil.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/FieldUtil.java
@@ -31,21 +31,21 @@
package com.android.tools.smali.dexlib2.util;
import com.android.tools.smali.dexlib2.iface.Field;
-import com.google.common.base.Predicate;
import com.android.tools.smali.dexlib2.AccessFlags;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.function.Predicate;
public final class FieldUtil {
public static Predicate<Field> FIELD_IS_STATIC = new Predicate<Field>() {
- @Override public boolean apply(@Nullable Field input) {
+ @Override public boolean test(@Nullable Field input) {
return input!=null && isStatic(input);
}
};
public static Predicate<Field> FIELD_IS_INSTANCE = new Predicate<Field>() {
- @Override public boolean apply(@Nullable Field input) {
+ @Override public boolean test(@Nullable Field input) {
return input!= null && !isStatic(input);
}
};
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/MethodUtil.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/MethodUtil.java
index 2c9812ae..848544a3 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/MethodUtil.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/MethodUtil.java
@@ -30,7 +30,6 @@
package com.android.tools.smali.dexlib2.util;
-import com.google.common.base.Predicate;
import com.android.tools.smali.dexlib2.AccessFlags;
import com.android.tools.smali.dexlib2.iface.Method;
import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
@@ -39,19 +38,20 @@ import com.android.tools.smali.util.CharSequenceUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
+import java.util.function.Predicate;
public final class MethodUtil {
private static int directMask = AccessFlags.STATIC.getValue() | AccessFlags.PRIVATE.getValue() |
AccessFlags.CONSTRUCTOR.getValue();
public static Predicate<Method> METHOD_IS_DIRECT = new Predicate<Method>() {
- @Override public boolean apply(@Nullable Method input) {
+ @Override public boolean test(@Nullable Method input) {
return input != null && isDirect(input);
}
};
public static Predicate<Method> METHOD_IS_VIRTUAL = new Predicate<Method>() {
- @Override public boolean apply(@Nullable Method input) {
+ @Override public boolean test(@Nullable Method input) {
return input != null && !isDirect(input);
}
};
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/SyntheticAccessorResolver.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/SyntheticAccessorResolver.java
index dadc9f64..543f2c08 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/SyntheticAccessorResolver.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/SyntheticAccessorResolver.java
@@ -33,20 +33,22 @@ package com.android.tools.smali.dexlib2.util;
import com.android.tools.smali.dexlib2.iface.ClassDef;
import com.android.tools.smali.dexlib2.iface.Method;
import com.android.tools.smali.dexlib2.iface.MethodImplementation;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
import com.android.tools.smali.dexlib2.AccessFlags;
import com.android.tools.smali.dexlib2.Opcodes;
import com.android.tools.smali.dexlib2.iface.instruction.Instruction;
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction;
import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
import com.android.tools.smali.dexlib2.iface.reference.Reference;
+import com.android.tools.smali.util.IteratorUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
public class SyntheticAccessorResolver {
public static final int METHOD = 0;
@@ -70,17 +72,17 @@ public class SyntheticAccessorResolver {
private final SyntheticAccessorFSM syntheticAccessorFSM;
private final Map<String, ClassDef> classDefMap;
- private final Map<MethodReference, AccessedMember> resolvedAccessors = Maps.newConcurrentMap();
+ private final Map<MethodReference, AccessedMember> resolvedAccessors = new ConcurrentHashMap<>();
public SyntheticAccessorResolver(@Nonnull Opcodes opcodes, @Nonnull Iterable<? extends ClassDef> classDefs) {
this.syntheticAccessorFSM = new SyntheticAccessorFSM(opcodes);
- ImmutableMap.Builder<String, ClassDef> builder = ImmutableMap.builder();
+ HashMap<String, ClassDef> classDefMap = new HashMap<>();
for (ClassDef classDef: classDefs) {
- builder.put(classDef.getType(), classDef);
+ classDefMap.put(classDef.getType(), classDef);
}
- this.classDefMap = builder.build();
+ this.classDefMap = Collections.unmodifiableMap(classDefMap);
}
public static boolean looksLikeSyntheticAccessor(String methodName) {
@@ -122,7 +124,8 @@ public class SyntheticAccessorResolver {
return null;
}
- List<Instruction> instructions = ImmutableList.copyOf(matchedMethodImpl.getInstructions());
+ List<Instruction> instructions = Collections.unmodifiableList(
+ IteratorUtils.toList(matchedMethodImpl.getInstructions()));
int accessType = syntheticAccessorFSM.test(instructions);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/DebugInfoCache.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/DebugInfoCache.java
new file mode 100644
index 00000000..6bdfe55e
--- /dev/null
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/DebugInfoCache.java
@@ -0,0 +1,30 @@
+package com.android.tools.smali.dexlib2.writer;
+
+import java.util.Arrays;
+
+public class DebugInfoCache {
+ private final byte[] data;
+ private final int threshold = 128;
+
+ public DebugInfoCache(byte[] data) {
+ this.data = data;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DebugInfoCache that = (DebugInfoCache) o;
+ return Arrays.equals(data, that.data);
+ }
+
+ @Override
+ public int hashCode() {
+ int hashSize = Math.min(data.length, threshold);
+ int result = 0;
+ for (int i = 0; i < hashSize; i++) {
+ result = 31 * result + data[i];
+ }
+ return result;
+ }
+}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/DexWriter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/DexWriter.java
index 205ca2fe..3e28b388 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/DexWriter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/DexWriter.java
@@ -90,11 +90,6 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
import com.android.tools.smali.dexlib2.iface.reference.StringReference;
import com.android.tools.smali.dexlib2.iface.reference.TypeReference;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Ordering;
-import com.google.common.primitives.Ints;
import com.android.tools.smali.dexlib2.base.BaseAnnotation;
import com.android.tools.smali.dexlib2.base.BaseAnnotationElement;
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation;
@@ -116,8 +111,12 @@ import com.android.tools.smali.dexlib2.writer.io.DeferredOutputStreamFactory;
import com.android.tools.smali.dexlib2.writer.io.DexDataStore;
import com.android.tools.smali.dexlib2.writer.io.MemoryDeferredOutputStream;
import com.android.tools.smali.dexlib2.writer.util.TryListBuilder;
+import com.android.tools.smali.util.ChainedIterator;
+import com.android.tools.smali.util.CollectionUtils;
import com.android.tools.smali.util.ExceptionWithContext;
+import com.android.tools.smali.util.IteratorUtils;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -223,6 +222,8 @@ public abstract class DexWriter<
private final IndexSection<?>[] overflowableSections;
+ private final Map<DebugInfoCache, Integer> debugInfoCaches = new HashMap<>();
+
protected DexWriter(Opcodes opcodes) {
this.opcodes = opcodes;
@@ -263,7 +264,7 @@ public abstract class DexWriter<
public int compare(Entry<? extends CallSiteKey, Integer> o1, Entry<? extends CallSiteKey, Integer> o2) {
int offset1 = encodedArraySection.getItemOffset(callSiteSection.getEncodedCallSite(o1.getKey()));
int offset2 = encodedArraySection.getItemOffset(callSiteSection.getEncodedCallSite(o2.getKey()));
- return Ints.compare(offset1, offset2);
+ return Integer.compare(offset1, offset2);
}
};
@@ -316,7 +317,7 @@ public abstract class DexWriter<
@Nonnull
public List<String> getMethodReferences() {
- List<String> methodReferences = Lists.newArrayList();
+ List<String> methodReferences = new ArrayList<>();
for (Entry<? extends MethodRefKey, Integer> methodReference: methodSection.getItems()) {
methodReferences.add(DexFormatter.INSTANCE.getMethodDescriptor(methodReference.getKey()));
}
@@ -325,7 +326,7 @@ public abstract class DexWriter<
@Nonnull
public List<String> getFieldReferences() {
- List<String> fieldReferences = Lists.newArrayList();
+ List<String> fieldReferences = new ArrayList<>();
for (Entry<? extends FieldRefKey, Integer> fieldReference: fieldSection.getItems()) {
fieldReferences.add(DexFormatter.INSTANCE.getFieldDescriptor(fieldReference.getKey()));
}
@@ -334,7 +335,7 @@ public abstract class DexWriter<
@Nonnull
public List<String> getTypeReferences() {
- List<String> classReferences = Lists.newArrayList();
+ List<String> classReferences = new ArrayList<>();
for (Entry<? extends TypeKey, Integer> typeReference: typeSection.getItems()) {
classReferences.add(typeReference.getKey().toString());
}
@@ -470,7 +471,7 @@ public abstract class DexWriter<
stringIndexSectionOffset = indexWriter.getPosition();
stringDataSectionOffset = offsetWriter.getPosition();
int index = 0;
- List<Entry<? extends StringKey, Integer>> stringEntries = Lists.newArrayList(stringSection.getItems());
+ List<Entry<? extends StringKey, Integer>> stringEntries = new ArrayList<>(stringSection.getItems());
Collections.sort(stringEntries, toStringKeyComparator);
for (Map.Entry<? extends StringKey, Integer> entry: stringEntries) {
@@ -487,7 +488,7 @@ public abstract class DexWriter<
typeSectionOffset = writer.getPosition();
int index = 0;
- List<Map.Entry<? extends TypeKey, Integer>> typeEntries = Lists.newArrayList(typeSection.getItems());
+ List<Map.Entry<? extends TypeKey, Integer>> typeEntries = new ArrayList<>(typeSection.getItems());
Collections.sort(typeEntries, toStringKeyComparator);
for (Map.Entry<? extends TypeKey, Integer> entry : typeEntries) {
@@ -500,7 +501,7 @@ public abstract class DexWriter<
protoSectionOffset = writer.getPosition();
int index = 0;
- List<Map.Entry<? extends ProtoRefKey, Integer>> protoEntries = Lists.newArrayList(protoSection.getItems());
+ List<Map.Entry<? extends ProtoRefKey, Integer>> protoEntries = new ArrayList<>(protoSection.getItems());
Collections.sort(protoEntries, DexWriter.<ProtoRefKey>comparableKeyComparator());
for (Map.Entry<? extends ProtoRefKey, Integer> entry: protoEntries) {
@@ -516,7 +517,7 @@ public abstract class DexWriter<
fieldSectionOffset = writer.getPosition();
int index = 0;
- List<Map.Entry<? extends FieldRefKey, Integer>> fieldEntries = Lists.newArrayList(fieldSection.getItems());
+ List<Map.Entry<? extends FieldRefKey, Integer>> fieldEntries = new ArrayList<>(fieldSection.getItems());
Collections.sort(fieldEntries, DexWriter.<FieldRefKey>comparableKeyComparator());
for (Map.Entry<? extends FieldRefKey, Integer> entry: fieldEntries) {
@@ -532,7 +533,7 @@ public abstract class DexWriter<
methodSectionOffset = writer.getPosition();
int index = 0;
- List<Map.Entry<? extends MethodRefKey, Integer>> methodEntries = Lists.newArrayList(methodSection.getItems());
+ List<Map.Entry<? extends MethodRefKey, Integer>> methodEntries = new ArrayList<>(methodSection.getItems());
Collections.sort(methodEntries, DexWriter.<MethodRefKey>comparableKeyComparator());
for (Map.Entry<? extends MethodRefKey, Integer> entry: methodEntries) {
@@ -549,7 +550,7 @@ public abstract class DexWriter<
classIndexSectionOffset = indexWriter.getPosition();
classDataSectionOffset = offsetWriter.getPosition();
- List<Map.Entry<? extends ClassKey, Integer>> classEntriesKeySorted = Lists.newArrayList(classSection.getItems());
+ List<Map.Entry<? extends ClassKey, Integer>> classEntriesKeySorted = new ArrayList<>(classSection.getItems());
Collections.sort(classEntriesKeySorted, DexWriter.<ClassKey>comparableKeyComparator());
int index = 0;
@@ -564,7 +565,7 @@ public abstract class DexWriter<
offsetWriter.align();
hiddenApiRestrictionsOffset = offsetWriter.getPosition();
- List<Map.Entry<? extends ClassKey, Integer>> classEntriesValueSorted = Lists.newArrayList(classSection.getItems());
+ List<Map.Entry<? extends ClassKey, Integer>> classEntriesValueSorted = new ArrayList<>(classSection.getItems());
classEntriesValueSorted.sort(DexWriter.comparableValueComparator());
RestrictionsWriter restrictionsWriter = new RestrictionsWriter(dataStore, offsetWriter, classEntriesValueSorted.size());
@@ -765,7 +766,7 @@ public abstract class DexWriter<
callSiteSectionOffset = writer.getPosition();
List<Map.Entry<? extends CallSiteKey, Integer>> callSiteEntries =
- Lists.newArrayList(callSiteSection.getItems());
+ new ArrayList<>(callSiteSection.getItems());
Collections.sort(callSiteEntries, callSiteComparator);
int index = 0;
@@ -883,8 +884,8 @@ public abstract class DexWriter<
writer.writeUbyte(annotationSection.getVisibility(key));
writer.writeUleb128(typeSection.getItemIndex(annotationSection.getType(key)));
- Collection<? extends AnnotationElement> elements = Ordering.from(BaseAnnotationElement.BY_NAME)
- .immutableSortedCopy(annotationSection.getElements(key));
+ Collection<? extends AnnotationElement> elements = CollectionUtils.immutableSortedCopy(
+ annotationSection.getElements(key), BaseAnnotationElement.BY_NAME);
writer.writeUleb128(elements.size());
@@ -902,9 +903,9 @@ public abstract class DexWriter<
writer.writeInt(0);
}
for (Map.Entry<? extends AnnotationSetKey, Integer> entry: annotationSetSection.getItems()) {
- Collection<? extends AnnotationKey> annotations = Ordering.from(BaseAnnotation.BY_TYPE)
- .immutableSortedCopy(annotationSetSection.getAnnotations(entry.getKey()));
-
+ Collection<? extends AnnotationKey> annotations = CollectionUtils.immutableSortedCopy(
+ annotationSetSection.getAnnotations(entry.getKey()), BaseAnnotation.BY_TYPE);
+
writer.align();
entry.setValue(writer.getPosition());
writer.writeInt(annotations.size());
@@ -917,7 +918,7 @@ public abstract class DexWriter<
private void writeAnnotationSetRefs(@Nonnull DexDataWriter writer) throws IOException {
writer.align();
annotationSetRefSectionOffset = writer.getPosition();
- HashMap<List<? extends AnnotationSetKey>, Integer> internedItems = Maps.newHashMap();
+ HashMap<List<? extends AnnotationSetKey>, Integer> internedItems = new HashMap<>();
for (ClassKey classKey: classSection.getSortedClasses()) {
for (MethodKey methodKey: classSection.getSortedMethods(classKey)) {
@@ -953,7 +954,7 @@ public abstract class DexWriter<
private void writeAnnotationDirectories(@Nonnull DexDataWriter writer) throws IOException {
writer.align();
annotationDirectorySectionOffset = writer.getPosition();
- HashMap<AnnotationSetKey, Integer> internedItems = Maps.newHashMap();
+ HashMap<AnnotationSetKey, Integer> internedItems = new HashMap<>();
ByteBuffer tempBuffer = ByteBuffer.allocate(65536);
tempBuffer.order(ByteOrder.LITTLE_ENDIAN);
@@ -1049,18 +1050,17 @@ public abstract class DexWriter<
@Nonnull DeferredOutputStream temp) throws IOException {
ByteArrayOutputStream ehBuf = new ByteArrayOutputStream();
debugSectionOffset = offsetWriter.getPosition();
- DebugWriter<StringKey, TypeKey> debugWriter =
- new DebugWriter<StringKey, TypeKey>(stringSection, typeSection, offsetWriter);
DexDataWriter codeWriter = new DexDataWriter(temp, 0);
- List<CodeItemOffset<MethodKey>> codeOffsets = Lists.newArrayList();
+ List<CodeItemOffset<MethodKey>> codeOffsets = new ArrayList<>();
for (ClassKey classKey: classSection.getSortedClasses()) {
Collection<? extends MethodKey> directMethods = classSection.getSortedDirectMethods(classKey);
Collection<? extends MethodKey> virtualMethods = classSection.getSortedVirtualMethods(classKey);
- Iterable<MethodKey> methods = Iterables.concat(directMethods, virtualMethods);
+ Iterable<MethodKey> methods = new ChainedIterator<MethodKey>(
+ (Collection<MethodKey>)directMethods, (Collection<MethodKey>)virtualMethods);
for (MethodKey methodKey: methods) {
List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks =
@@ -1091,8 +1091,7 @@ public abstract class DexWriter<
}
}
- int debugItemOffset = writeDebugItem(offsetWriter, debugWriter,
- classSection.getParameterNames(methodKey), debugItems);
+ int debugItemOffset = writeDebugItem(offsetWriter, classSection.getParameterNames(methodKey), debugItems);
int codeItemOffset;
try {
codeItemOffset = writeCodeItem(
@@ -1138,13 +1137,12 @@ public abstract class DexWriter<
}
private int writeDebugItem(@Nonnull DexDataWriter writer,
- @Nonnull DebugWriter<StringKey, TypeKey> debugWriter,
@Nullable Iterable<? extends StringKey> parameterNames,
@Nullable Iterable<? extends DebugItem> debugItems) throws IOException {
int parameterCount = 0;
int lastNamedParameterIndex = -1;
if (parameterNames != null) {
- parameterCount = Iterables.size(parameterNames);
+ parameterCount = IteratorUtils.size(parameterNames);
int index = 0;
for (StringKey parameterName: parameterNames) {
if (parameterName != null) {
@@ -1155,12 +1153,11 @@ public abstract class DexWriter<
}
- if (lastNamedParameterIndex == -1 && (debugItems == null || Iterables.isEmpty(debugItems))) {
+ if (lastNamedParameterIndex == -1 && (debugItems == null
+ || !debugItems.iterator().hasNext())) {
return NO_OFFSET;
}
- numDebugInfoItems++;
-
int debugItemOffset = writer.getPosition();
int startingLineNumber = 0;
@@ -1172,9 +1169,14 @@ public abstract class DexWriter<
}
}
}
- writer.writeUleb128(startingLineNumber);
- writer.writeUleb128(parameterCount);
+ ByteArrayOutputStream tempByteOutput = new ByteArrayOutputStream();
+ DexDataWriter tempDataWriter = new DexDataWriter(tempByteOutput, 0, 64);
+ DebugWriter tempDebugWriter = new DebugWriter(stringSection, typeSection, tempDataWriter);
+
+ tempDataWriter.writeUleb128(startingLineNumber);
+
+ tempDataWriter.writeUleb128(parameterCount);
if (parameterNames != null) {
int index = 0;
for (StringKey parameterName: parameterNames) {
@@ -1182,21 +1184,32 @@ public abstract class DexWriter<
break;
}
index++;
- writer.writeUleb128(stringSection.getNullableItemIndex(parameterName) + 1);
+ tempDataWriter.writeUleb128(stringSection.getNullableItemIndex(parameterName) + 1);
}
}
if (debugItems != null) {
- debugWriter.reset(startingLineNumber);
+ tempDebugWriter.reset(startingLineNumber);
for (DebugItem debugItem: debugItems) {
- classSection.writeDebugItem(debugWriter, debugItem);
+ classSection.writeDebugItem(tempDebugWriter, debugItem);
}
}
// write an END_SEQUENCE opcode, to end the debug item
- writer.write(0);
-
- return debugItemOffset;
+ tempDataWriter.write(0);
+
+ tempDataWriter.flush();
+ byte[] debugInfo = tempByteOutput.toByteArray();
+ DebugInfoCache wrapBytes = new DebugInfoCache(debugInfo);
+ int cacheBytes = debugInfoCaches.getOrDefault(wrapBytes, -1);
+ if (cacheBytes >= 0) {
+ return cacheBytes;
+ } else {
+ writer.write(debugInfo);
+ debugInfoCaches.put(wrapBytes, debugItemOffset);
+ numDebugInfoItems++;
+ return debugItemOffset;
+ }
}
private int writeCodeItem(@Nonnull DexDataWriter writer,
@@ -1381,7 +1394,7 @@ public abstract class DexWriter<
writer.align();
// filter out unique lists of exception handlers
- Map<List<? extends ExceptionHandler>, Integer> exceptionHandlerOffsetMap = Maps.newHashMap();
+ Map<List<? extends ExceptionHandler>, Integer> exceptionHandlerOffsetMap = new HashMap<>();
for (TryBlock<? extends ExceptionHandler> tryBlock: tryBlocks) {
exceptionHandlerOffsetMap.put(tryBlock.getExceptionHandlers(), 0);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/EncodedValueWriter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/EncodedValueWriter.java
index 77c647b5..890a13ac 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/EncodedValueWriter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/EncodedValueWriter.java
@@ -30,16 +30,19 @@
package com.android.tools.smali.dexlib2.writer;
-import com.google.common.collect.Ordering;
import com.android.tools.smali.dexlib2.ValueType;
import com.android.tools.smali.dexlib2.base.BaseAnnotationElement;
import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
+import com.android.tools.smali.util.CollectionUtils;
import javax.annotation.Nonnull;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Collection;
+import java.util.Collections;
public abstract class EncodedValueWriter<StringKey, TypeKey, FieldRefKey extends FieldReference,
MethodRefKey extends MethodReference, AnnotationElement extends com.android.tools.smali.dexlib2.iface.AnnotationElement,
@@ -80,8 +83,8 @@ public abstract class EncodedValueWriter<StringKey, TypeKey, FieldRefKey extends
writer.writeUleb128(typeSection.getItemIndex(annotationType));
writer.writeUleb128(elements.size());
- Collection<? extends AnnotationElement> sortedElements = Ordering.from(BaseAnnotationElement.BY_NAME)
- .immutableSortedCopy(elements);
+ List<? extends AnnotationElement> sortedElements = CollectionUtils.immutableSortedCopy(
+ elements, BaseAnnotationElement.BY_NAME);
for (AnnotationElement element: sortedElements) {
writer.writeUleb128(stringSection.getItemIndex(annotationSection.getElementName(element)));
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/InstructionWriter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/InstructionWriter.java
index 0aa674f3..795e9315 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/InstructionWriter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/InstructionWriter.java
@@ -74,18 +74,19 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
import com.android.tools.smali.dexlib2.iface.reference.Reference;
import com.android.tools.smali.dexlib2.iface.reference.StringReference;
import com.android.tools.smali.dexlib2.iface.reference.TypeReference;
-import com.google.common.collect.Ordering;
-import com.google.common.primitives.Ints;
import com.android.tools.smali.dexlib2.Opcode;
import com.android.tools.smali.dexlib2.Opcodes;
import com.android.tools.smali.dexlib2.ReferenceType;
import com.android.tools.smali.dexlib2.iface.instruction.DualReferenceInstruction;
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction;
import com.android.tools.smali.dexlib2.iface.instruction.SwitchElement;
+import com.android.tools.smali.util.CollectionUtils;
import com.android.tools.smali.util.ExceptionWithContext;
import javax.annotation.Nonnull;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -535,8 +536,9 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
try {
writer.writeUbyte(0);
writer.writeUbyte(getOpcodeValue(instruction.getOpcode()) >> 8);
- List<? extends SwitchElement> elements = Ordering.from(switchElementComparator).immutableSortedCopy(
- instruction.getSwitchElements());
+ List<? extends SwitchElement> elements = CollectionUtils.immutableSortedCopy(
+ instruction.getSwitchElements(), switchElementComparator);
+
writer.writeUshort(elements.size());
for (SwitchElement element: elements) {
writer.writeInt(element.getKey());
@@ -551,7 +553,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
private final Comparator<SwitchElement> switchElementComparator = new Comparator<SwitchElement>() {
@Override public int compare(SwitchElement element1, SwitchElement element2) {
- return Ints.compare(element1.getKey(), element2.getKey());
+ return Integer.compare(element1.getKey(), element2.getKey());
}
};
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationPool.java
index 637dd05e..4d3e1072 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationPool.java
@@ -32,18 +32,18 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.writer.AnnotationSection;
-import com.google.common.collect.Maps;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderEncodedValue;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
class BuilderAnnotationPool extends BaseBuilderPool implements AnnotationSection<BuilderStringReference,
BuilderTypeReference, BuilderAnnotation, BuilderAnnotationElement, BuilderEncodedValue> {
@Nonnull private final ConcurrentMap<Annotation, BuilderAnnotation> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();
public BuilderAnnotationPool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSet.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSet.java
index ae281301..915e771b 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSet.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSet.java
@@ -31,16 +31,16 @@
package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.writer.DexWriter;
-import com.google.common.collect.ImmutableSet;
import javax.annotation.Nonnull;
import java.util.AbstractSet;
+import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
public class BuilderAnnotationSet extends AbstractSet<BuilderAnnotation> {
public static final BuilderAnnotationSet EMPTY =
- new BuilderAnnotationSet(ImmutableSet.<BuilderAnnotation>of());
+ new BuilderAnnotationSet(Collections.emptySet());
@Nonnull final Set<BuilderAnnotation> annotations;
int offset = DexWriter.NO_OFFSET;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSetPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSetPool.java
index eacb472f..f53e9434 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSetPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderAnnotationSetPool.java
@@ -33,22 +33,21 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.writer.AnnotationSetSection;
import com.android.tools.smali.dexlib2.writer.DexWriter;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Maps;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.stream.Collectors;
class BuilderAnnotationSetPool extends BaseBuilderPool
implements AnnotationSetSection<BuilderAnnotation, BuilderAnnotationSet> {
@Nonnull private final ConcurrentMap<Set<? extends Annotation>, BuilderAnnotationSet> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();
public BuilderAnnotationSetPool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
@@ -65,12 +64,9 @@ class BuilderAnnotationSetPool extends BaseBuilderPool
}
BuilderAnnotationSet annotationSet = new BuilderAnnotationSet(
- ImmutableSet.copyOf(Iterators.transform(annotations.iterator(),
- new Function<Annotation, BuilderAnnotation>() {
- @Nullable @Override public BuilderAnnotation apply(Annotation input) {
- return dexBuilder.annotationSection.internAnnotation(input);
- }
- })));
+ Collections.unmodifiableSet(annotations.stream()
+ .map(annotation -> dexBuilder.annotationSection.internAnnotation(annotation))
+ .collect(Collectors.toSet())));
ret = internedItems.putIfAbsent(annotationSet, annotationSet);
return ret==null?annotationSet:ret;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSitePool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSitePool.java
index df7a1987..23bf45ed 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSitePool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSitePool.java
@@ -32,19 +32,19 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.writer.CallSiteSection;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderArrayEncodedValue;
-import com.google.common.collect.Maps;
import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
import com.android.tools.smali.dexlib2.writer.util.CallSiteUtil;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class BuilderCallSitePool extends BaseBuilderPool
implements CallSiteSection<BuilderCallSiteReference, BuilderArrayEncodedValue> {
@Nonnull private final ConcurrentMap<CallSiteReference, BuilderCallSiteReference> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();
public BuilderCallSitePool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSiteReference.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSiteReference.java
index 75803034..a610e578 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSiteReference.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderCallSiteReference.java
@@ -31,7 +31,6 @@
package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.writer.DexWriter;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.base.reference.BaseCallSiteReference;
import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderArrayEncodedValue;
@@ -40,6 +39,7 @@ import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.Build
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderMethodTypeEncodedValue;
import javax.annotation.Nonnull;
+import java.util.Collections;
import java.util.List;
public class BuilderCallSiteReference extends BaseCallSiteReference implements BuilderReference {
@@ -71,7 +71,7 @@ public class BuilderCallSiteReference extends BaseCallSiteReference implements B
@Nonnull @Override public List<? extends BuilderEncodedValue> getExtraArguments() {
if (encodedCallSite.elements.size() <= 3) {
- return ImmutableList.of();
+ return Collections.emptyList();
}
return encodedCallSite.elements.subList(3, encodedCallSite.elements.size());
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassDef.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassDef.java
index 43375b1c..b6d0c29a 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassDef.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassDef.java
@@ -33,21 +33,20 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.iface.ClassDef;
import com.android.tools.smali.dexlib2.util.MethodUtil;
import com.android.tools.smali.dexlib2.writer.DexWriter;
-import com.google.common.base.Functions;
import com.android.tools.smali.dexlib2.base.reference.BaseTypeReference;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderArrayEncodedValue;
+import com.android.tools.smali.util.ArraySortedSet;
+import com.android.tools.smali.util.CollectionUtils;
+import com.android.tools.smali.util.IteratorUtils;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Ordering;
import java.util.AbstractCollection;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -78,13 +77,13 @@ public class BuilderClassDef extends BaseTypeReference implements ClassDef {
@Nullable Iterable<? extends BuilderMethod> methods,
@Nullable BuilderArrayEncodedValue staticInitializers) {
if (methods == null) {
- methods = ImmutableList.of();
+ methods = Collections.emptyList();
}
if (staticFields == null) {
- staticFields = ImmutableSortedSet.of();
+ staticFields = Collections.emptySortedSet();
}
if (instanceFields == null) {
- instanceFields = ImmutableSortedSet.of();
+ instanceFields = Collections.emptySortedSet();
}
this.type = type;
@@ -95,8 +94,10 @@ public class BuilderClassDef extends BaseTypeReference implements ClassDef {
this.annotations = annotations;
this.staticFields = staticFields;
this.instanceFields = instanceFields;
- this.directMethods = ImmutableSortedSet.copyOf(Iterables.filter(methods, MethodUtil.METHOD_IS_DIRECT));
- this.virtualMethods = ImmutableSortedSet.copyOf(Iterables.filter(methods, MethodUtil.METHOD_IS_VIRTUAL));
+ this.directMethods = ArraySortedSet.copyOf(CollectionUtils.naturalOrdering(), IteratorUtils.toList(
+ (Iterator<? extends BuilderMethod>)IteratorUtils.filter(methods, MethodUtil.METHOD_IS_DIRECT)));
+ this.virtualMethods = ArraySortedSet.copyOf(CollectionUtils.naturalOrdering(), IteratorUtils.toList(
+ (Iterator<? extends BuilderMethod>)IteratorUtils.filter(methods, MethodUtil.METHOD_IS_VIRTUAL)));
this.staticInitializers = staticInitializers;
}
@@ -112,15 +113,18 @@ public class BuilderClassDef extends BaseTypeReference implements ClassDef {
@Nonnull @Override
public List<String> getInterfaces() {
- return Lists.transform(this.interfaces, Functions.toStringFunction());
+ return this.interfaces.stream()
+ .map(iface -> iface.toString())
+ .collect(Collectors.toList());
}
@Nonnull @Override public Collection<BuilderField> getFields() {
return new AbstractCollection<BuilderField>() {
@Nonnull @Override public Iterator<BuilderField> iterator() {
- return Iterators.mergeSorted(
- ImmutableList.of(staticFields.iterator(), instanceFields.iterator()),
- Ordering.natural());
+ ArrayList<BuilderField> fields = new ArrayList<>(staticFields);
+ fields.addAll(instanceFields);
+ Collections.sort(fields, CollectionUtils.naturalOrdering());
+ return fields.iterator();
}
@Override public int size() {
@@ -132,9 +136,10 @@ public class BuilderClassDef extends BaseTypeReference implements ClassDef {
@Nonnull @Override public Collection<BuilderMethod> getMethods() {
return new AbstractCollection<BuilderMethod>() {
@Nonnull @Override public Iterator<BuilderMethod> iterator() {
- return Iterators.mergeSorted(
- ImmutableList.of(directMethods.iterator(), virtualMethods.iterator()),
- Ordering.natural());
+ ArrayList<BuilderMethod> methods = new ArrayList<>(directMethods);
+ methods.addAll(virtualMethods);
+ Collections.sort(methods, CollectionUtils.naturalOrdering());
+ return methods.iterator();
}
@Override public int size() {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassPool.java
index 0b6f92e7..25f780fd 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderClassPool.java
@@ -46,9 +46,8 @@ import com.android.tools.smali.dexlib2.util.EncodedValueUtils;
import com.android.tools.smali.dexlib2.writer.ClassSection;
import com.android.tools.smali.dexlib2.writer.DebugWriter;
import com.android.tools.smali.util.AbstractForwardSequentialList;
+import com.android.tools.smali.util.CollectionUtils;
import com.android.tools.smali.util.ExceptionWithContext;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation;
import com.android.tools.smali.dexlib2.iface.instruction.Instruction;
import com.android.tools.smali.dexlib2.iface.reference.StringReference;
@@ -57,16 +56,17 @@ import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderArrayEncodedValue;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderEncodedValue;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Ordering;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
@@ -77,7 +77,7 @@ public class BuilderClassPool extends BaseBuilderPool implements ClassSection<Bu
BuilderTypeReference, BuilderTypeList, BuilderClassDef, BuilderField, BuilderMethod, BuilderAnnotationSet,
BuilderArrayEncodedValue> {
@Nonnull private final ConcurrentMap<String, BuilderClassDef> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();
public BuilderClassPool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
@@ -91,10 +91,11 @@ public class BuilderClassPool extends BaseBuilderPool implements ClassSection<Bu
return classDef;
}
- private ImmutableList<BuilderClassDef> sortedClasses = null;
+ private List<BuilderClassDef> sortedClasses = null;
@Nonnull @Override public Collection<? extends BuilderClassDef> getSortedClasses() {
if (sortedClasses == null) {
- sortedClasses = Ordering.natural().immutableSortedCopy(internedItems.values());
+ sortedClasses = CollectionUtils.immutableSortedCopy(
+ internedItems.values(), CollectionUtils.naturalOrdering());
}
return sortedClasses;
}
@@ -147,7 +148,7 @@ public class BuilderClassPool extends BaseBuilderPool implements ClassSection<Bu
private static final Predicate<Field> HAS_INITIALIZER = new Predicate<Field>() {
@Override
- public boolean apply(Field input) {
+ public boolean test(Field input) {
EncodedValue encodedValue = input.getInitialValue();
return encodedValue != null && !EncodedValueUtils.isDefaultValue(encodedValue);
}
@@ -242,7 +243,7 @@ public class BuilderClassPool extends BaseBuilderPool implements ClassSection<Bu
private static final Predicate<BuilderMethodParameter> HAS_PARAMETER_ANNOTATIONS =
new Predicate<BuilderMethodParameter>() {
@Override
- public boolean apply(BuilderMethodParameter input) {
+ public boolean test(BuilderMethodParameter input) {
return input.getAnnotations().size() > 0;
}
};
@@ -258,13 +259,12 @@ public class BuilderClassPool extends BaseBuilderPool implements ClassSection<Bu
@Nullable @Override public List<? extends BuilderAnnotationSet> getParameterAnnotations(
@Nonnull final BuilderMethod method) {
final List<? extends BuilderMethodParameter> parameters = method.getParameters();
- boolean hasParameterAnnotations = Iterables.any(parameters, HAS_PARAMETER_ANNOTATIONS);
+ boolean hasParameterAnnotations = parameters.stream().anyMatch(HAS_PARAMETER_ANNOTATIONS);
if (hasParameterAnnotations) {
return new AbstractForwardSequentialList<BuilderAnnotationSet>() {
@Nonnull @Override public Iterator<BuilderAnnotationSet> iterator() {
- return FluentIterable.from(parameters)
- .transform(PARAMETER_ANNOTATIONS).iterator();
+ return parameters.stream().map(PARAMETER_ANNOTATIONS).iterator();
}
@Override public int size() {
@@ -286,11 +286,8 @@ public class BuilderClassPool extends BaseBuilderPool implements ClassSection<Bu
@Nullable @Override
public Iterable<? extends BuilderStringReference> getParameterNames(@Nonnull BuilderMethod method) {
- return Iterables.transform(method.getParameters(), new Function<BuilderMethodParameter, BuilderStringReference>() {
- @Nullable @Override public BuilderStringReference apply(BuilderMethodParameter input) {
- return input.name;
- }
- });
+ return method.getParameters().stream().map(
+ builderMethodParameter -> builderMethodParameter.name).collect(Collectors.toList());
}
@Override public int getRegisterCount(@Nonnull BuilderMethod builderMethod) {
@@ -314,7 +311,7 @@ public class BuilderClassPool extends BaseBuilderPool implements ClassSection<Bu
public List<? extends TryBlock<? extends ExceptionHandler>> getTryBlocks(@Nonnull BuilderMethod builderMethod) {
MethodImplementation impl = builderMethod.getImplementation();
if (impl == null) {
- return ImmutableList.of();
+ return Collections.emptyList();
}
return impl.getTryBlocks();
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderEncodedArrayPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderEncodedArrayPool.java
index d5a0e468..db390d97 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderEncodedArrayPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderEncodedArrayPool.java
@@ -33,19 +33,19 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.writer.EncodedArraySection;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderArrayEncodedValue;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderEncodedValue;
-import com.google.common.collect.Maps;
import com.android.tools.smali.dexlib2.iface.value.ArrayEncodedValue;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class BuilderEncodedArrayPool extends BaseBuilderPool implements
EncodedArraySection<BuilderArrayEncodedValue, BuilderEncodedValue> {
@Nonnull private final ConcurrentMap<ArrayEncodedValue, BuilderArrayEncodedValue> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();
public BuilderEncodedArrayPool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderFieldPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderFieldPool.java
index 1cba2260..32d00373 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderFieldPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderFieldPool.java
@@ -32,19 +32,19 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableFieldReference;
import com.android.tools.smali.dexlib2.writer.FieldSection;
-import com.google.common.collect.Maps;
import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class BuilderFieldPool extends BaseBuilderPool
implements
FieldSection<BuilderStringReference, BuilderTypeReference, BuilderFieldReference, BuilderField> {
@Nonnull private final ConcurrentMap<FieldReference, BuilderFieldReference> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();
public BuilderFieldPool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodHandlePool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodHandlePool.java
index e63c9937..76b6b082 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodHandlePool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodHandlePool.java
@@ -33,13 +33,13 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.MethodHandleType;
import com.android.tools.smali.dexlib2.writer.MethodHandleSection;
import com.android.tools.smali.util.ExceptionWithContext;
-import com.google.common.collect.Maps;
import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
import javax.annotation.Nonnull;
import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
@@ -47,7 +47,7 @@ public class BuilderMethodHandlePool extends BaseBuilderPool
implements
MethodHandleSection<BuilderMethodHandleReference, BuilderFieldReference, BuilderMethodReference> {
@Nonnull private final ConcurrentMap<MethodHandleReference, BuilderMethodHandleReference> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();;
public BuilderMethodHandlePool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodPool.java
index 725de9ea..cf8ef1e6 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderMethodPool.java
@@ -31,7 +31,6 @@
package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.writer.MethodSection;
-import com.google.common.collect.Maps;
import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
@@ -39,12 +38,13 @@ import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
class BuilderMethodPool extends BaseBuilderPool implements MethodSection<BuilderStringReference, BuilderTypeReference,
BuilderMethodProtoReference, BuilderMethodReference, BuilderMethod> {
@Nonnull private final ConcurrentMap<MethodReference, BuilderMethodReference> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();
public BuilderMethodPool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderProtoPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderProtoPool.java
index 00f0ed19..027a924e 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderProtoPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderProtoPool.java
@@ -33,7 +33,6 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodProtoReference;
import com.android.tools.smali.dexlib2.util.MethodUtil;
import com.android.tools.smali.dexlib2.writer.ProtoSection;
-import com.google.common.collect.Maps;
import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference;
import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
@@ -41,13 +40,14 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
class BuilderProtoPool extends BaseBuilderPool
implements
ProtoSection<BuilderStringReference, BuilderTypeReference, BuilderMethodProtoReference, BuilderTypeList> {
@Nonnull private final ConcurrentMap<MethodProtoReference, BuilderMethodProtoReference> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();
public BuilderProtoPool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderStringPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderStringPool.java
index 406da029..ac2fa64a 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderStringPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderStringPool.java
@@ -32,16 +32,16 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.writer.DexWriter;
import com.android.tools.smali.dexlib2.writer.StringSection;
-import com.google.common.collect.Maps;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
class BuilderStringPool implements StringSection<BuilderStringReference, BuilderStringReference> {
- @Nonnull private final ConcurrentMap<String, BuilderStringReference> internedItems = Maps.newConcurrentMap();
+ @Nonnull private final ConcurrentMap<String, BuilderStringReference> internedItems = new ConcurrentHashMap<>();
@Nonnull BuilderStringReference internString(@Nonnull String string) {
BuilderStringReference ret = internedItems.get(string);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeList.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeList.java
index 0cb9b7ed..7dbec167 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeList.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeList.java
@@ -31,14 +31,14 @@
package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.writer.DexWriter;
-import com.google.common.collect.ImmutableList;
import javax.annotation.Nonnull;
import java.util.AbstractList;
+import java.util.Collections;
import java.util.List;
public class BuilderTypeList extends AbstractList<BuilderTypeReference> {
- static final BuilderTypeList EMPTY = new BuilderTypeList(ImmutableList.<BuilderTypeReference>of());
+ static final BuilderTypeList EMPTY = new BuilderTypeList(Collections.emptyList());
@Nonnull final List<? extends BuilderTypeReference> types;
int offset = DexWriter.NO_OFFSET;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeListPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeListPool.java
index 4b7942b2..049463e2 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeListPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypeListPool.java
@@ -32,22 +32,21 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.writer.DexWriter;
import com.android.tools.smali.dexlib2.writer.TypeListSection;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
+import java.util.stream.Collectors;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
class BuilderTypeListPool extends BaseBuilderPool implements
TypeListSection<BuilderTypeReference, BuilderTypeList> {
@Nonnull private final ConcurrentMap<List<? extends CharSequence>, BuilderTypeList> internedItems =
- Maps.newConcurrentMap();
+ new ConcurrentHashMap<>();
public BuilderTypeListPool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
@@ -64,11 +63,10 @@ class BuilderTypeListPool extends BaseBuilderPool implements
}
BuilderTypeList typeList = new BuilderTypeList(
- ImmutableList.copyOf(Iterables.transform(types, new Function<CharSequence, BuilderTypeReference>() {
- @Nonnull @Override public BuilderTypeReference apply(CharSequence input) {
- return dexBuilder.typeSection.internType(input.toString());
- }
- })));
+ Collections.unmodifiableList(
+ types.stream()
+ .map(type -> dexBuilder.typeSection.internType(type.toString()))
+ .collect(Collectors.toList())));
ret = internedItems.putIfAbsent(typeList, typeList);
return ret==null?typeList:ret;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypePool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypePool.java
index dfd6c20d..a14dcaac 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypePool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/BuilderTypePool.java
@@ -32,17 +32,17 @@ package com.android.tools.smali.dexlib2.writer.builder;
import com.android.tools.smali.dexlib2.writer.DexWriter;
import com.android.tools.smali.dexlib2.writer.TypeSection;
-import com.google.common.collect.Maps;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
class BuilderTypePool extends BaseBuilderPool
implements TypeSection<BuilderStringReference, BuilderTypeReference, BuilderTypeReference> {
- @Nonnull private final ConcurrentMap<String, BuilderTypeReference> internedItems = Maps.newConcurrentMap();
+ @Nonnull private final ConcurrentMap<String, BuilderTypeReference> internedItems = new ConcurrentHashMap<>();
public BuilderTypePool(@Nonnull DexBuilder dexBuilder) {
super(dexBuilder);
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/DexBuilder.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/DexBuilder.java
index cd54a6e4..1b1abcc1 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/DexBuilder.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/builder/DexBuilder.java
@@ -84,22 +84,24 @@ import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.Build
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderShortEncodedValue;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderStringEncodedValue;
import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderTypeEncodedValue;
+import com.android.tools.smali.util.ArraySortedSet;
+import com.android.tools.smali.util.CollectionUtils;
import com.android.tools.smali.util.ExceptionWithContext;
-import com.google.common.base.Function;
+import com.android.tools.smali.util.IteratorUtils;
+import com.android.tools.smali.util.TransformedIterator;
import com.android.tools.smali.dexlib2.writer.util.StaticInitializerUtil;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Sets;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.SortedSet;
+import java.util.function.Function;
+import java.util.stream.Collectors;
public class DexBuilder extends DexWriter<BuilderStringReference, BuilderStringReference, BuilderTypeReference,
BuilderTypeReference, BuilderMethodProtoReference, BuilderFieldReference, BuilderMethodReference,
@@ -140,7 +142,7 @@ public class DexBuilder extends DexWriter<BuilderStringReference, BuilderStringR
@Nonnull Set<HiddenApiRestriction> hiddenApiRestrictions,
@Nullable MethodImplementation methodImplementation) {
if (parameters == null) {
- parameters = ImmutableList.of();
+ parameters = Collections.emptyList();
}
return new BuilderMethod(methodSection.internMethod(definingClass, name, parameters, returnType),
internMethodParameters(parameters),
@@ -159,9 +161,9 @@ public class DexBuilder extends DexWriter<BuilderStringReference, BuilderStringR
@Nullable Iterable<? extends BuilderField> fields,
@Nullable Iterable<? extends BuilderMethod> methods) {
if (interfaces == null) {
- interfaces = ImmutableList.of();
+ interfaces = Collections.emptyList();
} else {
- Set<String> interfaces_copy = Sets.newHashSet(interfaces);
+ Set<String> interfaces_copy = new HashSet<>(interfaces);
Iterator<String> interfaceIterator = interfaces.iterator();
while (interfaceIterator.hasNext()) {
String iface = interfaceIterator.next();
@@ -173,13 +175,18 @@ public class DexBuilder extends DexWriter<BuilderStringReference, BuilderStringR
}
}
- ImmutableSortedSet<BuilderField> staticFields = null;
- ImmutableSortedSet<BuilderField> instanceFields = null;
+ SortedSet<BuilderField> staticFields = null;
+ SortedSet<BuilderField> instanceFields = null;
BuilderArrayEncodedValue internedStaticInitializers = null;
if (fields != null) {
- staticFields = ImmutableSortedSet.copyOf(Iterables.filter(fields, FieldUtil.FIELD_IS_STATIC));
- instanceFields = ImmutableSortedSet.copyOf(Iterables.filter(fields, FieldUtil.FIELD_IS_INSTANCE));
- ArrayEncodedValue staticInitializers = StaticInitializerUtil.getStaticInitializers(staticFields);
+ staticFields = ArraySortedSet.copyOf(CollectionUtils.naturalOrdering(),
+ IteratorUtils.toList((Iterator<? extends BuilderField>) IteratorUtils
+ .filter(fields, FieldUtil.FIELD_IS_STATIC)));
+ instanceFields = ArraySortedSet.copyOf(CollectionUtils.naturalOrdering(),
+ IteratorUtils.toList((Iterator<? extends BuilderField>) IteratorUtils
+ .filter(fields, FieldUtil.FIELD_IS_INSTANCE)));
+ ArrayEncodedValue staticInitializers = StaticInitializerUtil
+ .getStaticInitializers(staticFields);
if (staticInitializers != null) {
internedStaticInitializers = encodedArraySection.internArrayEncodedValue(staticInitializers);
}
@@ -267,14 +274,10 @@ public class DexBuilder extends DexWriter<BuilderStringReference, BuilderStringR
@Nonnull private List<BuilderMethodParameter> internMethodParameters(
@Nullable List<? extends MethodParameter> methodParameters) {
if (methodParameters == null) {
- return ImmutableList.of();
+ return Collections.emptyList();
}
- return ImmutableList.copyOf(Iterators.transform(methodParameters.iterator(),
- new Function<MethodParameter, BuilderMethodParameter>() {
- @Nullable @Override public BuilderMethodParameter apply(MethodParameter input) {
- return internMethodParameter(input);
- }
- }));
+ return Collections.unmodifiableList(methodParameters.stream().map(methodParam ->
+ internMethodParameter(methodParam)).collect(Collectors.toList()));
}
@Nonnull private BuilderMethodParameter internMethodParameter(@Nonnull MethodParameter methodParameter) {
@@ -350,14 +353,8 @@ public class DexBuilder extends DexWriter<BuilderStringReference, BuilderStringR
@Nonnull Set<? extends BuilderAnnotationElement> internAnnotationElements(
@Nonnull Set<? extends AnnotationElement> elements) {
- return ImmutableSet.copyOf(
- Iterators.transform(elements.iterator(),
- new Function<AnnotationElement, BuilderAnnotationElement>() {
- @Nullable @Override
- public BuilderAnnotationElement apply(AnnotationElement input) {
- return internAnnotationElement(input);
- }
- }));
+ return Collections.unmodifiableSet(elements.stream().map(annotationElement ->
+ internAnnotationElement(annotationElement)).collect(Collectors.toSet()));
}
@Nonnull private BuilderAnnotationElement internAnnotationElement(@Nonnull AnnotationElement annotationElement) {
@@ -423,14 +420,8 @@ public class DexBuilder extends DexWriter<BuilderStringReference, BuilderStringR
}
@Nonnull private BuilderArrayEncodedValue internArrayEncodedValue(@Nonnull ArrayEncodedValue value) {
- return new BuilderArrayEncodedValue(
- ImmutableList.copyOf(
- Iterators.transform(value.getValue().iterator(),
- new Function<EncodedValue, BuilderEncodedValue>() {
- @Nullable @Override public BuilderEncodedValue apply(EncodedValue input) {
- return internEncodedValue(input);
- }
- })));
+ return new BuilderArrayEncodedValue(Collections.unmodifiableList(value.getValue().stream()
+ .map(encodedVal -> internEncodedValue(encodedVal)).collect(Collectors.toList())));
}
@Nonnull private BuilderEnumEncodedValue internEnumEncodedValue(@Nonnull EnumEncodedValue value) {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/FileDeferredOutputStream.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/FileDeferredOutputStream.java
index c425e297..a89af844 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/FileDeferredOutputStream.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/FileDeferredOutputStream.java
@@ -30,7 +30,7 @@
package com.android.tools.smali.dexlib2.writer.io;
-import com.google.common.io.ByteStreams;
+import com.android.tools.smali.util.InputStreamUtil;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -71,7 +71,7 @@ public class FileDeferredOutputStream extends DeferredOutputStream {
// did we actually write something out to disk?
if (count != writtenBytes) {
InputStream fis = new FileInputStream(backingFile);
- ByteStreams.copy(fis, dest);
+ InputStreamUtil.copy(fis, dest);
backingFile.delete();
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/MemoryDeferredOutputStream.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/MemoryDeferredOutputStream.java
index e9811009..d4392fa9 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/MemoryDeferredOutputStream.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/io/MemoryDeferredOutputStream.java
@@ -30,11 +30,10 @@
package com.android.tools.smali.dexlib2.writer.io;
-import com.google.common.collect.Lists;
-
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -43,7 +42,7 @@ import java.util.List;
public class MemoryDeferredOutputStream extends DeferredOutputStream {
private static final int DEFAULT_BUFFER_SIZE = 16 * 1024;
- private final List<byte[]> buffers = Lists.newArrayList();
+ private final List<byte[]> buffers = new ArrayList<>();
private byte[] currentBuffer;
private int currentPosition;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/BasePool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/BasePool.java
index 63c12f2a..c81f9a27 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/BasePool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/BasePool.java
@@ -30,15 +30,14 @@
package com.android.tools.smali.dexlib2.writer.pool;
-import com.google.common.collect.Maps;
-
import javax.annotation.Nonnull;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.Map;
public class BasePool<Key, Value> implements Markable {
@Nonnull protected final DexPool dexPool;
- @Nonnull protected final Map<Key, Value> internedItems = Maps.newLinkedHashMap();
+ @Nonnull protected final Map<Key, Value> internedItems = new LinkedHashMap<>();
private int markedItemCount = -1;
public BasePool(@Nonnull DexPool dexPool) {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/ClassPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/ClassPool.java
index a6a6fbb0..be61f1b9 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/ClassPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/ClassPool.java
@@ -59,13 +59,9 @@ import com.android.tools.smali.dexlib2.writer.ClassSection;
import com.android.tools.smali.dexlib2.writer.DebugWriter;
import com.android.tools.smali.dexlib2.writer.util.StaticInitializerUtil;
import com.android.tools.smali.util.AbstractForwardSequentialList;
+import com.android.tools.smali.util.CollectionUtils;
import com.android.tools.smali.util.ExceptionWithContext;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Ordering;
+import com.android.tools.smali.util.TransformedIterator;
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation;
import com.android.tools.smali.dexlib2.formatter.DexFormatter;
import com.android.tools.smali.dexlib2.iface.instruction.DualReferenceInstruction;
@@ -75,12 +71,16 @@ import com.android.tools.smali.dexlib2.iface.value.ArrayEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
import java.util.AbstractCollection;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
@@ -235,10 +235,11 @@ public class ClassPool extends BasePool<String, PoolClassDef> implements ClassSe
}
}
- private ImmutableList<PoolClassDef> sortedClasses = null;
+ private List<PoolClassDef> sortedClasses = null;
@Nonnull @Override public Collection<? extends PoolClassDef> getSortedClasses() {
if (sortedClasses == null) {
- sortedClasses = Ordering.natural().immutableSortedCopy(internedItems.values());
+ sortedClasses = CollectionUtils.immutableSortedCopy(
+ internedItems.values(), CollectionUtils.usingToStringOrdering());
}
return sortedClasses;
}
@@ -360,7 +361,7 @@ public class ClassPool extends BasePool<String, PoolClassDef> implements ClassSe
private static final Predicate<MethodParameter> HAS_PARAMETER_ANNOTATIONS = new Predicate<MethodParameter>() {
@Override
- public boolean apply(MethodParameter input) {
+ public boolean test(MethodParameter input) {
return input.getAnnotations().size() > 0;
}
};
@@ -376,13 +377,12 @@ public class ClassPool extends BasePool<String, PoolClassDef> implements ClassSe
@Nullable @Override public List<? extends Set<? extends Annotation>> getParameterAnnotations(
@Nonnull final PoolMethod method) {
final List<? extends MethodParameter> parameters = method.getParameters();
- boolean hasParameterAnnotations = Iterables.any(parameters, HAS_PARAMETER_ANNOTATIONS);
+ boolean hasParameterAnnotations = parameters.stream().anyMatch(HAS_PARAMETER_ANNOTATIONS);
if (hasParameterAnnotations) {
return new AbstractForwardSequentialList<Set<? extends Annotation>>() {
@Nonnull @Override public Iterator<Set<? extends Annotation>> iterator() {
- return FluentIterable.from(parameters)
- .transform(PARAMETER_ANNOTATIONS).iterator();
+ return new TransformedIterator<>(parameters.iterator(), PARAMETER_ANNOTATIONS);
}
@Override public int size() {
@@ -402,7 +402,7 @@ public class ClassPool extends BasePool<String, PoolClassDef> implements ClassSe
}
@Nullable @Override public Iterable<CharSequence> getParameterNames(@Nonnull PoolMethod method) {
- return Iterables.transform(method.getParameters(), new Function<MethodParameter, CharSequence>() {
+ return new TransformedIterator(method.getParameters(), new Function<MethodParameter, CharSequence>() {
@Nullable @Override public CharSequence apply(MethodParameter input) {
return input.getName();
}
@@ -431,7 +431,7 @@ public class ClassPool extends BasePool<String, PoolClassDef> implements ClassSe
if (impl != null) {
return impl.getTryBlocks();
}
- return ImmutableList.of();
+ return Collections.emptyList();
}
@Nullable @Override public CharSequence getExceptionType(@Nonnull ExceptionHandler handler) {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolClassDef.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolClassDef.java
index 59e4a5bb..fc146ec0 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolClassDef.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolClassDef.java
@@ -30,32 +30,33 @@
package com.android.tools.smali.dexlib2.writer.pool;
+import com.android.tools.smali.dexlib2.base.reference.BaseTypeReference;
import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.ClassDef;
import com.android.tools.smali.dexlib2.iface.Field;
-import com.android.tools.smali.dexlib2.base.reference.BaseTypeReference;
+import com.android.tools.smali.util.ArraySortedSet;
+import com.android.tools.smali.util.CollectionUtils;
+import com.android.tools.smali.util.IteratorUtils;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Ordering;
import java.util.AbstractCollection;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
class PoolClassDef extends BaseTypeReference implements ClassDef {
@Nonnull final ClassDef classDef;
@Nonnull final TypeListPool.Key<List<String>> interfaces;
- @Nonnull final ImmutableSortedSet<Field> staticFields;
- @Nonnull final ImmutableSortedSet<Field> instanceFields;
- @Nonnull final ImmutableSortedSet<PoolMethod> directMethods;
- @Nonnull final ImmutableSortedSet<PoolMethod> virtualMethods;
+ @Nonnull final SortedSet<Field> staticFields;
+ @Nonnull final SortedSet<Field> instanceFields;
+ @Nonnull final SortedSet<PoolMethod> directMethods;
+ @Nonnull final SortedSet<PoolMethod> virtualMethods;
int classDefIndex = DexPool.NO_INDEX;
int annotationDirectoryOffset = DexPool.NO_OFFSET;
@@ -63,13 +64,17 @@ class PoolClassDef extends BaseTypeReference implements ClassDef {
PoolClassDef(@Nonnull ClassDef classDef) {
this.classDef = classDef;
- interfaces = new TypeListPool.Key<List<String>>(ImmutableList.copyOf(classDef.getInterfaces()));
- staticFields = ImmutableSortedSet.copyOf(classDef.getStaticFields());
- instanceFields = ImmutableSortedSet.copyOf(classDef.getInstanceFields());
- directMethods = ImmutableSortedSet.copyOf(
- Iterables.transform(classDef.getDirectMethods(), PoolMethod.TRANSFORM));
- virtualMethods = ImmutableSortedSet.copyOf(
- Iterables.transform(classDef.getVirtualMethods(), PoolMethod.TRANSFORM));
+ interfaces = new TypeListPool.Key<List<String>>(Collections.unmodifiableList(new ArrayList<>(classDef.getInterfaces())));
+ staticFields = ArraySortedSet.copyOf(CollectionUtils.naturalOrdering(),
+ IteratorUtils.toList(classDef.getStaticFields()));
+ instanceFields = ArraySortedSet.copyOf(CollectionUtils.naturalOrdering(),
+ IteratorUtils.toList(classDef.getInstanceFields()));
+ directMethods = ArraySortedSet.copyOf(CollectionUtils.naturalOrdering(),
+ IteratorUtils.toList(classDef.getDirectMethods()).stream().map(PoolMethod.TRANSFORM)
+ .collect(Collectors.toList()));
+ virtualMethods = ArraySortedSet.of(CollectionUtils.naturalOrdering(),
+ IteratorUtils.toList(classDef.getVirtualMethods()).stream().map(PoolMethod.TRANSFORM)
+ .collect(Collectors.toList()));
}
@Nonnull @Override public String getType() {
@@ -107,9 +112,10 @@ class PoolClassDef extends BaseTypeReference implements ClassDef {
@Nonnull @Override public Collection<Field> getFields() {
return new AbstractCollection<Field>() {
@Nonnull @Override public Iterator<Field> iterator() {
- return Iterators.mergeSorted(
- ImmutableList.of(staticFields.iterator(), instanceFields.iterator()),
- Ordering.natural());
+ ArrayList<Field> fields = new ArrayList<>(staticFields);
+ fields.addAll(instanceFields);
+ fields.sort(CollectionUtils.naturalOrdering());
+ return fields.iterator();
}
@Override public int size() {
@@ -129,9 +135,10 @@ class PoolClassDef extends BaseTypeReference implements ClassDef {
@Nonnull @Override public Collection<PoolMethod> getMethods() {
return new AbstractCollection<PoolMethod>() {
@Nonnull @Override public Iterator<PoolMethod> iterator() {
- return Iterators.mergeSorted(
- ImmutableList.of(directMethods.iterator(), virtualMethods.iterator()),
- Ordering.natural());
+ ArrayList<PoolMethod> methods = new ArrayList<>(directMethods);
+ methods.addAll(virtualMethods);
+ methods.sort(CollectionUtils.naturalOrdering());
+ return methods.iterator();
}
@Override public int size() {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolMethod.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolMethod.java
index 7594f5e7..7df8be50 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolMethod.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/PoolMethod.java
@@ -35,14 +35,13 @@ import com.android.tools.smali.dexlib2.iface.Annotation;
import com.android.tools.smali.dexlib2.iface.Method;
import com.android.tools.smali.dexlib2.iface.MethodImplementation;
import com.android.tools.smali.dexlib2.iface.MethodParameter;
-import com.google.common.base.Function;
import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Set;
-
+import java.util.function.Function;
class PoolMethod extends BaseMethodReference implements Method {
@Nonnull private final Method method;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/TypeListPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/TypeListPool.java
index 98e77c08..b36df14f 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/TypeListPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/TypeListPool.java
@@ -32,12 +32,12 @@ package com.android.tools.smali.dexlib2.writer.pool;
import com.android.tools.smali.dexlib2.writer.DexWriter;
import com.android.tools.smali.dexlib2.writer.TypeListSection;
-import com.google.common.collect.ImmutableList;
import com.android.tools.smali.dexlib2.writer.pool.TypeListPool.Key;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
public class TypeListPool extends BaseNullableOffsetPool<Key<? extends Collection<? extends CharSequence>>>
@@ -64,7 +64,7 @@ public class TypeListPool extends BaseNullableOffsetPool<Key<? extends Collectio
@Nonnull @Override
public Collection<? extends CharSequence> getTypes(Key<? extends Collection<? extends CharSequence>> typesKey) {
if (typesKey == null) {
- return ImmutableList.of();
+ return Collections.emptyList();
}
return typesKey.types;
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/CallSiteUtil.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/CallSiteUtil.java
index b17eddb8..53473a33 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/CallSiteUtil.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/CallSiteUtil.java
@@ -31,7 +31,6 @@
package com.android.tools.smali.dexlib2.writer.util;
import com.android.tools.smali.dexlib2.immutable.value.ImmutableStringEncodedValue;
-import com.google.common.collect.Lists;
import com.android.tools.smali.dexlib2.base.value.BaseArrayEncodedValue;
import com.android.tools.smali.dexlib2.base.value.BaseMethodHandleEncodedValue;
import com.android.tools.smali.dexlib2.base.value.BaseMethodTypeEncodedValue;
@@ -42,6 +41,7 @@ import com.android.tools.smali.dexlib2.iface.value.ArrayEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
+import java.util.ArrayList;
import java.util.List;
public class CallSiteUtil {
@@ -50,7 +50,7 @@ public class CallSiteUtil {
@Nonnull
@Override
public List<? extends EncodedValue> getValue() {
- List<EncodedValue> encodedCallSite = Lists.newArrayList();
+ List<EncodedValue> encodedCallSite = new ArrayList<>();
encodedCallSite.add(new BaseMethodHandleEncodedValue() {
@Nonnull
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/StaticInitializerUtil.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/StaticInitializerUtil.java
index 1974c95d..11c9a010 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/StaticInitializerUtil.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/StaticInitializerUtil.java
@@ -35,15 +35,15 @@ import com.android.tools.smali.dexlib2.immutable.value.ImmutableEncodedValueFact
import com.android.tools.smali.dexlib2.util.EncodedValueUtils;
import com.android.tools.smali.util.AbstractForwardSequentialList;
import com.android.tools.smali.util.CollectionUtils;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
import com.android.tools.smali.dexlib2.base.value.BaseArrayEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.ArrayEncodedValue;
import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
@@ -60,9 +60,8 @@ public class StaticInitializerUtil {
public List<? extends EncodedValue> getValue() {
return new AbstractForwardSequentialList<EncodedValue>() {
@Nonnull @Override public Iterator<EncodedValue> iterator() {
- return FluentIterable.from(sortedStaticFields)
- .limit(lastIndex+1)
- .transform(GET_INITIAL_VALUE).iterator();
+ return sortedStaticFields.stream().limit(lastIndex + 1)
+ .map(GET_INITIAL_VALUE).collect(Collectors.toList()).iterator();
}
@Override public int size() {
@@ -77,7 +76,7 @@ public class StaticInitializerUtil {
private static final Predicate<Field> HAS_INITIALIZER = new Predicate<Field>() {
@Override
- public boolean apply(Field input) {
+ public boolean test(Field input) {
EncodedValue encodedValue = input.getInitialValue();
return encodedValue != null && !EncodedValueUtils.isDefaultValue(encodedValue);
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/TryListBuilder.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/TryListBuilder.java
index 4670d16f..152bbff0 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/TryListBuilder.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/util/TryListBuilder.java
@@ -34,10 +34,11 @@ import com.android.tools.smali.dexlib2.base.BaseTryBlock;
import com.android.tools.smali.dexlib2.iface.ExceptionHandler;
import com.android.tools.smali.dexlib2.iface.TryBlock;
import com.android.tools.smali.util.ExceptionWithContext;
-import com.google.common.collect.Lists;
+import com.android.tools.smali.util.IteratorUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
@@ -101,7 +102,7 @@ public class TryListBuilder<EH extends ExceptionHandler>
public int startCodeAddress;
public int endCodeAddress;
- @Nonnull public List<EH> exceptionHandlers = Lists.newArrayList();
+ @Nonnull public List<EH> exceptionHandlers = new ArrayList<>();
public MutableTryBlock(int startCodeAddress, int endCodeAddress) {
this.startCodeAddress = startCodeAddress;
@@ -112,7 +113,7 @@ public class TryListBuilder<EH extends ExceptionHandler>
@Nonnull List<EH> exceptionHandlers) {
this.startCodeAddress = startCodeAddress;
this.endCodeAddress = endCodeAddress;
- this.exceptionHandlers = Lists.newArrayList(exceptionHandlers);
+ this.exceptionHandlers = new ArrayList<>(exceptionHandlers);
}
@Override public int getStartCodeAddress() {
@@ -312,7 +313,7 @@ public class TryListBuilder<EH extends ExceptionHandler>
}
public List<TryBlock<EH>> getTryBlocks() {
- return Lists.newArrayList(new Iterator<TryBlock<EH>>() {
+ return IteratorUtils.toList(new Iterator<TryBlock<EH>>() {
// The next TryBlock to return. This has already been merged, if needed.
@Nullable private MutableTryBlock<EH> next;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/AbstractIterator.java b/dexlib2/src/main/java/com/android/tools/smali/util/AbstractIterator.java
new file mode 100644
index 00000000..907a8635
--- /dev/null
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/AbstractIterator.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2024, Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.tools.smali.util;
+
+import javax.annotation.Nullable;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+public abstract class AbstractIterator<T> implements Iterator<T>, Iterable<T> {
+ /** We have computed the next element and haven't returned it yet. */
+ private static final int STATE_READY = 1;
+
+ /** We haven't yet computed or have already returned the element. */
+ private static final int STATE_NOT_READY = 2;
+
+ /** We have reached the end of the data and are finished. */
+ private static final int STATE_DONE = 3;
+
+ /** We've suffered an exception and are kaputt. */
+ private static final int STATE_FAILED = 4;
+
+ private int state = STATE_NOT_READY;
+ private T next;
+
+ protected final T endOfData() {
+ state = STATE_DONE;
+ return null;
+ }
+
+ @Override
+ public final boolean hasNext() {
+ switch (state) {
+ case STATE_DONE:
+ return false;
+ case STATE_READY:
+ return true;
+ case STATE_FAILED:
+ throw new IllegalStateException();
+ default:
+ }
+ return tryToComputeNext();
+ }
+
+ private boolean tryToComputeNext() {
+ state = STATE_FAILED; // temporary pessimism
+ next = computeNext();
+ if (state != STATE_DONE) {
+ state = STATE_READY;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public final T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ state = STATE_NOT_READY;
+ T result = next;
+ next = null;
+ return result;
+ }
+
+ @Override
+ public final Iterator<T> iterator() {
+ return this;
+ }
+
+ /**
+ * Computes next item for the iterator. If the end of the list has been reached, it should call
+ * endOfData. endOfData has a return value of T, so you can simply {@code return endOfData()}
+ *
+ * @return The item that was read. If endOfData was called, the return value is ignored.
+ */
+
+ @Nullable
+ protected abstract T computeNext();
+}
+
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/ArraySortedSet.java b/dexlib2/src/main/java/com/android/tools/smali/util/ArraySortedSet.java
index 46c90b64..7bc16138 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/ArraySortedSet.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/ArraySortedSet.java
@@ -30,31 +30,56 @@
package com.android.tools.smali.util;
-import com.google.common.collect.Iterators;
-
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
+/* A sorted set implemented with an underlying array. ArraySortedSet is inmutable. */
public class ArraySortedSet<T> implements SortedSet<T> {
@Nonnull private final Comparator<? super T> comparator;
@Nonnull private final Object[] arr;
private ArraySortedSet(@Nonnull Comparator<? super T> comparator, @Nonnull T[] arr) {
- // we assume arr is already sorted by comparator, and all entries are unique
this.comparator = comparator;
this.arr = arr;
+ assert assertSorted();
+ }
+
+ private ArraySortedSet(@Nonnull Comparator<? super T> comparator, @Nonnull Collection<? extends T> collection) {
+ this.comparator = comparator;
+ this.arr = collection.toArray();
+ assert assertSorted();
}
public static <T> ArraySortedSet<T> of(@Nonnull Comparator<? super T> comparator, @Nonnull T[] arr) {
return new ArraySortedSet<T>(comparator, arr);
}
+ public static <T> ArraySortedSet<T> of(@Nonnull Comparator<? super T> comparator, @Nonnull Collection<? extends T> collection) {
+ return new ArraySortedSet<T>(comparator, collection);
+ }
+
+ /* Copies without duplicates and sorts the given collection to create an ArraySortedSet from it */
+ public static <T> ArraySortedSet<T> copyOf(@Nonnull Comparator<? super T> comparator, @Nonnull Collection<? extends T> collection) {
+ List<T> tmp = (List<T>)collection.stream().distinct().sorted(comparator).collect(Collectors.toList());
+ return new ArraySortedSet<T>(comparator, (T[])tmp.toArray());
+ }
+
+ private boolean assertSorted() {
+ for (int i = 1; i < arr.length; i++) {
+ assert comparator.compare((T)arr[i - 1], (T)arr[i]) < 0;
+ }
+ return true;
+ }
+
@Override
public int size() {
return arr.length;
@@ -74,7 +99,7 @@ public class ArraySortedSet<T> implements SortedSet<T> {
@Override
@SuppressWarnings("unchecked")
public Iterator<T> iterator() {
- return Iterators.forArray((T[])arr);
+ return Arrays.asList((T[])arr).iterator();
}
@Override
@@ -189,7 +214,7 @@ public class ArraySortedSet<T> implements SortedSet<T> {
if (arr.length != other.size()) {
return false;
}
- return Iterators.elementsEqual(iterator(), other.iterator());
+ return IteratorUtils.elementsEqual(iterator(), other.iterator());
}
if (o instanceof Set) {
Set other = (Set)o;
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/ChainedIterator.java b/dexlib2/src/main/java/com/android/tools/smali/util/ChainedIterator.java
index ed8eab1f..3c342471 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/ChainedIterator.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/ChainedIterator.java
@@ -32,7 +32,6 @@ package com.android.tools.smali.util;
import java.lang.Iterable;
import java.util.Iterator;
-import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Combines two iterators into a single iterator. The returned iterator iterates across the elements
@@ -41,7 +40,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
* <p>
* The returned iterator does not support {@code remove()}.
*/
-public class ChainedIterator<T extends @Nullable Object> implements Iterator<T>, Iterable<T> {
+public class ChainedIterator<T extends Object> implements Iterator<T>, Iterable<T> {
Iterator<T> iteratorA;
Iterator<T> iteratorB;
@@ -50,6 +49,11 @@ public class ChainedIterator<T extends @Nullable Object> implements Iterator<T>,
this.iteratorB = iterableB.iterator();
}
+ public ChainedIterator(Iterator<T> iteratorA, Iterator<T> iteratorB) {
+ this.iteratorA = iteratorA;
+ this.iteratorB = iteratorB;
+ }
+
@Override
public final boolean hasNext() {
return iteratorA.hasNext() || iteratorB.hasNext();
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/CharSequenceUtils.java b/dexlib2/src/main/java/com/android/tools/smali/util/CharSequenceUtils.java
index 587cf2a1..f7b08e32 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/CharSequenceUtils.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/CharSequenceUtils.java
@@ -30,21 +30,25 @@
package com.android.tools.smali.util;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.collect.Lists;
+import java.util.function.Function;
+import java.util.Iterator;
import java.util.List;
public class CharSequenceUtils {
- private static final Function<Object, String> TO_STRING = Functions.toStringFunction();
+ private static final Function<Object, String> TO_STRING = new Function<Object,String>() {
+ @Override
+ public String apply(Object o) {
+ return o.toString();
+ }
+ };
public static int listHashCode(List<? extends CharSequence> list) {
- return Lists.transform(list, TO_STRING).hashCode();
+ return IteratorUtils.toList((Iterator)new TransformedIterator(list.iterator(), TO_STRING)).hashCode();
}
public static boolean listEquals(List<? extends CharSequence> list1, List<? extends CharSequence> list2) {
- return Lists.transform(list1, TO_STRING).equals(
- Lists.transform(list2, TO_STRING));
+ return IteratorUtils.toList((Iterator)new TransformedIterator(list1.iterator(), TO_STRING)).equals(
+ IteratorUtils.toList((Iterator)new TransformedIterator(list2.iterator(), TO_STRING)));
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/CollectionUtils.java b/dexlib2/src/main/java/com/android/tools/smali/util/CollectionUtils.java
index 2fe222af..7883dcfa 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/CollectionUtils.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/CollectionUtils.java
@@ -30,14 +30,16 @@
package com.android.tools.smali.util;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableSortedSet;
+import com.android.tools.smali.util.ArraySortedSet;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
+import java.util.List;
import java.util.SortedSet;
+import java.util.function.Predicate;
import javax.annotation.Nonnull;
@@ -54,7 +56,7 @@ public class CollectionUtils {
int index = 0;
int lastMatchingIndex = -1;
for (T item: iterable) {
- if (predicate.apply(item)) {
+ if (predicate.test(item)) {
lastMatchingIndex = index;
}
index++;
@@ -177,7 +179,7 @@ public class CollectionUtils {
}
}
- return ImmutableSortedSet.copyOf(elementComparator, collection);
+ return Collections.unmodifiableSortedSet(ArraySortedSet.of(elementComparator, collection));
}
@Nonnull
@@ -224,6 +226,13 @@ public class CollectionUtils {
return 0;
}
+ public static <T> List<T> immutableSortedCopy(
+ @Nonnull Collection<T> collection, @Nonnull Comparator<? super T> comparator) {
+ ArrayList<T> copy = new ArrayList<>(collection);
+ copy.sort(comparator);
+ return Collections.unmodifiableList(copy);
+ }
+
public static <T> Comparator<? super T> usingToStringOrdering() {
return UsingToStringOrdering.INSTANCE;
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/ImmutableConverter.java b/dexlib2/src/main/java/com/android/tools/smali/util/ImmutableConverter.java
index a526c74d..5d48d705 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/ImmutableConverter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/ImmutableConverter.java
@@ -30,28 +30,34 @@
package com.android.tools.smali.util;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
+import static java.util.Collections.unmodifiableList;
+import static java.util.Collections.unmodifiableSet;
+import static java.util.Collections.unmodifiableSortedSet;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
import java.util.SortedSet;
+import java.util.TreeSet;
public abstract class ImmutableConverter<ImmutableItem, Item> {
protected abstract boolean isImmutable(@Nonnull Item item);
@Nonnull protected abstract ImmutableItem makeImmutable(@Nonnull Item item);
@Nonnull
- public ImmutableList<ImmutableItem> toList(@Nullable final Iterable<? extends Item> iterable) {
+ public List<ImmutableItem> toList(@Nullable final Iterable<? extends Item> iterable) {
if (iterable == null) {
- return ImmutableList.of();
+ return Collections.emptyList();
}
boolean needsCopy = false;
- if (iterable instanceof ImmutableList) {
+ if (iterable instanceof List) {
for (Item element: iterable) {
if (!isImmutable(element)) {
needsCopy = true;
@@ -63,26 +69,27 @@ public abstract class ImmutableConverter<ImmutableItem, Item> {
}
if (!needsCopy) {
- return (ImmutableList<ImmutableItem>)iterable;
+ return unmodifiableList((List<ImmutableItem>)iterable);
}
final Iterator<? extends Item> iter = iterable.iterator();
- return ImmutableList.copyOf(new Iterator<ImmutableItem>() {
- @Override public boolean hasNext() { return iter.hasNext(); }
- @Override public ImmutableItem next() { return makeImmutable(iter.next()); }
- @Override public void remove() { iter.remove(); }
- });
+ ArrayList<ImmutableItem> list = new ArrayList<ImmutableItem>();
+ while (iter.hasNext()) {
+ list.add(makeImmutable(iter.next()));
+ }
+
+ return unmodifiableList(list);
}
@Nonnull
- public ImmutableSet<ImmutableItem> toSet(@Nullable final Iterable<? extends Item> iterable) {
+ public Set<ImmutableItem> toSet(@Nullable final Iterable<? extends Item> iterable) {
if (iterable == null) {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
boolean needsCopy = false;
- if (iterable instanceof ImmutableSet) {
+ if (iterable instanceof Set) {
for (Item element: iterable) {
if (!isImmutable(element)) {
needsCopy = true;
@@ -94,28 +101,28 @@ public abstract class ImmutableConverter<ImmutableItem, Item> {
}
if (!needsCopy) {
- return (ImmutableSet<ImmutableItem>)iterable;
+ return unmodifiableSet((Set<ImmutableItem>)iterable);
}
final Iterator<? extends Item> iter = iterable.iterator();
- return ImmutableSet.copyOf(new Iterator<ImmutableItem>() {
- @Override public boolean hasNext() { return iter.hasNext(); }
- @Override public ImmutableItem next() { return makeImmutable(iter.next()); }
- @Override public void remove() { iter.remove(); }
- });
+ HashSet<ImmutableItem> set = new HashSet<ImmutableItem>();
+ while (iter.hasNext()) {
+ set.add(makeImmutable(iter.next()));
+ }
+ return unmodifiableSet(set);
}
@Nonnull
- public ImmutableSortedSet<ImmutableItem> toSortedSet(@Nonnull Comparator<? super ImmutableItem> comparator,
+ public SortedSet<ImmutableItem> toSortedSet(@Nonnull Comparator<? super ImmutableItem> comparator,
@Nullable final Iterable<? extends Item> iterable) {
if (iterable == null) {
- return ImmutableSortedSet.of();
+ return Collections.emptySortedSet();
}
boolean needsCopy = false;
- if (iterable instanceof ImmutableSortedSet &&
- ((ImmutableSortedSet)iterable).comparator().equals(comparator)) {
+ if (iterable instanceof SortedSet &&
+ ((SortedSet)iterable).comparator().equals(comparator)) {
for (Item element: iterable) {
if (!isImmutable(element)) {
needsCopy = true;
@@ -127,33 +134,15 @@ public abstract class ImmutableConverter<ImmutableItem, Item> {
}
if (!needsCopy) {
- return (ImmutableSortedSet<ImmutableItem>)iterable;
+ return unmodifiableSortedSet((SortedSet<ImmutableItem>)iterable);
}
final Iterator<? extends Item> iter = iterable.iterator();
-
- return ImmutableSortedSet.copyOf(comparator, new Iterator<ImmutableItem>() {
- @Override public boolean hasNext() { return iter.hasNext(); }
- @Override public ImmutableItem next() { return makeImmutable(iter.next()); }
- @Override public void remove() { iter.remove(); }
- });
- }
-
- @Nonnull
- public SortedSet<ImmutableItem> toSortedSet(@Nonnull Comparator<? super ImmutableItem> comparator,
- @Nullable final SortedSet<? extends Item> sortedSet) {
- if (sortedSet == null || sortedSet.size() == 0) {
- return ImmutableSortedSet.of();
- }
-
- @SuppressWarnings("unchecked")
- ImmutableItem[] newItems = (ImmutableItem[])new Object[sortedSet.size()];
- int index = 0;
- for (Item item: sortedSet) {
- newItems[index++] = makeImmutable(item);
+ TreeSet<ImmutableItem> treeSet = new TreeSet<ImmutableItem>(comparator);
+ while (iter.hasNext()) {
+ treeSet.add(makeImmutable(iter.next()));
}
-
- return ArraySortedSet.of(comparator, newItems);
+ return unmodifiableSortedSet(treeSet);
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/ImmutableUtils.java b/dexlib2/src/main/java/com/android/tools/smali/util/ImmutableUtils.java
index fbd67e3d..0107f856 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/ImmutableUtils.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/ImmutableUtils.java
@@ -30,32 +30,36 @@
package com.android.tools.smali.util;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
+import static java.util.Collections.unmodifiableSet;
+import static java.util.Collections.unmodifiableSortedSet;
+import static java.util.Collections.unmodifiableList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
public class ImmutableUtils {
- @Nonnull public static <T> ImmutableList<T> nullToEmptyList(@Nullable ImmutableList<T> list) {
+ @Nonnull public static <T> List<T> nullToEmptyList(@Nullable List<T> list) {
if (list == null) {
- return ImmutableList.of();
+ return Collections.emptyList();
}
- return list;
+ return unmodifiableList(list);
}
- @Nonnull public static <T> ImmutableSet<T> nullToEmptySet(@Nullable ImmutableSet<T> set) {
+ @Nonnull public static <T> Set<T> nullToEmptySet(@Nullable Set<T> set) {
if (set == null) {
- return ImmutableSet.of();
+ return Collections.emptySet();
}
- return set;
+ return unmodifiableSet(set);
}
- @Nonnull public static <T> ImmutableSortedSet<T> nullToEmptySortedSet(@Nullable ImmutableSortedSet<T> set) {
+ @Nonnull public static <T> SortedSet<T> nullToEmptySortedSet(@Nullable SortedSet<T> set) {
if (set == null) {
- return ImmutableSortedSet.of();
+ return Collections.emptySortedSet();
}
- return set;
+ return unmodifiableSortedSet(set);
}
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/InputStreamUtil.java b/dexlib2/src/main/java/com/android/tools/smali/util/InputStreamUtil.java
index 46f696a1..0532f0c2 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/InputStreamUtil.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/InputStreamUtil.java
@@ -38,6 +38,7 @@ import java.io.DataInput;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Queue;
@@ -259,4 +260,30 @@ public final class InputStreamUtil {
}
return total;
}
+
+ /**
+ * Copies all bytes from the input stream to the output stream. Does not close or flush either
+ * stream.
+ *
+ * @param from the input stream to read from
+ * @param to the output stream to write to
+ * @return the number of bytes copied
+ * @throws IOException if an I/O error occurs
+ */
+ public static long copy(InputStream from, OutputStream to) throws IOException {
+ if (from == null || to == null) {
+ throw new NullPointerException();
+ }
+ byte[] buf = new byte[BUFFER_SIZE];
+ long total = 0;
+ while (true) {
+ int r = from.read(buf);
+ if (r == -1) {
+ break;
+ }
+ to.write(buf, 0, r);
+ total += r;
+ }
+ return total;
+ }
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/IteratorUtils.java b/dexlib2/src/main/java/com/android/tools/smali/util/IteratorUtils.java
index 6f6c8576..4894d5a6 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/IteratorUtils.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/IteratorUtils.java
@@ -30,13 +30,16 @@
package com.android.tools.smali.util;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Iterator;
-
-import org.checkerframework.checker.nullness.qual.Nullable;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Predicate;
public final class IteratorUtils {
- public static <T extends @Nullable Object> T getLast(Iterator<T> iterator) {
+ public static <T extends Object> T getLast(Iterator<T> iterator) {
while (true) {
T current = iterator.next();
if (!iterator.hasNext()) {
@@ -44,4 +47,67 @@ public final class IteratorUtils {
}
}
}
+
+ public static <T extends Object> AbstractIterator<T> filter(
+ Iterable<T> unfiltered, Predicate<? super T> retainIfTrue) {
+ return filter(unfiltered.iterator(), retainIfTrue);
+ }
+
+ public static <T extends Object> AbstractIterator<T> filter(
+ Iterator<T> unfiltered, Predicate<? super T> retainIfTrue) {
+ return new AbstractIterator<T>() {
+ @Override
+ protected T computeNext() {
+ while (unfiltered.hasNext()) {
+ T next = unfiltered.next();
+ if (retainIfTrue.test(next)) {
+ return next;
+ }
+ }
+ return endOfData();
+ }
+ };
+ }
+
+ public static <T extends Object> List<T> toList(Iterable<T> iterable) {
+ return toList(iterable.iterator());
+ }
+
+ public static <T extends Object> List<T> toList(Iterator<T> iterator) {
+ ArrayList<T> list = new ArrayList<T>();
+ while (iterator.hasNext()) {
+ list.add(iterator.next());
+ }
+ return list;
+ }
+
+ public static <T extends Object> void addAll(Collection<T> collection, Iterator<T> iterator) {
+ while (iterator.hasNext()) {
+ collection.add(iterator.next());
+ }
+ }
+
+ public static boolean elementsEqual(Iterator<?> iterator1, Iterator<?> iterator2) {
+ while (iterator1.hasNext()) {
+ if (!iterator2.hasNext()) {
+ return false;
+ }
+ Object o1 = iterator1.next();
+ Object o2 = iterator2.next();
+ if (!Objects.equals(o1, o2)) {
+ return false;
+ }
+ }
+ return !iterator2.hasNext();
+ }
+
+ public static int size(Iterable<?> iterable) {
+ Iterator<?> iterator = iterable.iterator();
+ int count = 0;
+ while (iterator.hasNext()) {
+ count++;
+ iterator.next();
+ }
+ return count;
+ }
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/Range.java b/dexlib2/src/main/java/com/android/tools/smali/util/Range.java
new file mode 100644
index 00000000..f74377f9
--- /dev/null
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/Range.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2024, Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.tools.smali.util;
+
+import java.util.Comparator;
+import java.util.Objects;
+
+/*
+ * Represents a Range of values of type C. It can have open bounds if the range doesn't include the
+ * bound value. It can also be unbounded on the lower or upper side. Simplified version of a guava
+ * Range.
+ */
+public class Range<C extends Comparable> {
+ public static final Comparator<Range<?>> RANGE_LEX_COMPARATOR = new Comparator<Range<?>>() {
+ @Override
+ public int compare(Range<?> left, Range<?> right) {
+ int cmp = 0;
+ if (!left.hasLowerBound() && right.hasLowerBound()) {
+ return -1;
+ } else if (!right.hasLowerBound() && left.hasLowerBound()) {
+ return 1;
+ } else if (left.hasLowerBound() && right.hasLowerBound()) {
+ cmp = left.lowerBound.compareTo(right.lowerBound);
+ }
+
+ if (cmp != 0) {
+ return cmp;
+ }
+ if (!left.hasUpperBound() && right.hasUpperBound()) {
+ return 1;
+ } else if (!right.hasUpperBound() && left.hasUpperBound()) {
+ return -1;
+ } else if (left.hasUpperBound() && right.hasUpperBound()) {
+ cmp = left.upperBound.compareTo(right.upperBound);
+ }
+ return cmp;
+ }
+ };
+
+ private C lowerBound;
+ private C upperBound;
+ private boolean lowerOpen;
+ private boolean upperOpen;
+ private boolean allValues;
+
+ public static <C extends Comparable> Range<C> closed(C lowerBound, C upperBound) {
+ if (lowerBound == null || upperBound == null) {
+ throw new NullPointerException();
+ }
+ if (lowerBound.compareTo(upperBound) > 0) {
+ throw new IllegalArgumentException("lowerBound must be <= upperBound");
+ }
+ return new Range<>(lowerBound, upperBound, false, false);
+ }
+
+ public static <C extends Comparable> Range<C> open(C lowerBound, C upperBound) {
+ if (lowerBound == null || upperBound == null) {
+ throw new NullPointerException();
+ }
+ if (lowerBound.compareTo(upperBound) > 0) {
+ throw new IllegalArgumentException("lowerBound must be <= upperBound");
+ }
+ return new Range<>(lowerBound, upperBound, true, true);
+ }
+
+ public static <C extends Comparable> Range<C> openClosed(C lowerBound, C upperBound) {
+ if (lowerBound == null || upperBound == null) {
+ throw new NullPointerException();
+ }
+ if (lowerBound.compareTo(upperBound) > 0) {
+ throw new IllegalArgumentException("lowerBound must be <= upperBound");
+ }
+ return new Range<>(lowerBound, upperBound, true, false);
+ }
+
+ public static <C extends Comparable> Range<C> closedOpen(C lowerBound, C upperBound) {
+ if (lowerBound == null || upperBound == null) {
+ throw new NullPointerException();
+ }
+ if (lowerBound.compareTo(upperBound) > 0) {
+ throw new IllegalArgumentException("lowerBound must be <= upperBound");
+ }
+ return new Range<>(lowerBound, upperBound, false, true);
+ }
+
+ public static <C extends Comparable> Range<C> atLeast(C lowerBound) {
+ if (lowerBound == null) {
+ throw new NullPointerException();
+ }
+ return new Range<>(lowerBound, null, false, false);
+ }
+
+ public static <C extends Comparable> Range<C> atMost(C upperBound) {
+ if (upperBound == null) {
+ throw new NullPointerException();
+ }
+ return new Range<>(null, upperBound, false, false);
+ }
+
+ public static <C extends Comparable> Range<C> allValues() {
+ return new Range<>();
+ }
+
+ private Range(C lowerBound, C upperBound, boolean lowerOpen, boolean upperOpen) {
+ this.lowerBound = lowerBound;
+ this.upperBound = upperBound;
+ this.lowerOpen = lowerOpen;
+ this.upperOpen = upperOpen;
+ allValues = false;
+ }
+
+ private Range() {
+ allValues = true;
+ lowerBound = null;
+ upperBound = null;
+ lowerOpen = false;
+ upperOpen = false;
+ }
+
+ public boolean isEmpty() {
+ return !allValues
+ && Objects.equals(lowerBound, upperBound)
+ && (lowerOpen || upperOpen);
+ }
+
+ public C getLowerBound() {
+ return lowerBound;
+ }
+
+ public C getUpperBound() {
+ return upperBound;
+ }
+
+ public boolean openLowerBound() {
+ return lowerOpen;
+ }
+
+ public boolean openUpperBound() {
+ return upperOpen;
+ }
+
+ public boolean hasAllValues() {
+ return allValues;
+ }
+
+ public boolean hasLowerBound() {
+ return lowerBound != null;
+ }
+
+ public boolean hasUpperBound() {
+ return upperBound != null;
+ }
+
+ /* Returns true if value is included in the Range */
+ public boolean contains(C value) {
+ if (value == null) {
+ return false;
+ }
+ if (allValues) {
+ return true;
+ }
+
+ if (lowerBound != null) {
+ if (lowerOpen && value.compareTo(lowerBound) == 0) {
+ return false;
+ }
+ if (value.compareTo(lowerBound) < 0) {
+ return false;
+ }
+ }
+ if (upperBound != null) {
+ if (upperOpen && value.compareTo(upperBound) == 0) {
+ return false;
+ }
+ if (value.compareTo(upperBound) > 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * Returns true if there exists a (possibly empty) range which is enclosed by both this range
+ * and other.
+ */
+ public boolean isConnected(Range<C> other) {
+ return (!hasLowerBound() || !other.hasUpperBound()
+ || lowerBound.compareTo(other.getUpperBound()) <= 0)
+ && (!hasUpperBound() || !other.hasLowerBound()
+ || other.getLowerBound().compareTo(upperBound) <= 0);
+ }
+
+ /* Returns the maximal range enclosed by both this range and other, if such a range exists. */
+ public Range<C> intersection(Range<C> other) {
+ if (!isConnected(other)) {
+ return null;
+ }
+
+ // select the max of the lowerBounds. If they're equal,
+ // choose the range that has an open lower bound
+ Range<C> lowerBoundRange;
+ if (!hasLowerBound() || !other.hasLowerBound()) {
+ lowerBoundRange = hasLowerBound() ? this : other;
+ } else if (Objects.equals(lowerBound, other.getLowerBound())) {
+ lowerBoundRange = lowerOpen ? this : other;
+ } else {
+ lowerBoundRange = lowerBound.compareTo(other.getLowerBound()) > 0 ? this : other;
+ }
+
+ // and the min of the upperBounds, or the open upper bound if they're equal
+ Range<C> upperBoundRange;
+ if (!hasUpperBound() || !other.hasUpperBound()) {
+ upperBoundRange = hasUpperBound() ? this : other;
+ } else if (Objects.equals(upperBound, other.getUpperBound())) {
+ upperBoundRange = upperOpen ? this : other;
+ } else {
+ upperBoundRange = upperBound.compareTo(other.getUpperBound()) < 0 ? this : other;
+ }
+
+ return new Range<C>(
+ lowerBoundRange.getLowerBound(),
+ upperBoundRange.getUpperBound(),
+ lowerBoundRange.openLowerBound(),
+ upperBoundRange.openUpperBound());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof Range)) {
+ return false;
+ }
+ Range<?> other = (Range<?>) o;
+
+ if (allValues != other.hasAllValues()) {
+ return false;
+ }
+
+ return Objects.equals(lowerBound, other.lowerBound)
+ && Objects.equals(upperBound, other.upperBound)
+ && lowerOpen == other.openLowerBound()
+ && upperOpen == other.openUpperBound();
+ }
+
+ @Override
+ public String toString() {
+ if (allValues) {
+ return "[*]";
+ }
+ String sb = "";
+ if (lowerOpen) {
+ sb += "(";
+ } else {
+ sb += "[";
+ }
+ sb += lowerBound;
+ sb += ", ";
+ sb += upperBound;
+ if (upperOpen) {
+ sb += ")";
+ } else {
+ sb += "]";
+ }
+ return sb;
+ }
+
+}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/StringUtils.java b/dexlib2/src/main/java/com/android/tools/smali/util/StringUtils.java
index 730caa8f..767c6ddf 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/StringUtils.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/StringUtils.java
@@ -31,15 +31,18 @@
package com.android.tools.smali.util;
import com.android.tools.smali.dexlib2.formatter.DexFormattedWriter;
+import com.android.tools.smali.dexlib2.iface.value.CharEncodedValue;
+
import java.io.IOException;
import java.io.Writer;
+import java.util.Collection;
import java.util.Iterator;
-import java.util.List;
public class StringUtils {
/**
- * @deprecated Use {@link com.android.tools.smali.baksmali.formatter.BaksmaliWriter#writeCharEncodedValue}
+ * @deprecated Use @see
+ * com.android.tools.smali.baksmali.formatter.BaksmaliWriter}#writeCharEncodedValue()
*/
@Deprecated
public static void writeEscapedChar(Writer writer, char c) throws IOException {
@@ -51,9 +54,15 @@ public class StringUtils {
return;
} else if (c <= 0x7f) {
switch (c) {
- case '\n': writer.write("\\n"); return;
- case '\r': writer.write("\\r"); return;
- case '\t': writer.write("\\t"); return;
+ case '\n':
+ writer.write("\\n");
+ return;
+ case '\r':
+ writer.write("\\r");
+ return;
+ case '\t':
+ writer.write("\\t");
+ return;
}
}
@@ -80,9 +89,15 @@ public class StringUtils {
continue;
} else if (c <= 0x7f) {
switch (c) {
- case '\n': writer.write("\\n"); continue;
- case '\r': writer.write("\\r"); continue;
- case '\t': writer.write("\\t"); continue;
+ case '\n':
+ writer.write("\\n");
+ continue;
+ case '\r':
+ writer.write("\\r");
+ continue;
+ case '\t':
+ writer.write("\\t");
+ continue;
}
}
@@ -109,9 +124,15 @@ public class StringUtils {
continue;
} else if (c <= 0x7f) {
switch (c) {
- case '\n': sb.append("\\n"); continue;
- case '\r': sb.append("\\r"); continue;
- case '\t': sb.append("\\t"); continue;
+ case '\n':
+ sb.append("\\n");
+ continue;
+ case '\r':
+ sb.append("\\r");
+ continue;
+ case '\t':
+ sb.append("\\t");
+ continue;
}
}
@@ -125,7 +146,7 @@ public class StringUtils {
return sb.toString();
}
- public static String join(List<? extends Object> parts, String separator) {
+ public static String join(Collection<? extends Object> parts, String separator) {
StringBuilder builder = new StringBuilder();
Iterator<? extends Object> it = parts.iterator();
if (it.hasNext()) {
@@ -137,4 +158,35 @@ public class StringUtils {
}
return builder.toString();
}
+
+ // Base on the repeat method in guava Strings, of the same signature.
+ public static String repeat(String string, int count) {
+ if (string == null) {
+ throw new NullPointerException("string == null");
+ }
+
+ if (count <= 1) {
+ if (count >= 0) {
+ throw new IllegalArgumentException("invalid count: " + count);
+ }
+ return (count == 0) ? "" : string;
+ }
+
+ final int len = string.length();
+ final long longSize = (long) len * (long) count;
+ final int size = (int) longSize;
+ if (size != longSize) {
+ throw new ArrayIndexOutOfBoundsException("Required array size too large: " + longSize);
+ }
+
+ final char[] array = new char[size];
+ string.getChars(0, len, array, 0);
+ int n;
+ for (n = len; n < size - n; n <<= 1) {
+ System.arraycopy(array, 0, array, n, n);
+ }
+ System.arraycopy(array, 0, array, n, size - n);
+ return new String(array);
+
+ }
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/TransformedIterator.java b/dexlib2/src/main/java/com/android/tools/smali/util/TransformedIterator.java
index bf89ea99..ab5179a1 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/TransformedIterator.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/TransformedIterator.java
@@ -32,7 +32,6 @@ package com.android.tools.smali.util;
import java.util.Iterator;
import java.util.function.Function;
-import org.checkerframework.checker.nullness.qual.Nullable;
/**
* An iterator that will return the results of applying {@code transformFunction} to each element of
@@ -40,11 +39,17 @@ import org.checkerframework.checker.nullness.qual.Nullable;
* <p>
* The returned iterator supports {@code remove()} if {@code backingIterator} does.
*/
-public class TransformedIterator<F extends @Nullable Object, T extends @Nullable Object>
- implements Iterator<T> {
+public class TransformedIterator<F extends Object, T extends Object>
+ implements Iterator<T>, Iterable<T> {
final Iterator<? extends F> backingIterator;
final Function<F, T> transformFunction;
+ public TransformedIterator(Iterable<? extends F> backingIterable,
+ Function<F, T> transformFunction) {
+ this.backingIterator = backingIterable.iterator();
+ this.transformFunction = transformFunction;
+ }
+
public TransformedIterator(Iterator<? extends F> backingIterator,
Function<F, T> transformFunction) {
this.backingIterator = backingIterator;
@@ -65,4 +70,9 @@ public class TransformedIterator<F extends @Nullable Object, T extends @Nullable
public final void remove() {
backingIterator.remove();
}
+
+ @Override
+ public final Iterator<T> iterator() {
+ return this;
+ }
}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/UnmodifiableRangeMap.java b/dexlib2/src/main/java/com/android/tools/smali/util/UnmodifiableRangeMap.java
new file mode 100644
index 00000000..eed14b63
--- /dev/null
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/UnmodifiableRangeMap.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2024, Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.tools.smali.util;
+
+import javax.annotation.CheckForNull;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/*
+ * Based on guava's ImmutableRangeMap
+ */
+public class UnmodifiableRangeMap<K extends Comparable<?>, V> {
+ private static final UnmodifiableRangeMap<Comparable<?>, Object> EMPTY = new UnmodifiableRangeMap<>(
+ Collections.emptyList(), Collections.emptyList());
+
+ /** Returns a new builder for an immutable range map. */
+ public static <K extends Comparable<?>, V> Builder<K, V> builder() {
+ return new Builder<>();
+ }
+
+ /**
+ * Returns an empty immutable range map.
+ * <p>
+ * <b>Performance note:</b> the instance returned is a singleton.
+ */
+ public static <K extends Comparable<?>, V> UnmodifiableRangeMap<K, V> of() {
+ return (UnmodifiableRangeMap<K, V>) EMPTY;
+ }
+
+ /**
+ * A builder for immutable range maps. Overlapping ranges are prohibited.
+ *
+ * @since 14.0
+ */
+ public static final class Builder<K extends Comparable<?>, V> {
+
+ private final List<Entry<Range<K>, V>> entries;
+
+ public Builder() {
+ this.entries = new ArrayList<>();
+ }
+
+ /**
+ * Associates the specified range with the specified value.
+ *
+ * @throws IllegalArgumentException if {@code range} is empty
+ */
+ public Builder<K, V> put(Range<K> range, V value) {
+ if (range == null || value == null) {
+ throw new NullPointerException("Both range and value must be non-null");
+ }
+
+ if (range.isEmpty()) {
+ throw new IllegalArgumentException("Ranges cannot be empty");
+ }
+ entries.add(new UnmodifiableEntry(range, value));
+ return this;
+ }
+
+ /**
+ * Returns an {@code ImmutableRangeMap} containing the associations previously added to this
+ * builder.
+ *
+ * @throws IllegalArgumentException if any two ranges inserted into this builder overlap
+ */
+ public UnmodifiableRangeMap<K, V> build() {
+ Collections.sort(entries,
+ (e1, e2) -> Range.RANGE_LEX_COMPARATOR.compare(e1.getKey(), e2.getKey()));
+ ArrayList<Range<K>> rangesList = new ArrayList<>(entries.size());
+ ArrayList<V> valuesList = new ArrayList<>(entries.size());
+ for (int i = 0; i < entries.size(); i++) {
+ Range<K> range = entries.get(i).getKey();
+ if (i > 0) {
+ Range<K> prevRange = entries.get(i - 1).getKey();
+ if (range.isConnected(prevRange) && !range.intersection(prevRange).isEmpty()) {
+ throw new IllegalArgumentException(
+ "Overlapping ranges: range " + prevRange + " overlaps with entry "
+ + range);
+ }
+ }
+ rangesList.add(range);
+ valuesList.add(entries.get(i).getValue());
+ }
+ return new UnmodifiableRangeMap(rangesList, valuesList);
+ }
+ }
+
+ private final transient List<Range<K>> ranges;
+ private final transient List<V> values;
+
+ private UnmodifiableRangeMap(List<Range<K>> ranges, List<V> values) {
+ this.ranges = Collections.unmodifiableList(ranges);
+ this.values = Collections.unmodifiableList(values);
+ }
+
+ @CheckForNull
+ public V get(K key) {
+ if (key == null) {
+ return null;
+ }
+
+ int index = rangeBinarySearch(ranges, key);
+ if (index == -1) {
+ return null;
+ } else {
+ Range<K> range = ranges.get(index);
+ return range.contains(key) ? values.get(index) : null;
+ }
+ }
+
+ @CheckForNull
+ public Entry<Range<K>, V> getEntry(K key) {
+ if (key == null) {
+ return null;
+ }
+
+ int index = rangeBinarySearch(ranges, key);
+ if (index == -1) {
+ return null;
+ } else {
+ Range<K> range = ranges.get(index);
+ return range.contains(key) ? new UnmodifiableEntry(range, values.get(index)) : null;
+ }
+ }
+
+ private static <T extends Comparable> int rangeBinarySearch(List<Range<T>> l, T key) {
+ int low = 0;
+ int high = l.size() - 1;
+
+ while (low <= high) {
+ int mid = (low + high) >>> 1;
+ Range<T> midRange = l.get(mid);
+ if (midRange.contains(key)) {
+ return mid;
+ }
+
+ int cmp = midRange.hasLowerBound() ? key.compareTo(midRange.getLowerBound())
+ : key.compareTo(midRange.getUpperBound());
+
+ if (cmp > 0)
+ low = mid + 1;
+ else if (cmp < 0)
+ high = mid - 1;
+ else
+ return mid; // key found
+ }
+ return -1; // key not found
+ }
+
+ public static class UnmodifiableEntry<K, V> implements Map.Entry<K, V> {
+ private final K key;
+ private final V value;
+
+ public UnmodifiableEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public K getKey() {
+ return key;
+ }
+
+ @Override
+ public V getValue() {
+ return value;
+ }
+
+ @Override
+ public V setValue(V value) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/util/WrappedIndentingWriter.java b/dexlib2/src/main/java/com/android/tools/smali/util/WrappedIndentingWriter.java
index bf1798e1..16873e93 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/util/WrappedIndentingWriter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/util/WrappedIndentingWriter.java
@@ -30,8 +30,6 @@
package com.android.tools.smali.util;
-import com.google.common.collect.Lists;
-
import java.io.FilterWriter;
import java.io.IOException;
import java.io.Writer;
@@ -76,7 +74,8 @@ public class WrappedIndentingWriter extends FilterWriter {
}
private void wrapLine() throws IOException {
- List<String> wrapped = Lists.newArrayList(StringWrapper.wrapStringOnBreaks(line.toString(), maxWidth));
+ List<String> wrapped = IteratorUtils.toList(
+ StringWrapper.wrapStringOnBreaks(line.toString(), maxWidth));
out.write(wrapped.get(0), 0, wrapped.get(0).length());
out.write('\n');
diff --git a/dexlib2/src/test/java/com/android/tools/smali/dexlib2/util/RangeTest.java b/dexlib2/src/test/java/com/android/tools/smali/dexlib2/util/RangeTest.java
new file mode 100644
index 00000000..23fea452
--- /dev/null
+++ b/dexlib2/src/test/java/com/android/tools/smali/dexlib2/util/RangeTest.java
@@ -0,0 +1,499 @@
+
+/*
+ * Copyright 2024, Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.tools.smali.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.smali.util.Range;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class RangeTest {
+
+ @Test
+ public void testClosed() {
+ Range<Integer> range = Range.closed(1, 10);
+ assertTrue(range.contains(1));
+ assertTrue(range.contains(10));
+ assertTrue(range.contains(5));
+ assertFalse(range.contains(0));
+ assertFalse(range.contains(11));
+ }
+
+ @Test
+ public void testOpenClosed() {
+ Range<Integer> range = Range.openClosed(1, 10);
+ assertTrue(range.contains(10));
+ assertFalse(range.contains(1));
+ assertTrue(range.contains(5));
+ assertFalse(range.contains(0));
+ assertFalse(range.contains(11));
+ }
+
+ @Test
+ public void testClosedOpen() {
+ Range<Integer> range = Range.closedOpen(1, 10);
+ assertFalse(range.contains(10));
+ assertTrue(range.contains(1));
+ assertTrue(range.contains(5));
+ assertFalse(range.contains(0));
+ assertFalse(range.contains(11));
+ }
+
+ @Test
+ public void testOpen() {
+ Range<Integer> range = Range.open(1, 10);
+ assertFalse(range.contains(10));
+ assertFalse(range.contains(1));
+ assertTrue(range.contains(5));
+ assertFalse(range.contains(11));
+ assertFalse(range.contains(0));
+ }
+
+ @Test
+ public void testAtLeast() {
+ Range<Integer> range = Range.atLeast(1);
+ assertTrue(range.contains(1));
+ assertTrue(range.contains(10));
+ assertFalse(range.contains(0));
+ }
+
+ @Test
+ public void testAtMost() {
+ Range<Integer> range = Range.atMost(10);
+ assertFalse(range.contains(11));
+ assertTrue(range.contains(10));
+ assertTrue(range.contains(5));
+ }
+
+ @Test
+ public void testAllValues() {
+ Range<Integer> range = Range.allValues();
+ assertTrue(range.contains(1));
+ assertTrue(range.contains(10));
+ assertTrue(range.contains(0));
+ assertTrue(range.contains(11));
+ }
+
+ @Test
+ public void testEquals() {
+ Range<Integer> range1 = Range.closed(1, 10);
+ Range<Integer> range2 = Range.closed(1, 10);
+ assertTrue(range1.equals(range2));
+
+ range1 = Range.open(1, 10);
+ range2 = Range.open(1, 10);
+ assertTrue(range1.equals(range2));
+
+ range1 = Range.closedOpen(1, 10);
+ range2 = Range.closedOpen(1, 10);
+ assertTrue(range1.equals(range2));
+
+ range1 = Range.openClosed(1, 10);
+ range2 = Range.openClosed(1, 10);
+ assertTrue(range1.equals(range2));
+
+ range1 = Range.atLeast(1);
+ range2 = Range.atLeast(1);
+ assertTrue(range1.equals(range2));
+
+ range1 = Range.atMost(10);
+ range2 = Range.atMost(10);
+ assertTrue(range1.equals(range2));
+
+ range1 = Range.allValues();
+ range2 = Range.allValues();
+ assertTrue(range1.equals(range2));
+
+ range1 = Range.closed(1, 10);
+ range2 = Range.closed(1, 11);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.open(1, 10);
+ range2 = Range.open(0, 10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closed(1, 10);
+ range2 = Range.open(1, 10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closed(1, 10);
+ range2 = Range.closedOpen(1, 10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closedOpen(1, 10);
+ range2 = Range.openClosed(1, 10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closed(1, 10);
+ range2 = Range.atLeast(1);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closed(1, 10);
+ range2 = Range.atMost(10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closed(1, 10);
+ range2 = Range.allValues();
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.open(1, 10);
+ range2 = Range.closedOpen(1, 10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.open(1, 10);
+ range2 = Range.openClosed(1, 10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.open(1, 10);
+ range2 = Range.atLeast(1);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.open(1, 10);
+ range2 = Range.atMost(10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.open(1, 10);
+ range2 = Range.allValues();
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closedOpen(1, 10);
+ range2 = Range.openClosed(1, 10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closedOpen(1, 10);
+ range2 = Range.atLeast(1);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closedOpen(1, 10);
+ range2 = Range.atMost(10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.closedOpen(1, 10);
+ range2 = Range.allValues();
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.openClosed(1, 10);
+ range2 = Range.atLeast(1);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.openClosed(1, 10);
+ range2 = Range.atMost(10);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.openClosed(1, 10);
+ range2 = Range.allValues();
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.atLeast(1);
+ range2 = Range.atMost(1);
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.atLeast(1);
+ range2 = Range.allValues();
+ assertFalse(range1.equals(range2));
+
+ range1 = Range.atMost(10);
+ range2 = Range.allValues();
+ assertFalse(range1.equals(range2));
+ }
+
+ @Test
+ public void testIsEmpty() {
+ Range<Integer> range = Range.closed(1, 1);
+ assertFalse(range.isEmpty());
+
+ range = Range.openClosed(2, 2);
+ assertTrue(range.isEmpty());
+
+ range = Range.closedOpen(3, 3);
+ assertTrue(range.isEmpty());
+
+ range = Range.open(4, 4);
+ assertTrue(range.isEmpty());
+
+ range = Range.open(4, 5);
+ assertFalse(range.isEmpty());
+
+ range = Range.atMost(10);
+ assertFalse(range.isEmpty());
+
+ range = Range.atLeast(10);
+ assertFalse(range.isEmpty());
+
+ range = Range.allValues();
+ assertFalse(range.isEmpty());
+ }
+
+ @Test
+ public void testGetLowerBound() {
+ Range<Integer> range = Range.closed(1, 10);
+ assertEquals((Integer) 1, range.getLowerBound());
+ }
+
+ @Test
+ public void testGetUpperBound() {
+ Range<Integer> range = Range.closed(1, 10);
+ assertEquals((Integer) 10, range.getUpperBound());
+ }
+
+ @Test
+ public void testHasLowerBound() {
+ assertTrue(Range.closed(1, 10).hasLowerBound());
+ assertTrue(Range.open(1, 10).hasLowerBound());
+ assertTrue(Range.openClosed(1, 10).hasLowerBound());
+ assertTrue(Range.closedOpen(1, 10).hasLowerBound());
+ assertTrue(Range.atLeast(1).hasLowerBound());
+ assertFalse(Range.atMost(10).hasLowerBound());
+ assertFalse(Range.allValues().hasLowerBound());
+ }
+
+ @Test
+ public void testHasUpperBound() {
+ assertTrue(Range.closed(1, 10).hasUpperBound());
+ assertTrue(Range.open(1, 10).hasUpperBound());
+ assertTrue(Range.openClosed(1, 10).hasUpperBound());
+ assertTrue(Range.closedOpen(1, 10).hasUpperBound());
+ assertFalse(Range.atLeast(1).hasUpperBound());
+ assertTrue(Range.atMost(10).hasUpperBound());
+ assertFalse(Range.allValues().hasUpperBound());
+ }
+
+ @Test
+ public void testIsConnected() {
+ Range<Integer> range1 = Range.closed(1, 5);
+ Range<Integer> range2 = Range.closed(3, 7);
+ assertTrue(range1.isConnected(range2));
+ assertTrue(range2.isConnected(range1));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(6, 7);
+ assertFalse(range1.isConnected(range2));
+ assertFalse(range2.isConnected(range1));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(0, 2);
+ assertTrue(range1.isConnected(range2));
+ assertTrue(range2.isConnected(range1));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(10, 20);
+ assertFalse(range1.isConnected(range2));
+ assertFalse(range2.isConnected(range1));
+ }
+
+ @Test
+ public void testIsConnected_edgeConnection() {
+ Range<Integer> range1 = Range.closed(1, 5);
+ Range<Integer> range2 = Range.closed(5, 7);
+ assertTrue(range1.isConnected(range2));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(3, 5);
+ assertTrue(range1.isConnected(range2));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(1, 3);
+ assertTrue(range1.isConnected(range2));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(1, 5);
+ assertTrue(range1.isConnected(range2));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(5, 5);
+ assertTrue(range1.isConnected(range2));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.openClosed(5, 10);
+ assertTrue(range1.isConnected(range2));
+ }
+
+ @Test
+ public void testIntersection() {
+ Range<Integer> range1 = Range.closed(1, 5);
+ Range<Integer> range2 = Range.closed(3, 7);
+ assertEquals(Range.closed(3, 5), range1.intersection(range2));
+ assertEquals(Range.closed(3, 5), range2.intersection(range1));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(6, 7);
+ assertNull(range1.intersection(range2));
+ assertNull(range2.intersection(range1));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(0, 2);
+ assertEquals(Range.closed(1, 2), range1.intersection(range2));
+ assertEquals(Range.closed(1, 2), range2.intersection(range1));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(5, 7);
+ assertEquals(Range.closed(5, 5), range1.intersection(range2));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(3, 5);
+ assertEquals(Range.closed(3, 5), range1.intersection(range2));
+ assertEquals(Range.closed(3, 5), range2.intersection(range1));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(2, 4);
+ assertEquals(Range.closed(2, 4), range1.intersection(range2));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(1, 3);
+ assertEquals(Range.closed(1, 3), range1.intersection(range2));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(1, 5);
+ assertEquals(Range.closed(1, 5), range1.intersection(range2));
+
+ range1 = Range.closed(1, 5);
+ range2 = Range.closed(5, 5);
+ assertEquals(Range.closed(5, 5), range1.intersection(range2));
+ }
+
+ @Test
+ public void testIntersection_openBounds() {
+ Range<Integer> range1 = Range.openClosed(1, 5);
+ Range<Integer> range2 = Range.closed(3, 7);
+ assertEquals(Range.closed(3, 5), range1.intersection(range2));
+
+ range1 = Range.openClosed(1, 5);
+ range2 = Range.closed(6, 7);
+ assertNull(range1.intersection(range2));
+
+ range1 = Range.openClosed(1, 5);
+ range2 = Range.closed(5, 7);
+ assertEquals(Range.closed(5, 5), range1.intersection(range2));
+
+ range1 = Range.openClosed(4, 6);
+ range2 = Range.closed(1, 5);
+ assertEquals(Range.openClosed(4, 5), range1.intersection(range2));
+
+ range1 = Range.closedOpen(1, 5);
+ range2 = Range.closed(3, 5);
+ assertEquals(Range.closedOpen(3, 5), range1.intersection(range2));
+
+ range1 = Range.openClosed(1, 5);
+ range2 = Range.closed(2, 4);
+ assertEquals(Range.closed(2, 4), range1.intersection(range2));
+
+ range1 = Range.open(1, 5);
+ range2 = Range.closed(1, 3);
+ assertEquals(Range.openClosed(1, 3), range1.intersection(range2));
+
+ range1 = Range.open(1, 5);
+ range2 = Range.closed(1, 5);
+ assertEquals(Range.open(1, 5), range1.intersection(range2));
+
+ range1 = Range.closed(1, 10);
+ range2 = Range.open(2, 4);
+ assertEquals(Range.open(2, 4), range1.intersection(range2));
+
+ range1 = Range.open(1, 10);
+ range2 = Range.closed(2, 5);
+ assertEquals(Range.closed(2, 5), range1.intersection(range2));
+
+ range1 = Range.openClosed(1, 5);
+ range2 = Range.closed(1, 5);
+ assertEquals(Range.openClosed(1, 5), range1.intersection(range2));
+
+ range1 = Range.closedOpen(1, 5);
+ range2 = Range.closed(1, 5);
+ assertEquals(Range.closedOpen(1, 5), range1.intersection(range2));
+ }
+
+ @Test
+ public void testIntersection_atLeastAtMost(){
+ Range<Integer> range1 = Range.atLeast(1);
+ Range<Integer> range2 = Range.atLeast(5);
+ assertEquals(Range.atLeast(5), range1.intersection(range2));
+
+ range1 = Range.atMost(1);
+ range2 = Range.atMost(5);
+ assertEquals(Range.atMost(1), range1.intersection(range2));
+ }
+
+ @Test
+ public void testRangeLexComparator() {
+ List<Range<Integer>> ranges = Arrays.asList(
+ Range.closed(1, 3),
+ Range.closed(2, 4),
+ Range.closed(1, 4),
+ Range.closed(2, 3),
+ Range.closed(7, 10),
+ Range.closed(3, 4),
+ Range.closed(1, 2));
+ ranges.sort(Range.RANGE_LEX_COMPARATOR);
+ assertEquals(
+ Arrays.asList(
+ Range.closed(1, 2),
+ Range.closed(1, 3),
+ Range.closed(1, 4),
+ Range.closed(2, 3),
+ Range.closed(2, 4),
+ Range.closed(3, 4),
+ Range.closed(7, 10)),
+ ranges);
+ }
+
+ @Test
+ public void testRangeLexComparator_openBounds() {
+ List<Range<Integer>> ranges = Arrays.asList(
+ Range.closed(2, 4),
+ Range.closed(1, 4),
+ Range.closed(2, 3),
+ Range.atLeast(7),
+ Range.atMost(3),
+ Range.closed(3, 4),
+ Range.closed(1, 2));
+ ranges.sort(Range.RANGE_LEX_COMPARATOR);
+ assertEquals(
+ Arrays.asList(
+ Range.atMost(3),
+ Range.closed(1, 2),
+ Range.closed(1, 4),
+ Range.closed(2, 3),
+ Range.closed(2, 4),
+ Range.closed(3, 4),
+ Range.atLeast(7)),
+ ranges);
+ }
+}
diff --git a/dexlib2/src/test/java/com/android/tools/smali/dexlib2/util/UnmodifiableRangeMapTest.java b/dexlib2/src/test/java/com/android/tools/smali/dexlib2/util/UnmodifiableRangeMapTest.java
new file mode 100644
index 00000000..dead33e4
--- /dev/null
+++ b/dexlib2/src/test/java/com/android/tools/smali/dexlib2/util/UnmodifiableRangeMapTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2024, Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.tools.smali.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import com.android.tools.smali.util.Range;
+import com.android.tools.smali.util.UnmodifiableRangeMap;
+
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UnmodifiableRangeMapTest {
+
+ @Test
+ public void testEmpty() {
+ UnmodifiableRangeMap<Integer, String> map = UnmodifiableRangeMap.of();
+ Assert.assertNull(map.get(0));
+ Assert.assertNull(map.getEntry(0));
+ }
+
+ @Test
+ public void testBuilder() {
+ UnmodifiableRangeMap<Integer, String> rangeMap =
+ UnmodifiableRangeMap.<Integer, String>builder()
+ .put(Range.closed(1, 3), "a")
+ .put(Range.closed(4, 6), "b")
+ .build();
+ assertEquals("a", rangeMap.get(2));
+ assertEquals("b", rangeMap.get(5));
+ assertNull(rangeMap.get(0));
+ assertNull(rangeMap.get(7));
+ assertNull(rangeMap.get(null));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBuilderEmptyRange() {
+ UnmodifiableRangeMap.<Integer, String>builder().put(Range.open(1, 1), "a").build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBuilderOverlappingRanges() {
+ UnmodifiableRangeMap.<Integer, String>builder()
+ .put(Range.closed(1, 3), "a")
+ .put(Range.closed(2, 4), "b")
+ .build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBuilderEdgeOverlappingRanges() {
+ UnmodifiableRangeMap.<Integer, String>builder()
+ .put(Range.closed(1, 3), "a")
+ .put(Range.closed(3, 7), "b")
+ .build();
+ }
+
+ @Test
+ public void testGet_oddSizeMap() {
+ UnmodifiableRangeMap<Integer, String> rangeMap =
+ UnmodifiableRangeMap.<Integer, String>builder()
+ .put(Range.closed(1, 3), "a")
+ .put(Range.closed(4, 6), "b")
+ .put(Range.closed(11, 20), "c")
+ .build();
+ assertEquals("a", rangeMap.get(2));
+ assertEquals("c", rangeMap.get(15));
+ assertNull(rangeMap.get(0));
+ assertNull(rangeMap.get(7));
+ }
+
+ @Test
+ public void testGet_evenSizeMap() {
+ UnmodifiableRangeMap<Integer, String> rangeMap =
+ UnmodifiableRangeMap.<Integer, String>builder()
+ .put(Range.closed(1, 3), "a")
+ .put(Range.closed(4, 6), "b")
+ .put(Range.closed(11, 20), "c")
+ .put(Range.closed(21, 30), "d")
+ .build();
+ assertEquals("a", rangeMap.get(2));
+ assertEquals("b", rangeMap.get(6));
+ assertEquals("c", rangeMap.get(15));
+ assertEquals("d", rangeMap.get(23));
+ assertNull(rangeMap.get(0));
+ assertNull(rangeMap.get(7));
+ }
+
+ @Test
+ public void testEntry() {
+ UnmodifiableRangeMap<Integer, String> rangeMap =
+ UnmodifiableRangeMap.<Integer, String>builder()
+ .put(Range.closed(1, 3), "a")
+ .put(Range.closed(4, 6), "b")
+ .put(Range.closed(10, 15), "c")
+ .build();
+ Map.Entry<Range<Integer>, String> entry = rangeMap.getEntry(2);
+ assertEquals(Range.closed(1, 3), entry.getKey());
+ assertEquals("a", entry.getValue());
+ assertNull(rangeMap.getEntry(null));
+ }
+
+ @Test
+ public void testRanges_AtMostAtLeast() {
+ UnmodifiableRangeMap<Integer, String> rangeMap =
+ UnmodifiableRangeMap.<Integer, String>builder()
+ .put(Range.atMost(3), "a")
+ .put(Range.closed(10, 15), "b")
+ .put(Range.atLeast(25), "c")
+ .build();
+ assertEquals("a", rangeMap.get(2));
+ assertNull(rangeMap.get(5));
+ assertEquals("b", rangeMap.get(12));
+ assertEquals("c", rangeMap.get(30));
+ assertNull(rangeMap.get(null));
+ }
+
+ @Test
+ public void testRanges_openBounds() {
+ UnmodifiableRangeMap<Integer, String> rangeMap =
+ UnmodifiableRangeMap.<Integer, String>builder()
+ .put(Range.openClosed(1, 3), "a")
+ .put(Range.open(10, 15), "b")
+ .put(Range.closedOpen(25, 30), "c")
+ .build();
+
+ assertNull(rangeMap.get(0));
+ assertNull(rangeMap.get(1));
+ assertEquals("a", rangeMap.get(2));
+ assertEquals("b", rangeMap.get(12));
+ assertNull(rangeMap.get(5));
+ assertNull(rangeMap.get(15));
+ assertEquals("c", rangeMap.get(25));
+ assertEquals("c", rangeMap.get(25));
+ }
+} \ No newline at end of file
diff --git a/dexlib2/src/test/java/com/android/tools/smali/util/ArraySortedSetTest.java b/dexlib2/src/test/java/com/android/tools/smali/util/ArraySortedSetTest.java
new file mode 100644
index 00000000..658ad4dd
--- /dev/null
+++ b/dexlib2/src/test/java/com/android/tools/smali/util/ArraySortedSetTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2024, Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.tools.smali.util;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Iterator;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ArraySortedSetTest {
+ @Test
+ public void testOf() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(), new Integer[] {
+ 1, 2, 3
+ });
+ Assert.assertEquals(set.size(), 3);
+ Assert.assertTrue(set.contains(1));
+ Assert.assertTrue(set.contains(2));
+ Assert.assertTrue(set.contains(3));
+ Assert.assertFalse(set.contains(4));
+ }
+
+ @Test
+ public void testOfCollection() {
+ List<Integer> list = Arrays.asList(1, 2, 3);
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(), list);
+ Assert.assertEquals(set.size(), 3);
+ Assert.assertTrue(set.contains(1));
+ Assert.assertTrue(set.contains(2));
+ Assert.assertTrue(set.contains(3));
+ Assert.assertFalse(set.contains(4));
+ }
+
+ @Test(expected = AssertionError.class)
+ public void testOfUnsorted() {
+ ArraySortedSet.of(Comparator.naturalOrder(), new Integer[] {
+ 3, 1, 2
+ });
+ }
+
+ @Test(expected = AssertionError.class)
+ public void testOfCollectionUnsorted() {
+ ArraySortedSet.of(Comparator.naturalOrder(), Arrays.asList(3, 1, 2));
+ }
+
+ @Test
+ public void testIterator() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ Iterator<Integer> it = set.iterator();
+ Assert.assertEquals(it.next(), (Integer) 1);
+ Assert.assertEquals(it.next(), (Integer) 2);
+ Assert.assertEquals(it.next(), (Integer) 3);
+ }
+
+ @Test
+ public void testToArray() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ Assert.assertArrayEquals(set.toArray(), new Integer[] {
+ 1, 2, 3
+ });
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testAdd() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ set.add(4);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testRemove() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ set.remove(2);
+ }
+
+ @Test
+ public void testContainsAll() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ Assert.assertTrue(set.containsAll(Arrays.asList(1, 2)));
+ Assert.assertTrue(set.containsAll(Arrays.asList(1, 2, 3)));
+ Assert.assertFalse(set.containsAll(Arrays.asList(1, 2, 3, 4)));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testAddAll() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ set.addAll(Arrays.asList(4));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testRemoveAll() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ set.removeAll(Arrays.asList(2));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testClear() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ set.clear();
+ }
+
+ @Test
+ public void testComparator() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ Assert.assertEquals(set.comparator(), Comparator.naturalOrder());
+ }
+
+ @Test
+ public void testFirst() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ Assert.assertEquals(set.first(), (Integer) 1);
+ }
+
+ @Test
+ public void testLast() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ Assert.assertEquals(set.last(), (Integer) 3);
+ }
+
+ @Test
+ public void testHashCode() {
+ ArraySortedSet<Integer> set = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ Assert.assertEquals(set.hashCode(), 6);
+ }
+
+ @Test
+ public void testEquals() {
+ ArraySortedSet<Integer> set1 = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ ArraySortedSet<Integer> set2 = ArraySortedSet.of(Comparator.naturalOrder(),
+ Arrays.asList(1, 2, 3));
+ Assert.assertTrue(set1.equals(set2));
+ }
+}
diff --git a/smali/Android.bp b/smali/Android.bp
index 73ec6520..4184deb5 100644
--- a/smali/Android.bp
+++ b/smali/Android.bp
@@ -34,6 +34,7 @@ java_binary_host {
manifest: "manifest.txt",
static_libs: [
+ "guava",
"antlr-runtime",
"jcommander",
"smali-dexlib2",
@@ -43,4 +44,4 @@ java_binary_host {
java_resources: [":android-smali_version"],
wrapper: ":android-smali_script",
-} \ No newline at end of file
+}