accept that with different library versions inheritance relation may be intransitive...
[idea/community.git] / java / java-tests / testSrc / com / intellij / psi / resolve / ResolveInLibrariesTest.groovy
1 /*
2  * Copyright 2000-2012 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.psi.resolve
17 import com.intellij.openapi.application.ex.PathManagerEx
18 import com.intellij.openapi.vfs.LocalFileSystem
19 import com.intellij.psi.JavaPsiFacade
20 import com.intellij.psi.PsiClass
21 import com.intellij.psi.PsiMethod
22 import com.intellij.psi.search.GlobalSearchScope
23 import com.intellij.psi.search.searches.ClassInheritorsSearch
24 import com.intellij.psi.search.searches.OverridingMethodsSearch
25 import com.intellij.testFramework.PsiTestUtil
26 import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
27 /**
28  * @author peter
29  */
30 class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
31
32   public void "test prefer current library when navigation from its source"() {
33     def lib = LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManagerEx.getTestDataPath() + "/../../../lib")
34     def nanoJar = lib.children.find { it.name.startsWith("nanoxml") }
35     def nanoSrc = lib.findChild("src").children.find { it.name.startsWith("nanoxml") }
36
37     def jarCopy = myFixture.copyFileToProject(nanoJar.path, 'lib/nanoJar.jar')
38     def srcCopy = myFixture.copyFileToProject(nanoSrc.path, 'lib/nanoSrc.zip')
39
40     PsiTestUtil.addLibrary(myModule, 'nano1', lib.path, ["/$nanoJar.name!/"] as String[], ["/src/$nanoSrc.name!/"] as String[])
41     PsiTestUtil.addLibrary(myModule, 'nano2', jarCopy.parent.path, ["/$jarCopy.name!/"] as String[], ["/$srcCopy.name!/"] as String[])
42
43     def parsers = JavaPsiFacade.getInstance(project).findClasses('net.n3.nanoxml.IXMLParser', GlobalSearchScope.allScope(project))
44     assert parsers.size() == 2
45
46     def file0 = parsers[0].navigationElement.containingFile
47     assert file0.virtualFile.path.startsWith(nanoSrc.path)
48     assert file0.findReferenceAt(file0.text.indexOf('IXMLReader reader')).resolve().navigationElement.containingFile.virtualFile.path.startsWith(nanoSrc.path)
49
50     def file1 = parsers[1].navigationElement.containingFile
51     assert file1.virtualFile.path.startsWith(srcCopy.path)
52     assert file1.findReferenceAt(file1.text.indexOf('IXMLReader reader')).resolve().navigationElement.containingFile.virtualFile.path.startsWith(srcCopy.path)
53
54   }
55
56   public void "test inheritance transitivity"() {
57     def lib = LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManagerEx.getTestDataPath() + "/../../../lib")
58     def protoJar = lib.children.find { it.name.startsWith("protobuf") }
59
60     def jarCopy = myFixture.copyFileToProject(protoJar.path, 'lib/protoJar.jar')
61
62     PsiTestUtil.addLibrary(myModule, 'proto1', lib.path, ["/$protoJar.name!/"] as String[], [] as String[])
63     PsiTestUtil.addLibrary(myModule, 'proto2', jarCopy.parent.path, ["/$jarCopy.name!/"] as String[], [] as String[])
64
65     def scope = GlobalSearchScope.allScope(project)
66
67     def bottoms = JavaPsiFacade.getInstance(project).findClasses('com.google.protobuf.AbstractMessage', scope)
68     assert bottoms.size() == 2
69
70     def middles = JavaPsiFacade.getInstance(project).findClasses('com.google.protobuf.AbstractMessageLite', scope)
71     assert middles.size() == 2
72
73     def intfs = JavaPsiFacade.getInstance(project).findClasses('com.google.protobuf.MessageLite', scope)
74     assert intfs.size() == 2
75
76     for (i in 0..1) {
77       assert ClassInheritorsSearch.search(intfs[i]).findAll().containsAll([middles[i], bottoms[i]])
78       intfs[i].methods.each {
79         assert OverridingMethodsSearch.search(it).findAll()
80       }
81
82       assert middles[i].isInheritor(intfs[i], true)
83       assert bottoms[i].isInheritor(intfs[i], true)
84       assert bottoms[i].isInheritor(middles[i], true)
85     }
86
87   }
88
89   public void "test accept that with different library versions inheritance relation may be intransitive"() {
90     def lib = LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManagerEx.getTestDataPath() + "/libResolve/inheritance")
91
92     //Foo, Middle implements Foo, Other extends Middle
93     PsiTestUtil.addLibrary(myModule, 'full', lib.path, ["/fullLibrary.jar!/"] as String[], [] as String[])
94
95     //Middle, Bottom extends Middle
96     PsiTestUtil.addLibrary(myModule, 'partial', lib.path, ["/middleBottom.jar!/"] as String[], [] as String[])
97
98     def scope = GlobalSearchScope.allScope(project)
99
100     def i0 = JavaPsiFacade.getInstance(project).findClass('Intf', scope)
101     def other0 = JavaPsiFacade.getInstance(project).findClass('Other', scope)
102     def b1 = JavaPsiFacade.getInstance(project).findClass('Bottom', scope)
103
104     def middles = JavaPsiFacade.getInstance(project).findClasses('Middle', scope)
105     assert middles.size() == 2
106     def m0 = middles[0]
107     def m1 = middles[1]
108
109     for (deep in [false, true]) {
110       assert m0.isInheritor(i0, deep)
111       assert other0.isInheritor(m0, deep)
112
113       assert !b1.isInheritor(i0, deep)
114
115       assert b1.isInheritor(m0, deep)
116       assert b1.isInheritor(m1, deep)
117
118       assert !m1.isInheritor(i0, deep)
119     }
120
121     assert other0.isInheritor(i0, true)
122     assert !other0.isInheritor(i0, false)
123
124     assert ClassInheritorsSearch.search(i0).findAll() == [m0, b1, other0]
125     assert ClassInheritorsSearch.search(m0).findAll() == [b1, other0]
126
127     assert fooInheritors(i0) == [fooMethod(m0), fooMethod(other0)] as Set
128     assert fooInheritors(m0) == [fooMethod(other0), fooMethod(b1)] as Set
129     assert fooInheritors(m1) == [fooMethod(other0), fooMethod(b1)] as Set
130   }
131
132   private PsiMethod fooMethod(PsiClass c) { c.findMethodsByName('foo', false)[0] }
133   private Set<PsiMethod> fooInheritors(PsiClass c) { OverridingMethodsSearch.search(fooMethod(c)).findAll() as Set }
134
135 }