All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.reandroid.dex.model.DexClassRepository Maven / Gradle / Ivy

The newest version!
/*
 *  Copyright (C) 2022 github.com/REAndroid
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.reandroid.dex.model;

import com.reandroid.arsc.base.BlockRefresh;
import com.reandroid.arsc.item.IntegerReference;
import com.reandroid.dex.common.FullRefresh;
import com.reandroid.dex.common.SectionItem;
import com.reandroid.dex.data.AnnotationElement;
import com.reandroid.dex.data.AnnotationItem;
import com.reandroid.dex.data.DebugInfo;
import com.reandroid.dex.id.ClassId;
import com.reandroid.dex.id.MethodId;
import com.reandroid.dex.id.SourceFile;
import com.reandroid.dex.key.*;
import com.reandroid.dex.sections.Marker;
import com.reandroid.dex.sections.Section;
import com.reandroid.dex.sections.SectionType;
import com.reandroid.utils.ObjectsUtil;
import com.reandroid.utils.collection.*;

import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;

public interface DexClassRepository extends FullRefresh, BlockRefresh {

    int getDexClassesCount();
    DexClass getDexClass(TypeKey typeKey);
    default DexClass getDexClass(String name) {
        return getDexClass(TypeKey.create(name));
    }
    Iterator getDexClasses(Predicate filter);
    Iterator getDexClassesCloned(Predicate filter);
    int shrink();
    default Iterator searchExtending(TypeKey typeKey){
        return EmptyIterator.of();
    }
    default Iterator searchImplementations(TypeKey typeKey){
        return EmptyIterator.of();
    }
     Iterator> getSections(SectionType sectionType);
    default  Iterator getItems(SectionType sectionType) {
        return new IterableIterator, T>(getSections(sectionType)) {
            @Override
            public Iterator iterator(Section element) {
                return element.iterator();
            }
        };
    }
    default  Iterator getClonedItems(SectionType sectionType){
        return new IterableIterator, T>(getSections(sectionType)) {
            @Override
            public Iterator iterator(Section element) {
                return element.clonedIterator();
            }
        };
    }
    default  Iterator getItems(SectionType sectionType, Key key) {
        return new IterableIterator, T>(getSections(sectionType)) {
            @Override
            public Iterator iterator(Section element) {
                return element.getAll(key);
            }
        };
    }
    default  T getItem(SectionType sectionType, Key key){
        Iterator> iterator = getSections(sectionType);
        while (iterator.hasNext()){
            Section section = iterator.next();
            T item = section.get(key);
            if(item != null){
                return item;
            }
        }
        return null;
    }
    default boolean contains(SectionType sectionType, Key key){
        return getItems(sectionType, key).hasNext();
    }
    default boolean contains(Key key){
        if(key == null){
            return false;
        }
        if(key instanceof StringKey){
            return contains(SectionType.STRING_ID, key);
        }
        if(key instanceof TypeKey){
            return contains(SectionType.TYPE_ID, key);
        }
        if(key instanceof FieldKey){
            return contains(SectionType.FIELD_ID, key);
        }
        if(key instanceof ProtoKey){
            return contains(SectionType.PROTO_ID, key);
        }
        if(key instanceof MethodKey){
            return contains(SectionType.METHOD_ID, key);
        }
        if(key instanceof TypeListKey){
            return contains(SectionType.TYPE_LIST, key);
        }
        throw new IllegalArgumentException("Unknown key type: " + key.getClass() + ", '" + key + "'");
    }
    default boolean containsClass(TypeKey key){
        return contains(SectionType.CLASS_ID, key);
    }
     boolean removeEntries(SectionType sectionType, Predicate filter);
     boolean removeEntriesWithKey(SectionType sectionType, Predicate filter);
     boolean removeEntry(SectionType sectionType, Key key);
    void clearPoolMap();

    default  Iterator getClonedItems(SectionType sectionType, Predicate filter) {
        return FilterIterator.of(getClonedItems(sectionType), filter);
    }

    default Iterator findUserClasses(Key key){
        return new UniqueIterator<>(getDexClasses(),
                dexClass -> dexClass.uses(key));
    }
    default Iterator getDexClasses(){
        return getDexClasses(null);
    }
    default Iterator getDexClassesCloned(){
        return getDexClassesCloned(null);
    }
    default Iterator getPackageClasses(String packageName){
        return getPackageClasses(packageName, true);
    }
    default Iterator getPackageClasses(String packageName, boolean includeSubPackages){
        return getDexClasses(key -> key.isPackage(packageName, includeSubPackages));
    }
    default DexMethod getDeclaredMethod(MethodKey methodKey){
        DexClass dexClass = getDexClass(methodKey.getDeclaring());
        if(dexClass != null){
            DexMethod dexMethod = dexClass.getDeclaredMethod(methodKey, false);
            if(dexMethod == null) {
                dexMethod = dexClass.getDeclaredMethod(methodKey, true);
            }
            return dexMethod;
        }
        return null;
    }
    default DexMethod getDeclaredMethod(MethodKey methodKey, boolean ignoreReturnType){
        DexClass dexClass = getDexClass(methodKey.getDeclaring());
        if(dexClass != null){
            return dexClass.getDeclaredMethod(methodKey, ignoreReturnType);
        }
        return null;
    }
    default DexField getDeclaredField(FieldKey fieldKey){
        DexClass dexClass = getDexClass(fieldKey.getDeclaring());
        if(dexClass != null){
            return dexClass.getDeclaredField(fieldKey);
        }
        return null;
    }
    default DexDeclaration getDexDeclaration(Key key){
        if(key instanceof TypeKey){
            return getDexClass((TypeKey) key);
        }
        if(key instanceof MethodKey){
            return getDeclaredMethod((MethodKey) key);
        }
        if(key instanceof FieldKey){
            return getDeclaredField((FieldKey) key);
        }
        return null;
    }
    default Iterator getDeclaredMethods(){
        return new IterableIterator(getDexClasses()) {
            @Override
            public Iterator iterator(DexClass dexClass) {
                return dexClass.getDeclaredMethods();
            }
        };
    }
    default Iterator getDeclaredFields(){
        return new IterableIterator(getDexClasses()) {
            @Override
            public Iterator iterator(DexClass dexClass) {
                return dexClass.getDeclaredFields();
            }
        };
    }
    default Iterator visitIntegers(){
        return new DexIntegerVisitor(this);
    }

    default boolean removeClass(TypeKey typeKey) {
        return removeEntry(SectionType.CLASS_ID, typeKey);
    }
    boolean removeClasses(Predicate filter);
    default boolean removeClassesWithKeys(Predicate filter) {
        return removeEntriesWithKey(SectionType.CLASS_ID, ObjectsUtil.cast(filter));
    }
    default boolean removeAnnotations(TypeKey typeKey) {
        return removeEntries(SectionType.ANNOTATION_ITEM,
                annotationItem -> typeKey.equals(annotationItem.getTypeKey()));
    }
    default int removeAnnotationElements(MethodKey methodKey) {
        int removeCount = 0;

        TypeKey typeKey = methodKey.getDeclaring();
        Predicate elementFilter = element -> element.is(methodKey);

        Iterator iterator = getClonedItems(SectionType.ANNOTATION_ITEM);
        while (iterator.hasNext()) {
            AnnotationItem annotationItem = iterator.next();
            if(typeKey.equals(methodKey.getDeclaring())) {
                if(annotationItem.removeIf(elementFilter)){
                    if(annotationItem.isEmpty()) {
                        annotationItem.removeSelf();
                    }
                    removeCount ++;
                }
            }
        }
        return removeCount;
    }
    default void clearDebug() {
        Iterator> iterator = getSections(SectionType.DEBUG_INFO);
        while (iterator.hasNext()) {
            iterator.next().removeSelf();
        }
    }

    default List getExternalTypeKeyReferenceList() {
        return ArrayCollection.empty();
    }

    default Iterator findEquivalentMethods(MethodKey methodKey){
        DexClass defining = getDexClass(methodKey.getDeclaring());
        if(defining == null){
            return EmptyIterator.of();
        }
        Iterator iterator = defining.getMethods(methodKey);
        return new IterableIterator(iterator) {
            @Override
            public Iterator iterator(DexMethod element) {
                element = element.getDeclared();
                MethodKey definingKey = element.getKey();
                return CombiningIterator.two(SingleIterator.of(definingKey),
                        element.getOverridingKeys());
            }
        };
    }
    default Iterator getMethods(MethodKey methodKey) {
        return ComputeIterator.of(findEquivalentMethods(methodKey), this::getDeclaredMethod);
    }
    default Iterator getMethodIds(MethodKey methodKey){
        return new IterableIterator(findEquivalentMethods(methodKey)) {
            @Override
            public Iterator iterator(MethodKey element) {
                return getItems(SectionType.METHOD_ID, element);
            }
        };
    }

    Iterator getMarkers();
    default void clearMarkers(){
        Iterator iterator = getMarkers();
        while (iterator.hasNext()) {
            iterator.next().removeSelf();
        }
    }
    default void setClassSourceFileAll(){
        setClassSourceFileAll(SourceFile.SourceFile);
    }
    default void setClassSourceFileAll(String sourceFile){
        Iterator iterator = getItems(SectionType.CLASS_ID);
        while (iterator.hasNext()){
            ClassId classId = iterator.next();
            classId.setSourceFile(sourceFile);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy