Move MethodReference.getParameters() to Method, and replace with getParameterTypes()

It's common that the caller only needs the parameter type info, and not the
name/annotation/etc, and retrieving just the parameter types can be implemented
more efficiently.
This commit is contained in:
Ben Gruver
2012-12-30 20:58:13 -08:00
parent a70faf072b
commit d4b08e1b21
12 changed files with 122 additions and 49 deletions

View File

@ -31,6 +31,7 @@
package org.jf.dexlib2.base.reference;
import com.google.common.collect.Ordering;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.util.CollectionUtils;
@ -43,7 +44,7 @@ public abstract class BaseMethodReference implements MethodReference {
int hashCode = getDefiningClass().hashCode();
hashCode = hashCode*31 + getName().hashCode();
hashCode = hashCode*31 + getReturnType().hashCode();
return hashCode*31 + getParameters().hashCode();
return hashCode*31 + getParameterTypes().hashCode();
}
@Override
@ -53,7 +54,7 @@ public abstract class BaseMethodReference implements MethodReference {
return getDefiningClass().equals(other.getDefiningClass()) &&
getName().equals(other.getName()) &&
getReturnType().equals(other.getReturnType()) &&
getParameters().equals(other.getParameters());
getParameterTypes().equals(other.getParameterTypes());
}
return false;
}
@ -66,6 +67,6 @@ public abstract class BaseMethodReference implements MethodReference {
if (res != 0) return res;
res = getReturnType().compareTo(o.getReturnType());
if (res != 0) return res;
return CollectionUtils.compareAsIterable(getParameters(), o.getParameters());
return CollectionUtils.compareAsIterable(Ordering.usingToString(), getParameterTypes(), o.getParameterTypes());
}
}

View File

@ -172,6 +172,26 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
return ImmutableList.of();
}
@Nonnull
@Override
public List<String> getParameterTypes() {
int protoIdItemOffset = getProtoIdItemOffset();
final int parametersOffset = dexBuf.readSmallUint(protoIdItemOffset + DexBuffer.PROTO_PARAM_LIST_OFF_OFFSET);
if (parametersOffset > 0) {
final int parameterCount = dexBuf.readSmallUint(parametersOffset + DexBuffer.TYPE_LIST_SIZE_OFFSET);
final int paramListStart = parametersOffset + DexBuffer.TYPE_LIST_LIST_OFFSET;
return new FixedSizeList<String>() {
@Nonnull
@Override
public String readItem(final int index) {
return dexBuf.getType(dexBuf.readUshort(paramListStart + 2*index));
}
@Override public int size() { return parameterCount; }
};
}
return ImmutableList.of();
}
@Nonnull
@Override
public Set<? extends Annotation> getAnnotations() {

View File

@ -33,10 +33,8 @@ package org.jf.dexlib2.dexbacked.reference;
import com.google.common.collect.ImmutableList;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.base.reference.BaseTypeReference;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
import org.jf.dexlib2.iface.reference.TypeReference;
import javax.annotation.Nonnull;
import java.util.List;
@ -65,25 +63,17 @@ public class DexBackedMethodReference extends BaseMethodReference {
@Nonnull
@Override
public List<? extends TypeReference> getParameters() {
public List<String> getParameterTypes() {
int protoIdItemOffset = getProtoIdItemOffset();
final int parametersOffset = dexBuf.readSmallUint(protoIdItemOffset + DexBuffer.PROTO_PARAM_LIST_OFF_OFFSET);
if (parametersOffset > 0) {
final int parameterCount = dexBuf.readSmallUint(parametersOffset + DexBuffer.TYPE_LIST_SIZE_OFFSET);
final int paramListStart = parametersOffset + DexBuffer.TYPE_LIST_LIST_OFFSET;
return new FixedSizeList<TypeReference>() {
return new FixedSizeList<String>() {
@Nonnull
@Override
public TypeReference readItem(final int index) {
// Can't use DexBackedTypeReference, because we don't want to read in the type index until it
// is asked for
return new BaseTypeReference() {
@Nonnull
@Override
public String getType() {
return dexBuf.getType(dexBuf.readUshort(paramListStart + 2*index));
}
};
public String readItem(final int index) {
return dexBuf.getType(dexBuf.readUshort(paramListStart + 2*index));
}
@Override public int size() { return parameterCount; }
};

View File

@ -60,7 +60,7 @@ public interface Method extends MethodReference {
@Override @Nonnull String getName();
/**
* Gets a list of the types of the parameters of this method.
* Gets a list of the parameters of this method.
*
* As per the MethodReference interface, the MethodParameter objects contained in the returned list also act
* as a simple reference to the type of the parameter. However, the MethodParameter object can also contain
@ -70,7 +70,7 @@ public interface Method extends MethodReference {
*
* @return A list of MethodParameter objects, representing the parameters of this method.
*/
@Override @Nonnull List<? extends MethodParameter> getParameters();
@Nonnull List<? extends MethodParameter> getParameters();
/**
* Gets the return type of this method.

View File

@ -54,13 +54,11 @@ public interface MethodReference extends Reference, Comparable<MethodReference>
@Nonnull String getName();
/**
* Gets a list of the types of the parameters of the referenced method.
* Gets a list of the types of the parameters of this method.
*
* Note: In some implementations, the returned list is likely to *not* provide efficient random access.
*
* @return A list of the types of the parameters of the referenced method
* @return A list of the parameter types of this method, as strings.
*/
@Nonnull List<? extends TypeReference> getParameters();
@Nonnull List<? extends CharSequence> getParameterTypes();
/**
* Gets the return type of the referenced method.

View File

@ -105,6 +105,7 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
@Nonnull public String getDefiningClass() { return definingClass; }
@Nonnull public String getName() { return name; }
@Nonnull public ImmutableList<? extends CharSequence> getParameterTypes() { return parameters; }
@Nonnull public ImmutableList<? extends ImmutableMethodParameter> getParameters() { return parameters; }
@Nonnull public String getReturnType() { return returnType; }
public int getAccessFlags() { return accessFlags; }

View File

@ -34,7 +34,7 @@ package org.jf.dexlib2.immutable.reference;
import com.google.common.collect.ImmutableList;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.iface.reference.TypeReference;
import org.jf.dexlib2.immutable.util.CharSequenceConverter;
import org.jf.util.ImmutableUtils;
import javax.annotation.Nonnull;
@ -44,22 +44,22 @@ import java.util.List;
public class ImmutableMethodReference extends BaseMethodReference implements ImmutableReference {
@Nonnull protected final String definingClass;
@Nonnull protected final String name;
@Nonnull protected final ImmutableList<? extends ImmutableTypeReference> parameters;
@Nonnull protected final ImmutableList<String> parameters;
@Nonnull protected final String returnType;
public ImmutableMethodReference(@Nonnull String definingClass,
@Nonnull String name,
@Nullable List<? extends TypeReference> parameters,
@Nullable List<String> parameters,
@Nonnull String returnType) {
this.definingClass = definingClass;
this.name = name;
this.parameters = ImmutableTypeReference.immutableListOf(parameters);
this.parameters = ImmutableList.copyOf(parameters);
this.returnType = returnType;
}
public ImmutableMethodReference(@Nonnull String definingClass,
@Nonnull String name,
@Nullable ImmutableList<? extends ImmutableTypeReference> parameters,
@Nullable ImmutableList<String> parameters,
@Nonnull String returnType) {
this.definingClass = definingClass;
this.name = name;
@ -75,12 +75,14 @@ public class ImmutableMethodReference extends BaseMethodReference implements Imm
return new ImmutableMethodReference(
methodReference.getDefiningClass(),
methodReference.getName(),
ImmutableList.copyOf(methodReference.getParameters()),
CharSequenceConverter.immutableStringList(methodReference.getParameterTypes()),
methodReference.getReturnType());
}
@Nonnull @Override public String getDefiningClass() { return definingClass; }
@Nonnull @Override public String getName() { return name; }
@Nonnull @Override public List<? extends ImmutableTypeReference> getParameters() { return parameters; }
@Nonnull @Override public ImmutableList<String> getParameterTypes() { return parameters; }
@Nonnull @Override public String getReturnType() { return returnType; }
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.immutable.util;
import com.google.common.collect.ImmutableList;
import org.jf.util.ImmutableConverter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
public final class CharSequenceConverter {
private CharSequenceConverter() {
}
@Nonnull
public static ImmutableList<String> immutableStringList(@Nullable List<? extends CharSequence> list) {
return CONVERTER.toList(list);
}
private static final ImmutableConverter<String, CharSequence> CONVERTER =
new ImmutableConverter<String, CharSequence>() {
@Override
protected boolean isImmutable(@Nonnull CharSequence item) {
return item instanceof String;
}
@Nonnull
@Override
protected String makeImmutable(@Nonnull CharSequence item) {
return item.toString();
}
};
}

View File

@ -34,7 +34,6 @@ package org.jf.dexlib2.util;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.iface.Method;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.iface.reference.TypeReference;
import javax.annotation.Nonnull;
@ -52,8 +51,8 @@ public final class MethodUtil {
public static int getParameterRegisterCount(@Nonnull MethodReference methodRef, boolean isStatic) {
int regCount = 0;
for (TypeReference param: methodRef.getParameters()) {
int firstChar = param.getType().charAt(0);
for (CharSequence paramType: methodRef.getParameterTypes()) {
int firstChar = paramType.charAt(0);
if (firstChar == 'J' || firstChar == 'D') {
regCount += 2;
} else {

View File

@ -33,7 +33,6 @@ package org.jf.dexlib2.util;
import org.jf.dexlib2.iface.reference.FieldReference;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.iface.reference.TypeReference;
import java.io.IOException;
import java.io.Writer;
@ -46,8 +45,8 @@ public final class ReferenceUtil {
sb.append("->");
sb.append(methodReference.getName());
sb.append('(');
for (TypeReference param: methodReference.getParameters()) {
sb.append(param.getType());
for (CharSequence paramType: methodReference.getParameterTypes()) {
sb.append(paramType);
}
sb.append(')');
sb.append(methodReference.getReturnType());
@ -59,8 +58,8 @@ public final class ReferenceUtil {
writer.write("->");
writer.write(methodReference.getName());
writer.write('(');
for (TypeReference param: methodReference.getParameters()) {
writer.write(param.getType());
for (CharSequence paramType: methodReference.getParameterTypes()) {
writer.write(paramType.toString());
}
writer.write(')');
writer.write(methodReference.getReturnType());

View File

@ -146,6 +146,6 @@ public class SyntheticAccessorResolver {
// we already know the containing class matches
return ref1.getName().equals(ref2.getName()) &&
ref1.getReturnType().equals(ref2.getReturnType()) &&
ref1.getParameters().equals(ref2.getParameters());
ref1.getParameterTypes().equals(ref2.getParameterTypes());
}
}

View File

@ -33,8 +33,8 @@ package org.jf.dexlib2.writer;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.iface.reference.TypeReference;
import org.jf.util.CollectionUtils;
import org.jf.util.ExceptionWithContext;
@ -65,7 +65,7 @@ public class ProtoPool {
if (prev == null) {
dexFile.stringPool.intern(key.getShorty());
dexFile.typePool.intern(method.getReturnType());
dexFile.typeListPool.intern(method.getParameters());
dexFile.typeListPool.intern(method.getParameterTypes());
}
}
@ -116,15 +116,15 @@ public class ProtoPool {
}
@Nonnull public String getReturnType() { return method.getReturnType(); }
@Nonnull public Collection<? extends TypeReference> getParameters() {
return method.getParameters();
@Nonnull public Collection<? extends CharSequence> getParameters() {
return method.getParameterTypes();
}
public String getShorty() {
Collection<? extends TypeReference> params = method.getParameters();
Collection<? extends CharSequence> params = getParameters();
StringBuilder sb = new StringBuilder(params.size() + 1);
sb.append(getShortyType(method.getReturnType()));
for (TypeReference typeRef: params) {
for (CharSequence typeRef: params) {
sb.append(getShortyType(typeRef));
}
return sb.toString();
@ -140,8 +140,8 @@ public class ProtoPool {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('(');
for (TypeReference type: getParameters()) {
sb.append(type);
for (CharSequence paramType: getParameters()) {
sb.append(paramType);
}
sb.append(')');
sb.append(getReturnType());
@ -168,7 +168,7 @@ public class ProtoPool {
public int compareTo(@Nonnull Key o) {
int res = getReturnType().compareTo(o.getReturnType());
if (res != 0) return res;
return CollectionUtils.compareAsIterable(getParameters(), o.getParameters());
return CollectionUtils.compareAsIterable(Ordering.usingToString(), getParameters(), o.getParameters());
}
}
}