Tôi đang cố gắng sử dụng IntelliJ SDK làm trình phân tích cú pháp java độc lập và nó hoạt động tốt trong hầu hết các trường hợp, nhưng không giải quyết được kiểu trả về của các phương thức chung.Độ phân giải biểu tượng trong trình phân tích cú pháp IntelliJ độc lập
Khi tôi gỡ lỗi resolveMethod
cho verify(mock).simpleMethod()
trong mẫu tiếp theo bên trong IntelliJ:
public class ResolutionTest {
private interface IMethods {
String simpleMethod();
}
private IMethods mock;
public static <T> T verify(T m) {
return m;
}
public void test() {
verify(mock).simpleMethod();
}
}
Tôi thấy kiểu trả về của verify(mock)
như IMethods
và simpleMethod
cũng giải quyết một cách chính xác. Nhưng trong loại phân tích cú pháp của tôi, loại trả lại là verify(mock)
là T
và simpleMethod
không thành công. Tôi đoán tôi không đăng ký một số dịch vụ hoặc mở rộng nhưng tôi không thể tìm ra cái nào.
phân tích cú pháp của tôi:
import com.intellij.codeInsight.ContainerProvider;
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
import com.intellij.core.CoreApplicationEnvironment;
import com.intellij.core.CoreJavaFileManager;
import com.intellij.core.JavaCoreApplicationEnvironment;
import com.intellij.core.JavaCoreProjectEnvironment;
import com.intellij.mock.MockProject;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.augment.TypeAnnotationModifier;
import com.intellij.psi.compiled.ClassFileDecompilers;
import com.intellij.psi.impl.JavaClassSupersImpl;
import com.intellij.psi.impl.PsiElementFinderImpl;
import com.intellij.psi.impl.PsiNameHelperImpl;
import com.intellij.psi.impl.PsiTreeChangePreprocessor;
import com.intellij.psi.impl.file.impl.JavaFileManager;
import com.intellij.psi.meta.MetaDataContributor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.stubs.BinaryFileStubBuilders;
import com.intellij.psi.util.JavaClassSupers;
import java.io.File;
public class Main {
static class Analyzer extends PsiElementVisitor {
static final Disposable disposable =() -> {
};
private static class ProjectEnvironment extends JavaCoreProjectEnvironment {
public ProjectEnvironment(Disposable parentDisposable, CoreApplicationEnvironment applicationEnvironment) {
super(parentDisposable, applicationEnvironment);
}
@Override
protected void registerJavaPsiFacade() {
JavaFileManager javaFileManager = getProject().getComponent(JavaFileManager.class);
CoreJavaFileManager coreJavaFileManager = (CoreJavaFileManager) javaFileManager;
ServiceManager.getService(getProject(), CoreJavaFileManager.class);
getProject().registerService(CoreJavaFileManager.class, coreJavaFileManager);
getProject().registerService(PsiNameHelper.class, PsiNameHelperImpl.getInstance());
PsiElementFinder finder = new PsiElementFinderImpl(getProject(), coreJavaFileManager);
ExtensionsArea area = Extensions.getArea(getProject());
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(finder);
super.registerJavaPsiFacade();
}
@Override
protected void preregisterServices() {
super.preregisterServices();
ExtensionsArea area = Extensions.getArea(getProject());
CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor.class);
CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder.class);
}
}
private static class ApplicationEnvironment extends JavaCoreApplicationEnvironment {
public ApplicationEnvironment(Disposable parentDisposable) {
super(parentDisposable);
myApplication.registerService(JavaClassSupers.class, new JavaClassSupersImpl());
}
}
final ApplicationEnvironment applicationEnvironment;
final ProjectEnvironment projectEnvironment;
public Analyzer() {
ExtensionsArea rootArea = Extensions.getRootArea();
CoreApplicationEnvironment.registerExtensionPoint(rootArea, BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint.class);
CoreApplicationEnvironment.registerExtensionPoint(rootArea, FileContextProvider.EP_NAME, FileContextProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(rootArea, MetaDataContributor.EP_NAME, MetaDataContributor.class);
CoreApplicationEnvironment.registerExtensionPoint(rootArea, PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(rootArea, JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(rootArea, ContainerProvider.EP_NAME, ContainerProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(rootArea, ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
CoreApplicationEnvironment.registerExtensionPoint(rootArea, TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier.class);
applicationEnvironment = new ApplicationEnvironment(disposable);
projectEnvironment = new ProjectEnvironment(disposable, applicationEnvironment);
}
public void add(final String[] args) throws Exception {
for (String arg : args) {
final VirtualFile root = applicationEnvironment.getLocalFileSystem().findFileByIoFile(new File(arg));
projectEnvironment.addSourcesToClasspath(root);
}
}
public void run() {
MockProject project = projectEnvironment.getProject();
PsiClass cls = project.getComponent(JavaFileManager.class)
.findClass("ResolutionTest", GlobalSearchScope.projectScope(project));
if (cls != null) {
PsiMethod[] methods = cls.findMethodsByName("test", false);
if (methods.length == 1) {
PsiMethod method = methods[0];
for (PsiStatement s : method.getBody().getStatements()) {
System.out.println(s.getNode().getText());
process(s);
}
}
}
}
private void process(PsiMethodCallExpression expression) {
PsiExpression qualifierExpression = expression.getMethodExpression().getQualifierExpression();
if (qualifierExpression instanceof PsiMethodCallExpression) {
process((PsiMethodCallExpression) qualifierExpression);
} else if (qualifierExpression instanceof PsiReference) {
System.out.println("Resolving reference " + qualifierExpression.getText());
PsiElement targetElement = ((PsiReference) qualifierExpression).resolve();
if (targetElement == null) {
System.out.println("Resolution failed");
} else if (targetElement instanceof PsiClass) {
System.out.println("Class " + ((PsiClass) targetElement).getName());
} else if (targetElement instanceof PsiVariable) {
System.out.println("Variable " + ((PsiVariable) targetElement).getTypeElement().getText());
}
}
System.out.println("Resolving method " + expression.getMethodExpression().getText());
PsiMethod method = expression.resolveMethod();
if (method == null) {
System.out.println("Resolution failed");
} else {
PsiClass clazz = method.getContainingClass();
System.out.println(clazz.getName() + "." + method.getName());
}
}
private void process(PsiExpression e) {
if (e instanceof PsiMethodCallExpression) {
process((PsiMethodCallExpression) e);
}
}
private void process(PsiStatement s) {
if (s instanceof PsiExpressionStatement) {
process(((PsiExpressionStatement) s).getExpression());
}
}
}
public static void main(String[] args) {
try {
Analyzer analyzer = new Analyzer();
analyzer.add(args);
analyzer.run();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
Và đầu ra:
verify(mock).simpleMethod();
Resolving method verify
ResolutionTest.verify
Resolving method verify(mock).simpleMethod
Resolution failed