2016-11-10 24 views
6

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ư IMethodssimpleMethod 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)TsimpleMethod 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 

Trả lời

6

Để thực hiện mẫu này để làm việc tôi đã có thêm rt.jar qua projectEnvironment.addJarToClassPath(file); - tiếc là tôi vẫn nhận 2 thất bại giải quyết phương pháp trong mockito và tôi không thể tạo mẫu nhỏ tái tạo sự cố. Tuy nhiên, thông tin về rt.jar có thể hữu ích đối với ai đó vì vậy tôi sẽ thêm nó làm câu trả lời.

Chức năng với các vấn đề:

@Test 
public void any_should_be_actual_alias_to_anyObject() { 
    mock.simpleMethod((Object) null); 

    verify(mock).simpleMethod(any()); 
    verify(mock).simpleMethod(anyObject()); 
} 

hiểu biết hiện tại của tôi về một vấn đề: bất kỳ() trả lại là chung chung và simpleMethod có nhiều quá tải và phân giải không thể chọn một trong những phù hợp, nhưng ý tưởng riêng của mình có thể chọn phiên bản phù hợp .

P.S. Sau khi thiết lập cấp độ ngôn ngữ java đến 6 (như trong các nguồn mockito) - không còn thất bại nữa.

Các vấn đề liên quan