Implement light classes for Kotlin scripts
This commit is contained in:
+24
-10
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
|||||||
import org.jetbrains.kotlin.asJava.builder.*
|
import org.jetbrains.kotlin.asJava.builder.*
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
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.asJava.classes.KtLightClassForSourceDeclaration
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
@@ -92,10 +93,18 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getContext(): LightClassConstructionContext {
|
override fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade {
|
||||||
return LightClassConstructionContext(bindingContext, module)
|
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> {
|
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||||
return ResolveSessionUtils.getClassDescriptorsByFqName(module, fqName).mapNotNull {
|
return ResolveSessionUtils.getClassDescriptorsByFqName(module, fqName).mapNotNull {
|
||||||
val element = DescriptorToSourceUtils.getSourceFromDescriptor(it)
|
val element = DescriptorToSourceUtils.getSourceFromDescriptor(it)
|
||||||
@@ -143,9 +152,9 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? {
|
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = KtLightClassForSourceDeclaration.create(classOrObject)
|
||||||
return KtLightClassForSourceDeclaration.create(classOrObject)
|
|
||||||
}
|
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
|
||||||
|
|
||||||
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
|
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
|
||||||
return bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
|
return bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
|
||||||
@@ -163,6 +172,16 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
|||||||
KtLightClassForFacade.createForFacade(psiManager, facadeFqName, scope, filesForFacade))
|
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> {
|
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||||
//
|
//
|
||||||
return emptyList()
|
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 {
|
override fun createTrace(): BindingTraceContext {
|
||||||
return NoScopeRecordCliBindingTrace()
|
return NoScopeRecordCliBindingTrace()
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-4
@@ -22,12 +22,10 @@ import com.intellij.psi.PsiClass
|
|||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.asJava.builder.*
|
import org.jetbrains.kotlin.asJava.builder.*
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
typealias LightClassBuilder = (LightClassConstructionContext) -> LightClassBuilderResult
|
typealias LightClassBuilder = (LightClassConstructionContext) -> LightClassBuilderResult
|
||||||
@@ -38,6 +36,8 @@ abstract class LightClassGenerationSupport {
|
|||||||
|
|
||||||
abstract fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade
|
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>
|
abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -61,6 +61,8 @@ abstract class LightClassGenerationSupport {
|
|||||||
|
|
||||||
abstract fun getLightClass(classOrObject: KtClassOrObject): KtLightClass?
|
abstract fun getLightClass(classOrObject: KtClassOrObject): KtLightClass?
|
||||||
|
|
||||||
|
abstract fun getLightClassForScript(script: KtScript): KtLightClassForScript?
|
||||||
|
|
||||||
abstract fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor?
|
abstract fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor?
|
||||||
|
|
||||||
abstract fun analyze(element: KtElement): BindingContext
|
abstract fun analyze(element: KtElement): BindingContext
|
||||||
@@ -69,6 +71,8 @@ abstract class LightClassGenerationSupport {
|
|||||||
|
|
||||||
abstract fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
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 getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||||
|
|
||||||
abstract fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
abstract fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||||
|
|||||||
+5
-1
@@ -53,6 +53,10 @@ interface LightClassDataHolder {
|
|||||||
interface ForFacade : LightClassDataHolder {
|
interface ForFacade : LightClassDataHolder {
|
||||||
fun findDataForFacade(classFqName: FqName): LightClassData = findData { it.findDelegate(classFqName) }
|
fun findDataForFacade(classFqName: FqName): LightClassData = findData { it.findDelegate(classFqName) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ForScript : ForClass {
|
||||||
|
fun findDataForScript(scriptFqName: FqName): LightClassData = findData { it.findDelegate(scriptFqName) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LightClassData {
|
interface LightClassData {
|
||||||
@@ -85,7 +89,7 @@ object InvalidLightClassDataHolder : LightClassDataHolder.ForClass {
|
|||||||
class LightClassDataHolderImpl(
|
class LightClassDataHolderImpl(
|
||||||
override val javaFileStub: PsiJavaFileStub,
|
override val javaFileStub: PsiJavaFileStub,
|
||||||
override val extraDiagnostics: Diagnostics
|
override val extraDiagnostics: Diagnostics
|
||||||
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade {
|
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade, LightClassDataHolder.ForScript {
|
||||||
override fun findData(findDelegate: (PsiJavaFileStub) -> PsiClass) = findDelegate(javaFileStub).let(::LightClassDataImpl)
|
override fun findData(findDelegate: (PsiJavaFileStub) -> PsiClass) = findDelegate(javaFileStub).let(::LightClassDataImpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
@@ -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 {
|
interface StubComputationTracker {
|
||||||
fun onStubComputed(javaFileStub: PsiJavaFileStub, context: LightClassConstructionContext)
|
fun onStubComputed(javaFileStub: PsiJavaFileStub, context: LightClassConstructionContext)
|
||||||
}
|
}
|
||||||
@@ -181,3 +206,17 @@ object ClassFilterForFacade : GenerationState.GenerateClassFilter() {
|
|||||||
override fun shouldGeneratePackagePart(ktFile: KtFile) = true
|
override fun shouldGeneratePackagePart(ktFile: KtFile) = true
|
||||||
override fun shouldGenerateScript(script: KtScript) = false
|
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
|
||||||
|
}
|
||||||
|
|||||||
+161
@@ -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
|
||||||
|
}
|
||||||
+5
-7
@@ -39,10 +39,7 @@ import org.jetbrains.kotlin.asJava.ImpreciseResolveResult
|
|||||||
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE
|
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE
|
||||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||||
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
|
import org.jetbrains.kotlin.asJava.builder.*
|
||||||
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.elements.FakeFileForLightClass
|
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
|
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
|
||||||
@@ -334,7 +331,7 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
|||||||
|
|
||||||
|
|
||||||
fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
|
fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
|
||||||
if (classOrObject.containingKtFile.isScript() || classOrObject.hasModifier(KtTokens.HEADER_KEYWORD)) {
|
if (classOrObject.hasModifier(KtTokens.HEADER_KEYWORD)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,10 +363,11 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getLightClassDataHolder(classOrObject: KtClassOrObject): LightClassDataHolder.ForClass {
|
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 =
|
var value =
|
||||||
getOutermostClassOrObject(classOrObject).getUserData(JAVA_API_STUB) // stub computed for outer class can be used for inner/nested
|
getOutermostClassOrObject(classOrObject).getUserData(JAVA_API_STUB) // stub computed for outer class can be used for inner/nested
|
||||||
?: classOrObject.getUserData(JAVA_API_STUB)
|
?: classOrObject.getUserData(JAVA_API_STUB)
|
||||||
|
|||||||
+1
-5
@@ -33,10 +33,7 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport;
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.name.FqNamesUtilKt;
|
import org.jetbrains.kotlin.name.FqNamesUtilKt;
|
||||||
import org.jetbrains.kotlin.psi.KtClass;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
|
||||||
import org.jetbrains.kotlin.psi.KtEnumEntry;
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile;
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker;
|
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -90,7 +87,6 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
|||||||
FqName qualifiedName = new FqName(qualifiedNameString);
|
FqName qualifiedName = new FqName(qualifiedNameString);
|
||||||
|
|
||||||
findClassesAndObjects(qualifiedName, scope, answer);
|
findClassesAndObjects(qualifiedName, scope, answer);
|
||||||
|
|
||||||
answer.addAll(lightClassGenerationSupport.getFacadeClasses(qualifiedName, scope));
|
answer.addAll(lightClassGenerationSupport.getFacadeClasses(qualifiedName, scope));
|
||||||
answer.addAll(lightClassGenerationSupport.getKotlinInternalClasses(qualifiedName, scope));
|
answer.addAll(lightClassGenerationSupport.getKotlinInternalClasses(qualifiedName, scope));
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.intellij.psi.*
|
|||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
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.KtLightAnnotationForSourceEntry
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
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
|
.firstOrNull { it is KtLightClassForFacade && this in it.files } as? KtLightClass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KtScript.toLightClass(): KtLightClassForScript? = LightClassGenerationSupport.getInstance(project).getLightClassForScript(this)
|
||||||
|
|
||||||
fun KtElement.toLightElements(): List<PsiNamedElement> =
|
fun KtElement.toLightElements(): List<PsiNamedElement> =
|
||||||
when (this) {
|
when (this) {
|
||||||
is KtClassOrObject -> listOfNotNull(toLightClass())
|
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,
|
expectedFile: File,
|
||||||
testDataFile: File,
|
testDataFile: File,
|
||||||
findLightClass: (String) -> PsiClass?,
|
findLightClass: (String) -> PsiClass?,
|
||||||
normalizeText: (String) -> String = { it }
|
normalizeText: (String) -> String
|
||||||
) {
|
) {
|
||||||
val text = FileUtil.loadFile(testDataFile, true)
|
val text = FileUtil.loadFile(testDataFile, true)
|
||||||
val matcher = SUBJECT_FQ_NAME_PATTERN.matcher(text)
|
val matcher = SUBJECT_FQ_NAME_PATTERN.matcher(text)
|
||||||
@@ -57,8 +57,8 @@ object LightClassTestCommon {
|
|||||||
|
|
||||||
val buffer = StringBuilder()
|
val buffer = StringBuilder()
|
||||||
(delegate as ClsElementImpl).appendMirrorText(0, buffer)
|
(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
|
// Actual text for light class is generated with ClsElementImpl.appendMirrorText() that can find empty DefaultImpl inner class in stubs
|
||||||
|
|||||||
+2
-2
@@ -81,7 +81,7 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KtUsefulTestCase
|
|||||||
CollectionsKt.plus(Collections.singletonList(KotlinTestUtils.getAnnotationsJar()), getExtraClasspath()),
|
CollectionsKt.plus(Collections.singletonList(KotlinTestUtils.getAnnotationsJar()), getExtraClasspath()),
|
||||||
isJavaSourceRootNeeded() ? Collections.singletonList(javaFilesDir) : Collections.emptyList()
|
isJavaSourceRootNeeded() ? Collections.singletonList(javaFilesDir) : Collections.emptyList()
|
||||||
);
|
);
|
||||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition.INSTANCE);
|
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition.INSTANCE);
|
||||||
if (isKotlinSourceRootNeeded()) {
|
if (isKotlinSourceRootNeeded()) {
|
||||||
ContentRootsKt.addKotlinSourceRoot(configuration, kotlinSourceRoot.getPath());
|
ContentRootsKt.addKotlinSourceRoot(configuration, kotlinSourceRoot.getPath());
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KtUsefulTestCase
|
|||||||
writeSourceFile(fileName, text, javaFilesDir);
|
writeSourceFile(fileName, text, javaFilesDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileName.endsWith(".kt") && kotlinSourceRoot != null) {
|
if ((fileName.endsWith(".kt") || fileName.endsWith(".kts")) && kotlinSourceRoot != null) {
|
||||||
writeSourceFile(fileName, text, kotlinSourceRoot);
|
writeSourceFile(fileName, text, kotlinSourceRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ public class KotlinTestUtils {
|
|||||||
else {
|
else {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
for (File childFile : file.listFiles()) {
|
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));
|
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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,63 +14,50 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.asJava;
|
package org.jetbrains.kotlin.asJava
|
||||||
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
import com.intellij.psi.PsiClass
|
||||||
import org.jetbrains.annotations.NotNull;
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder;
|
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||||
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava;
|
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
import java.io.File;
|
abstract class AbstractCompilerLightClassTest : KotlinMultiFileTestWithJava<Void, Void>() {
|
||||||
import java.io.IOException;
|
override fun getConfigurationKind(): ConfigurationKind = ConfigurationKind.ALL
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public abstract class AbstractCompilerLightClassTest extends KotlinMultiFileTestWithJava<Void, Void> {
|
override fun isKotlinSourceRootNeeded(): Boolean = true
|
||||||
@NotNull
|
|
||||||
@Override
|
override fun doMultiFileTest(file: File, modules: MutableMap<String, ModuleAndDependencies>, files: MutableList<Void>) {
|
||||||
protected ConfigurationKind getConfigurationKind() {
|
val environment = createEnvironment(file)
|
||||||
return ConfigurationKind.ALL;
|
val expectedFile = KotlinTestUtils.replaceExtension(file, "java")
|
||||||
|
LightClassTestCommon.testLightClass(
|
||||||
|
expectedFile,
|
||||||
|
file,
|
||||||
|
{ fqname -> findLightClass(environment, fqname) },
|
||||||
|
LightClassTestCommon::removeEmptyDefaultImpls
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun createTestModule(name: String): Void? = null
|
||||||
protected boolean isKotlinSourceRootNeeded() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
override fun createTestFile(module: Void?, fileName: String, text: String, directives: Map<String, String>): Void? = null
|
||||||
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);
|
|
||||||
|
|
||||||
return JavaElementFinder.getInstance(environment.getProject());
|
companion object {
|
||||||
}
|
fun findLightClass(environment: KotlinCoreEnvironment, fqname: String): PsiClass? {
|
||||||
|
KotlinTestUtils.resolveAllKotlinFiles(environment)
|
||||||
|
|
||||||
@Override
|
val lightCLassForScript = LightClassGenerationSupport
|
||||||
protected void doMultiFileTest(File file, Map<String, ModuleAndDependencies> modules, List<Void> files) throws IOException {
|
.getInstance(environment.project)
|
||||||
KotlinCoreEnvironment environment = createEnvironment(file);
|
.getScriptClasses(FqName(fqname), GlobalSearchScope.allScope(environment.project))
|
||||||
File expectedFile = KotlinTestUtils.replaceExtension(file, "java");
|
.firstOrNull()
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
return lightCLassForScript ?: JavaElementFinder
|
||||||
protected Void createTestModule(@NotNull String name) {
|
.getInstance(environment.project)
|
||||||
return null;
|
.findClass(fqname, GlobalSearchScope.allScope(environment.project))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Void createTestFile(Void module, String fileName, String text, Map<String, String> directives) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassTest {
|
public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassTest {
|
||||||
public void testAllFilesPresentInLightClasses() throws Exception {
|
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")
|
@TestMetadata("AnnotationClass.kt")
|
||||||
@@ -155,7 +155,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class CompilationErrors extends AbstractCompilerLightClassTest {
|
public static class CompilationErrors extends AbstractCompilerLightClassTest {
|
||||||
public void testAllFilesPresentInCompilationErrors() throws Exception {
|
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")
|
@TestMetadata("AnnotationModifiers.kt")
|
||||||
@@ -206,7 +206,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Delegation extends AbstractCompilerLightClassTest {
|
public static class Delegation extends AbstractCompilerLightClassTest {
|
||||||
public void testAllFilesPresentInDelegation() throws Exception {
|
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")
|
@TestMetadata("Function.kt")
|
||||||
@@ -220,12 +220,6 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/delegation/Property.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/delegation/Property.kt");
|
||||||
doTest(fileName);
|
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")
|
@TestMetadata("compiler/testData/asJava/lightClasses/facades")
|
||||||
@@ -233,13 +227,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Facades extends AbstractCompilerLightClassTest {
|
public static class Facades extends AbstractCompilerLightClassTest {
|
||||||
public void testAllFilesPresentInFacades() throws Exception {
|
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("EmptyFile.NoCompile.kt")
|
|
||||||
public void testEmptyFile_NoCompile() throws Exception {
|
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/facades/EmptyFile.NoCompile.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("MultiFile.kt")
|
@TestMetadata("MultiFile.kt")
|
||||||
@@ -266,7 +254,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class NullabilityAnnotations extends AbstractCompilerLightClassTest {
|
public static class NullabilityAnnotations extends AbstractCompilerLightClassTest {
|
||||||
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
|
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")
|
@TestMetadata("Class.kt")
|
||||||
@@ -383,7 +371,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Object extends AbstractCompilerLightClassTest {
|
public static class Object extends AbstractCompilerLightClassTest {
|
||||||
public void testAllFilesPresentInObject() throws Exception {
|
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")
|
@TestMetadata("SimpleObject.kt")
|
||||||
@@ -398,7 +386,7 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class PublicField extends AbstractCompilerLightClassTest {
|
public static class PublicField extends AbstractCompilerLightClassTest {
|
||||||
public void testAllFilesPresentInPublicField() throws Exception {
|
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")
|
@TestMetadata("CompanionObject.kt")
|
||||||
@@ -413,4 +401,25 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
|||||||
doTest(fileName);
|
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
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
KotlinCoreEnvironment environment = getEnvironment();
|
||||||
finder = AbstractCompilerLightClassTest.createFinder(getEnvironment());
|
KotlinTestUtils.resolveAllKotlinFiles(environment);
|
||||||
|
finder = JavaElementFinder.getInstance(environment.getProject());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -197,6 +197,8 @@ import java.util.*
|
|||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
@Language("RegExp") private val KT_OR_KTS = """^(.+)\.(kt|kts)$"""
|
@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$"""
|
@Language("RegExp") private val KT_WITHOUT_DOTS_IN_NAME = """^([^.]+)\.kt$"""
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
@@ -467,7 +469,7 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractCompilerLightClassTest> {
|
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> {
|
testClass<AbstractTypeBindingTest> {
|
||||||
@@ -1129,11 +1131,11 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractIdeLightClassTest> {
|
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> {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-4
@@ -27,10 +27,7 @@ import org.jetbrains.kotlin.asJava.LightClassBuilder
|
|||||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||||
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
|
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
|
||||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
||||||
import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage
|
import org.jetbrains.kotlin.asJava.classes.*
|
||||||
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.finder.JavaElementFinder
|
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
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> {
|
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||||
return runReadAction {
|
return runReadAction {
|
||||||
KotlinFullClassNameIndex.getInstance().get(fqName.asString(), project, sourceAndClassFiles(searchScope, project))
|
KotlinFullClassNameIndex.getInstance().get(fqName.asString(), project, sourceAndClassFiles(searchScope, project))
|
||||||
@@ -131,6 +136,8 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
|
||||||
|
|
||||||
private fun withFakeLightClasses(
|
private fun withFakeLightClasses(
|
||||||
lightClassForFacade: KtLightClassForFacade?,
|
lightClassForFacade: KtLightClassForFacade?,
|
||||||
facadeFiles: List<KtFile>
|
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> {
|
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||||
if (fqName.isRoot) return emptyList()
|
if (fqName.isRoot) return emptyList()
|
||||||
|
|
||||||
|
|||||||
+35
-9
@@ -129,6 +129,21 @@ object IDELightClassContexts {
|
|||||||
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, EXACT)
|
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? {
|
fun lightContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext? {
|
||||||
if (!isDummyResolveApplicable(classOrObject)) return null
|
if (!isDummyResolveApplicable(classOrObject)) return null
|
||||||
|
|
||||||
@@ -139,6 +154,26 @@ object IDELightClassContexts {
|
|||||||
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, LIGHT)
|
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 {
|
private fun isDummyResolveApplicable(classOrObject: KtClassOrObject): Boolean {
|
||||||
if (classOrObject.hasLightClassMatchingErrors) return false
|
if (classOrObject.hasLightClassMatchingErrors) return false
|
||||||
|
|
||||||
@@ -193,15 +228,6 @@ object IDELightClassContexts {
|
|||||||
return result
|
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) {
|
fun forceResolvePackageDeclarations(files: Collection<KtFile>, session: ResolveSession) {
|
||||||
for (file in files) {
|
for (file in files) {
|
||||||
if (file.isScript()) continue
|
if (file.isScript()) continue
|
||||||
|
|||||||
+4
@@ -74,6 +74,10 @@ sealed class LazyLightClassDataHolder(
|
|||||||
builder: LightClassBuilder, exactContextProvider: ExactLightClassContextProvider, dummyContextProvider: DummyLightClassContextProvider
|
builder: LightClassBuilder, exactContextProvider: ExactLightClassContextProvider, dummyContextProvider: DummyLightClassContextProvider
|
||||||
) : LazyLightClassDataHolder(builder, exactContextProvider, dummyContextProvider), LightClassDataHolder.ForFacade
|
) : LazyLightClassDataHolder(builder, exactContextProvider, dummyContextProvider), LightClassDataHolder.ForFacade
|
||||||
|
|
||||||
|
class ForScript(
|
||||||
|
builder: LightClassBuilder, exactContextProvider: ExactLightClassContextProvider, dummyContextProvider: DummyLightClassContextProvider
|
||||||
|
) : LazyLightClassDataHolder(builder, exactContextProvider, dummyContextProvider), LightClassDataHolder.ForScript
|
||||||
|
|
||||||
private inner class LazyLightClassData(
|
private inner class LazyLightClassData(
|
||||||
findDelegate: (LightClassBuilderResult) -> PsiClass
|
findDelegate: (LightClassBuilderResult) -> PsiClass
|
||||||
) : LightClassData {
|
) : 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.KtLightClassForFacade
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||||
import org.jetbrains.kotlin.asJava.elements.*
|
import org.jetbrains.kotlin.asJava.elements.*
|
||||||
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.idea.KotlinDaemonAnalyzerTestCase
|
import org.jetbrains.kotlin.idea.KotlinDaemonAnalyzerTestCase
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.LightClassLazinessChecker.Tracker.Level.*
|
import org.jetbrains.kotlin.idea.caches.resolve.LightClassLazinessChecker.Tracker.Level.*
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.IDELightClassConstructionContext
|
import org.jetbrains.kotlin.idea.caches.resolve.lightClasses.IDELightClassConstructionContext
|
||||||
@@ -53,9 +54,13 @@ import kotlin.test.assertTrue
|
|||||||
|
|
||||||
abstract class AbstractIdeLightClassTest : KotlinLightCodeInsightFixtureTestCase() {
|
abstract class AbstractIdeLightClassTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||||
fun doTest(testDataPath: String) {
|
fun doTest(testDataPath: String) {
|
||||||
val extraFilePath = testDataPath.replace(".kt", ".extra.kt")
|
val extraFilePath = when {
|
||||||
val testFiles = if (File(extraFilePath).isFile) listOf(testDataPath, extraFilePath) else listOf(testDataPath)
|
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)
|
val lazinessMode = lazinessModeByFileText(testDataPath)
|
||||||
myFixture.configureByFiles(*testFiles.toTypedArray())
|
myFixture.configureByFiles(*testFiles.toTypedArray())
|
||||||
@@ -91,11 +96,13 @@ abstract class AbstractIdeCompiledLightClassTest : KotlinDaemonAnalyzerTestCase(
|
|||||||
val testName = getTestName(false)
|
val testName = getTestName(false)
|
||||||
if (KotlinTestUtils.isAllFilesPresentTest(testName)) return
|
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) + "!/"
|
val jarUrl = "jar://" + FileUtilRt.toSystemIndependentName(libraryJar.absolutePath) + "!/"
|
||||||
ModuleRootModificationUtil.addModuleLibrary(module, jarUrl)
|
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 s1", "java.lang.String p1")
|
||||||
.replace("java.lang.String s2", "java.lang.String p2")
|
.replace("java.lang.String s2", "java.lang.String p2")
|
||||||
.replace("java.lang.Object o)", "java.lang.Object p)")
|
.replace("java.lang.Object o)", "java.lang.Object p)")
|
||||||
|
.replace("java.lang.String[] strings", "java.lang.String[] p")
|
||||||
.removeLinesStartingWith("@" + JvmAnnotationNames.METADATA_FQ_NAME.asString())
|
.removeLinesStartingWith("@" + JvmAnnotationNames.METADATA_FQ_NAME.asString())
|
||||||
.run(normalize)
|
.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? {
|
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)) ?:
|
return JavaPsiFacade.getInstance(project).findClass(fqName, GlobalSearchScope.allScope(project)) ?:
|
||||||
PsiTreeUtil.findChildrenOfType(ktFile, KtClassOrObject::class.java)
|
PsiTreeUtil.findChildrenOfType(ktFile, KtClassOrObject::class.java)
|
||||||
.find { fqName.endsWith(it.nameAsName!!.asString()) }
|
.find { fqName.endsWith(it.nameAsName!!.asString()) }
|
||||||
|
|||||||
+27
-6
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLightClassTest {
|
public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLightClassTest {
|
||||||
public void testAllFilesPresentInLightClasses() throws Exception {
|
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")
|
@TestMetadata("AnnotationClass.kt")
|
||||||
@@ -155,7 +155,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Delegation extends AbstractIdeCompiledLightClassTest {
|
public static class Delegation extends AbstractIdeCompiledLightClassTest {
|
||||||
public void testAllFilesPresentInDelegation() throws Exception {
|
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")
|
@TestMetadata("Function.kt")
|
||||||
@@ -176,7 +176,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Facades extends AbstractIdeCompiledLightClassTest {
|
public static class Facades extends AbstractIdeCompiledLightClassTest {
|
||||||
public void testAllFilesPresentInFacades() throws Exception {
|
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")
|
@TestMetadata("MultiFile.kt")
|
||||||
@@ -203,7 +203,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class NullabilityAnnotations extends AbstractIdeCompiledLightClassTest {
|
public static class NullabilityAnnotations extends AbstractIdeCompiledLightClassTest {
|
||||||
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
|
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")
|
@TestMetadata("Class.kt")
|
||||||
@@ -320,7 +320,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Object extends AbstractIdeCompiledLightClassTest {
|
public static class Object extends AbstractIdeCompiledLightClassTest {
|
||||||
public void testAllFilesPresentInObject() throws Exception {
|
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")
|
@TestMetadata("SimpleObject.kt")
|
||||||
@@ -335,7 +335,7 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class PublicField extends AbstractIdeCompiledLightClassTest {
|
public static class PublicField extends AbstractIdeCompiledLightClassTest {
|
||||||
public void testAllFilesPresentInPublicField() throws Exception {
|
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")
|
@TestMetadata("CompanionObject.kt")
|
||||||
@@ -350,4 +350,25 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
|||||||
doTest(fileName);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-8
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||||
public void testAllFilesPresentInLightClasses() throws Exception {
|
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")
|
@TestMetadata("AnnotationClass.kt")
|
||||||
@@ -155,7 +155,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class CompilationErrors extends AbstractIdeLightClassTest {
|
public static class CompilationErrors extends AbstractIdeLightClassTest {
|
||||||
public void testAllFilesPresentInCompilationErrors() throws Exception {
|
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")
|
@TestMetadata("AnnotationModifiers.kt")
|
||||||
@@ -206,7 +206,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Facades extends AbstractIdeLightClassTest {
|
public static class Facades extends AbstractIdeLightClassTest {
|
||||||
public void testAllFilesPresentInFacades() throws Exception {
|
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")
|
@TestMetadata("MultiFile.kt")
|
||||||
@@ -233,7 +233,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class IdeRegression extends AbstractIdeLightClassTest {
|
public static class IdeRegression extends AbstractIdeLightClassTest {
|
||||||
public void testAllFilesPresentInIdeRegression() throws Exception {
|
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")
|
@TestMetadata("AllOpenAnnotatedClasses.kt")
|
||||||
@@ -290,7 +290,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Local extends AbstractIdeLightClassTest {
|
public static class Local extends AbstractIdeLightClassTest {
|
||||||
public void testAllFilesPresentInLocal() throws Exception {
|
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")
|
@TestMetadata("DollarsInNameLocal.kt")
|
||||||
@@ -305,7 +305,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class NullabilityAnnotations extends AbstractIdeLightClassTest {
|
public static class NullabilityAnnotations extends AbstractIdeLightClassTest {
|
||||||
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
|
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")
|
@TestMetadata("Class.kt")
|
||||||
@@ -422,7 +422,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Object extends AbstractIdeLightClassTest {
|
public static class Object extends AbstractIdeLightClassTest {
|
||||||
public void testAllFilesPresentInObject() throws Exception {
|
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")
|
@TestMetadata("SimpleObject.kt")
|
||||||
@@ -437,7 +437,7 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class PublicField extends AbstractIdeLightClassTest {
|
public static class PublicField extends AbstractIdeLightClassTest {
|
||||||
public void testAllFilesPresentInPublicField() throws Exception {
|
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")
|
@TestMetadata("CompanionObject.kt")
|
||||||
@@ -452,4 +452,25 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
|||||||
doTest(fileName);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user