Implement light classes for Kotlin scripts

This commit is contained in:
Vyacheslav Gerasimov
2017-09-04 15:30:47 +03:00
parent 26cbcfa1ac
commit 89257e6397
25 changed files with 495 additions and 139 deletions
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.*
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -92,10 +93,18 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
)
}
private fun getContext(): LightClassConstructionContext {
return LightClassConstructionContext(bindingContext, module)
override fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade {
val (stub, _, diagnostics) = builder(getContext())
return LightClassDataHolderImpl(stub, diagnostics)
}
override fun createDataHolderForScript(script: KtScript, builder: LightClassBuilder): LightClassDataHolder.ForScript {
val (stub, _, diagnostics) = builder(getContext())
return LightClassDataHolderImpl(stub, diagnostics)
}
private fun getContext(): LightClassConstructionContext = LightClassConstructionContext(bindingContext, module)
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
return ResolveSessionUtils.getClassDescriptorsByFqName(module, fqName).mapNotNull {
val element = DescriptorToSourceUtils.getSourceFromDescriptor(it)
@@ -143,9 +152,9 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
})
}
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? {
return KtLightClassForSourceDeclaration.create(classOrObject)
}
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = KtLightClassForSourceDeclaration.create(classOrObject)
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
return bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
@@ -163,6 +172,16 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
KtLightClassForFacade.createForFacade(psiManager, facadeFqName, scope, filesForFacade))
}
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
if (scriptFqName.isRoot) {
return emptyList()
}
return findFilesForPackage(scriptFqName.parent(), scope).mapNotNull { file ->
file.script?.takeIf { it.fqName == scriptFqName }?.let { it -> getLightClassForScript(it) }
}
}
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
//
return emptyList()
@@ -176,11 +195,6 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
}
}
override fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade {
val (stub, _, diagnostics) = builder(getContext())
return LightClassDataHolderImpl(stub, diagnostics)
}
override fun createTrace(): BindingTraceContext {
return NoScopeRecordCliBindingTrace()
}
@@ -22,12 +22,10 @@ import com.intellij.psi.PsiClass
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.asJava.builder.*
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
typealias LightClassBuilder = (LightClassConstructionContext) -> LightClassBuilderResult
@@ -38,6 +36,8 @@ abstract class LightClassGenerationSupport {
abstract fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade
abstract fun createDataHolderForScript(script: KtScript, builder: LightClassBuilder): LightClassDataHolder.ForScript
abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
/*
@@ -61,6 +61,8 @@ abstract class LightClassGenerationSupport {
abstract fun getLightClass(classOrObject: KtClassOrObject): KtLightClass?
abstract fun getLightClassForScript(script: KtScript): KtLightClassForScript?
abstract fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor?
abstract fun analyze(element: KtElement): BindingContext
@@ -69,6 +71,8 @@ abstract class LightClassGenerationSupport {
abstract fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
abstract fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
abstract fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
abstract fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
@@ -53,6 +53,10 @@ interface LightClassDataHolder {
interface ForFacade : LightClassDataHolder {
fun findDataForFacade(classFqName: FqName): LightClassData = findData { it.findDelegate(classFqName) }
}
interface ForScript : ForClass {
fun findDataForScript(scriptFqName: FqName): LightClassData = findData { it.findDelegate(scriptFqName) }
}
}
interface LightClassData {
@@ -85,7 +89,7 @@ object InvalidLightClassDataHolder : LightClassDataHolder.ForClass {
class LightClassDataHolderImpl(
override val javaFileStub: PsiJavaFileStub,
override val extraDiagnostics: Diagnostics
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade {
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade, LightClassDataHolder.ForScript {
override fun findData(findDelegate: (PsiJavaFileStub) -> PsiClass) = findDelegate(javaFileStub).let(::LightClassDataImpl)
}
@@ -128,6 +128,31 @@ sealed class LightClassDataProviderForFileFacade constructor(
}
class LightClassDataProviderForScript(private val script: KtScript) : CachedValueProvider<LightClassDataHolder.ForScript> {
private fun computeLightClassData(): LightClassDataHolder.ForScript {
return LightClassGenerationSupport.getInstance(script.project).createDataHolderForScript(script) {
constructionContext ->
buildLightClass(
script.fqName.parent(),
listOf(script.containingKtFile),
ClassFilterForScript(script),
constructionContext
) generate@ {
state, files ->
val scriptFile = files.first()
val codegen = state.factory.forPackage(scriptFile.packageFqName, files)
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION)
state.factory.done()
}
}
}
override fun compute(): CachedValueProvider.Result<LightClassDataHolder.ForScript>? =
CachedValueProvider.Result.create(computeLightClassData(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT)
override fun toString(): String = this::class.java.name + " for ${script.fqName}"
}
interface StubComputationTracker {
fun onStubComputed(javaFileStub: PsiJavaFileStub, context: LightClassConstructionContext)
}
@@ -181,3 +206,17 @@ object ClassFilterForFacade : GenerationState.GenerateClassFilter() {
override fun shouldGeneratePackagePart(ktFile: KtFile) = true
override fun shouldGenerateScript(script: KtScript) = false
}
private class ClassFilterForScript(val script: KtScript) : GenerationState.GenerateClassFilter() {
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean =
shouldGenerateClass(processingClassOrObject)
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean =
processingClassOrObject.isAncestor(script, true)
override fun shouldGenerateClassMembers(processingClassOrObject: KtClassOrObject): Boolean = true
override fun shouldGeneratePackagePart(ktFile: KtFile): Boolean = script.containingKtFile === ktFile
override fun shouldGenerateScript(script: KtScript): Boolean = this.script === script
}
@@ -0,0 +1,161 @@
/*
* Copyright 2010-2017 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.asJava.classes
import com.intellij.openapi.util.Comparing
import com.intellij.openapi.util.Key
import com.intellij.psi.*
import com.intellij.psi.impl.light.LightEmptyImplementsList
import com.intellij.psi.impl.light.LightModifierList
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForScript
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtScript
import javax.swing.Icon
class KtLightClassForScript private constructor(
val script: KtScript,
private val lightClassDataCache: CachedValue<LightClassDataHolder.ForScript>
) : KtLazyLightClass(script.manager) {
private val hashCode: Int = computeHashCode()
private val packageFqName: FqName = script.fqName.parent()
private val modifierList: PsiModifierList = LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC)
private val implementsList: LightEmptyImplementsList = LightEmptyImplementsList(manager)
private val _containingFile by lazyPub {
FakeFileForLightClass(
script.containingKtFile,
lightClass = { this },
stub = { lightClassDataCache.value.javaFileStub },
packageFqName = packageFqName)
}
override val kotlinOrigin: KtClassOrObject? get() = null
val fqName: FqName = script.fqName
override fun getModifierList() = modifierList
override fun hasModifierProperty(@NonNls name: String) = modifierList.hasModifierProperty(name)
override fun isDeprecated() = false
override fun isInterface() = false
override fun isAnnotationType() = false
override fun isEnum() = false
override fun getContainingClass() = null
override fun getContainingFile() = _containingFile
override fun hasTypeParameters() = false
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
override fun getTypeParameterList() = null
override fun getDocComment() = null
override fun getImplementsList() = implementsList
override fun getImplementsListTypes(): Array<PsiClassType> = PsiClassType.EMPTY_ARRAY
override fun getInterfaces(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
override fun getOwnInnerClasses(): List<PsiClass> {
return script.declarations.filterIsInstance<KtClassOrObject>()
// workaround for ClassInnerStuffCache not supporting classes with null names, see KT-13927
// inner classes with null names can't be searched for and can't be used from java anyway
// we can't prohibit creating light classes with null names either since they can contain members
.filter { it.name != null }
.mapNotNull { KtLightClassForSourceDeclaration.create(it) }
}
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
override fun getName() = script.fqName.shortName().asString()
override fun getQualifiedName() = script.fqName.asString()
override fun isValid() = script.isValid
override fun copy() = KtLightClassForScript(script, lightClassDataCache)
override val lightClassData = lightClassDataCache.value.findDataForScript(script.fqName)
override fun getNavigationElement() = script
override fun isEquivalentTo(another: PsiElement?): Boolean =
another is PsiClass && Comparing.equal(another.qualifiedName, qualifiedName)
override fun getElementIcon(flags: Int): Icon? = throw UnsupportedOperationException("This should be done by JetIconProvider")
override fun hashCode() = hashCode
private fun computeHashCode(): Int {
var result = manager.hashCode()
result = 31 * result + script.hashCode()
return result
}
override fun equals(other: Any?): Boolean {
if (other == null || this::class.java != other::class.java) {
return false
}
val lightClass = other as KtLightClassForScript
if (this === other) return true
if (this.hashCode != lightClass.hashCode) return false
if (manager != lightClass.manager) return false
if (script != lightClass.script) return false
return true
}
override fun toString() = "${KtLightClassForScript::class.java.simpleName}:${script.fqName}"
companion object {
private val JAVA_API_STUB_FOR_SCRIPT = Key.create<CachedValue<LightClassDataHolder.ForScript>>("JAVA_API_STUB_FOR_SCRIPT")
fun create(script: KtScript): KtLightClassForScript = KtLightClassForScript(script, getLightClassCachedValue(script))
fun getLightClassCachedValue(script: KtScript): CachedValue<LightClassDataHolder.ForScript> {
return script.getUserData(JAVA_API_STUB_FOR_SCRIPT) ?:
createCachedValueForScript(script).also { script.putUserData(JAVA_API_STUB_FOR_SCRIPT, it) }
}
private fun createCachedValueForScript(script: KtScript): CachedValue<LightClassDataHolder.ForScript> =
CachedValuesManager.getManager(script.project).createCachedValue(LightClassDataProviderForScript(script), false)
}
override val originKind: LightClassOriginKind get() = LightClassOriginKind.SOURCE
}
@@ -39,10 +39,7 @@ import org.jetbrains.kotlin.asJava.ImpreciseResolveResult
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject
import org.jetbrains.kotlin.asJava.builder.*
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
@@ -334,7 +331,7 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
if (classOrObject.containingKtFile.isScript() || classOrObject.hasModifier(KtTokens.HEADER_KEYWORD)) {
if (classOrObject.hasModifier(KtTokens.HEADER_KEYWORD)) {
return null
}
@@ -366,10 +363,11 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
}
fun getLightClassDataHolder(classOrObject: KtClassOrObject): LightClassDataHolder.ForClass {
return getLightClassCachedValue(classOrObject).value
return classOrObject.containingKtFile.script?.let { KtLightClassForScript.getLightClassCachedValue(it).value } ?:
getLightClassCachedValue(classOrObject).value
}
fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<LightClassDataHolder.ForClass> {
private fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<LightClassDataHolder.ForClass> {
var value =
getOutermostClassOrObject(classOrObject).getUserData(JAVA_API_STUB) // stub computed for outer class can be used for inner/nested
?: classOrObject.getUserData(JAVA_API_STUB)
@@ -33,10 +33,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNamesUtilKt;
import org.jetbrains.kotlin.psi.KtClass;
import org.jetbrains.kotlin.psi.KtClassOrObject;
import org.jetbrains.kotlin.psi.KtEnumEntry;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker;
import java.util.Collection;
@@ -90,7 +87,6 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
FqName qualifiedName = new FqName(qualifiedNameString);
findClassesAndObjects(qualifiedName, scope, answer);
answer.addAll(lightClassGenerationSupport.getFacadeClasses(qualifiedName, scope));
answer.addAll(lightClassGenerationSupport.getKotlinInternalClasses(qualifiedName, scope));
@@ -20,6 +20,7 @@ import com.intellij.psi.*
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
import org.jetbrains.kotlin.asJava.elements.KtLightAnnotationForSourceEntry
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
@@ -52,6 +53,8 @@ fun KtFile.findFacadeClass(): KtLightClass? {
.firstOrNull { it is KtLightClassForFacade && this in it.files } as? KtLightClass
}
fun KtScript.toLightClass(): KtLightClassForScript? = LightClassGenerationSupport.getInstance(project).getLightClassForScript(this)
fun KtElement.toLightElements(): List<PsiNamedElement> =
when (this) {
is KtClassOrObject -> listOfNotNull(toLightClass())
@@ -0,0 +1,3 @@
public class HelloWorld extends kotlin.script.templates.standard.ScriptTemplateWithArgs {
public HelloWorld(java.lang.String[] p) { /* compiled code */ }
}
@@ -0,0 +1,3 @@
// HelloWorld
println("Hello world!")
@@ -0,0 +1,22 @@
public class InnerClasses extends kotlin.script.templates.standard.ScriptTemplateWithArgs {
public InnerClasses(java.lang.String[] p) { /* compiled code */ }
public static final class Bar {
private final int b = 0;
private final int a;
public final int getB() { /* compiled code */ }
public final int getAPlusB() { /* compiled code */ }
public final int getA() { /* compiled code */ }
public Bar(int a) { /* compiled code */ }
public static final class Baz {
public final void doSomething() { /* compiled code */ }
public Baz() { /* compiled code */ }
}
}
}
@@ -0,0 +1,13 @@
// InnerClasses
class Bar(val a: Int) {
val b: Int = 0
fun getAPlusB() = a + b
class Baz {
fun doSomething() {
}
}
}
@@ -33,7 +33,7 @@ object LightClassTestCommon {
expectedFile: File,
testDataFile: File,
findLightClass: (String) -> PsiClass?,
normalizeText: (String) -> String = { it }
normalizeText: (String) -> String
) {
val text = FileUtil.loadFile(testDataFile, true)
val matcher = SUBJECT_FQ_NAME_PATTERN.matcher(text)
@@ -57,8 +57,8 @@ object LightClassTestCommon {
val buffer = StringBuilder()
(delegate as ClsElementImpl).appendMirrorText(0, buffer)
val actual = normalizeText(buffer.toString())
return actual
return normalizeText(buffer.toString())
}
// Actual text for light class is generated with ClsElementImpl.appendMirrorText() that can find empty DefaultImpl inner class in stubs
@@ -81,7 +81,7 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KtUsefulTestCase
CollectionsKt.plus(Collections.singletonList(KotlinTestUtils.getAnnotationsJar()), getExtraClasspath()),
isJavaSourceRootNeeded() ? Collections.singletonList(javaFilesDir) : Collections.emptyList()
);
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition.INSTANCE);
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition.INSTANCE);
if (isKotlinSourceRootNeeded()) {
ContentRootsKt.addKotlinSourceRoot(configuration, kotlinSourceRoot.getPath());
}
@@ -157,7 +157,7 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KtUsefulTestCase
writeSourceFile(fileName, text, javaFilesDir);
}
if (fileName.endsWith(".kt") && kotlinSourceRoot != null) {
if ((fileName.endsWith(".kt") || fileName.endsWith(".kts")) && kotlinSourceRoot != null) {
writeSourceFile(fileName, text, kotlinSourceRoot);
}
@@ -563,7 +563,7 @@ public class KotlinTestUtils {
else {
//noinspection ConstantConditions
for (File childFile : file.listFiles()) {
if (childFile.getName().endsWith(".kt")) {
if (childFile.getName().endsWith(".kt") || childFile.getName().endsWith(".kts")) {
ktFiles.add(loadJetFile(environment.getProject(), childFile));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -14,63 +14,50 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.asJava;
package org.jetbrains.kotlin.asJava
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder;
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.test.ConfigurationKind;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
import com.intellij.psi.PsiClass
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
abstract class AbstractCompilerLightClassTest : KotlinMultiFileTestWithJava<Void, Void>() {
override fun getConfigurationKind(): ConfigurationKind = ConfigurationKind.ALL
public abstract class AbstractCompilerLightClassTest extends KotlinMultiFileTestWithJava<Void, Void> {
@NotNull
@Override
protected ConfigurationKind getConfigurationKind() {
return ConfigurationKind.ALL;
override fun isKotlinSourceRootNeeded(): Boolean = true
override fun doMultiFileTest(file: File, modules: MutableMap<String, ModuleAndDependencies>, files: MutableList<Void>) {
val environment = createEnvironment(file)
val expectedFile = KotlinTestUtils.replaceExtension(file, "java")
LightClassTestCommon.testLightClass(
expectedFile,
file,
{ fqname -> findLightClass(environment, fqname) },
LightClassTestCommon::removeEmptyDefaultImpls
)
}
@Override
protected boolean isKotlinSourceRootNeeded() {
return true;
}
override fun createTestModule(name: String): Void? = null
@NotNull
public static JavaElementFinder createFinder(@NotNull KotlinCoreEnvironment environment) throws IOException {
// We need to resolve all the files in order too fill in the trace that sits inside LightClassGenerationSupport
KotlinTestUtils.resolveAllKotlinFiles(environment);
override fun createTestFile(module: Void?, fileName: String, text: String, directives: Map<String, String>): Void? = null
return JavaElementFinder.getInstance(environment.getProject());
}
companion object {
fun findLightClass(environment: KotlinCoreEnvironment, fqname: String): PsiClass? {
KotlinTestUtils.resolveAllKotlinFiles(environment)
@Override
protected void doMultiFileTest(File file, Map<String, ModuleAndDependencies> modules, List<Void> files) throws IOException {
KotlinCoreEnvironment environment = createEnvironment(file);
File expectedFile = KotlinTestUtils.replaceExtension(file, "java");
LightClassTestCommon.INSTANCE.testLightClass(expectedFile, file, s -> {
try {
return createFinder(environment).findClass(s, GlobalSearchScope.allScope(environment.getProject()));
}
catch (IOException e) {
throw ExceptionUtilsKt.rethrow(e);
}
}, LightClassTestCommon.INSTANCE::removeEmptyDefaultImpls);
}
val lightCLassForScript = LightClassGenerationSupport
.getInstance(environment.project)
.getScriptClasses(FqName(fqname), GlobalSearchScope.allScope(environment.project))
.firstOrNull()
@Override
protected Void createTestModule(@NotNull String name) {
return null;
}
@Override
protected Void createTestFile(Void module, String fileName, String text, Map<String, String> directives) {
return null;
return lightCLassForScript ?: JavaElementFinder
.getInstance(environment.project)
.findClass(fqname, GlobalSearchScope.allScope(environment.project))
}
}
}
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
@RunWith(JUnit3RunnerWithInners.class)
public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassTest {
public void testAllFilesPresentInLightClasses() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true, "local", "ideRegression");
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true, "local", "ideRegression");
}
@TestMetadata("AnnotationClass.kt")
@@ -155,7 +155,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
@RunWith(JUnit3RunnerWithInners.class)
public static class CompilationErrors extends AbstractCompilerLightClassTest {
public void testAllFilesPresentInCompilationErrors() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/compilationErrors"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/compilationErrors"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("AnnotationModifiers.kt")
@@ -206,7 +206,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
@RunWith(JUnit3RunnerWithInners.class)
public static class Delegation extends AbstractCompilerLightClassTest {
public void testAllFilesPresentInDelegation() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("Function.kt")
@@ -220,12 +220,6 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/delegation/Property.kt");
doTest(fileName);
}
@TestMetadata("WithPlatformTypes.NoCompile.kt")
public void testWithPlatformTypes_NoCompile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/delegation/WithPlatformTypes.NoCompile.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/asJava/lightClasses/facades")
@@ -233,13 +227,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
@RunWith(JUnit3RunnerWithInners.class)
public static class Facades extends AbstractCompilerLightClassTest {
public void testAllFilesPresentInFacades() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("EmptyFile.NoCompile.kt")
public void testEmptyFile_NoCompile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/facades/EmptyFile.NoCompile.kt");
doTest(fileName);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("MultiFile.kt")
@@ -266,7 +254,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
@RunWith(JUnit3RunnerWithInners.class)
public static class NullabilityAnnotations extends AbstractCompilerLightClassTest {
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("Class.kt")
@@ -383,7 +371,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
@RunWith(JUnit3RunnerWithInners.class)
public static class Object extends AbstractCompilerLightClassTest {
public void testAllFilesPresentInObject() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("SimpleObject.kt")
@@ -398,7 +386,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
@RunWith(JUnit3RunnerWithInners.class)
public static class PublicField extends AbstractCompilerLightClassTest {
public void testAllFilesPresentInPublicField() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("CompanionObject.kt")
@@ -413,4 +401,25 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
doTest(fileName);
}
}
@TestMetadata("compiler/testData/asJava/lightClasses/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Script extends AbstractCompilerLightClassTest {
public void testAllFilesPresentInScript() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/script"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("HelloWorld.kts")
public void testHelloWorld() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/HelloWorld.kts");
doTest(fileName);
}
@TestMetadata("InnerClasses.kts")
public void testInnerClasses() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/InnerClasses.kts");
doTest(fileName);
}
}
}
@@ -54,8 +54,9 @@ public abstract class KotlinAsJavaTestBase extends KotlinTestWithEnvironment {
@Override
protected void setUp() throws Exception {
super.setUp();
finder = AbstractCompilerLightClassTest.createFinder(getEnvironment());
KotlinCoreEnvironment environment = getEnvironment();
KotlinTestUtils.resolveAllKotlinFiles(environment);
finder = JavaElementFinder.getInstance(environment.getProject());
}
@Override
@@ -197,6 +197,8 @@ import java.util.*
import java.util.regex.Pattern
@Language("RegExp") private val KT_OR_KTS = """^(.+)\.(kt|kts)$"""
@Language("RegExp") private val KT_OR_KTS_WITHOUT_DOTS_IN_NAME = """^([^.]+)\.(kt|kts)$"""
@Language("RegExp") private val KT_WITHOUT_DOTS_IN_NAME = """^([^.]+)\.kt$"""
fun main(args: Array<String>) {
@@ -467,7 +469,7 @@ fun main(args: Array<String>) {
}
testClass<AbstractCompilerLightClassTest> {
model("asJava/lightClasses", excludeDirs = listOf("local", "ideRegression"))
model("asJava/lightClasses", excludeDirs = listOf("local", "ideRegression"), pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME)
}
testClass<AbstractTypeBindingTest> {
@@ -1129,11 +1131,11 @@ fun main(args: Array<String>) {
}
testClass<AbstractIdeLightClassTest> {
model("asJava/lightClasses", excludeDirs = listOf("delegation"), pattern = KT_WITHOUT_DOTS_IN_NAME)
model("asJava/lightClasses", excludeDirs = listOf("delegation"), pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME)
}
testClass<AbstractIdeCompiledLightClassTest> {
model("asJava/lightClasses", excludeDirs = listOf("local", "compilationErrors", "ideRegression"), pattern = KT_WITHOUT_DOTS_IN_NAME)
model("asJava/lightClasses", excludeDirs = listOf("local", "compilationErrors", "ideRegression"), pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME)
}
}
@@ -27,10 +27,7 @@ import org.jetbrains.kotlin.asJava.LightClassBuilder
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
@@ -84,6 +81,14 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
)
}
override fun createDataHolderForScript(script: KtScript, builder: LightClassBuilder): LightClassDataHolder.ForScript {
return LazyLightClassDataHolder.ForScript(
builder,
exactContextProvider = { IDELightClassContexts.contextForScript(script) },
dummyContextProvider = { IDELightClassContexts.lightContextForScript(script) }
)
}
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
return runReadAction {
KotlinFullClassNameIndex.getInstance().get(fqName.asString(), project, sourceAndClassFiles(searchScope, project))
@@ -131,6 +136,8 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
return null
}
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
private fun withFakeLightClasses(
lightClassForFacade: KtLightClassForFacade?,
facadeFiles: List<KtFile>
@@ -155,6 +162,12 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
}
}
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
return KotlinScriptFqnIndex.instance.get(scriptFqName.asString(), project, scope).mapNotNull {
getLightClassForScript(it)
}
}
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
if (fqName.isRoot) return emptyList()
@@ -129,6 +129,21 @@ object IDELightClassContexts {
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, EXACT)
}
fun contextForScript(script: KtScript): LightClassConstructionContext {
val resolutionFacade = script.getResolutionFacade()
val bindingContext = resolutionFacade.analyze(script)
val descriptor = bindingContext[BindingContext.SCRIPT, script]
if (descriptor == null) {
LOG.warn("No script descriptor in context for script: " + script.getElementTextWithContext())
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, EXACT)
}
ForceResolveUtil.forceResolveAllContents(descriptor)
return IDELightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor, EXACT)
}
fun lightContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext? {
if (!isDummyResolveApplicable(classOrObject)) return null
@@ -139,6 +154,26 @@ object IDELightClassContexts {
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, LIGHT)
}
fun lightContextForFacade(files: List<KtFile>): LightClassConstructionContext {
val representativeFile = files.first()
val resolveSession = setupAdHocResolve(representativeFile.project, representativeFile.getResolutionFacade().moduleDescriptor, files)
forceResolvePackageDeclarations(files, resolveSession)
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, LIGHT)
}
fun lightContextForScript(script: KtScript): LightClassConstructionContext {
val resolveSession = setupAdHocResolve(
script.project,
script.getResolutionFacade().moduleDescriptor,
listOf(script.containingKtFile))
ForceResolveUtil.forceResolveAllContents(resolveSession.resolveToDescriptor(script))
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, LIGHT)
}
private fun isDummyResolveApplicable(classOrObject: KtClassOrObject): Boolean {
if (classOrObject.hasLightClassMatchingErrors) return false
@@ -193,15 +228,6 @@ object IDELightClassContexts {
return result
}
fun lightContextForFacade(files: List<KtFile>): LightClassConstructionContext {
val representativeFile = files.first()
val resolveSession = setupAdHocResolve(representativeFile.project, representativeFile.getResolutionFacade().moduleDescriptor, files)
forceResolvePackageDeclarations(files, resolveSession)
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, LIGHT)
}
fun forceResolvePackageDeclarations(files: Collection<KtFile>, session: ResolveSession) {
for (file in files) {
if (file.isScript()) continue
@@ -74,6 +74,10 @@ sealed class LazyLightClassDataHolder(
builder: LightClassBuilder, exactContextProvider: ExactLightClassContextProvider, dummyContextProvider: DummyLightClassContextProvider
) : LazyLightClassDataHolder(builder, exactContextProvider, dummyContextProvider), LightClassDataHolder.ForFacade
class ForScript(
builder: LightClassBuilder, exactContextProvider: ExactLightClassContextProvider, dummyContextProvider: DummyLightClassContextProvider
) : LazyLightClassDataHolder(builder, exactContextProvider, dummyContextProvider), LightClassDataHolder.ForScript
private inner class LazyLightClassData(
findDelegate: (LightClassBuilderResult) -> PsiClass
) : LightClassData {
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.idea.KotlinDaemonAnalyzerTestCase
import org.jetbrains.kotlin.idea.caches.resolve.LightClassLazinessChecker.Tracker.Level.*
import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.IDELightClassConstructionContext
@@ -53,9 +54,13 @@ import kotlin.test.assertTrue
abstract class AbstractIdeLightClassTest : KotlinLightCodeInsightFixtureTestCase() {
fun doTest(testDataPath: String) {
val extraFilePath = testDataPath.replace(".kt", ".extra.kt")
val testFiles = if (File(extraFilePath).isFile) listOf(testDataPath, extraFilePath) else listOf(testDataPath)
val extraFilePath = when {
testDataPath.endsWith(".kt") -> testDataPath.replace(".kt", ".extra.kt")
testDataPath.endsWith(".kts") -> testDataPath.replace(".kts", ".extra.kts")
else -> error("Invalid test data extension")
}
val testFiles = if (File(extraFilePath).isFile) listOf(testDataPath, extraFilePath) else listOf(testDataPath)
val lazinessMode = lazinessModeByFileText(testDataPath)
myFixture.configureByFiles(*testFiles.toTypedArray())
@@ -91,11 +96,13 @@ abstract class AbstractIdeCompiledLightClassTest : KotlinDaemonAnalyzerTestCase(
val testName = getTestName(false)
if (KotlinTestUtils.isAllFilesPresentTest(testName)) return
val filePath = "${KotlinTestUtils.getTestsRoot(this::class.java)}/${getTestName(false)}.kt"
val filePathWithoutExtension = "${KotlinTestUtils.getTestsRoot(this::class.java)}/${getTestName(false)}"
val testFile = File("$filePathWithoutExtension.kt").takeIf { it.exists() } ?:
File("$filePathWithoutExtension.kts").takeIf { it.exists() }
Assert.assertTrue("File doesn't exist $filePath", File(filePath).exists())
Assert.assertNotNull("Test file not found!", testFile)
val libraryJar = MockLibraryUtil.compileJvmLibraryToJar(filePath, libName())
val libraryJar = MockLibraryUtil.compileJvmLibraryToJar(testFile!!.canonicalPath, libName())
val jarUrl = "jar://" + FileUtilRt.toSystemIndependentName(libraryJar.absolutePath) + "!/"
ModuleRootModificationUtil.addModuleLibrary(module, jarUrl)
}
@@ -128,6 +135,7 @@ private fun testLightClass(expected: File, testData: File, normalize: (String) -
.replace("java.lang.String s1", "java.lang.String p1")
.replace("java.lang.String s2", "java.lang.String p2")
.replace("java.lang.Object o)", "java.lang.Object p)")
.replace("java.lang.String[] strings", "java.lang.String[] p")
.removeLinesStartingWith("@" + JvmAnnotationNames.METADATA_FQ_NAME.asString())
.run(normalize)
}
@@ -135,6 +143,10 @@ private fun testLightClass(expected: File, testData: File, normalize: (String) -
}
private fun findClass(fqName: String, ktFile: KtFile?, project: Project): PsiClass? {
ktFile?.script?.let {
return it.toLightClass()
}
return JavaPsiFacade.getInstance(project).findClass(fqName, GlobalSearchScope.allScope(project)) ?:
PsiTreeUtil.findChildrenOfType(ktFile, KtClassOrObject::class.java)
.find { fqName.endsWith(it.nameAsName!!.asString()) }
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
@RunWith(JUnit3RunnerWithInners.class)
public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLightClassTest {
public void testAllFilesPresentInLightClasses() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true, "local", "compilationErrors", "ideRegression");
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true, "local", "compilationErrors", "ideRegression");
}
@TestMetadata("AnnotationClass.kt")
@@ -155,7 +155,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
@RunWith(JUnit3RunnerWithInners.class)
public static class Delegation extends AbstractIdeCompiledLightClassTest {
public void testAllFilesPresentInDelegation() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("Function.kt")
@@ -176,7 +176,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
@RunWith(JUnit3RunnerWithInners.class)
public static class Facades extends AbstractIdeCompiledLightClassTest {
public void testAllFilesPresentInFacades() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("MultiFile.kt")
@@ -203,7 +203,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
@RunWith(JUnit3RunnerWithInners.class)
public static class NullabilityAnnotations extends AbstractIdeCompiledLightClassTest {
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("Class.kt")
@@ -320,7 +320,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
@RunWith(JUnit3RunnerWithInners.class)
public static class Object extends AbstractIdeCompiledLightClassTest {
public void testAllFilesPresentInObject() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("SimpleObject.kt")
@@ -335,7 +335,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
@RunWith(JUnit3RunnerWithInners.class)
public static class PublicField extends AbstractIdeCompiledLightClassTest {
public void testAllFilesPresentInPublicField() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("CompanionObject.kt")
@@ -350,4 +350,25 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
doTest(fileName);
}
}
@TestMetadata("compiler/testData/asJava/lightClasses/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Script extends AbstractIdeCompiledLightClassTest {
public void testAllFilesPresentInScript() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/script"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("HelloWorld.kts")
public void testHelloWorld() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/HelloWorld.kts");
doTest(fileName);
}
@TestMetadata("InnerClasses.kts")
public void testInnerClasses() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/InnerClasses.kts");
doTest(fileName);
}
}
}
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
@RunWith(JUnit3RunnerWithInners.class)
public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
public void testAllFilesPresentInLightClasses() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true, "delegation");
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true, "delegation");
}
@TestMetadata("AnnotationClass.kt")
@@ -155,7 +155,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
@RunWith(JUnit3RunnerWithInners.class)
public static class CompilationErrors extends AbstractIdeLightClassTest {
public void testAllFilesPresentInCompilationErrors() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/compilationErrors"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/compilationErrors"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("AnnotationModifiers.kt")
@@ -206,7 +206,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
@RunWith(JUnit3RunnerWithInners.class)
public static class Facades extends AbstractIdeLightClassTest {
public void testAllFilesPresentInFacades() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("MultiFile.kt")
@@ -233,7 +233,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
@RunWith(JUnit3RunnerWithInners.class)
public static class IdeRegression extends AbstractIdeLightClassTest {
public void testAllFilesPresentInIdeRegression() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/ideRegression"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/ideRegression"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("AllOpenAnnotatedClasses.kt")
@@ -290,7 +290,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
@RunWith(JUnit3RunnerWithInners.class)
public static class Local extends AbstractIdeLightClassTest {
public void testAllFilesPresentInLocal() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/local"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/local"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("DollarsInNameLocal.kt")
@@ -305,7 +305,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
@RunWith(JUnit3RunnerWithInners.class)
public static class NullabilityAnnotations extends AbstractIdeLightClassTest {
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("Class.kt")
@@ -422,7 +422,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
@RunWith(JUnit3RunnerWithInners.class)
public static class Object extends AbstractIdeLightClassTest {
public void testAllFilesPresentInObject() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("SimpleObject.kt")
@@ -437,7 +437,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
@RunWith(JUnit3RunnerWithInners.class)
public static class PublicField extends AbstractIdeLightClassTest {
public void testAllFilesPresentInPublicField() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("CompanionObject.kt")
@@ -452,4 +452,25 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
doTest(fileName);
}
}
@TestMetadata("compiler/testData/asJava/lightClasses/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Script extends AbstractIdeLightClassTest {
public void testAllFilesPresentInScript() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/script"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("HelloWorld.kts")
public void testHelloWorld() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/HelloWorld.kts");
doTest(fileName);
}
@TestMetadata("InnerClasses.kts")
public void testInnerClasses() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/script/InnerClasses.kts");
doTest(fileName);
}
}
}