| // Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| package com.android.tools.r8.graph; |
| |
| import static com.google.common.base.Predicates.alwaysTrue; |
| |
| import com.android.tools.r8.ProgramResource; |
| import com.android.tools.r8.ProgramResource.Kind; |
| import com.android.tools.r8.dex.MixedSectionCollection; |
| import com.android.tools.r8.errors.Unreachable; |
| import com.android.tools.r8.graph.GenericSignature.ClassSignature; |
| import com.android.tools.r8.kotlin.KotlinClassLevelInfo; |
| import com.android.tools.r8.origin.Origin; |
| import com.android.tools.r8.utils.structural.StructuralItem; |
| import com.android.tools.r8.utils.structural.StructuralMapping; |
| import com.android.tools.r8.utils.structural.StructuralSpecification; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.function.Consumer; |
| import java.util.function.Predicate; |
| import java.util.function.Supplier; |
| |
| public class DexClasspathClass extends DexClass |
| implements ClasspathClass, Supplier<DexClasspathClass>, StructuralItem<DexClasspathClass> { |
| |
| public DexClasspathClass( |
| DexType type, |
| ProgramResource.Kind kind, |
| Origin origin, |
| ClassAccessFlags accessFlags, |
| DexType superType, |
| DexTypeList interfaces, |
| DexString sourceFile, |
| NestHostClassAttribute nestHost, |
| List<NestMemberClassAttribute> nestMembers, |
| EnclosingMethodAttribute enclosingMember, |
| List<InnerClassAttribute> innerClasses, |
| ClassSignature classSignature, |
| DexAnnotationSet annotations, |
| DexEncodedField[] staticFields, |
| DexEncodedField[] instanceFields, |
| DexEncodedMethod[] directMethods, |
| DexEncodedMethod[] virtualMethods, |
| boolean skipNameValidationForTesting) { |
| super( |
| sourceFile, |
| interfaces, |
| accessFlags, |
| superType, |
| type, |
| staticFields, |
| instanceFields, |
| directMethods, |
| virtualMethods, |
| nestHost, |
| nestMembers, |
| enclosingMember, |
| innerClasses, |
| classSignature, |
| annotations, |
| origin, |
| skipNameValidationForTesting); |
| assert kind == Kind.CF : "Invalid kind " + kind + " for class-path class " + type; |
| } |
| |
| @Override |
| public void accept( |
| Consumer<DexProgramClass> programClassConsumer, |
| Consumer<DexClasspathClass> classpathClassConsumer, |
| Consumer<DexLibraryClass> libraryClassConsumer) { |
| classpathClassConsumer.accept(this); |
| } |
| |
| public void forEachClasspathMethod(Consumer<? super ClasspathMethod> consumer) { |
| forEachClasspathMethodMatching(alwaysTrue(), consumer); |
| } |
| |
| public void forEachClasspathMethodMatching( |
| Predicate<DexEncodedMethod> predicate, Consumer<? super ClasspathMethod> consumer) { |
| methodCollection.forEachMethodMatching( |
| predicate, method -> consumer.accept(new ClasspathMethod(this, method))); |
| } |
| |
| @Override |
| public String toString() { |
| return type.toString() + "(classpath class)"; |
| } |
| |
| @Override |
| public void addDependencies(MixedSectionCollection collector) { |
| // Should never happen but does not harm. |
| assert false; |
| } |
| |
| @Override |
| public boolean isClasspathClass() { |
| return true; |
| } |
| |
| @Override |
| public DexClasspathClass asClasspathClass() { |
| return this; |
| } |
| |
| @Override |
| public DexClasspathClass asClasspathOrLibraryClass() { |
| return this; |
| } |
| |
| public static DexClasspathClass asClasspathClassOrNull(DexClass clazz) { |
| return clazz != null ? clazz.asClasspathClass() : null; |
| } |
| |
| @Override |
| public boolean isNotProgramClass() { |
| return true; |
| } |
| |
| @Override |
| public KotlinClassLevelInfo getKotlinInfo() { |
| throw new Unreachable("Kotlin info on classpath class is not supported yet."); |
| } |
| |
| @Override |
| public DexClasspathClass get() { |
| return this; |
| } |
| |
| @Override |
| boolean internalClassOrInterfaceMayHaveInitializationSideEffects( |
| AppView<?> appView, |
| DexClass initialAccessHolder, |
| Predicate<DexType> ignore, |
| Set<DexType> seen) { |
| if (!seen.add(getType()) || ignore.test(getType())) { |
| return false; |
| } |
| return !isInterface() || appView.options().classpathInterfacesMayHaveStaticInitialization; |
| } |
| |
| @Override |
| public DexClasspathClass self() { |
| return this; |
| } |
| |
| @Override |
| public StructuralMapping<DexClasspathClass> getStructuralMapping() { |
| return DexClasspathClass::specify; |
| } |
| |
| private static void specify(StructuralSpecification<DexClasspathClass, ?> spec) { |
| spec.withItem(DexClass::getType) |
| .withItem(DexClass::getSuperType) |
| .withItem(DexClass::getInterfaces) |
| .withItem(DexClass::getAccessFlags) |
| .withNullableItem(DexClass::getSourceFile) |
| .withNullableItem(DexClass::getNestHostClassAttribute) |
| .withItemCollection(DexClass::getNestMembersClassAttributes) |
| .withItem(DexDefinition::annotations) |
| // TODO(b/158159959): Make signatures structural. |
| .withAssert(c -> c.classSignature == ClassSignature.noSignature()) |
| .withItemArray(c -> c.staticFields) |
| .withItemArray(c -> c.instanceFields) |
| .withItemCollection(DexClass::allMethodsSorted); |
| } |
| } |