blob: d1347f3d76b398623332da4f8679464bb23cc9ee [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.synthesis;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens.NonIdentityGraphLens;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* Reference to a synthetic method item.
*
* <p>This class is internal to the synthetic items collection, thus package-protected.
*/
class SyntheticMethodReference
extends SyntheticReference<SyntheticMethodReference, SyntheticMethodDefinition, DexProgramClass>
implements SyntheticProgramReference, Rewritable<SyntheticMethodReference> {
final DexMethod method;
SyntheticMethodReference(SyntheticKind kind, SynthesizingContext context, DexMethod method) {
super(kind, context);
this.method = method;
}
@Override
public DexType getHolder() {
return method.holder;
}
@Override
DexMethod getReference() {
return method;
}
@Override
SyntheticMethodDefinition lookupDefinition(Function<DexType, DexClass> definitions) {
DexClass clazz = definitions.apply(method.holder);
if (clazz == null) {
return null;
}
assert clazz.isProgramClass();
ProgramMethod definition = clazz.asProgramClass().lookupProgramMethod(method);
return definition != null
? new SyntheticMethodDefinition(getKind(), getContext(), definition)
: null;
}
@Override
SyntheticMethodReference internalRewrite(
SynthesizingContext rewrittenContext, NonIdentityGraphLens lens) {
DexMethod rewritten = lens.getRenamedMethodSignature(method);
// If the reference has been non-trivially rewritten the compiler has changed it and it can no
// longer be considered a synthetic. The context may or may not have changed.
if (method.getHolderType() != rewritten.getHolderType()
&& !lens.isSimpleRenaming(method, rewritten)) {
// If the referenced item is rewritten, it should be moved to a non-internal synthetic holder
// as the synthetic holder is no longer part of the synthetic collection.
assert SyntheticNaming.verifyNotInternalSynthetic(rewritten.holder);
return null;
}
if (rewrittenContext == getContext() && rewritten == method) {
return this;
}
return new SyntheticMethodReference(getKind(), rewrittenContext, rewritten);
}
@Override
public void apply(
Consumer<SyntheticMethodReference> onMethod,
Consumer<SyntheticProgramClassReference> onClass) {
onMethod.accept(this);
}
}