Create KotlinCoreEnvironment a bit later in tests
Before this change, diagnostic tests with Java source files failed because KotlinCoreEnvironment was being created in the test's setUp, even before the test data file has been split into .java/.kt and the resulting .java files have been copied to a temporary directory. In KotlinCoreEnvironment's constructor, we now inspect all roots for module-info files, which involves calling VirtualFile.getChildren on all roots in the configuration. CoreLocalVirtualFile.getChildren is cached on the first access, and so because the temporary directory with .java files was empty at this point, the VirtualFile for that directory returned empty array in getChildren later in the test, resulting in unresolved reference errors. This is fixed by creating the environment _after_ the .java files have been copied to a temporary directory. Note that slow assertions for flexible types are now enabled in KtUsefulTestCase instead of KotlinTestWithEnvironmentManagement, because BaseDiagnosticsTest no longer inherits from the latter
This commit is contained in:
@@ -16,11 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.checkers
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Condition
|
||||
import com.intellij.openapi.util.Conditions
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiFileFactory
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
@@ -28,6 +27,7 @@ import org.jetbrains.kotlin.asJava.getJvmSignatureDiagnostics
|
||||
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestFile
|
||||
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestModule
|
||||
import org.jetbrains.kotlin.checkers.CheckerTestUtil.ActualDiagnostic
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
@@ -42,8 +42,19 @@ import org.junit.Assert
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.reflect.jvm.javaField
|
||||
|
||||
abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, TestFile>() {
|
||||
protected lateinit var environment: KotlinCoreEnvironment
|
||||
|
||||
protected val project: Project
|
||||
get() = environment.project
|
||||
|
||||
override fun tearDown() {
|
||||
this::environment.javaField!![this] = null
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
override fun createTestModule(name: String): TestModule =
|
||||
TestModule(name)
|
||||
|
||||
@@ -61,6 +72,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
})
|
||||
}
|
||||
|
||||
environment = createEnvironment()
|
||||
|
||||
analyzeAndCheck(file, testFiles)
|
||||
}
|
||||
|
||||
@@ -120,7 +133,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
private val diagnosedRanges: List<CheckerTestUtil.DiagnosedRange> = ArrayList()
|
||||
val expectedText: String
|
||||
private val clearText: String
|
||||
val ktFile: KtFile?
|
||||
private val createKtFile: Lazy<KtFile?>
|
||||
private val whatDiagnosticsToConsider: Condition<Diagnostic>
|
||||
val customLanguageVersionSettings: LanguageVersionSettings?
|
||||
val declareCheckType: Boolean
|
||||
@@ -137,19 +150,20 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
this.declareFlexibleType = EXPLICIT_FLEXIBLE_TYPES_DIRECTIVE in directives
|
||||
this.markDynamicCalls = MARK_DYNAMIC_CALLS_DIRECTIVE in directives
|
||||
if (fileName.endsWith(".java")) {
|
||||
PsiFileFactory.getInstance(project).createFileFromText(fileName, JavaLanguage.INSTANCE, textWithMarkers)
|
||||
// TODO: check there's not syntax errors
|
||||
this.ktFile = null
|
||||
// TODO: check there are no syntax errors in .java sources
|
||||
this.createKtFile = lazyOf(null)
|
||||
this.clearText = textWithMarkers
|
||||
this.expectedText = this.clearText
|
||||
}
|
||||
else {
|
||||
this.expectedText = textWithMarkers
|
||||
this.clearText = CheckerTestUtil.parseDiagnosedRanges(addExtras(expectedText), diagnosedRanges)
|
||||
this.ktFile = TestCheckerUtil.createCheckAndReturnPsiFile(fileName, clearText, project)
|
||||
this.createKtFile = lazy { TestCheckerUtil.createCheckAndReturnPsiFile(fileName, clearText, project) }
|
||||
}
|
||||
}
|
||||
|
||||
val ktFile: KtFile? by createKtFile
|
||||
|
||||
private val imports: String
|
||||
get() = buildString {
|
||||
// Line separator is "\n" intentionally here (see DocumentImpl.assertValidSeparators)
|
||||
@@ -196,7 +210,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
actualText: StringBuilder,
|
||||
skipJvmSignatureDiagnostics: Boolean
|
||||
): Boolean {
|
||||
if (this.ktFile == null) {
|
||||
val ktFile = this.ktFile
|
||||
if (ktFile == null) {
|
||||
// TODO: check java files too
|
||||
actualText.append(this.clearText)
|
||||
return true
|
||||
|
||||
+21
-13
@@ -30,8 +30,8 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys;
|
||||
import org.jetbrains.kotlin.script.StandardScriptDefinition;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment;
|
||||
import org.jetbrains.kotlin.test.TestJdkKind;
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
@@ -39,10 +39,27 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class KotlinMultiFileTestWithJava<M, F> extends KotlinTestWithEnvironment {
|
||||
public abstract class KotlinMultiFileTestWithJava<M, F> extends KtUsefulTestCase {
|
||||
private File javaFilesDir;
|
||||
private File kotlinSourceRoot;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
// TODO: do not create temporary directory for tests without Java sources
|
||||
javaFilesDir = KotlinTestUtils.tmpDir("java-files");
|
||||
if (isKotlinSourceRootNeeded()) {
|
||||
kotlinSourceRoot = KotlinTestUtils.tmpDir("kotlin-src");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (javaFilesDir != null) FileUtil.delete(javaFilesDir);
|
||||
if (kotlinSourceRoot != null) FileUtil.delete(kotlinSourceRoot);
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public class ModuleAndDependencies {
|
||||
final M module;
|
||||
final List<String> dependencies;
|
||||
@@ -55,10 +72,8 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KotlinTestWithEn
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected KotlinCoreEnvironment createEnvironment() throws Exception {
|
||||
// TODO: do not create temporary directory for tests without Java sources
|
||||
javaFilesDir = KotlinTestUtils.tmpDir("java-files");
|
||||
@NotNull
|
||||
protected KotlinCoreEnvironment createEnvironment() {
|
||||
CompilerConfiguration configuration = KotlinTestUtils.newConfiguration(
|
||||
getConfigurationKind(),
|
||||
getTestJdkKind(),
|
||||
@@ -67,18 +82,11 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KotlinTestWithEn
|
||||
);
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition.INSTANCE);
|
||||
if (isKotlinSourceRootNeeded()) {
|
||||
kotlinSourceRoot = KotlinTestUtils.tmpDir("kotlin-src");
|
||||
ContentRootsKt.addKotlinSourceRoot(configuration, kotlinSourceRoot.getPath());
|
||||
}
|
||||
return KotlinCoreEnvironment.createForTests(getTestRootDisposable(), configuration, getEnvironmentConfigFiles());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeEnvironment() throws Exception {
|
||||
if (javaFilesDir != null) FileUtil.delete(javaFilesDir);
|
||||
if (kotlinSourceRoot != null) FileUtil.delete(kotlinSourceRoot);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected ConfigurationKind getConfigurationKind() {
|
||||
return ConfigurationKind.JDK_ONLY;
|
||||
|
||||
@@ -31,13 +31,11 @@ public abstract class KotlinTestWithEnvironment extends KotlinTestWithEnvironmen
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
removeEnvironment();
|
||||
environment = null;
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected abstract KotlinCoreEnvironment createEnvironment() throws Exception;
|
||||
protected void removeEnvironment() throws Exception {}
|
||||
|
||||
@NotNull
|
||||
public KotlinCoreEnvironment getEnvironment() {
|
||||
|
||||
-2
@@ -19,12 +19,10 @@ package org.jetbrains.kotlin.test;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase;
|
||||
import org.jetbrains.kotlin.types.FlexibleTypeImpl;
|
||||
|
||||
public abstract class KotlinTestWithEnvironmentManagement extends KtUsefulTestCase {
|
||||
static {
|
||||
System.setProperty("java.awt.headless", "true");
|
||||
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.types.FlexibleTypeImpl;
|
||||
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
||||
import org.junit.Assert;
|
||||
|
||||
@@ -80,6 +81,8 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
static {
|
||||
// Radar #5755208: Command line Java applications need a way to launch without a Dock icon.
|
||||
System.setProperty("apple.awt.UIElement", "true");
|
||||
|
||||
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true;
|
||||
}
|
||||
|
||||
private boolean oldDisposerDebug;
|
||||
|
||||
@@ -31,5 +31,6 @@
|
||||
<orderEntry type="library" name="intellij-core" level="project" />
|
||||
<orderEntry type="library" name="idea-full" level="project" />
|
||||
<orderEntry type="module" module-name="backend.jvm" />
|
||||
<orderEntry type="library" name="kotlin-reflect" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -52,10 +52,11 @@ public abstract class AbstractCompilerLightClassTest extends KotlinMultiFileTest
|
||||
|
||||
@Override
|
||||
protected void doMultiFileTest(File file, Map<String, ModuleAndDependencies> modules, List<Void> files) throws IOException {
|
||||
KotlinCoreEnvironment environment = createEnvironment();
|
||||
File expectedFile = KotlinTestUtils.replaceExtension(file, "java");
|
||||
LightClassTestCommon.INSTANCE.testLightClass(expectedFile, file, s -> {
|
||||
try {
|
||||
return createFinder(getEnvironment()).findClass(s, GlobalSearchScope.allScope(getEnvironment().getProject()));
|
||||
return createFinder(environment).findClass(s, GlobalSearchScope.allScope(environment.getProject()));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
|
||||
@@ -36,22 +36,19 @@ import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.util.*
|
||||
import kotlin.reflect.jvm.javaField
|
||||
|
||||
abstract class AbstractDiagnosticsTestWithJsStdLib : AbstractDiagnosticsTest() {
|
||||
protected lateinit var config: JsConfig
|
||||
private set
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
config = JsConfig(project, environment.configuration.copy().apply {
|
||||
private var lazyConfig: Lazy<JsConfig>? = lazy(LazyThreadSafetyMode.NONE) {
|
||||
JsConfig(project, environment.configuration.copy().apply {
|
||||
put(CommonConfigurationKeys.MODULE_NAME, KotlinTestUtils.TEST_MODULE_NAME)
|
||||
put(JSConfigurationKeys.LIBRARIES, JsConfig.JS_STDLIB)
|
||||
})
|
||||
}
|
||||
|
||||
protected val config: JsConfig get() = lazyConfig!!.value
|
||||
|
||||
override fun tearDown() {
|
||||
(AbstractDiagnosticsTestWithJsStdLib::config).javaField!!.set(this, null)
|
||||
lazyConfig = null
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
|
||||
+15
-23
@@ -24,22 +24,11 @@ import org.jetbrains.kotlin.codegen.CodegenTestUtil
|
||||
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import org.jetbrains.kotlin.test.*
|
||||
import java.io.File
|
||||
import java.io.StringWriter
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
abstract class AbstractAnnotationProcessorBoxTest : KotlinTestWithEnvironment() {
|
||||
private var javaSourceRoot: File by Delegates.notNull()
|
||||
|
||||
override fun setUp() {
|
||||
javaSourceRoot = KotlinTestUtils.tmpDir("java-files")
|
||||
super.setUp()
|
||||
}
|
||||
|
||||
abstract class AbstractAnnotationProcessorBoxTest : KotlinTestWithEnvironmentManagement() {
|
||||
fun doTest(path: String) {
|
||||
val testDir = File(path)
|
||||
|
||||
@@ -53,9 +42,19 @@ abstract class AbstractAnnotationProcessorBoxTest : KotlinTestWithEnvironment()
|
||||
val supportStubs = testName.contains("stubs", ignoreCase = true)
|
||||
|
||||
val javaFiles = filesByExtension("java")
|
||||
if (javaFiles.isNotEmpty()) {
|
||||
javaFiles.forEach { it.copyTo(File(javaSourceRoot, it.name)) }
|
||||
}
|
||||
val javaSourceRoot =
|
||||
if (javaFiles.isNotEmpty()) {
|
||||
KotlinTestUtils.tmpDir("java-files").also { javaSourceRoot ->
|
||||
javaFiles.forEach { javaFile -> javaFile.copyTo(File(javaSourceRoot, javaFile.name)) }
|
||||
}
|
||||
}
|
||||
else null
|
||||
|
||||
val configuration = KotlinTestUtils.newConfiguration(
|
||||
ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, listOf(KotlinTestUtils.getAnnotationsJar()), listOfNotNull(javaSourceRoot)
|
||||
)
|
||||
val environment = KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||
val project = environment.project
|
||||
|
||||
val collectorExtension = AnnotationCollectorExtensionForTests(supportInheritedAnnotations)
|
||||
ClassBuilderInterceptorExtension.registerExtension(project, collectorExtension)
|
||||
@@ -76,13 +75,6 @@ abstract class AbstractAnnotationProcessorBoxTest : KotlinTestWithEnvironment()
|
||||
KotlinTestUtils.assertEqualsToFile(expectedAnnotationsFile, actualAnnotations)
|
||||
}
|
||||
|
||||
override fun createEnvironment(): KotlinCoreEnvironment {
|
||||
val configuration = KotlinTestUtils.newConfiguration(
|
||||
ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, listOf(KotlinTestUtils.getAnnotationsJar()), listOf(javaSourceRoot)
|
||||
)
|
||||
return KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||
}
|
||||
|
||||
private class AnnotationCollectorExtensionForTests(
|
||||
supportInheritedAnnotations: Boolean
|
||||
) : AnnotationCollectorExtensionBase(supportInheritedAnnotations) {
|
||||
|
||||
Reference in New Issue
Block a user