2016-11-10 21 views
6

IntelliJ SDK'yı bağımsız java ayrıştırıcısı olarak kullanmaya çalışıyorum ve çoğu durumda iyi çalışıyor, ancak genel yöntemlerin dönüş türünü çözümlemiyor.Bağımsız IntelliJ çözümleyicide semboller çözünürlüğü

I intellij içinde bir sonraki örnek verify(mock).simpleMethod() için resolveMethod ayıklarken:

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(); 
    } 

} 

I IMethods ve doğru bir şekilde çözülmesi simpleMethod olarak verify(mock) dönüş türü bkz. Ancak, çözümleyici verify(mock) türünde T ve simpleMethod çözünürlüğü bunun için başarısız oluyor. Sanırım bir servis veya uzatma kaydı yapmıyorum ama hangisi olduğunu anlayamıyorum.

Benim ayrıştırıcı:

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); 
     } 
    } 
} 

Ve çıkışı:

verify(mock).simpleMethod(); 
Resolving method verify 
ResolutionTest.verify 
Resolving method verify(mock).simpleMethod 
Resolution failed 

cevap

6

Ben rt.jarprojectEnvironment.addJarToClassPath(file); yoluyla eklemek zorunda çalışmak için bu örneği yapmak amacıyla - maalesef hala 2 yöntem çözünürlüğü hatalarını alıyorum mockito içinde ve bir sorunu yeniden üreten küçük bir örnek oluşturamıyorum. rt.jar ile ilgili hala bilgi birileri için yararlı olabilir, bu yüzden yanıt olarak ekliyorum. sorunları ile

Fonksiyon:

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

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

bir sorun Benim şimdiki anlayış: Herhangi() dönüş jenerik ve simpleMethod birden fazla yüke ve uygun bir seçim olamazdı çözümleyicinizi vardır, ama fikir kendisi doğru varyantını seçmek yapabiliyor .

P.S. Java dil seviyesini 6'ya ayarladıktan sonra (mockito kaynaklarında olduğu gibi) - daha fazla arıza olmaz.