Tests: Introduce LightClassComputationControl to track when stubs for light classes are built
Use it to track when light classes are built in KotlinSourceInJavaCompletionTest
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.asJava
|
||||
|
||||
import com.google.common.collect.Lists
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -107,6 +108,8 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
|
||||
if (pop !== javaFileStub) {
|
||||
LOG.error("Unbalanced stack operations: " + pop)
|
||||
}
|
||||
|
||||
ServiceManager.getService(project, StubComputationTracker::class.java)?.onStubComputed(javaFileStub)
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
@@ -354,3 +357,8 @@ class LightClassDataProviderForFileFacade(
|
||||
return this.javaClass.name + " for $facadeFqName"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface StubComputationTracker {
|
||||
fun onStubComputed(javaFileStub: PsiJavaFileStub)
|
||||
}
|
||||
|
||||
@@ -4,3 +4,4 @@ public class Testing {
|
||||
|
||||
// EXIST: c
|
||||
// EXIST: d
|
||||
// LIGHT_CLASS: mockLib.foo.Anno
|
||||
@@ -5,3 +5,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: foo
|
||||
// LIGHT_CLASS: mockLib.foo.LibClass
|
||||
+2
-1
@@ -4,4 +4,5 @@ public class Testing {
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: classObjectFun
|
||||
// EXIST: classObjectFun
|
||||
// LIGHT_CLASS: mockLib.foo.LibClass
|
||||
@@ -5,3 +5,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: Companion
|
||||
// LIGHT_CLASS: mockLib.foo.LibClass
|
||||
@@ -5,3 +5,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: RED, GREEN, BLUE
|
||||
// LIGHT_CLASS: mockLib.foo.LibEnum
|
||||
@@ -5,3 +5,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: DefaultImpls
|
||||
// LIGHT_CLASS: mockLib.foo.MyInterface
|
||||
@@ -6,3 +6,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: foo
|
||||
// LIGHT_CLASS: mockLib.foo.MyInterface
|
||||
@@ -5,3 +5,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: foo
|
||||
// LIGHT_CLASS: mockLib.foo.MyInterface
|
||||
+1
@@ -6,3 +6,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: foo
|
||||
// LIGHT_CLASS: mockLib.foo.MyInterface
|
||||
@@ -6,4 +6,4 @@ public class Testing {
|
||||
|
||||
// EXIST: funInFacade
|
||||
// EXIST: funInFacade2
|
||||
|
||||
// LIGHT_CLASS: facades.MultiFileFacadeClass
|
||||
@@ -7,3 +7,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: LibClass.Nested
|
||||
// LIGHT_CLASS: mockLib.foo.LibClass
|
||||
@@ -6,3 +6,4 @@ public class Testing {
|
||||
|
||||
// EXIST: getValInNested
|
||||
// EXIST: funInNested
|
||||
// LIGHT_CLASS: mockLib.foo.LibClass
|
||||
@@ -6,3 +6,4 @@ public class Testing {
|
||||
|
||||
// EXIST: getValInNested
|
||||
// EXIST: funInNested
|
||||
// LIGHT_CLASS: mockLib.foo.LibClass
|
||||
@@ -5,3 +5,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: INSTANCE
|
||||
// LIGHT_CLASS: mockLib.foo.LibClass
|
||||
@@ -4,3 +4,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: F
|
||||
// LIGHT_CLASS: mockLib.foo.F
|
||||
|
||||
@@ -5,3 +5,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: INSTANCE
|
||||
// LIGHT_CLASS: mockLib.foo.LibObject
|
||||
@@ -8,4 +8,4 @@ public class Testing {
|
||||
// EXIST: topLevelExtFunction
|
||||
// EXIST: getTopLevelVar
|
||||
// EXIST: setTopLevelVar
|
||||
|
||||
// LIGHT_CLASS: mockLib.foo.MainKt
|
||||
|
||||
@@ -7,3 +7,4 @@ public class Testing {
|
||||
// EXIST: topLevelFunction
|
||||
// EXIST: topLevelExtFunction
|
||||
// EXIST: getTopLevelVar, setTopLevelVar
|
||||
// LIGHT_CLASS: mockLib.foo.MainKt
|
||||
+1
-1
@@ -5,4 +5,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: foo
|
||||
|
||||
// LIGHT_CLASS: mockLib.foo.LibTrait
|
||||
+8
-13
@@ -19,10 +19,6 @@ package org.jetbrains.kotlin.idea.completion.test
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.util.ArrayUtil
|
||||
import com.intellij.util.Function
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import java.io.File
|
||||
|
||||
@@ -31,17 +27,16 @@ public abstract class AbstractKotlinSourceInJavaCompletionTest : KotlinFixtureCo
|
||||
|
||||
override fun doTest(testPath: String) {
|
||||
val mockLibDir = File(COMPLETION_TEST_DATA_BASE_PATH + "/injava/mockLib")
|
||||
val listFiles = mockLibDir.listFiles()
|
||||
TestCase.assertNotNull(listFiles)
|
||||
val paths = ArrayUtil.toStringArray(ContainerUtil.map<File, String>(listFiles, object : Function<File, String> {
|
||||
override fun `fun`(file: File): String {
|
||||
return FileUtil.toSystemIndependentName(file.getAbsolutePath())
|
||||
}
|
||||
}))
|
||||
val paths = mockLibDir.listFiles()!!.map {
|
||||
FileUtil.toSystemIndependentName(it.absolutePath)
|
||||
}.toTypedArray()
|
||||
|
||||
myFixture.configureByFiles(*paths)
|
||||
super.doTest(testPath)
|
||||
LightClassComputationControl.testWithControl(project, FileUtil.loadFile(File(testPath))) {
|
||||
super.doTest(testPath)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor() = LightCodeInsightFixtureTestCase.JAVA_LATEST
|
||||
override fun defaultCompletionType() = CompletionType.BASIC
|
||||
}
|
||||
}
|
||||
+1
@@ -133,6 +133,7 @@ public object ExpectedCompletionUtils {
|
||||
NOTHING_ELSE_PREFIX,
|
||||
RUNTIME_TYPE,
|
||||
COMPLETION_TYPE_PREFIX,
|
||||
LightClassComputationControl.LIGHT_CLASS_DIRECTIVE,
|
||||
AstAccessControl.ALLOW_AST_ACCESS_DIRECTIVE)
|
||||
|
||||
public fun itemsShouldExist(fileText: String, platform: TargetPlatform?): Array<CompletionProposal> {
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion.test
|
||||
|
||||
import com.intellij.openapi.components.ComponentManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.impl.java.stubs.PsiClassStub
|
||||
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
||||
import org.jetbrains.kotlin.asJava.StubComputationTracker
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.junit.Assert
|
||||
import org.picocontainer.MutablePicoContainer
|
||||
import java.util.*
|
||||
|
||||
object LightClassComputationControl {
|
||||
fun testWithControl(project: Project, testText: String, testBody: () -> Unit) {
|
||||
val expectedLightClassFqNames = InTextDirectivesUtils.findLinesWithPrefixesRemoved(
|
||||
testText, "// $LIGHT_CLASS_DIRECTIVE"
|
||||
).map { it.trim() }
|
||||
|
||||
val actualFqNames = ArrayList<String>()
|
||||
val stubComputationTracker = object : StubComputationTracker {
|
||||
override fun onStubComputed(javaFileStub: PsiJavaFileStub) {
|
||||
val qualifiedName = (javaFileStub.childrenStubs.single() as PsiClassStub<*>).qualifiedName!!
|
||||
actualFqNames.add(qualifiedName)
|
||||
}
|
||||
}
|
||||
|
||||
project.withServiceRegistered<StubComputationTracker>(stubComputationTracker) {
|
||||
testBody()
|
||||
}
|
||||
|
||||
if (expectedLightClassFqNames.toSortedSet() != actualFqNames.toSortedSet()) {
|
||||
Assert.fail(
|
||||
"Expected to compute: ${expectedLightClassFqNames.prettyToString()}\n" +
|
||||
"Actually computed: ${actualFqNames.prettyToString()}\n" +
|
||||
"Use $LIGHT_CLASS_DIRECTIVE to specify expected light class computations"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val LIGHT_CLASS_DIRECTIVE = "LIGHT_CLASS:"
|
||||
|
||||
private fun List<String>.prettyToString() = if (isEmpty()) "<empty>" else joinToString()
|
||||
}
|
||||
|
||||
private inline fun <reified T : Any> ComponentManager.withServiceRegistered(instance: T, body: () -> Unit) {
|
||||
val picoContainer = picoContainer as MutablePicoContainer
|
||||
val key = T::class.java.name
|
||||
try {
|
||||
picoContainer.unregisterComponent(key)
|
||||
picoContainer.registerComponentInstance(key, instance)
|
||||
body()
|
||||
}
|
||||
finally {
|
||||
picoContainer.unregisterComponent(key)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user