blob: 9ac65be546df6725f7fdce182a8a32a60bb463de [file] [log] [blame]
// Copyright (c) 2020, 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.retrace.internal;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.TypeReference;
import com.android.tools.r8.retrace.RetracedMethodReference;
import com.android.tools.r8.utils.ComparatorUtils;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
public abstract class RetracedMethodReferenceImpl implements RetracedMethodReference {
private static final int NO_POSITION = -1;
private RetracedMethodReferenceImpl() {}
@Override
public boolean isUnknown() {
return true;
}
@Override
public final boolean isKnown() {
return !isUnknown();
}
@Override
public KnownRetracedMethodReferenceImpl asKnown() {
return null;
}
@Override
public int compareTo(RetracedMethodReference other) {
return Comparator.comparing(RetracedMethodReference::getMethodName)
.thenComparing(RetracedMethodReference::isKnown)
.thenComparing(
RetracedMethodReference::asKnown,
Comparator.nullsFirst(
Comparator.comparing(
(KnownRetracedMethodReference m) -> {
if (m == null) {
return null;
}
return m.isVoid() ? "void" : m.getReturnType().getTypeName();
}))
.thenComparing(
KnownRetracedMethodReference::getFormalTypes,
ComparatorUtils.listComparator(
Comparator.comparing(TypeReference::getTypeName))))
.compare(this, other);
}
public static final class KnownRetracedMethodReferenceImpl extends RetracedMethodReferenceImpl
implements KnownRetracedMethodReference {
private final MethodReference methodReference;
private final int position;
private KnownRetracedMethodReferenceImpl(MethodReference methodReference, int position) {
assert methodReference != null;
this.methodReference = methodReference;
this.position = position;
}
@Override
public boolean isUnknown() {
return false;
}
@Override
public boolean isVoid() {
return methodReference.getReturnType() == null;
}
@Override
public KnownRetracedMethodReferenceImpl asKnown() {
return this;
}
@Override
public RetracedClassReferenceImpl getHolderClass() {
return RetracedClassReferenceImpl.create(methodReference.getHolderClass());
}
@Override
public String getMethodName() {
return methodReference.getMethodName();
}
@Override
public boolean hasPosition() {
return position != NO_POSITION;
}
@Override
public int getOriginalPositionOrDefault(int defaultPosition) {
return hasPosition() ? position : defaultPosition;
}
@Override
public TypeReference getReturnType() {
assert !isVoid();
return methodReference.getReturnType();
}
@Override
public List<TypeReference> getFormalTypes() {
return methodReference.getFormalTypes();
}
@Override
public MethodReference getMethodReference() {
return methodReference;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
KnownRetracedMethodReferenceImpl that = (KnownRetracedMethodReferenceImpl) o;
return position == that.position && methodReference.equals(that.methodReference);
}
@Override
public int hashCode() {
return Objects.hash(methodReference, position);
}
}
public static final class UnknownRetracedMethodReferenceImpl extends RetracedMethodReferenceImpl {
private final MethodDefinition methodDefinition;
private final int position;
private UnknownRetracedMethodReferenceImpl(MethodDefinition methodDefinition, int position) {
this.methodDefinition = methodDefinition;
this.position = position;
}
@Override
public RetracedClassReferenceImpl getHolderClass() {
return RetracedClassReferenceImpl.create(methodDefinition.getHolderClass());
}
@Override
public String getMethodName() {
return methodDefinition.getName();
}
@Override
public boolean hasPosition() {
return position != NO_POSITION;
}
@Override
public int getOriginalPositionOrDefault(int defaultPosition) {
return hasPosition() ? position : defaultPosition;
}
public Optional<MethodReference> getMethodReference() {
if (!methodDefinition.isFullMethodDefinition()) {
return Optional.empty();
}
return Optional.of(methodDefinition.asFullMethodDefinition().getMethodReference());
}
}
static RetracedMethodReferenceImpl create(MethodDefinition methodDefinition) {
return create(methodDefinition, NO_POSITION);
}
static RetracedMethodReferenceImpl create(MethodDefinition methodDefinition, int position) {
if (methodDefinition.isFullMethodDefinition()) {
return new KnownRetracedMethodReferenceImpl(
methodDefinition.asFullMethodDefinition().getMethodReference(), position);
}
return new UnknownRetracedMethodReferenceImpl(methodDefinition, position);
}
static RetracedMethodReferenceImpl create(MethodReference methodReference) {
return create(methodReference, NO_POSITION);
}
static RetracedMethodReferenceImpl create(MethodReference methodReference, int position) {
return new KnownRetracedMethodReferenceImpl(methodReference, position);
}
}