142627b850c8f68a594f105e04b97c512b292b698Ben Gruver/* 242627b850c8f68a594f105e04b97c512b292b698Ben Gruver * Copyright 2013, Google Inc. 342627b850c8f68a594f105e04b97c512b292b698Ben Gruver * All rights reserved. 442627b850c8f68a594f105e04b97c512b292b698Ben Gruver * 542627b850c8f68a594f105e04b97c512b292b698Ben Gruver * Redistribution and use in source and binary forms, with or without 642627b850c8f68a594f105e04b97c512b292b698Ben Gruver * modification, are permitted provided that the following conditions are 742627b850c8f68a594f105e04b97c512b292b698Ben Gruver * met: 842627b850c8f68a594f105e04b97c512b292b698Ben Gruver * 942627b850c8f68a594f105e04b97c512b292b698Ben Gruver * * Redistributions of source code must retain the above copyright 1042627b850c8f68a594f105e04b97c512b292b698Ben Gruver * notice, this list of conditions and the following disclaimer. 1142627b850c8f68a594f105e04b97c512b292b698Ben Gruver * * Redistributions in binary form must reproduce the above 1242627b850c8f68a594f105e04b97c512b292b698Ben Gruver * copyright notice, this list of conditions and the following disclaimer 1342627b850c8f68a594f105e04b97c512b292b698Ben Gruver * in the documentation and/or other materials provided with the 1442627b850c8f68a594f105e04b97c512b292b698Ben Gruver * distribution. 1542627b850c8f68a594f105e04b97c512b292b698Ben Gruver * * Neither the name of Google Inc. nor the names of its 1642627b850c8f68a594f105e04b97c512b292b698Ben Gruver * contributors may be used to endorse or promote products derived from 1742627b850c8f68a594f105e04b97c512b292b698Ben Gruver * this software without specific prior written permission. 1842627b850c8f68a594f105e04b97c512b292b698Ben Gruver * 1942627b850c8f68a594f105e04b97c512b292b698Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2042627b850c8f68a594f105e04b97c512b292b698Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2142627b850c8f68a594f105e04b97c512b292b698Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2242627b850c8f68a594f105e04b97c512b292b698Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2342627b850c8f68a594f105e04b97c512b292b698Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2442627b850c8f68a594f105e04b97c512b292b698Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2542627b850c8f68a594f105e04b97c512b292b698Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2642627b850c8f68a594f105e04b97c512b292b698Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2742627b850c8f68a594f105e04b97c512b292b698Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2842627b850c8f68a594f105e04b97c512b292b698Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2942627b850c8f68a594f105e04b97c512b292b698Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3042627b850c8f68a594f105e04b97c512b292b698Ben Gruver */ 3142627b850c8f68a594f105e04b97c512b292b698Ben Gruver 3242627b850c8f68a594f105e04b97c512b292b698Ben Gruverpackage org.jf.dexlib2.writer.builder; 3342627b850c8f68a594f105e04b97c512b292b698Ben Gruver 3442627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport com.google.common.base.Function; 3542627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport com.google.common.base.Predicate; 3642627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport com.google.common.collect.*; 3742627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.DebugItemType; 389a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruverimport org.jf.dexlib2.builder.MutableMethodImplementation; 396f135aeb74b0a5b5720bafa2a9aaa32880f0549fBen Gruverimport org.jf.dexlib2.iface.ExceptionHandler; 4042627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.iface.Field; 41dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruverimport org.jf.dexlib2.iface.MethodImplementation; 4242627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.iface.TryBlock; 439bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruverimport org.jf.dexlib2.iface.debug.*; 44dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruverimport org.jf.dexlib2.iface.instruction.Instruction; 459bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruverimport org.jf.dexlib2.iface.reference.StringReference; 469bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruverimport org.jf.dexlib2.iface.reference.TypeReference; 4742627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.iface.value.EncodedValue; 4842627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.util.EncodedValueUtils; 4942627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.writer.ClassSection; 5042627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.writer.DebugWriter; 5142627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.writer.builder.BuilderEncodedValues.BuilderEncodedValue; 5242627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.util.AbstractForwardSequentialList; 5342627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.util.CollectionUtils; 5442627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.util.ExceptionWithContext; 5542627b850c8f68a594f105e04b97c512b292b698Ben Gruver 5642627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport javax.annotation.Nonnull; 5742627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport javax.annotation.Nullable; 5842627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.io.IOException; 5942627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.*; 6042627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.Map.Entry; 6142627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.concurrent.ConcurrentMap; 6242627b850c8f68a594f105e04b97c512b292b698Ben Gruver 635189797292086a051666cf8c96cf44c6a23321b6Ben Gruverpublic class BuilderClassPool extends BaseBuilderPool implements ClassSection<BuilderStringReference, 645189797292086a051666cf8c96cf44c6a23321b6Ben Gruver BuilderTypeReference, BuilderTypeList, BuilderClassDef, BuilderField, BuilderMethod, BuilderAnnotationSet, 655189797292086a051666cf8c96cf44c6a23321b6Ben Gruver BuilderEncodedValue> { 6642627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull private final ConcurrentMap<String, BuilderClassDef> internedItems = 6742627b850c8f68a594f105e04b97c512b292b698Ben Gruver Maps.newConcurrentMap(); 6842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 695189797292086a051666cf8c96cf44c6a23321b6Ben Gruver public BuilderClassPool(@Nonnull DexBuilder dexBuilder) { 705189797292086a051666cf8c96cf44c6a23321b6Ben Gruver super(dexBuilder); 7142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 7242627b850c8f68a594f105e04b97c512b292b698Ben Gruver 7342627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull BuilderClassDef internClass(@Nonnull BuilderClassDef classDef) { 7442627b850c8f68a594f105e04b97c512b292b698Ben Gruver BuilderClassDef prev = internedItems.put(classDef.getType(), classDef); 7542627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (prev != null) { 7642627b850c8f68a594f105e04b97c512b292b698Ben Gruver throw new ExceptionWithContext("Class %s has already been interned", classDef.getType()); 7742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 7842627b850c8f68a594f105e04b97c512b292b698Ben Gruver return classDef; 7942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 8042627b850c8f68a594f105e04b97c512b292b698Ben Gruver 8142627b850c8f68a594f105e04b97c512b292b698Ben Gruver private ImmutableList<BuilderClassDef> sortedClasses = null; 8242627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public Collection<? extends BuilderClassDef> getSortedClasses() { 8342627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (sortedClasses == null) { 8442627b850c8f68a594f105e04b97c512b292b698Ben Gruver sortedClasses = Ordering.natural().immutableSortedCopy(internedItems.values()); 8542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 8642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return sortedClasses; 8742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 8842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 8942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override 9042627b850c8f68a594f105e04b97c512b292b698Ben Gruver public Entry<? extends BuilderClassDef, Integer> getClassEntryByType(@Nullable BuilderTypeReference type) { 9142627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (type == null) { 9242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return null; 9342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 9442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 9542627b850c8f68a594f105e04b97c512b292b698Ben Gruver final BuilderClassDef classDef = internedItems.get(type.getType()); 9642627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (classDef == null) { 9742627b850c8f68a594f105e04b97c512b292b698Ben Gruver return null; 9842627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 9942627b850c8f68a594f105e04b97c512b292b698Ben Gruver 10042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return new Map.Entry<BuilderClassDef, Integer>() { 10142627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public BuilderClassDef getKey() { 10242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return classDef; 10342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 10442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 10542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public Integer getValue() { 10642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return classDef.classDefIndex; 10742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 10842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 10942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public Integer setValue(Integer value) { 11042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return classDef.classDefIndex = value; 11142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 11242627b850c8f68a594f105e04b97c512b292b698Ben Gruver }; 11342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 11442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 11542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public BuilderTypeReference getType(@Nonnull BuilderClassDef builderClassDef) { 11642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.type; 11742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 11842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 11942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getAccessFlags(@Nonnull BuilderClassDef builderClassDef) { 12042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.accessFlags; 12142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 12242627b850c8f68a594f105e04b97c512b292b698Ben Gruver 12342627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override public BuilderTypeReference getSuperclass(@Nonnull BuilderClassDef builderClassDef) { 12442627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.superclass; 12542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 12642627b850c8f68a594f105e04b97c512b292b698Ben Gruver 127c456c55c40d0731edb9913fae73f16b9d94ac45bAlex Light @Nullable @Override public BuilderTypeList getInterfaces(@Nonnull BuilderClassDef builderClassDef) { 12842627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.interfaces; 12942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 13042627b850c8f68a594f105e04b97c512b292b698Ben Gruver 13142627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override public BuilderStringReference getSourceFile(@Nonnull BuilderClassDef builderClassDef) { 13242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.sourceFile; 13342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 13442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 13542627b850c8f68a594f105e04b97c512b292b698Ben Gruver private static final Predicate<Field> HAS_INITIALIZER = new Predicate<Field>() { 13642627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override 13742627b850c8f68a594f105e04b97c512b292b698Ben Gruver public boolean apply(Field input) { 13842627b850c8f68a594f105e04b97c512b292b698Ben Gruver EncodedValue encodedValue = input.getInitialValue(); 13942627b850c8f68a594f105e04b97c512b292b698Ben Gruver return encodedValue != null && !EncodedValueUtils.isDefaultValue(encodedValue); 14042627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 14142627b850c8f68a594f105e04b97c512b292b698Ben Gruver }; 14242627b850c8f68a594f105e04b97c512b292b698Ben Gruver 14342627b850c8f68a594f105e04b97c512b292b698Ben Gruver private static final Function<BuilderField, BuilderEncodedValue> GET_INITIAL_VALUE = 14442627b850c8f68a594f105e04b97c512b292b698Ben Gruver new Function<BuilderField, BuilderEncodedValue>() { 14542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override 14642627b850c8f68a594f105e04b97c512b292b698Ben Gruver public BuilderEncodedValue apply(BuilderField input) { 14742627b850c8f68a594f105e04b97c512b292b698Ben Gruver BuilderEncodedValue initialValue = input.getInitialValue(); 14842627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (initialValue == null) { 14942627b850c8f68a594f105e04b97c512b292b698Ben Gruver return BuilderEncodedValues.defaultValueForType(input.getType()); 15042627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 15142627b850c8f68a594f105e04b97c512b292b698Ben Gruver return initialValue; 15242627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 15342627b850c8f68a594f105e04b97c512b292b698Ben Gruver }; 15442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 15542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override 15642627b850c8f68a594f105e04b97c512b292b698Ben Gruver public Collection<? extends BuilderEncodedValue> getStaticInitializers(@Nonnull BuilderClassDef classDef) { 15742627b850c8f68a594f105e04b97c512b292b698Ben Gruver final SortedSet<BuilderField> sortedStaticFields = classDef.getStaticFields(); 15842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 15942627b850c8f68a594f105e04b97c512b292b698Ben Gruver final int lastIndex = CollectionUtils.lastIndexOf(sortedStaticFields, HAS_INITIALIZER); 16042627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (lastIndex > -1) { 16142627b850c8f68a594f105e04b97c512b292b698Ben Gruver return new AbstractCollection<BuilderEncodedValue>() { 16242627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public Iterator<BuilderEncodedValue> iterator() { 1631d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruver Iterable<BuilderField> fields = Iterables.limit(sortedStaticFields, lastIndex + 1); 1641d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruver return Iterables.transform(fields, GET_INITIAL_VALUE).iterator(); 16542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 16642627b850c8f68a594f105e04b97c512b292b698Ben Gruver 16742627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int size() { 16842627b850c8f68a594f105e04b97c512b292b698Ben Gruver return lastIndex+1; 16942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 17042627b850c8f68a594f105e04b97c512b292b698Ben Gruver }; 17142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 17242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return null; 17342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 17442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 17542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override 17642627b850c8f68a594f105e04b97c512b292b698Ben Gruver public Collection<? extends BuilderField> getSortedStaticFields(@Nonnull BuilderClassDef builderClassDef) { 17742627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.getStaticFields(); 17842627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 17942627b850c8f68a594f105e04b97c512b292b698Ben Gruver 18042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override 18142627b850c8f68a594f105e04b97c512b292b698Ben Gruver public Collection<? extends BuilderField> getSortedInstanceFields(@Nonnull BuilderClassDef builderClassDef) { 18242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.getInstanceFields(); 18342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 18442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 18542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override 18642627b850c8f68a594f105e04b97c512b292b698Ben Gruver public Collection<? extends BuilderField> getSortedFields(@Nonnull BuilderClassDef builderClassDef) { 18742627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.getFields(); 18842627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 18942627b850c8f68a594f105e04b97c512b292b698Ben Gruver 19042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override 19142627b850c8f68a594f105e04b97c512b292b698Ben Gruver public Collection<? extends BuilderMethod> getSortedDirectMethods(@Nonnull BuilderClassDef builderClassDef) { 19242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.getDirectMethods(); 19342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 19442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 19542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override 19642627b850c8f68a594f105e04b97c512b292b698Ben Gruver public Collection<? extends BuilderMethod> getSortedVirtualMethods(@Nonnull BuilderClassDef builderClassDef) { 19742627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.getVirtualMethods(); 19842627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 19942627b850c8f68a594f105e04b97c512b292b698Ben Gruver 20042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override 20142627b850c8f68a594f105e04b97c512b292b698Ben Gruver public Collection<? extends BuilderMethod> getSortedMethods(@Nonnull BuilderClassDef builderClassDef) { 20242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.getMethods(); 20342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 20442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 20542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getFieldAccessFlags(@Nonnull BuilderField builderField) { 20642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderField.accessFlags; 20742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 20842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 20942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getMethodAccessFlags(@Nonnull BuilderMethod builderMethod) { 21042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderMethod.accessFlags; 21142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 21242627b850c8f68a594f105e04b97c512b292b698Ben Gruver 21342627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override public BuilderAnnotationSet getClassAnnotations(@Nonnull BuilderClassDef builderClassDef) { 21442627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (builderClassDef.annotations.isEmpty()) { 21542627b850c8f68a594f105e04b97c512b292b698Ben Gruver return null; 21642627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 21742627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.annotations; 21842627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 21942627b850c8f68a594f105e04b97c512b292b698Ben Gruver 22042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override public BuilderAnnotationSet getFieldAnnotations(@Nonnull BuilderField builderField) { 22142627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (builderField.annotations.isEmpty()) { 22242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return null; 22342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 22442627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderField.annotations; 22542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 22642627b850c8f68a594f105e04b97c512b292b698Ben Gruver 22742627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override public BuilderAnnotationSet getMethodAnnotations(@Nonnull BuilderMethod builderMethod) { 22842627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (builderMethod.annotations.isEmpty()) { 22942627b850c8f68a594f105e04b97c512b292b698Ben Gruver return null; 23042627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 23142627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderMethod.annotations; 23242627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 23342627b850c8f68a594f105e04b97c512b292b698Ben Gruver 23442627b850c8f68a594f105e04b97c512b292b698Ben Gruver private static final Predicate<BuilderMethodParameter> HAS_PARAMETER_ANNOTATIONS = 23542627b850c8f68a594f105e04b97c512b292b698Ben Gruver new Predicate<BuilderMethodParameter>() { 23642627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override 23742627b850c8f68a594f105e04b97c512b292b698Ben Gruver public boolean apply(BuilderMethodParameter input) { 23842627b850c8f68a594f105e04b97c512b292b698Ben Gruver return input.getAnnotations().size() > 0; 23942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 24042627b850c8f68a594f105e04b97c512b292b698Ben Gruver }; 24142627b850c8f68a594f105e04b97c512b292b698Ben Gruver 24242627b850c8f68a594f105e04b97c512b292b698Ben Gruver private static final Function<BuilderMethodParameter, BuilderAnnotationSet> PARAMETER_ANNOTATIONS = 24342627b850c8f68a594f105e04b97c512b292b698Ben Gruver new Function<BuilderMethodParameter, BuilderAnnotationSet>() { 24442627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override 24542627b850c8f68a594f105e04b97c512b292b698Ben Gruver public BuilderAnnotationSet apply(BuilderMethodParameter input) { 24642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return input.getAnnotations(); 24742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 24842627b850c8f68a594f105e04b97c512b292b698Ben Gruver }; 24942627b850c8f68a594f105e04b97c512b292b698Ben Gruver 25042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override public List<? extends BuilderAnnotationSet> getParameterAnnotations( 25142627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull final BuilderMethod method) { 252f6958ae4bc66ec338f5547ef3952896e219e6c33Ben Gruver final List<? extends BuilderMethodParameter> parameters = method.getParameters(); 253f6958ae4bc66ec338f5547ef3952896e219e6c33Ben Gruver boolean hasParameterAnnotations = Iterables.any(parameters, HAS_PARAMETER_ANNOTATIONS); 25442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 255f6958ae4bc66ec338f5547ef3952896e219e6c33Ben Gruver if (hasParameterAnnotations) { 25642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return new AbstractForwardSequentialList<BuilderAnnotationSet>() { 25742627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public Iterator<BuilderAnnotationSet> iterator() { 2581d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruver return Iterables.transform(parameters, PARAMETER_ANNOTATIONS).iterator(); 25942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 26042627b850c8f68a594f105e04b97c512b292b698Ben Gruver 26142627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int size() { 262f6958ae4bc66ec338f5547ef3952896e219e6c33Ben Gruver return parameters.size(); 26342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 26442627b850c8f68a594f105e04b97c512b292b698Ben Gruver }; 26542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 26642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return null; 26742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 26842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 26942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override 2709bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver public Iterable<? extends DebugItem> getDebugItems(@Nonnull BuilderMethod builderMethod) { 271dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver MethodImplementation impl = builderMethod.getImplementation(); 27242627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (impl == null) { 27342627b850c8f68a594f105e04b97c512b292b698Ben Gruver return null; 27442627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 27542627b850c8f68a594f105e04b97c512b292b698Ben Gruver return impl.getDebugItems(); 27642627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 27742627b850c8f68a594f105e04b97c512b292b698Ben Gruver 27842627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override 27942627b850c8f68a594f105e04b97c512b292b698Ben Gruver public Iterable<? extends BuilderStringReference> getParameterNames(@Nonnull BuilderMethod method) { 28042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return Iterables.transform(method.getParameters(), new Function<BuilderMethodParameter, BuilderStringReference>() { 28142627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override public BuilderStringReference apply(BuilderMethodParameter input) { 28242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return input.name; 28342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 28442627b850c8f68a594f105e04b97c512b292b698Ben Gruver }); 28542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 28642627b850c8f68a594f105e04b97c512b292b698Ben Gruver 28742627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getRegisterCount(@Nonnull BuilderMethod builderMethod) { 288dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver MethodImplementation impl = builderMethod.getImplementation(); 28942627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (impl == null) { 29042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return 0; 29142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 292dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver return impl.getRegisterCount(); 29342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 29442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 29542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nullable @Override 296dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver public Iterable<? extends Instruction> getInstructions(@Nonnull BuilderMethod builderMethod) { 297dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver MethodImplementation impl = builderMethod.getImplementation(); 29842627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (impl == null) { 29942627b850c8f68a594f105e04b97c512b292b698Ben Gruver return null; 30042627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 30142627b850c8f68a594f105e04b97c512b292b698Ben Gruver return impl.getInstructions(); 30242627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 30342627b850c8f68a594f105e04b97c512b292b698Ben Gruver 30442627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override 305dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver public List<? extends TryBlock<? extends ExceptionHandler>> getTryBlocks(@Nonnull BuilderMethod builderMethod) { 306dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver MethodImplementation impl = builderMethod.getImplementation(); 30742627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (impl == null) { 30842627b850c8f68a594f105e04b97c512b292b698Ben Gruver return ImmutableList.of(); 30942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 31042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return impl.getTryBlocks(); 31142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 31242627b850c8f68a594f105e04b97c512b292b698Ben Gruver 3136f135aeb74b0a5b5720bafa2a9aaa32880f0549fBen Gruver @Nullable @Override public BuilderTypeReference getExceptionType(@Nonnull ExceptionHandler handler) { 3146f135aeb74b0a5b5720bafa2a9aaa32880f0549fBen Gruver return checkTypeReference(handler.getExceptionTypeReference()); 31542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 31642627b850c8f68a594f105e04b97c512b292b698Ben Gruver 3179a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver @Nonnull @Override 3189a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver public MutableMethodImplementation makeMutableMethodImplementation(@Nonnull BuilderMethod builderMethod) { 3199a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver MethodImplementation impl = builderMethod.getImplementation(); 3209a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver if (impl instanceof MutableMethodImplementation) { 3219a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver return (MutableMethodImplementation)impl; 3229a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver } 3239a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver return new MutableMethodImplementation(impl); 3249a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver } 3259a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver 32642627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public void setEncodedArrayOffset(@Nonnull BuilderClassDef builderClassDef, int offset) { 32742627b850c8f68a594f105e04b97c512b292b698Ben Gruver builderClassDef.encodedArrayOffset = offset; 32842627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 32942627b850c8f68a594f105e04b97c512b292b698Ben Gruver 33042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getEncodedArrayOffset(@Nonnull BuilderClassDef builderClassDef) { 33142627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.encodedArrayOffset; 33242627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 33342627b850c8f68a594f105e04b97c512b292b698Ben Gruver 33442627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public void setAnnotationDirectoryOffset(@Nonnull BuilderClassDef builderClassDef, int offset) { 33542627b850c8f68a594f105e04b97c512b292b698Ben Gruver builderClassDef.annotationDirectoryOffset = offset; 33642627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 33742627b850c8f68a594f105e04b97c512b292b698Ben Gruver 33842627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getAnnotationDirectoryOffset(@Nonnull BuilderClassDef builderClassDef) { 33942627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.annotationDirectoryOffset; 34042627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 34142627b850c8f68a594f105e04b97c512b292b698Ben Gruver 34242627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public void setAnnotationSetRefListOffset(@Nonnull BuilderMethod builderMethod, int offset) { 34342627b850c8f68a594f105e04b97c512b292b698Ben Gruver builderMethod.annotationSetRefListOffset = offset; 34442627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 34542627b850c8f68a594f105e04b97c512b292b698Ben Gruver 34642627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getAnnotationSetRefListOffset(@Nonnull BuilderMethod builderMethod) { 34742627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderMethod.annotationSetRefListOffset; 34842627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 34942627b850c8f68a594f105e04b97c512b292b698Ben Gruver 35042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public void setCodeItemOffset(@Nonnull BuilderMethod builderMethod, int offset) { 35142627b850c8f68a594f105e04b97c512b292b698Ben Gruver builderMethod.codeItemOffset = offset; 35242627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 35342627b850c8f68a594f105e04b97c512b292b698Ben Gruver 35442627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getCodeItemOffset(@Nonnull BuilderMethod builderMethod) { 35542627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderMethod.codeItemOffset; 35642627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 35742627b850c8f68a594f105e04b97c512b292b698Ben Gruver 3589bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver @Nullable private BuilderStringReference checkStringReference(@Nullable StringReference stringReference) { 3599bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver if (stringReference == null) { 3609bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver return null; 3619bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver } 3629bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver try { 3639bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver return (BuilderStringReference)stringReference; 3649bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver } catch (ClassCastException ex) { 3659bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver throw new IllegalStateException("Only StringReference instances returned by " + 3669bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver "DexBuilder.internStringReference or DexBuilder.internNullableStringReference may be used."); 3679bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver } 3689bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver } 3699bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver 3709bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver @Nullable private BuilderTypeReference checkTypeReference(@Nullable TypeReference typeReference) { 3719bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver if (typeReference == null) { 3729bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver return null; 3739bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver } 3749bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver try { 3759bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver return (BuilderTypeReference)typeReference; 3769bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver } catch (ClassCastException ex) { 3779bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver throw new IllegalStateException("Only TypeReference instances returned by " + 3789bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver "DexBuilder.internTypeReference or DexBuilder.internNullableTypeReference may be used."); 3799bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver } 3809bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver } 3819bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver 38242627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override 38342627b850c8f68a594f105e04b97c512b292b698Ben Gruver public void writeDebugItem(@Nonnull DebugWriter<BuilderStringReference, BuilderTypeReference> writer, 3849bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver DebugItem debugItem) throws IOException { 38542627b850c8f68a594f105e04b97c512b292b698Ben Gruver switch (debugItem.getDebugItemType()) { 38642627b850c8f68a594f105e04b97c512b292b698Ben Gruver case DebugItemType.START_LOCAL: { 3879bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver StartLocal startLocal = (StartLocal)debugItem; 38842627b850c8f68a594f105e04b97c512b292b698Ben Gruver writer.writeStartLocal(startLocal.getCodeAddress(), 3899bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver startLocal.getRegister(), 3909bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver checkStringReference(startLocal.getNameReference()), 3919bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver checkTypeReference(startLocal.getTypeReference()), 3929bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver checkStringReference(startLocal.getSignatureReference())); 39342627b850c8f68a594f105e04b97c512b292b698Ben Gruver break; 39442627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 39542627b850c8f68a594f105e04b97c512b292b698Ben Gruver case DebugItemType.END_LOCAL: { 39642627b850c8f68a594f105e04b97c512b292b698Ben Gruver EndLocal endLocal = (EndLocal)debugItem; 39742627b850c8f68a594f105e04b97c512b292b698Ben Gruver writer.writeEndLocal(endLocal.getCodeAddress(), endLocal.getRegister()); 39842627b850c8f68a594f105e04b97c512b292b698Ben Gruver break; 39942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 40042627b850c8f68a594f105e04b97c512b292b698Ben Gruver case DebugItemType.RESTART_LOCAL: { 40142627b850c8f68a594f105e04b97c512b292b698Ben Gruver RestartLocal restartLocal = (RestartLocal)debugItem; 40242627b850c8f68a594f105e04b97c512b292b698Ben Gruver writer.writeRestartLocal(restartLocal.getCodeAddress(), restartLocal.getRegister()); 40342627b850c8f68a594f105e04b97c512b292b698Ben Gruver break; 40442627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 40542627b850c8f68a594f105e04b97c512b292b698Ben Gruver case DebugItemType.PROLOGUE_END: { 40642627b850c8f68a594f105e04b97c512b292b698Ben Gruver writer.writePrologueEnd(debugItem.getCodeAddress()); 40742627b850c8f68a594f105e04b97c512b292b698Ben Gruver break; 40842627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 40942627b850c8f68a594f105e04b97c512b292b698Ben Gruver case DebugItemType.EPILOGUE_BEGIN: { 41042627b850c8f68a594f105e04b97c512b292b698Ben Gruver writer.writeEpilogueBegin(debugItem.getCodeAddress()); 41142627b850c8f68a594f105e04b97c512b292b698Ben Gruver break; 41242627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 41342627b850c8f68a594f105e04b97c512b292b698Ben Gruver case DebugItemType.LINE_NUMBER: { 41442627b850c8f68a594f105e04b97c512b292b698Ben Gruver LineNumber lineNumber = (LineNumber)debugItem; 41542627b850c8f68a594f105e04b97c512b292b698Ben Gruver writer.writeLineNumber(lineNumber.getCodeAddress(), lineNumber.getLineNumber()); 41642627b850c8f68a594f105e04b97c512b292b698Ben Gruver break; 41742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 41842627b850c8f68a594f105e04b97c512b292b698Ben Gruver case DebugItemType.SET_SOURCE_FILE: { 4199bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver SetSourceFile setSourceFile = (SetSourceFile)debugItem; 4209bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver writer.writeSetSourceFile(setSourceFile.getCodeAddress(), 4219bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver checkStringReference(setSourceFile.getSourceFileReference())); 422a37e508ffa2a512d70890c6a174c2c98ed803607Ben Gruver break; 42342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 42442627b850c8f68a594f105e04b97c512b292b698Ben Gruver default: 42542627b850c8f68a594f105e04b97c512b292b698Ben Gruver throw new ExceptionWithContext("Unexpected debug item type: %d", debugItem.getDebugItemType()); 42642627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 42742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 42842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 42942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getItemIndex(@Nonnull BuilderClassDef builderClassDef) { 43042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderClassDef.classDefIndex; 43142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 43242627b850c8f68a594f105e04b97c512b292b698Ben Gruver 43342627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public Collection<? extends Entry<? extends BuilderClassDef, Integer>> getItems() { 43442627b850c8f68a594f105e04b97c512b292b698Ben Gruver return new BuilderMapEntryCollection<BuilderClassDef>(internedItems.values()) { 43542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override protected int getValue(@Nonnull BuilderClassDef key) { 43642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return key.classDefIndex; 43742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 43842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 43942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override protected int setValue(@Nonnull BuilderClassDef key, int value) { 44042627b850c8f68a594f105e04b97c512b292b698Ben Gruver int prev = key.classDefIndex; 44142627b850c8f68a594f105e04b97c512b292b698Ben Gruver key.classDefIndex = value; 44242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return prev; 44342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 44442627b850c8f68a594f105e04b97c512b292b698Ben Gruver }; 44542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 44659256149f100fd06d7a5bebaa2d29a3f0847ee22Ben Gruver 44759256149f100fd06d7a5bebaa2d29a3f0847ee22Ben Gruver @Override public int getItemCount() { 44859256149f100fd06d7a5bebaa2d29a3f0847ee22Ben Gruver return internedItems.size(); 44959256149f100fd06d7a5bebaa2d29a3f0847ee22Ben Gruver } 45042627b850c8f68a594f105e04b97c512b292b698Ben Gruver} 451