blob: 12b0e3bff752f118149da7cba4c7ba479896dfe2 [file] [log] [blame]
// Copyright (c) 2016, 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 com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.lightir.LirConstant;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.utils.structural.CompareToVisitor;
import com.android.tools.r8.utils.structural.HashingVisitor;
import com.android.tools.r8.utils.structural.StructuralMapping;
import com.android.tools.r8.utils.structural.StructuralSpecification;
import com.google.common.collect.Iterables;
import java.util.Collections;
import java.util.function.Consumer;
public class DexProto extends IndexedDexItem
implements NamingLensComparable<DexProto>, LirConstant {
@SuppressWarnings("ReferenceEquality")
public static boolean identical(DexProto t1, DexProto t2) {
return t1 == t2;
}
public final boolean isIdenticalTo(DexProto other) {
return identical(this, other);
}
public final boolean isNotIdenticalTo(DexProto other) {
return !isIdenticalTo(other);
}
public static final DexProto SENTINEL = new DexProto(null, null);
public final DexType returnType;
public final DexTypeList parameters;
DexProto(DexType returnType, DexTypeList parameters) {
this.returnType = returnType;
this.parameters = parameters;
}
private static void specify(StructuralSpecification<DexProto, ?> spec) {
spec.withItem(DexProto::getReturnType).withItem(p -> p.parameters);
}
@Override
public StructuralMapping<DexProto> getStructuralMapping() {
return DexProto::specify;
}
@Override
public DexProto self() {
return this;
}
@Override
public boolean computeEquals(Object other) {
if (other instanceof DexProto) {
DexProto o = (DexProto) other;
return returnType.equals(o.returnType) && parameters.equals(o.parameters);
}
return false;
}
@Override
public int computeHashCode() {
return returnType.hashCode() * 7 + parameters.hashCode() * 13;
}
public DexType getReturnType() {
return returnType;
}
public Iterable<DexType> getParameterBaseTypes(DexItemFactory dexItemFactory) {
return Iterables.transform(parameters, type -> type.toBaseType(dexItemFactory));
}
public Iterable<DexType> getBaseTypes(DexItemFactory dexItemFactory) {
return Iterables.transform(getTypes(), type -> type.toBaseType(dexItemFactory));
}
public Iterable<DexType> getTypes() {
return Iterables.concat(Collections.singleton(returnType), parameters);
}
public void forEachType(Consumer<DexType> consumer) {
consumer.accept(returnType);
parameters.forEach(consumer);
}
public DexType getParameter(int index) {
return parameters.values[index];
}
public DexTypeList getParameters() {
return parameters;
}
public int getArity() {
return parameters.size();
}
public DexProto prependParameter(DexType parameter, DexItemFactory dexItemFactory) {
DexType[] parameterTypes = new DexType[getParameters().size() + 1];
parameterTypes[0] = parameter;
System.arraycopy(getParameters().getBacking(), 0, parameterTypes, 1, getParameters().size());
return dexItemFactory.createProto(getReturnType(), parameterTypes);
}
@Override
public String toString() {
return "Proto " + returnType + " " + parameters;
}
public void collectIndexedItems(AppView<?> appView, IndexedItemCollection indexedItems) {
if (indexedItems.addProto(this)) {
returnType.collectIndexedItems(appView, indexedItems);
parameters.collectIndexedItems(appView, indexedItems);
}
}
@Override
public int getOffset(ObjectToOffsetMapping mapping) {
return mapping.getOffsetFor(this);
}
@Override
public String toSmaliString() {
return toDescriptorString();
}
public String toDescriptorString() {
return toDescriptorString(NamingLens.getIdentityLens());
}
public String toDescriptorString(NamingLens lens) {
StringBuilder builder = new StringBuilder();
builder.append("(");
for (int i = 0; i < parameters.values.length; i++) {
builder.append(lens.lookupDescriptor(parameters.values[i]));
}
builder.append(")");
builder.append(lens.lookupDescriptor(returnType));
return builder.toString();
}
public String createShortyString() {
StringBuilder shortyBuilder = new StringBuilder();
shortyBuilder.append(returnType.toShorty());
for (DexType argumentType : parameters.values) {
shortyBuilder.append(argumentType.toShorty());
}
return shortyBuilder.toString();
}
@Override
public LirConstantOrder getLirConstantOrder() {
return LirConstantOrder.PROTO;
}
@Override
public int internalLirConstantAcceptCompareTo(LirConstant other, CompareToVisitor visitor) {
return acceptCompareTo((DexProto) other, visitor);
}
@Override
public void internalLirConstantAcceptHashing(HashingVisitor visitor) {
acceptHashing(visitor);
}
}