mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
towards compound keys
This commit is contained in:
+207
-27
@@ -19,11 +19,17 @@ 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.util.containers.HashMap;
|
||||
import com.intellij.util.containers.MostlySingularMultiMap;
|
||||
import com.intellij.util.io.PersistentStringEnumerator;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TIntObjectIterator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -39,33 +45,6 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
|
||||
|
||||
PersistentStringEnumerator internalKeyEnumerator;
|
||||
|
||||
IntIdEquation convert(Equation<Key, Value> equation) throws IOException {
|
||||
Result<Key, Value> rhs = equation.rhs;
|
||||
IntIdResult result;
|
||||
if (rhs instanceof Final) {
|
||||
result = new IntIdFinal(((Final<Key, Value>)rhs).value);
|
||||
} else {
|
||||
Pending<Key, Value> pending = (Pending<Key, Value>)rhs;
|
||||
Set<Set<Key>> deltaOrig = pending.delta;
|
||||
IntIdComponent[] components = new IntIdComponent[deltaOrig.size()];
|
||||
int componentI = 0;
|
||||
for (Set<Key> keyComponent : deltaOrig) {
|
||||
int[] ids = new int[keyComponent.size()];
|
||||
int idI = 0;
|
||||
for (Key id : keyComponent) {
|
||||
ids[idI] = internalKeyEnumerator.enumerate(Util.internalKeyString(id));
|
||||
idI++;
|
||||
}
|
||||
IntIdComponent intIdComponent = new IntIdComponent(ids);
|
||||
components[componentI] = intIdComponent;
|
||||
componentI++;
|
||||
}
|
||||
result = new IntIdPending(pending.infinum, components);
|
||||
}
|
||||
int key = internalKeyEnumerator.enumerate(Util.internalKeyString(equation.id));
|
||||
return new IntIdEquation(key, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
try {
|
||||
@@ -93,4 +72,205 @@ public class BytecodeAnalysisConverter implements ApplicationComponent {
|
||||
public String getComponentName() {
|
||||
return "BytecodeAnalysisConverter";
|
||||
}
|
||||
|
||||
IntIdEquation convert(Equation<Key, Value> equation) throws IOException {
|
||||
Result<Key, Value> rhs = equation.rhs;
|
||||
IntIdResult result;
|
||||
if (rhs instanceof Final) {
|
||||
result = new IntIdFinal(((Final<Key, Value>)rhs).value);
|
||||
} else {
|
||||
Pending<Key, Value> pending = (Pending<Key, Value>)rhs;
|
||||
Set<Set<Key>> deltaOrig = pending.delta;
|
||||
IntIdComponent[] components = new IntIdComponent[deltaOrig.size()];
|
||||
int componentI = 0;
|
||||
for (Set<Key> keyComponent : deltaOrig) {
|
||||
int[] ids = new int[keyComponent.size()];
|
||||
int idI = 0;
|
||||
for (Key id : keyComponent) {
|
||||
// TODO refactor here
|
||||
ids[idI] = internalKeyEnumerator.enumerate(internalKeyString(id));
|
||||
idI++;
|
||||
}
|
||||
IntIdComponent intIdComponent = new IntIdComponent(ids);
|
||||
components[componentI] = intIdComponent;
|
||||
componentI++;
|
||||
}
|
||||
result = new IntIdPending(pending.infinum, components);
|
||||
}
|
||||
int key = internalKeyEnumerator.enumerate(internalKeyString(equation.id));
|
||||
return new IntIdEquation(key, result);
|
||||
}
|
||||
|
||||
static class InternalKey {
|
||||
final String annotationKey;
|
||||
final Direction dir;
|
||||
|
||||
InternalKey(String annotationKey, Direction dir) {
|
||||
this.annotationKey = annotationKey;
|
||||
this.dir = dir;
|
||||
}
|
||||
}
|
||||
|
||||
public MostlySingularMultiMap<String, AnnotationData> makeAnnotations(TIntObjectHashMap<Value> internalIdSolutions) {
|
||||
MostlySingularMultiMap<String, AnnotationData> annotations = new MostlySingularMultiMap<String, AnnotationData>();
|
||||
HashMap<String, StringBuilder> contracts = new HashMap<String, StringBuilder>();
|
||||
TIntObjectIterator<Value> iterator = internalIdSolutions.iterator();
|
||||
for (int i = internalIdSolutions.size(); i-- > 0;) {
|
||||
iterator.advance();
|
||||
int inKey = iterator.key();
|
||||
Value value = iterator.value();
|
||||
if (value == Value.Top || value == Value.Bot) {
|
||||
continue;
|
||||
}
|
||||
InternalKey key;
|
||||
try {
|
||||
String s = internalKeyEnumerator.valueOf(inKey);
|
||||
key = readInternalKey(s);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (key != null) {
|
||||
Direction direction = key.dir;
|
||||
String baseAnnKey = key.annotationKey;
|
||||
|
||||
if (direction instanceof In && value == Value.NotNull) {
|
||||
String annKey = baseAnnKey + " " + ((In)direction).paramIndex;
|
||||
// TODO - here
|
||||
annotations.add(annKey, new AnnotationData("org.jetbrains.annotations.NotNull", ""));
|
||||
}
|
||||
else if (direction instanceof Out && value == Value.NotNull) {
|
||||
// TODO - here
|
||||
annotations.add(baseAnnKey, new AnnotationData("org.jetbrains.annotations.NotNull", ""));
|
||||
}
|
||||
// TODO - sort (normalize) contract clauses
|
||||
else if (direction instanceof InOut) {
|
||||
StringBuilder sb = contracts.get(baseAnnKey);
|
||||
if (sb == null) {
|
||||
sb = new StringBuilder("\"");
|
||||
contracts.put(baseAnnKey, sb);
|
||||
}
|
||||
else {
|
||||
sb.append(';');
|
||||
}
|
||||
contractElement(sb, calculateArity(baseAnnKey), (InOut)direction, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, StringBuilder> contract : contracts.entrySet()) {
|
||||
if (!annotations.containsKey(contract.getKey())) {
|
||||
annotations.add(contract.getKey(), new AnnotationData("org.jetbrains.annotations.Contract", contract.getValue().append('"').toString()));
|
||||
}
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
// TODO - this is a hack for now
|
||||
static int calculateArity(String annotationKey) {
|
||||
return annotationKey.split(",").length;
|
||||
}
|
||||
|
||||
static String contractValueString(Value v) {
|
||||
switch (v) {
|
||||
case False: return "false";
|
||||
case True: return "true";
|
||||
case NotNull: return "!null";
|
||||
case Null: return "null";
|
||||
default: return "_";
|
||||
}
|
||||
}
|
||||
|
||||
static String contractElement(StringBuilder sb, int arity, InOut inOut, Value value) {
|
||||
for (int i = 0; i < arity; i++) {
|
||||
Value currentValue = Value.Top;
|
||||
if (i == inOut.paramIndex) {
|
||||
currentValue = inOut.inValue;
|
||||
}
|
||||
if (i > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(contractValueString(currentValue));
|
||||
}
|
||||
sb.append("->");
|
||||
sb.append(contractValueString(value));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String internalKeyString(Key key) {
|
||||
return annotationKey(key.method) + ';' + direction2Key(key.direction);
|
||||
}
|
||||
|
||||
public static String direction2Key(Direction dir) {
|
||||
if (dir instanceof In) {
|
||||
return "In:" + ((In)dir).paramIndex;
|
||||
} else if (dir instanceof Out) {
|
||||
return "Out";
|
||||
} else {
|
||||
InOut inOut = (InOut)dir;
|
||||
return "InOut:" + inOut.paramIndex + ":" + inOut.inValue.name();
|
||||
}
|
||||
}
|
||||
|
||||
public static InternalKey readInternalKey(String s) {
|
||||
String[] parts = s.split(";");
|
||||
String annKey = parts[0];
|
||||
String[] dirStrings = parts[1].split(":");
|
||||
if ("In".equals(dirStrings[0])) {
|
||||
return new InternalKey(annKey, new In(Integer.valueOf(dirStrings[1])));
|
||||
} else if ("Out".equals(dirStrings[0])) {
|
||||
return new InternalKey(annKey, new Out());
|
||||
} else {
|
||||
return new InternalKey(annKey, new InOut(Integer.valueOf(dirStrings[1]), Value.valueOf(dirStrings[2])));
|
||||
}
|
||||
}
|
||||
|
||||
public static String annotationKey(Method method) {
|
||||
if ("<init>".equals(method.methodName)) {
|
||||
return canonical(method.internalClassName) + " " +
|
||||
simpleName(method.internalClassName) +
|
||||
parameters(method);
|
||||
} else {
|
||||
return canonical(method.internalClassName) + " " +
|
||||
returnType(method) + " " +
|
||||
method.methodName +
|
||||
parameters(method);
|
||||
}
|
||||
}
|
||||
|
||||
private static String returnType(Method method) {
|
||||
return canonical(Type.getReturnType(method.methodDesc).getClassName());
|
||||
}
|
||||
|
||||
public static String canonical(String internalName) {
|
||||
return internalName.replace('/', '.').replace('$', '.');
|
||||
}
|
||||
|
||||
private static String simpleName(String internalName) {
|
||||
String cn = canonical(internalName);
|
||||
int lastDotIndex = cn.lastIndexOf('.');
|
||||
if (lastDotIndex == -1) {
|
||||
return cn;
|
||||
} else {
|
||||
return cn.substring(lastDotIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private static String parameters(Method method) {
|
||||
Type[] argTypes = Type.getArgumentTypes(method.methodDesc);
|
||||
StringBuilder sb = new StringBuilder("(");
|
||||
boolean notFirst = false;
|
||||
for (Type argType : argTypes) {
|
||||
if (notFirst) {
|
||||
sb.append(", ");
|
||||
}
|
||||
else {
|
||||
notFirst = true;
|
||||
}
|
||||
sb.append(canonical(argType.getClassName()));
|
||||
}
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
+28
-19
@@ -42,6 +42,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MostlySingularMultiMap;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -49,16 +50,16 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class BytecodeAnalysisHandler extends AbstractProjectComponent {
|
||||
public class ProjectBytecodeAnalysis extends AbstractProjectComponent {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisHandler");
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalysis");
|
||||
private static final List<AnnotationData> NO_DATA = new ArrayList<AnnotationData>(1);
|
||||
|
||||
private final PsiManager myPsiManager;
|
||||
|
||||
private MostlySingularMultiMap<String, AnnotationData> myAnnotations = null;
|
||||
|
||||
public BytecodeAnalysisHandler(Project project, PsiManager psiManager) {
|
||||
public ProjectBytecodeAnalysis(Project project, PsiManager psiManager) {
|
||||
super(project);
|
||||
myPsiManager = psiManager;
|
||||
|
||||
@@ -77,6 +78,27 @@ public class BytecodeAnalysisHandler extends AbstractProjectComponent {
|
||||
});
|
||||
}
|
||||
|
||||
private void loadAnnotations() {
|
||||
LOG.info("initializing annotations");
|
||||
final IntIdSolver solver = new IntIdSolver();
|
||||
FileBasedIndex.getInstance().processValues(
|
||||
BytecodeAnalysisIndex.NAME, BytecodeAnalysisIndex.KEY, null, new FileBasedIndex.ValueProcessor<Collection<IntIdEquation>>() {
|
||||
@Override
|
||||
public boolean process(VirtualFile file, Collection<IntIdEquation> value) {
|
||||
for (IntIdEquation intIdEquation : value) {
|
||||
solver.addEquation(intIdEquation);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, ProjectScope.getLibrariesScope(myProject));
|
||||
LOG.info("equations are constructed");
|
||||
TIntObjectHashMap<Value> solutions = solver.solve();
|
||||
LOG.info("equations are solved");
|
||||
myAnnotations = BytecodeAnalysisConverter.getInstance().makeAnnotations(solutions);
|
||||
LOG.info("initialized " + myAnnotations.size());
|
||||
}
|
||||
|
||||
|
||||
// TODO: what follows was just copied/modified from BaseExternalAnnotationsManager
|
||||
// TODO: refactor?
|
||||
@Nullable
|
||||
@@ -94,7 +116,6 @@ public class BytecodeAnalysisHandler extends AbstractProjectComponent {
|
||||
return data.getAnnotation(this);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public PsiAnnotation[] findInferredAnnotations(@NotNull PsiModifierListOwner listOwner) {
|
||||
List<AnnotationData> result = collectInferredAnnotations(listOwner);
|
||||
@@ -102,7 +123,7 @@ public class BytecodeAnalysisHandler extends AbstractProjectComponent {
|
||||
PsiAnnotation[] myResult = ContainerUtil.map2Array(result, PsiAnnotation.EMPTY_ARRAY, new Function<AnnotationData, PsiAnnotation>() {
|
||||
@Override
|
||||
public PsiAnnotation fun(AnnotationData data) {
|
||||
return data.getAnnotation(BytecodeAnalysisHandler.this);
|
||||
return data.getAnnotation(ProjectBytecodeAnalysis.this);
|
||||
}
|
||||
});
|
||||
String key = getExternalName(listOwner);
|
||||
@@ -128,19 +149,7 @@ public class BytecodeAnalysisHandler extends AbstractProjectComponent {
|
||||
SmartList<AnnotationData> result = new SmartList<AnnotationData>();
|
||||
|
||||
if (myAnnotations == null) {
|
||||
LOG.info("initializing annotations");
|
||||
final IntIdSolver solver = new IntIdSolver();
|
||||
FileBasedIndex.getInstance().processValues(BytecodeAnalysisIndex.NAME, BytecodeAnalysisIndex.KEY, null, new FileBasedIndex.ValueProcessor<Collection<IntIdEquation>>() {
|
||||
@Override
|
||||
public boolean process(VirtualFile file, Collection<IntIdEquation> value) {
|
||||
for (IntIdEquation intIdEquation : value) {
|
||||
solver.addEquation(intIdEquation);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, ProjectScope.getLibrariesScope(myProject));
|
||||
myAnnotations = Util.makeAnnotations(solver.solve());
|
||||
LOG.info("initialized " + myAnnotations.size());
|
||||
loadAnnotations();
|
||||
}
|
||||
|
||||
Iterable<AnnotationData> inferred = myAnnotations.get(key);
|
||||
@@ -192,7 +201,7 @@ class AnnotationData {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
PsiAnnotation getAnnotation(@NotNull BytecodeAnalysisHandler context) {
|
||||
PsiAnnotation getAnnotation(@NotNull ProjectBytecodeAnalysis context) {
|
||||
PsiAnnotation a = annotation;
|
||||
if (a == null) {
|
||||
annotation = a = context.createAnnotationFromText("@" + annotationClassFqName + (annotationParameters.isEmpty() ? "" : "("+annotationParameters+")"));
|
||||
@@ -1,210 +0,0 @@
|
||||
/*
|
||||
* 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 com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.MostlySingularMultiMap;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TIntObjectIterator;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
public class Util {
|
||||
|
||||
static class InternalKey {
|
||||
final String annotationKey;
|
||||
final Direction dir;
|
||||
|
||||
InternalKey(String annotationKey, Direction dir) {
|
||||
this.annotationKey = annotationKey;
|
||||
this.dir = dir;
|
||||
}
|
||||
}
|
||||
|
||||
public static MostlySingularMultiMap<String, AnnotationData> makeAnnotations(TIntObjectHashMap<Value> internalIdSolutions) {
|
||||
BytecodeAnalysisConverter lowering = BytecodeAnalysisConverter.getInstance();
|
||||
MostlySingularMultiMap<String, AnnotationData> annotations = new MostlySingularMultiMap<String, AnnotationData>();
|
||||
HashMap<String, StringBuilder> contracts = new HashMap<String, StringBuilder>();
|
||||
TIntObjectIterator<Value> iterator = internalIdSolutions.iterator();
|
||||
for (int i = internalIdSolutions.size(); i-- > 0;) {
|
||||
iterator.advance();
|
||||
int inKey = iterator.key();
|
||||
Value value = iterator.value();
|
||||
if (value == Value.Top || value == Value.Bot) {
|
||||
continue;
|
||||
}
|
||||
InternalKey key;
|
||||
try {
|
||||
String s = lowering.internalKeyEnumerator.valueOf(inKey);
|
||||
key = readInternalKey(s);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (key != null) {
|
||||
Direction direction = key.dir;
|
||||
String baseAnnKey = key.annotationKey;
|
||||
|
||||
if (direction instanceof In && value == Value.NotNull) {
|
||||
String annKey = baseAnnKey + " " + ((In)direction).paramIndex;
|
||||
annotations.add(annKey, new AnnotationData("org.jetbrains.annotations.NotNull", ""));
|
||||
}
|
||||
else if (direction instanceof Out && value == Value.NotNull) {
|
||||
annotations.add(baseAnnKey, new AnnotationData("org.jetbrains.annotations.NotNull", ""));
|
||||
}
|
||||
// TODO - sort (normalize) contract clauses
|
||||
else if (direction instanceof InOut) {
|
||||
StringBuilder sb = contracts.get(baseAnnKey);
|
||||
if (sb == null) {
|
||||
sb = new StringBuilder("\"");
|
||||
contracts.put(baseAnnKey, sb);
|
||||
}
|
||||
else {
|
||||
sb.append(';');
|
||||
}
|
||||
contractElement(sb, calculateArity(baseAnnKey), (InOut)direction, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, StringBuilder> contract : contracts.entrySet()) {
|
||||
if (!annotations.containsKey(contract.getKey())) {
|
||||
annotations.add(contract.getKey(), new AnnotationData("org.jetbrains.annotations.Contract", contract.getValue().append('"').toString()));
|
||||
}
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
// TODO - this is a hack for now
|
||||
static int calculateArity(String annotationKey) {
|
||||
return annotationKey.split(",").length;
|
||||
}
|
||||
|
||||
static String contractValueString(Value v) {
|
||||
switch (v) {
|
||||
case False: return "false";
|
||||
case True: return "true";
|
||||
case NotNull: return "!null";
|
||||
case Null: return "null";
|
||||
default: return "_";
|
||||
}
|
||||
}
|
||||
|
||||
static String contractElement(StringBuilder sb, int arity, InOut inOut, Value value) {
|
||||
for (int i = 0; i < arity; i++) {
|
||||
Value currentValue = Value.Top;
|
||||
if (i == inOut.paramIndex) {
|
||||
currentValue = inOut.inValue;
|
||||
}
|
||||
if (i > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(contractValueString(currentValue));
|
||||
}
|
||||
sb.append("->");
|
||||
sb.append(contractValueString(value));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String annotationKey(Method method, Direction dir) {
|
||||
String annPrefix = annotationKey(method);
|
||||
if (dir instanceof In) {
|
||||
return annPrefix + " " + ((In)dir).paramIndex;
|
||||
} else {
|
||||
return annPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
public static String internalKeyString(Key key) {
|
||||
return annotationKey(key.method) + ';' + direction2Key(key.direction);
|
||||
}
|
||||
|
||||
public static String direction2Key(Direction dir) {
|
||||
if (dir instanceof In) {
|
||||
return "In:" + ((In)dir).paramIndex;
|
||||
} else if (dir instanceof Out) {
|
||||
return "Out";
|
||||
} else {
|
||||
InOut inOut = (InOut)dir;
|
||||
return "InOut:" + inOut.paramIndex + ":" + inOut.inValue.name();
|
||||
}
|
||||
}
|
||||
|
||||
public static InternalKey readInternalKey(String s) {
|
||||
String[] parts = s.split(";");
|
||||
String annKey = parts[0];
|
||||
String[] dirStrings = parts[1].split(":");
|
||||
if ("In".equals(dirStrings[0])) {
|
||||
return new InternalKey(annKey, new In(Integer.valueOf(dirStrings[1])));
|
||||
} else if ("Out".equals(dirStrings[0])) {
|
||||
return new InternalKey(annKey, new Out());
|
||||
} else {
|
||||
return new InternalKey(annKey, new InOut(Integer.valueOf(dirStrings[1]), Value.valueOf(dirStrings[2])));
|
||||
}
|
||||
}
|
||||
|
||||
public static String annotationKey(Method method) {
|
||||
if ("<init>".equals(method.methodName)) {
|
||||
return canonical(method.internalClassName) + " " +
|
||||
simpleName(method.internalClassName) +
|
||||
parameters(method);
|
||||
} else {
|
||||
return canonical(method.internalClassName) + " " +
|
||||
returnType(method) + " " +
|
||||
method.methodName +
|
||||
parameters(method);
|
||||
}
|
||||
}
|
||||
|
||||
private static String returnType(Method method) {
|
||||
return canonical(Type.getReturnType(method.methodDesc).getClassName());
|
||||
}
|
||||
|
||||
public static String canonical(String internalName) {
|
||||
return internalName.replace('/', '.').replace('$', '.');
|
||||
}
|
||||
|
||||
private static String simpleName(String internalName) {
|
||||
String cn = canonical(internalName);
|
||||
int lastDotIndex = cn.lastIndexOf('.');
|
||||
if (lastDotIndex == -1) {
|
||||
return cn;
|
||||
} else {
|
||||
return cn.substring(lastDotIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private static String parameters(Method method) {
|
||||
Type[] argTypes = Type.getArgumentTypes(method.methodDesc);
|
||||
StringBuilder sb = new StringBuilder("(");
|
||||
boolean notFirst = false;
|
||||
for (Type argType : argTypes) {
|
||||
if (notFirst) {
|
||||
sb.append(", ");
|
||||
}
|
||||
else {
|
||||
notFirst = true;
|
||||
}
|
||||
sb.append(canonical(argType.getClassName()));
|
||||
}
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisHandler;
|
||||
import com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalysis;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -25,12 +25,12 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager {
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiAnnotation findInferredAnnotation(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN) {
|
||||
return listOwner.getProject().getComponent(BytecodeAnalysisHandler.class).findInferredAnnotation(listOwner, annotationFQN);
|
||||
return listOwner.getProject().getComponent(ProjectBytecodeAnalysis.class).findInferredAnnotation(listOwner, annotationFQN);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiAnnotation[] findInferredAnnotations(@NotNull PsiModifierListOwner listOwner) {
|
||||
return listOwner.getProject().getComponent(BytecodeAnalysisHandler.class).findInferredAnnotations(listOwner);
|
||||
return listOwner.getProject().getComponent(ProjectBytecodeAnalysis.class).findInferredAnnotations(listOwner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
</component>
|
||||
|
||||
<component>
|
||||
<implementation-class>com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisHandler</implementation-class>
|
||||
<implementation-class>com.intellij.codeInspection.bytecodeAnalysis.ProjectBytecodeAnalysis</implementation-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user