blob: 358a016fc63e7f2e8a2e0a9ed30b50634ec10a40 [file] [log] [blame]
// Copyright (c) 2019, 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.utils.codeinspector;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.kotlin.Kotlin;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.DescriptorUtils;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import kotlinx.metadata.KmClass;
import kotlinx.metadata.KmType;
import kotlinx.metadata.KmTypeVisitor;
public class FoundKmClassSubject extends KmClassSubject {
private final CodeInspector codeInspector;
private final DexClass clazz;
private final KmClass kmClass;
FoundKmClassSubject(CodeInspector codeInspector, DexClass clazz, KmClass kmClass) {
this.codeInspector = codeInspector;
this.clazz = clazz;
this.kmClass = kmClass;
}
@Override
public DexClass getDexClass() {
return clazz;
}
@Override
public KmClass getKmClass(Kotlin kotlin) {
return kmClass;
}
@Override
public boolean isPresent() {
return true;
}
@Override
public boolean isRenamed() {
return !clazz.type.getInternalName().equals(kmClass.name);
}
@Override
public boolean isSynthetic() {
// TODO(b/70169921): This should return `true` conditionally if we start synthesizing @Metadata
// from scratch.
return false;
}
private String getDescriptorFromKmType(KmType kmType) {
if (kmType == null) {
return null;
}
Box<String> descriptor = new Box<>(null);
kmType.accept(new KmTypeVisitor() {
@Override
public void visitClass(String name) {
descriptor.set(DescriptorUtils.getDescriptorFromKotlinClassifier(name));
}
});
return descriptor.get();
}
@Override
public List<String> getSuperTypeDescriptors() {
return kmClass.getSupertypes().stream()
.map(this::getDescriptorFromKmType)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
@Override
public List<String> getParameterTypeDescriptorsInFunctions() {
return kmClass.getFunctions().stream()
.flatMap(kmFunction ->
kmFunction.getValueParameters().stream()
.map(kmValueParameter -> getDescriptorFromKmType(kmValueParameter.getType()))
.filter(Objects::nonNull))
.collect(Collectors.toList());
}
@Override
public List<String> getReturnTypeDescriptorsInFunctions() {
return kmClass.getFunctions().stream()
.map(kmFunction -> getDescriptorFromKmType(kmFunction.getReturnType()))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
@Override
public List<String> getReturnTypeDescriptorsInProperties() {
return kmClass.getProperties().stream()
.map(kmProperty -> getDescriptorFromKmType(kmProperty.getReturnType()))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
private ClassSubject getClassSubjectFromKmType(KmType kmType) {
String descriptor = getDescriptorFromKmType(kmType);
if (descriptor == null) {
return new AbsentClassSubject();
}
return codeInspector.clazz(Reference.classFromDescriptor(descriptor));
}
@Override
public List<ClassSubject> getSuperTypes() {
return kmClass.getSupertypes().stream()
.map(this::getClassSubjectFromKmType)
.filter(ClassSubject::isPresent)
.collect(Collectors.toList());
}
@Override
public List<ClassSubject> getParameterTypesInFunctions() {
return kmClass.getFunctions().stream()
.flatMap(kmFunction ->
kmFunction.getValueParameters().stream()
.map(kmValueParameter -> getClassSubjectFromKmType(kmValueParameter.getType()))
.filter(ClassSubject::isPresent))
.collect(Collectors.toList());
}
@Override
public List<ClassSubject> getReturnTypesInFunctions() {
return kmClass.getFunctions().stream()
.map(kmFunction -> getClassSubjectFromKmType(kmFunction.getReturnType()))
.filter(ClassSubject::isPresent)
.collect(Collectors.toList());
}
@Override
public List<ClassSubject> getReturnTypesInProperties() {
return kmClass.getProperties().stream()
.map(kmProperty -> getClassSubjectFromKmType(kmProperty.getReturnType()))
.filter(ClassSubject::isPresent)
.collect(Collectors.toList());
}
}