mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
BytecodeAnalysis refactoring: hashing in single place; cosmetics
This commit is contained in:
@@ -18,7 +18,6 @@ package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
import com.intellij.codeInspection.dataFlow.MethodContract.ValueConstraint;
|
||||
import com.intellij.codeInspection.dataFlow.StandardMethodContract;
|
||||
import com.intellij.openapi.util.ThreadLocalCachedValue;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
@@ -38,12 +37,6 @@ import static com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalys
|
||||
*/
|
||||
public class BytecodeAnalysisConverter {
|
||||
|
||||
// how many bytes are taken from class fqn digest
|
||||
public static final int CLASS_HASH_SIZE = 10;
|
||||
// how many bytes are taken from signature digest
|
||||
public static final int SIGNATURE_HASH_SIZE = 4;
|
||||
public static final int HASH_SIZE = CLASS_HASH_SIZE + SIGNATURE_HASH_SIZE;
|
||||
|
||||
private static final ThreadLocalCachedValue<MessageDigest> HASHER_CACHE = new ThreadLocalCachedValue<MessageDigest>() {
|
||||
@Override
|
||||
public MessageDigest create() {
|
||||
@@ -65,49 +58,26 @@ public class BytecodeAnalysisConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Psi method to a small hash key (Key).
|
||||
* Converts a Psi method to a hashed EKey.
|
||||
* Returns null if conversion is impossible (something is not resolvable).
|
||||
*/
|
||||
@Nullable
|
||||
public static EKey psiKey(@NotNull PsiMethod psiMethod, @NotNull Direction direction, @NotNull MessageDigest md) {
|
||||
final PsiClass psiClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class, false);
|
||||
final PsiClass psiClass = psiMethod.getContainingClass();
|
||||
if (psiClass == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] classDigest = psiClassDigest(psiClass, md);
|
||||
if (classDigest == null) {
|
||||
String className = descriptor(psiClass, 0, false);
|
||||
String methodSig = methodSignature(psiMethod);
|
||||
if (className == null || methodSig == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] sigDigest = methodDigest(psiMethod, md);
|
||||
if (sigDigest == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] digest = new byte[HASH_SIZE];
|
||||
System.arraycopy(classDigest, 0, digest, 0, CLASS_HASH_SIZE);
|
||||
System.arraycopy(sigDigest, 0, digest, CLASS_HASH_SIZE, SIGNATURE_HASH_SIZE);
|
||||
return new EKey(new HMethod(digest), direction, true, false);
|
||||
String methodName = psiMethod.getReturnType() == null ? "<init>" : psiMethod.getName();
|
||||
return new EKey(new Method(className, methodName, methodSig).hashed(md), direction, true, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static byte[] psiClassDigest(@NotNull PsiClass psiClass, @NotNull MessageDigest md) {
|
||||
String descriptor = descriptor(psiClass, 0, false);
|
||||
if (descriptor == null) {
|
||||
return null;
|
||||
}
|
||||
return md.digest(descriptor.getBytes(CharsetToolkit.UTF8_CHARSET));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static byte[] methodDigest(@NotNull PsiMethod psiMethod, @NotNull MessageDigest md) {
|
||||
String descriptor = descriptor(psiMethod);
|
||||
if (descriptor == null) {
|
||||
return null;
|
||||
}
|
||||
return md.digest(descriptor.getBytes(CharsetToolkit.UTF8_CHARSET));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String descriptor(@NotNull PsiMethod psiMethod) {
|
||||
private static String methodSignature(@NotNull PsiMethod psiMethod) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final PsiClass psiClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class, false);
|
||||
if (psiClass == null) {
|
||||
@@ -118,7 +88,6 @@ public class BytecodeAnalysisConverter {
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
PsiType returnType = psiMethod.getReturnType();
|
||||
|
||||
sb.append(returnType == null ? "<init>" : psiMethod.getName());
|
||||
sb.append('(');
|
||||
|
||||
String desc;
|
||||
|
||||
@@ -141,7 +141,7 @@ public class BytecodeAnalysisIndex extends ScalarIndexExtension<HMethod> {
|
||||
|
||||
@Override
|
||||
public HMethod read(@NotNull DataInput in) throws IOException {
|
||||
byte[] bytes = new byte[BytecodeAnalysisConverter.HASH_SIZE];
|
||||
byte[] bytes = new byte[HMethod.HASH_SIZE];
|
||||
in.readFully(bytes);
|
||||
return new HMethod(bytes);
|
||||
}
|
||||
@@ -270,7 +270,7 @@ public class BytecodeAnalysisIndex extends ScalarIndexExtension<HMethod> {
|
||||
effects.add(EffectQuantum.ThisChangeQuantum);
|
||||
}
|
||||
else if (effectMask == -3){
|
||||
byte[] bytes = new byte[BytecodeAnalysisConverter.HASH_SIZE];
|
||||
byte[] bytes = new byte[HMethod.HASH_SIZE];
|
||||
in.readFully(bytes);
|
||||
int rawDirKey = DataInputOutputUtil.readINT(in);
|
||||
boolean isStable = in.readBoolean();
|
||||
@@ -324,7 +324,7 @@ public class BytecodeAnalysisIndex extends ScalarIndexExtension<HMethod> {
|
||||
int componentSize = DataInputOutputUtil.readINT(in);
|
||||
EKey[] ids = new EKey[componentSize];
|
||||
for (int j = 0; j < componentSize; j++) {
|
||||
byte[] bytes = new byte[BytecodeAnalysisConverter.HASH_SIZE];
|
||||
byte[] bytes = new byte[HMethod.HASH_SIZE];
|
||||
in.readFully(bytes);
|
||||
int rawDirKey = DataInputOutputUtil.readINT(in);
|
||||
ids[j] = new EKey(new HMethod(bytes), Direction.fromInt(Math.abs(rawDirKey)), in.readBoolean(), rawDirKey < 0);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
|
||||
import com.intellij.util.ArrayFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -28,7 +27,6 @@ import java.util.Set;
|
||||
*/
|
||||
final class Component {
|
||||
static final Component[] EMPTY_ARRAY = new Component[0];
|
||||
static final ArrayFactory<Component> ARRAY_FACTORY = count -> count == 0 ? EMPTY_ARRAY : new Component[count];
|
||||
@NotNull Value value;
|
||||
@NotNull final EKey[] ids;
|
||||
|
||||
|
||||
@@ -15,19 +15,41 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import one.util.streamex.IntStreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisConverter.getMessageDigest;
|
||||
|
||||
/**
|
||||
* Hashed representation of method.
|
||||
*/
|
||||
public final class HMethod implements MethodDescriptor {
|
||||
// how many bytes are taken from class fqn digest
|
||||
private static final int CLASS_HASH_SIZE = 10;
|
||||
// how many bytes are taken from signature digest
|
||||
private static final int SIGNATURE_HASH_SIZE = 4;
|
||||
static final int HASH_SIZE = CLASS_HASH_SIZE + SIGNATURE_HASH_SIZE;
|
||||
|
||||
@NotNull
|
||||
final byte[] myBytes;
|
||||
|
||||
HMethod(Method method, MessageDigest md) {
|
||||
if (md == null) {
|
||||
md = getMessageDigest();
|
||||
}
|
||||
byte[] classDigest = md.digest(method.internalClassName.getBytes(CharsetToolkit.UTF8_CHARSET));
|
||||
md.update(method.methodName.getBytes(CharsetToolkit.UTF8_CHARSET));
|
||||
md.update(method.methodDesc.getBytes(CharsetToolkit.UTF8_CHARSET));
|
||||
byte[] sigDigest = md.digest();
|
||||
myBytes = new byte[HASH_SIZE];
|
||||
System.arraycopy(classDigest, 0, myBytes, 0, CLASS_HASH_SIZE);
|
||||
System.arraycopy(sigDigest, 0, myBytes, CLASS_HASH_SIZE, SIGNATURE_HASH_SIZE);
|
||||
}
|
||||
|
||||
public HMethod(@NotNull byte[] bytes) {
|
||||
myBytes = bytes;
|
||||
}
|
||||
|
||||
@@ -15,15 +15,12 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
import static com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisConverter.*;
|
||||
|
||||
public final class Method implements MethodDescriptor {
|
||||
final String internalClassName;
|
||||
final String methodName;
|
||||
@@ -72,17 +69,7 @@ public final class Method implements MethodDescriptor {
|
||||
@NotNull
|
||||
@Override
|
||||
public HMethod hashed(@Nullable MessageDigest md) {
|
||||
if (md == null) {
|
||||
md = getMessageDigest();
|
||||
}
|
||||
byte[] classDigest = md.digest(internalClassName.getBytes(CharsetToolkit.UTF8_CHARSET));
|
||||
md.update(methodName.getBytes(CharsetToolkit.UTF8_CHARSET));
|
||||
md.update(methodDesc.getBytes(CharsetToolkit.UTF8_CHARSET));
|
||||
byte[] sigDigest = md.digest();
|
||||
byte[] digest = new byte[HASH_SIZE];
|
||||
System.arraycopy(classDigest, 0, digest, 0, CLASS_HASH_SIZE);
|
||||
System.arraycopy(sigDigest, 0, digest, CLASS_HASH_SIZE, SIGNATURE_HASH_SIZE);
|
||||
return new HMethod(digest);
|
||||
return new HMethod(this, md);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user