Place light classes finder before standard PsiElementFinderImpl

Source elements should have priority over libraries.
This commit is contained in:
Nikolay Krasko
2015-05-08 16:22:27 +03:00
parent 6f4cae03fe
commit 3c7e7ffda6
12 changed files with 152 additions and 22 deletions
@@ -378,8 +378,10 @@ public class KotlinCoreEnvironment private(
registerService(javaClass<CodeAnalyzerInitializer>(), cliLightClassGenerationSupport)
val area = Extensions.getArea(this)
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(PsiElementFinderImpl(this, ServiceManager.getService(this, javaClass<JavaFileManager>())))
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(JavaElementFinder(this, cliLightClassGenerationSupport))
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(
PsiElementFinderImpl(this, ServiceManager.getService(this, javaClass<JavaFileManager>())))
}
}
}
@@ -25,11 +25,13 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.asJava.KotlinLightClass;
import org.jetbrains.kotlin.cli.jvm.compiler.CoreExternalAnnotationsManager;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.resolve.lazy.KotlinTestWithEnvironment;
import org.jetbrains.kotlin.resolve.lazy.LazyResolveTestUtil;
import org.jetbrains.kotlin.test.ConfigurationKind;
import org.jetbrains.kotlin.test.JetTestUtils;
import org.jetbrains.kotlin.test.TestJdkKind;
@@ -42,8 +44,13 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment {
@Override
protected KotlinCoreEnvironment createEnvironment() {
return JetTestUtils.createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(
KotlinCoreEnvironment environment = JetTestUtils.createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(
myTestRootDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS, TestJdkKind.FULL_JDK);
// Activate Kotlin light class finder
LazyResolveTestUtil.resolveProject(environment.getProject());
return environment;
}
@Override
@@ -90,9 +97,11 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment {
PsiClass psiClass = javaPsiFacade.findClass(classFqName.asString(), allScope);
assertNotNull("Class has annotation, but it is not found: " + classFqName, psiClass);
assertFalse("Kotlin light classes are not not expected", psiClass instanceof KotlinLightClass);
psiClass.accept(new JavaRecursiveElementVisitor() {
@Override
public void visitMethod(PsiMethod method) {
public void visitMethod(@NotNull PsiMethod method) {
super.visitMethod(method);
if (method.getReturnType() != null) { // disabled for constructors
checkAndReport(method);
@@ -100,19 +109,19 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment {
}
@Override
public void visitField(PsiField field) {
public void visitField(@NotNull PsiField field) {
super.visitField(field);
checkAndReport(field);
}
@Override
public void visitParameter(PsiParameter parameter) {
public void visitParameter(@NotNull PsiParameter parameter) {
super.visitParameter(parameter);
PsiMethod method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class);
assert method != null;
if (method.getReturnType() != null) { // disabled for constructors
if (!check(parameter, method, AnnotationsKind.KOTLIN_SIGNATURE) &&
!check(parameter, parameter, AnnotationsKind.NOT_NULL)) {
!check(parameter, parameter, AnnotationsKind.NOT_NULL)) {
declarationsWithMissingAnnotations.add(parameter);
}
}
@@ -128,8 +137,7 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment {
@NotNull PsiModifierListOwner ideaOwner,
@NotNull PsiModifierListOwner kotlinOwner,
@NotNull AnnotationsKind annotationsKind
)
{
) {
return !hasAnnotationInIdea(ideaOwner) || hasAnnotationInKotlin(kotlinOwner, annotationsKind);
}
@@ -172,7 +180,7 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment {
public final String[] annotationNames;
private AnnotationsKind(@NotNull String... annotationNames) {
AnnotationsKind(@NotNull String... annotationNames) {
this.annotationNames = annotationNames;
}
}
@@ -16,40 +16,65 @@
package org.jetbrains.kotlin.jvm.compiler
import org.jetbrains.kotlin.test.KotlinTestWithEnvironmentManagement
import org.jetbrains.kotlin.test.JetTestUtils
import java.io.File
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.asJava.KotlinLightClass
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
import org.jetbrains.kotlin.resolve.lazy.LazyResolveTestUtil
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.JetTestUtils
import org.jetbrains.kotlin.test.KotlinTestWithEnvironmentManagement
import org.jetbrains.kotlin.test.TestJdkKind
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import kotlin.test.assertNull
import kotlin.test.assertTrue
public class KotlinClassFinderTest : KotlinTestWithEnvironmentManagement() {
fun testAbsentClass() {
val tmpdir = JetTestUtils.tmpDirForTest(this)
val environment = createEnvironment(tmpdir)
val project = environment.project
val className = "test.A.B.D"
val psiClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project))
assertNull(psiClass, "Class is expected to be null, there should be no exceptions too.")
}
fun testNestedClass() {
val tmpdir = JetTestUtils.tmpDirForTest(this)
JetTestUtils.compileKotlinWithJava(
listOf(), listOf(File("compiler/testData/kotlinClassFinder/nestedClass.kt")), tmpdir, getTestRootDisposable()!!
)
val environment = KotlinCoreEnvironment.createForTests(getTestRootDisposable()!!,
JetTestUtils.compilerConfigurationForTests(
ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, tmpdir),
EnvironmentConfigFiles.JVM_CONFIG_FILES)
val environment = createEnvironment(tmpdir)
val project = environment.project
val className = "test.A.B.C"
val psiClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project))
assertNotNull(psiClass, "Psi class not found for $className")
assertTrue(psiClass !is KotlinLightClass, "Kotlin light classes are not not expected");
val binaryClass = VirtualFileFinder.SERVICE.getInstance(project).findKotlinClass(JavaClassImpl(psiClass!!))
assertNotNull(binaryClass, "No binary class for $className")
assertEquals("test/A.B.C", binaryClass?.getClassId()?.toString())
}
private fun createEnvironment(tmpdir: File?): KotlinCoreEnvironment {
val environment = KotlinCoreEnvironment.createForTests(getTestRootDisposable()!!,
JetTestUtils.compilerConfigurationForTests(
ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, tmpdir),
EnvironmentConfigFiles.JVM_CONFIG_FILES)
// Activate Kotlin light class finder
LazyResolveTestUtil.resolveProject(environment.project)
return environment
}
}
@@ -431,6 +431,20 @@ public class KotlinJpsBuildTest extends AbstractKotlinJpsBuildTestCase {
result.assertSuccessful();
}
public void testDependencyToOldKotlinLib() throws IOException {
initProject();
File libraryJar = MockLibraryUtil.compileLibraryToJar(
workDir.getAbsolutePath() + File.separator + "oldModuleLib/src", "module-lib", false);
addDependency(JpsJavaDependencyScope.COMPILE, Lists.newArrayList(findModule("module")), false, "module-lib", libraryJar);
addKotlinRuntimeDependency();
BuildResult result = makeAll();
result.assertSuccessful();
}
private void createKotlinJavaScriptLibraryArchive() {
File jarFile = new File(workDir, KOTLIN_JS_LIBRARY_JAR);
try {
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
<component name="CopyrightManager" default="">
<module2copyright />
</component>
<component name="DependencyValidationManager">
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</component>
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/module/module.iml" filepath="$PROJECT_DIR$/module/module.iml" />
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA_JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="xUTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="IDEA_JDK" jdkType="JavaSDK" />
<orderEntry type="module" module-name="module2" />
</component>
</module>
@@ -0,0 +1,6 @@
package module
public trait A {
fun oldFun(): Int = 1
fun newFun(): Int = 42
}
@@ -0,0 +1,9 @@
package module
public class B(private val c: C) {
fun foo() {
val a = c.getA()
a.oldFun()
a.newFun()
}
}
@@ -0,0 +1,5 @@
package module;
public interface C {
A getA();
}
@@ -0,0 +1,5 @@
package module
public trait A {
fun oldFun(): Int = 1
}
@@ -0,0 +1,8 @@
package module
public class B(private val c: C) {
fun foo() {
val a = c.getA()
a.oldFun()
}
}
@@ -0,0 +1,5 @@
package module;
public interface C {
A getA();
}