mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
initial implementation for compound keys
This commit is contained in:
+240
-9
@@ -19,16 +19,26 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.MostlySingularMultiMap;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import com.intellij.util.io.PersistentEnumeratorDelegate;
|
||||
import com.intellij.util.io.PersistentStringEnumerator;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TIntObjectIterator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -43,14 +53,23 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
|
||||
return ApplicationManager.getApplication().getComponent(BytecodeAnalysisConverter.class);
|
||||
}
|
||||
|
||||
PersistentStringEnumerator internalKeyEnumerator;
|
||||
private PersistentStringEnumerator myInternalKeyEnumerator;
|
||||
private PersistentStringEnumerator myPackageEnumerator;
|
||||
private PersistentStringEnumerator myNamesEnumerator;
|
||||
private PersistentEnumeratorDelegate<int[]> myCompoundKeyEnumerator;
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
try {
|
||||
File dir = new File(PathManager.getIndexRoot(), "bytecodeKeys");
|
||||
final File internalKeysFile = new File(dir, "faba.internalIds");
|
||||
internalKeyEnumerator = new PersistentStringEnumerator(internalKeysFile);
|
||||
File keysDir = new File(PathManager.getIndexRoot(), "bytecodeKeys");
|
||||
final File internalKeysFile = new File(keysDir, "faba.internalIds");
|
||||
final File packageKeysFile = new File(keysDir, "faba.packages");
|
||||
final File namesFile = new File(keysDir, "faba.names1");
|
||||
final File compoundKeysFile = new File(keysDir, "faba.keys");
|
||||
myInternalKeyEnumerator = new PersistentStringEnumerator(internalKeysFile);
|
||||
myPackageEnumerator = new PersistentStringEnumerator(packageKeysFile);
|
||||
myNamesEnumerator = new PersistentStringEnumerator(namesFile);
|
||||
myCompoundKeyEnumerator = new PersistentEnumeratorDelegate<int[]>(compoundKeysFile, new IntArrayKeyDescriptor(), 1024 * 4);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
@@ -60,7 +79,10 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
|
||||
@Override
|
||||
public void disposeComponent() {
|
||||
try {
|
||||
internalKeyEnumerator.close();
|
||||
myInternalKeyEnumerator.close();
|
||||
myPackageEnumerator.close();
|
||||
myNamesEnumerator.close();
|
||||
myCompoundKeyEnumerator.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
@@ -88,7 +110,7 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
|
||||
int idI = 0;
|
||||
for (Key id : keyComponent) {
|
||||
// TODO refactor here
|
||||
ids[idI] = internalKeyEnumerator.enumerate(internalKeyString(id));
|
||||
ids[idI] = myInternalKeyEnumerator.enumerate(internalKeyString(id));
|
||||
idI++;
|
||||
}
|
||||
IntIdComponent intIdComponent = new IntIdComponent(ids);
|
||||
@@ -97,11 +119,11 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
|
||||
}
|
||||
result = new IntIdPending(pending.infinum, components);
|
||||
}
|
||||
int key = internalKeyEnumerator.enumerate(internalKeyString(equation.id));
|
||||
int key = myInternalKeyEnumerator.enumerate(internalKeyString(equation.id));
|
||||
return new IntIdEquation(key, result);
|
||||
}
|
||||
|
||||
static class InternalKey {
|
||||
public static class InternalKey {
|
||||
final String annotationKey;
|
||||
final Direction dir;
|
||||
|
||||
@@ -111,6 +133,182 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public int[] mkCompoundKey(@NotNull Key key) throws IOException {
|
||||
Direction direction = key.direction;
|
||||
Method method = key.method;
|
||||
|
||||
Type ownerType = Type.getType(method.internalClassName);
|
||||
Type[] argTypes = Type.getArgumentTypes(method.methodDesc);
|
||||
Type returnType = Type.getReturnType(method.methodDesc);
|
||||
|
||||
int arity = argTypes.length;
|
||||
int[] compoundKey = new int[9 + arity * 2];
|
||||
|
||||
compoundKey[0] = direction.directionId();
|
||||
compoundKey[1] = direction.paramId();
|
||||
compoundKey[2] = direction.valueId();
|
||||
writeType(compoundKey, 3, ownerType);
|
||||
writeType(compoundKey, 5, returnType);
|
||||
compoundKey[7] = myNamesEnumerator.enumerate(method.methodName);
|
||||
compoundKey[8] = argTypes.length;
|
||||
|
||||
for (int i = 0; i < argTypes.length; i++) {
|
||||
writeType(compoundKey, 9 + 2*i, argTypes[i]);
|
||||
}
|
||||
return compoundKey;
|
||||
}
|
||||
|
||||
private void writeType(int[] compoundKey, int i, Type type) throws IOException {
|
||||
String className = type.getClassName();
|
||||
int dotIndex = className.lastIndexOf('.');
|
||||
|
||||
String packageName;
|
||||
String simpleName;
|
||||
if (dotIndex > 0) {
|
||||
packageName = className.substring(0, dotIndex);
|
||||
simpleName = className.substring(dotIndex + 1);
|
||||
} else {
|
||||
packageName = "";
|
||||
simpleName = className;
|
||||
}
|
||||
|
||||
compoundKey[i] = myPackageEnumerator.enumerate(packageName);
|
||||
compoundKey[i + 1] = myNamesEnumerator.enumerate(simpleName);
|
||||
myPackageEnumerator.valueOf(compoundKey[i]);
|
||||
myNamesEnumerator.valueOf(compoundKey[i + 1]);
|
||||
}
|
||||
|
||||
public String showCompoundKey(@NotNull int[] key) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(key[0]);
|
||||
sb.append(", ");
|
||||
sb.append(key[1]);
|
||||
sb.append(", ");
|
||||
sb.append(key[2]);
|
||||
sb.append(", ");
|
||||
sb.append(myPackageEnumerator.valueOf(key[3]));
|
||||
sb.append(", ");
|
||||
sb.append(myNamesEnumerator.valueOf(key[4]));
|
||||
sb.append(", ");
|
||||
sb.append(myPackageEnumerator.valueOf(key[5]));
|
||||
sb.append(", ");
|
||||
sb.append(myNamesEnumerator.valueOf(key[6]));
|
||||
sb.append(", ");
|
||||
sb.append(myNamesEnumerator.valueOf(key[7]));
|
||||
sb.append(", ");
|
||||
sb.append(key[8]);
|
||||
sb.append(", ");
|
||||
|
||||
for (int i = 0; i < key[8]; i++) {
|
||||
sb.append(myPackageEnumerator.valueOf(key[9 + 2*i]));
|
||||
sb.append(", ");
|
||||
sb.append(myNamesEnumerator.valueOf(key[9 + 2*i + 1]));
|
||||
sb.append(", ");
|
||||
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public int[] mkCompoundKey(@NotNull PsiMethod psiMethod, Direction direction) throws IOException {
|
||||
|
||||
final PsiClass psiClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class, false);
|
||||
if (psiClass == null) {
|
||||
return null;
|
||||
}
|
||||
PsiClass outerClass = psiClass.getContainingClass();
|
||||
boolean isInnerClassConstructor = psiMethod.isConstructor() && (outerClass != null) && !psiClass.hasModifierProperty(PsiModifier.STATIC);
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
|
||||
final int shift = isInnerClassConstructor ? 1 : 0;
|
||||
final int arity = parameters.length + shift;
|
||||
|
||||
int[] compoundKey = new int[9 + arity * 2];
|
||||
compoundKey[0] = direction.directionId();
|
||||
compoundKey[1] = direction.paramId();
|
||||
compoundKey[2] = direction.valueId();
|
||||
writeClass(compoundKey, 3, psiClass, 0);
|
||||
|
||||
PsiType returnType = psiMethod.getReturnType();
|
||||
if (returnType == null) {
|
||||
if (!writeType(compoundKey, 5, PsiType.VOID)) {
|
||||
return null;
|
||||
}
|
||||
compoundKey[7] = myNamesEnumerator.enumerate("<init>");
|
||||
} else {
|
||||
if (!writeType(compoundKey, 5, returnType)) {
|
||||
return null;
|
||||
}
|
||||
compoundKey[7] = myNamesEnumerator.enumerate(psiMethod.getName());
|
||||
}
|
||||
compoundKey[8] = arity;
|
||||
if (isInnerClassConstructor) {
|
||||
writeClass(compoundKey, 9, outerClass, 0);
|
||||
}
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiParameter parameter = parameters[i];
|
||||
if (!writeType(compoundKey, 9 + (2 * (i + shift)), parameter.getType())) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return compoundKey;
|
||||
}
|
||||
|
||||
private void writeClass(int[] compoundKey, int i, PsiClass psiClass, int dimensions) throws IOException {
|
||||
String packageName = "";
|
||||
|
||||
PsiClassOwner psiFile = (PsiClassOwner) psiClass.getContainingFile();
|
||||
if (psiFile != null) {
|
||||
packageName = psiFile.getPackageName();
|
||||
}
|
||||
String qname = psiClass.getQualifiedName();
|
||||
String className = qname;
|
||||
if (qname != null && packageName.length() > 0) {
|
||||
className = qname.substring(packageName.length() + 1).replace('.', '$');
|
||||
}
|
||||
compoundKey[i] = myPackageEnumerator.enumerate(packageName);
|
||||
if (dimensions == 0) {
|
||||
compoundKey[i + 1] = myNamesEnumerator.enumerate(className);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder(className);
|
||||
for (int j = 0; j < dimensions; j++) {
|
||||
sb.append("[]");
|
||||
}
|
||||
compoundKey[i + 1] = myNamesEnumerator.enumerate(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean writeType(int[] compoundKey, int i, PsiType psiType) throws IOException {
|
||||
int dimensions = 0;
|
||||
psiType = TypeConversionUtil.erasure(psiType);
|
||||
if (psiType instanceof PsiArrayType) {
|
||||
PsiArrayType arrayType = (PsiArrayType)psiType;
|
||||
psiType = arrayType.getDeepComponentType();
|
||||
dimensions = arrayType.getArrayDimensions();
|
||||
}
|
||||
|
||||
if (psiType instanceof PsiClassType) {
|
||||
PsiClass psiClass = ((PsiClassType)psiType).resolve();
|
||||
if (psiClass != null) {
|
||||
writeClass(compoundKey, i, psiClass, dimensions);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (psiType instanceof PsiPrimitiveType) {
|
||||
String packageName = "";
|
||||
String className = psiType.getPresentableText();
|
||||
compoundKey[i] = myPackageEnumerator.enumerate(packageName);
|
||||
compoundKey[i + 1] = myNamesEnumerator.enumerate(className);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public MostlySingularMultiMap<String, AnnotationData> makeAnnotations(TIntObjectHashMap<Value> internalIdSolutions) {
|
||||
MostlySingularMultiMap<String, AnnotationData> annotations = new MostlySingularMultiMap<String, AnnotationData>();
|
||||
HashMap<String, StringBuilder> contracts = new HashMap<String, StringBuilder>();
|
||||
@@ -124,7 +322,7 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
|
||||
}
|
||||
InternalKey key;
|
||||
try {
|
||||
String s = internalKeyEnumerator.valueOf(inKey);
|
||||
String s = myInternalKeyEnumerator.valueOf(inKey);
|
||||
key = readInternalKey(s);
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -273,4 +471,37 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static class IntArrayKeyDescriptor implements KeyDescriptor<int[]> {
|
||||
|
||||
@Override
|
||||
public void save(@NotNull DataOutput out, int[] value) throws IOException {
|
||||
DataInputOutputUtil.writeINT(out, value.length);
|
||||
for (int i : value) {
|
||||
DataInputOutputUtil.writeINT(out, i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] read(@NotNull DataInput in) throws IOException {
|
||||
int[] value = new int[DataInputOutputUtil.readINT(in)];
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
value[i] = DataInputOutputUtil.readINT(in);
|
||||
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHashCode(int[] value) {
|
||||
return Arrays.hashCode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEqual(int[] val1, int[] val2) {
|
||||
return Arrays.equals(val1, val2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -52,7 +52,15 @@ enum Value {
|
||||
Bot, NotNull, Null, True, False, Top
|
||||
}
|
||||
|
||||
interface Direction {}
|
||||
interface Direction {
|
||||
static final int OUT_DIRECTION = 0;
|
||||
static final int IN_DIRECTION = 1;
|
||||
static final int INOUT_DIRECTION = 2;
|
||||
int directionId();
|
||||
int paramId();
|
||||
int valueId();
|
||||
}
|
||||
|
||||
final class In implements Direction {
|
||||
final int paramIndex;
|
||||
|
||||
@@ -78,6 +86,21 @@ final class In implements Direction {
|
||||
public int hashCode() {
|
||||
return paramIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int directionId() {
|
||||
return IN_DIRECTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int paramId() {
|
||||
return paramIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int valueId() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
final class InOut implements Direction {
|
||||
@@ -113,6 +136,21 @@ final class InOut implements Direction {
|
||||
public String toString() {
|
||||
return "InOut " + paramIndex + " " + inValue.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int directionId() {
|
||||
return INOUT_DIRECTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int paramId() {
|
||||
return paramIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int valueId() {
|
||||
return inValue.ordinal();
|
||||
}
|
||||
}
|
||||
|
||||
final class Out implements Direction {
|
||||
@@ -130,6 +168,21 @@ final class Out implements Direction {
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int directionId() {
|
||||
return OUT_DIRECTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int paramId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int valueId() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
final class Key {
|
||||
|
||||
+78
-7
@@ -18,6 +18,9 @@ package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.InferredAnnotationsManager;
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.data.Test01;
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.data.Test02;
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.data.Test03;
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.data.TestAnnotation;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -27,10 +30,14 @@ import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author lambdamix
|
||||
@@ -40,14 +47,25 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
|
||||
private final String myClassesProjectRelativePath = "/classes/" + Test01.class.getPackage().getName().replace('.', '/');
|
||||
private JavaPsiFacade myJavaPsiFacade;
|
||||
private InferredAnnotationsManager myInferredAnnotationsManager;
|
||||
private BytecodeAnalysisConverter myBytecodeAnalysisConverter;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myJavaPsiFacade = JavaPsiFacade.getInstance(myModule.getProject());
|
||||
myInferredAnnotationsManager = InferredAnnotationsManager.getInstance(myModule.getProject());
|
||||
myBytecodeAnalysisConverter = BytecodeAnalysisConverter.getInstance();
|
||||
|
||||
setUpDataClasses();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
myBytecodeAnalysisConverter.disposeComponent();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
// TODO - test it, possible solution - via external annotation manager??
|
||||
/*
|
||||
public void testVelocityJar() {
|
||||
VirtualFile lib = LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManagerEx.getTestDataPath() + "/../../../lib");
|
||||
@@ -60,15 +78,22 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
|
||||
}
|
||||
*/
|
||||
|
||||
public void testDataClasses() throws IOException {
|
||||
VirtualFile dataClassesDir = setUpDataClasses();
|
||||
PsiTestUtil.addLibrary(myModule, "dataClasses", dataClassesDir.getPath(), new String[]{""}, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
//PsiClass psiClass = myJavaPsiFacade.findClass(Test01.class.getName(), GlobalSearchScope.moduleWithLibrariesScope(myModule));
|
||||
//assertNotNull(psiClass);
|
||||
|
||||
public void testInference() throws IOException {
|
||||
checkAnnotations(Test01.class);
|
||||
}
|
||||
|
||||
public void testCompoundKeys() throws IOException {
|
||||
checkCompoundIds(Test01.class);
|
||||
checkCompoundIds(Test02.class);
|
||||
checkCompoundIds(Test02.Inner1.class);
|
||||
checkCompoundIds(Test02.Inner2.class);
|
||||
checkCompoundIds(Test03.class);
|
||||
checkCompoundIds(Test03.Inner1.class);
|
||||
checkCompoundIds(Test03.Inner2.class);
|
||||
checkCompoundIds(TestAnnotation.class);
|
||||
}
|
||||
|
||||
private void checkAnnotations(Class<?> javaClass) {
|
||||
PsiClass psiClass = myJavaPsiFacade.findClass(javaClass.getName(), GlobalSearchScope.moduleWithLibrariesScope(myModule));
|
||||
assertNotNull(psiClass);
|
||||
@@ -111,13 +136,59 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private VirtualFile setUpDataClasses() throws IOException {
|
||||
private void checkCompoundIds(Class<?> javaClass) throws IOException {
|
||||
String javaClassName = javaClass.getCanonicalName();
|
||||
System.out.println(javaClassName);
|
||||
PsiClass psiClass = myJavaPsiFacade.findClass(javaClassName, GlobalSearchScope.moduleWithLibrariesScope(myModule));
|
||||
assertNotNull(psiClass);
|
||||
|
||||
for (java.lang.reflect.Method javaMethod : javaClass.getDeclaredMethods()) {
|
||||
System.out.println(javaMethod.getName());
|
||||
Method method = new Method(Type.getDescriptor(javaClass), javaMethod.getName(), Type.getMethodDescriptor(javaMethod));
|
||||
boolean noKey = javaMethod.getAnnotation(ExpectNoPsiKey.class) != null;
|
||||
PsiMethod psiMethod = psiClass.findMethodsByName(javaMethod.getName(), false)[0];
|
||||
checkCompoundId(method, psiMethod, noKey);
|
||||
}
|
||||
|
||||
for (Constructor<?> constructor : javaClass.getDeclaredConstructors()) {
|
||||
Method method = new Method(Type.getDescriptor(javaClass), "<init>", Type.getConstructorDescriptor(constructor));
|
||||
boolean noKey = constructor.getAnnotation(ExpectNoPsiKey.class) != null;
|
||||
PsiMethod[] constructors = psiClass.getConstructors();
|
||||
PsiMethod psiMethod = constructors[0];
|
||||
checkCompoundId(method, psiMethod, noKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCompoundId(Method method, PsiMethod psiMethod, boolean noKey) throws IOException {
|
||||
Direction direction = new Out();
|
||||
int[] psiKey = myBytecodeAnalysisConverter.mkCompoundKey(psiMethod, direction);
|
||||
if (noKey) {
|
||||
assertNull(psiKey);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
assertNotNull(psiKey);
|
||||
}
|
||||
|
||||
int[] asmKey = myBytecodeAnalysisConverter.mkCompoundKey(new Key(method, direction));
|
||||
|
||||
System.out.println(Arrays.toString(asmKey));
|
||||
System.out.println(Arrays.toString(psiKey));
|
||||
|
||||
System.out.println(myBytecodeAnalysisConverter.showCompoundKey(asmKey));
|
||||
System.out.println(myBytecodeAnalysisConverter.showCompoundKey(psiKey));
|
||||
|
||||
Assert.assertArrayEquals(asmKey, psiKey);
|
||||
}
|
||||
|
||||
private void setUpDataClasses() throws IOException {
|
||||
File classesDir = new File(Test01.class.getResource(".").getFile());
|
||||
File destDir = new File(myModule.getProject().getBaseDir().getPath() + myClassesProjectRelativePath);
|
||||
FileUtil.copyDir(classesDir, destDir);
|
||||
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destDir);
|
||||
assertNotNull(vFile);
|
||||
return vFile;
|
||||
|
||||
PsiTestUtil.addLibrary(myModule, "dataClasses", vFile.getPath(), new String[]{""}, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* @author lambdamix
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ExpectNoPsiKey {
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.bytecodeAnalysis.data;
|
||||
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisConverter;
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.ExpectNoPsiKey;
|
||||
|
||||
/**
|
||||
* @author lambdamix
|
||||
*/
|
||||
public class Test02 {
|
||||
|
||||
public static class Inner1 {
|
||||
public Inner1(Object o) {
|
||||
|
||||
}
|
||||
public Inner1[] Inner1test01(Inner1[] tests, Inner1... ellipsis) {
|
||||
return tests;
|
||||
}
|
||||
}
|
||||
|
||||
public class Inner2 {
|
||||
public Inner2(Object o) {
|
||||
|
||||
}
|
||||
public Inner2[] Inner2test01(Inner2[] tests, Inner2... ellipsis) {
|
||||
return tests;
|
||||
}
|
||||
}
|
||||
|
||||
public Test02(int x) {}
|
||||
|
||||
@ExpectNoPsiKey
|
||||
public BytecodeAnalysisConverter.InternalKey test01(BytecodeAnalysisConverter.InternalKey converter) {
|
||||
return converter;
|
||||
}
|
||||
|
||||
public Test02[] test02(Test02[] tests) {
|
||||
return tests;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.bytecodeAnalysis.data;
|
||||
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisConverter;
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.ExpectNoPsiKey;
|
||||
|
||||
/**
|
||||
* @author lambdamix
|
||||
*/
|
||||
public class Test03<A> {
|
||||
|
||||
public static class Inner1 {
|
||||
public Inner1(Object o) {
|
||||
|
||||
}
|
||||
public Inner1[] Inner1test01(Inner1[] tests, Inner1... ellipsis) {
|
||||
return tests;
|
||||
}
|
||||
}
|
||||
|
||||
public class Inner2 {
|
||||
public Inner2(A o) {
|
||||
|
||||
}
|
||||
public A[] Inner2test01(A[] tests, A... ellipsis) {
|
||||
return tests;
|
||||
}
|
||||
}
|
||||
|
||||
public Test03(@TestAnnotation int x) {}
|
||||
|
||||
@ExpectNoPsiKey
|
||||
public BytecodeAnalysisConverter.InternalKey test01(BytecodeAnalysisConverter.InternalKey converter) {
|
||||
return converter;
|
||||
}
|
||||
|
||||
public Test03[] test02(Test03[] tests) {
|
||||
return tests;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.bytecodeAnalysis.data;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* @author lambdamix
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TestAnnotation {
|
||||
}
|
||||
Reference in New Issue
Block a user