[light classes] drop old light classes and backend: iteration #1

drop clsDelegate and related

^KT-48773
This commit is contained in:
Dmitry Gridin
2022-06-20 14:42:24 +02:00
committed by Space
parent d42c9d833f
commit 3cb2df9360
61 changed files with 387 additions and 2000 deletions
@@ -1,4 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.decompiled.light.classes
@@ -23,7 +26,7 @@ import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.psi.KtClassOrObject
open class KtLightClassForDecompiledDeclaration(
override val clsDelegate: PsiClass,
clsDelegate: PsiClass,
private val clsParent: PsiElement,
private val file: KtClsFile,
kotlinOrigin: KtClassOrObject?
@@ -1,4 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.decompiled.light.classes
@@ -9,7 +12,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightElementBase
import org.jetbrains.kotlin.psi.KtClassOrObject
abstract class KtLightClassForDecompiledDeclarationBase(
override val clsDelegate: PsiClass,
val clsDelegate: PsiClass,
clsParent: PsiElement,
final override val kotlinOrigin: KtClassOrObject?
) : KtLightElementBase(clsParent), PsiClass, KtExtensibleLightClass
@@ -1,4 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.decompiled.light.classes
@@ -67,7 +70,5 @@ open class KtLightFieldForDecompiledDeclaration(
override fun toString(): String = "${this.javaClass.simpleName} of $fldParent"
override val clsDelegate: PsiField = fldDelegate
override fun isValid(): Boolean = parent.isValid
}
@@ -1,4 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.decompiled.light.classes
@@ -97,8 +100,6 @@ class KtLightMethodForDecompiledDeclaration(
override fun toString(): String = "${this.javaClass.simpleName} of $funParent"
override val clsDelegate: PsiMethod = funDelegate
override fun isValid(): Boolean = parent.isValid
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -21,9 +21,6 @@ internal abstract class FirLightMemberImpl<T : PsiMember>(
private val containingClass: KtLightClass,
) : KtLightElementBase(containingClass), PsiMember, KtLightMember<T> {
override val clsDelegate: T
get() = invalidAccess()
override fun hasModifierProperty(name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false
override fun toString(): String = "${this::class.java.simpleName}:$name"
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -15,9 +15,6 @@ import org.jetbrains.kotlin.psi.*
internal abstract class FirLightAbstractAnnotation(parent: PsiElement) :
KtLightElementBase(parent), PsiAnnotation, KtLightElement<KtCallElement, PsiAnnotation> {
override val clsDelegate: PsiAnnotation
get() = invalidAccess()
override fun getOwner() = parent as? PsiAnnotationOwner
private val KtExpression.nameReference: KtNameReferenceExpression?
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.light.classes.symbol
@@ -30,19 +19,16 @@ import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.PsiUtil
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.light.classes.symbol.classes.checkIsInheritor
import javax.swing.Icon
abstract class FirLightClassBase protected constructor(
manager: PsiManager
) : LightElement(manager, KotlinLanguage.INSTANCE), PsiClass, KtExtensibleLightClass {
override val clsDelegate: PsiClass
get() = invalidAccess()
private class FirLightClassesLazyCreator(private val project: Project) : KotlinClassInnerStuffCache.LazyCreator() {
@OptIn(KtAllowAnalysisOnEdt::class)
override fun <T : Any> get(initializer: () -> T, dependencies: List<Any>): Lazy<T> = object : Lazy<T> {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -10,6 +10,12 @@ import com.intellij.psi.*
import com.intellij.psi.impl.light.LightEmptyImplementsList
import com.intellij.psi.impl.light.LightModifierList
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.analysis.api.scopes.KtScope
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
@@ -18,12 +24,6 @@ import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.analysis.api.scopes.KtScope
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
import org.jetbrains.kotlin.light.classes.symbol.classes.analyseForLightClasses
import org.jetbrains.kotlin.light.classes.symbol.classes.createField
import org.jetbrains.kotlin.light.classes.symbol.classes.createMethods
@@ -50,8 +50,6 @@ class FirLightClassForFacade(
private val firstFileInFacade by lazyPub { files.first() }
override val clsDelegate: PsiClass get() = invalidAccess()
private val fileSymbols by lazyPub {
files.map { ktFile ->
analyseForLightClasses(ktFile) {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
internal class KtLightClassForDecompiledFacade(
override val clsDelegate: PsiClass,
clsDelegate: PsiClass,
clsParent: PsiElement,
file: KtClsFile,
kotlinOrigin: KtClassOrObject?,
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -24,9 +24,6 @@ internal abstract class FirLightField protected constructor(
private val containingClass: KtLightClass,
lightMemberOrigin: LightMemberOrigin?,
) : FirLightMemberImpl<PsiField>(lightMemberOrigin, containingClass), KtLightField {
override val clsDelegate: PsiField get() = invalidAccess()
override fun setInitializer(initializer: PsiExpression?) = cannotModify()
override fun isEquivalentTo(another: PsiElement?): Boolean =
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -20,9 +20,6 @@ internal abstract class FirLightModifierList<out T : KtLightElement<KtModifierLi
protected val owner: T
) : KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierListOwner> {
override val clsDelegate: PsiModifierListOwner
get() = invalidAccess()
override val kotlinOrigin: KtModifierList?
get() = owner.kotlinOrigin?.modifierList
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -16,9 +16,6 @@ import org.jetbrains.kotlin.psi.KtParameter
internal abstract class FirLightParameter(containingDeclaration: FirLightMethod) : PsiVariable, NavigationItem,
KtLightElement<KtParameter, PsiParameter>, KtLightParameter, KtLightElementBase(containingDeclaration) {
override val clsDelegate: PsiParameter
get() = invalidAccess()
override val givenAnnotations: List<KtLightAbstractAnnotation>
get() = invalidAccess()
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -8,10 +8,10 @@ package org.jetbrains.kotlin.light.classes.symbol
import com.intellij.psi.PsiParameter
import com.intellij.psi.PsiParameterList
import com.intellij.psi.impl.light.LightParameterListBuilder
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightElementBase
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtParameterList
@@ -28,7 +28,7 @@ internal class FirLightParameterList(
override val kotlinOrigin: KtParameterList?
get() = (parent.kotlinOrigin as? KtFunction)?.valueParameterList
override val clsDelegate: PsiParameterList by lazyPub {
private val clsDelegate: PsiParameterList by lazyPub {
val builder = LightParameterListBuilder(manager, language)
callableSymbol?.let {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -35,8 +35,6 @@ internal class FirLightTypeParameter(
) : LightElement(parent.manager, KotlinLanguage.INSTANCE), PsiTypeParameter,
KtLightDeclaration<KtTypeParameter, PsiTypeParameter> {
override val clsDelegate: PsiTypeParameter get() = invalidAccess()
override val givenAnnotations: List<KtLightAbstractAnnotation>? get() = invalidAccess()
override val kotlinOrigin: KtTypeParameter? = typeParameterSymbol.psi as? KtTypeParameter
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -13,7 +13,6 @@ import com.intellij.psi.search.PsiSearchScopeUtil
import com.intellij.util.SmartList
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer
@@ -109,11 +108,9 @@ class CliKotlinAsJavaSupport(
).mapNotNull { member -> (member as? PackageViewDescriptor)?.fqName }
}
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? =
KtLightClassForSourceDeclaration.create(classOrObject, traceHolder.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode))
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = KtLightClassForSourceDeclaration.create(classOrObject)
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? =
KtLightClassForScript.create(script)
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
return ResolveSessionUtils.getClassDescriptorsByFqName(traceHolder.module, fqName).mapNotNull {
@@ -130,6 +127,5 @@ class CliKotlinAsJavaSupport(
}.orEmpty()
}
override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass =
error("Should not be called")
override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass = error("Should not be called")
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.cli.jvm.compiler
@@ -30,7 +19,6 @@ import org.jetbrains.kotlin.asJava.classes.tryGetPredefinedName
import org.jetbrains.kotlin.codegen.ClassBuilderMode
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -105,9 +93,6 @@ class CliLightClassGenerationSupport(
return ultraLightSupport
}
override val useUltraLightClasses: Boolean
get() = !KtUltraLightSupport.forceUsingOldLightClasses && !traceHolder.languageVersionSettings.getFlag(JvmAnalysisFlags.disableUltraLightClasses)
override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {
//force resolve companion for light class generation
traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
@@ -1,27 +1,13 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiConstantEvaluationHelper
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiManager
import com.intellij.psi.util.CachedValue
import org.jetbrains.kotlin.asJava.builder.LightClassBuilderResult
import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
@@ -59,18 +45,11 @@ abstract class LightClassGenerationSupport {
ConstantExpressionEvaluator(moduleDescriptor, languageVersionSettings, expression.project)
}
abstract val useUltraLightClasses: Boolean
internal fun canCreateUltraLightClassForFacade(
files: Collection<KtFile>,
): Boolean {
return useUltraLightClasses && files.none { it.isScript() }
}
internal fun canCreateUltraLightClassForFacade(files: Collection<KtFile>): Boolean = files.none { it.isScript() }
fun createUltraLightClassForFacade(
manager: PsiManager,
facadeClassFqName: FqName,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
files: Collection<KtFile>,
): KtUltraLightClassForFacade? {
if (!canCreateUltraLightClassForFacade(files)) return null
@@ -82,16 +61,12 @@ abstract class LightClassGenerationSupport {
return KtUltraLightClassForFacade(
manager,
facadeClassFqName,
lightClassDataCache,
files,
filesToSupports
)
}
fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? {
if (!useUltraLightClasses) return null
if (element.shouldNotBeVisibleAsLightClass()) {
return null
}
@@ -117,8 +92,8 @@ abstract class LightClassGenerationSupport {
}
}
fun createUltraLightClassForScript(script: KtScript): KtUltraLightClassForScript? =
if (useUltraLightClasses) KtUltraLightClassForScript(script, support = getUltraLightClassSupport(script)) else null
fun createUltraLightClassForScript(script: KtScript): KtUltraLightClassForScript =
KtUltraLightClassForScript(script, support = getUltraLightClassSupport(script))
companion object {
@JvmStatic
@@ -1,22 +1,14 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava
import com.intellij.psi.*
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiField
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.impl.java.stubs.PsiClassStub
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.PsiFileStub
@@ -24,7 +16,10 @@ import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.elements.isSetter
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.load.java.JvmAbi
@@ -217,23 +212,6 @@ object LightClassUtil {
)
}
fun buildLightTypeParameterList(
owner: PsiTypeParameterListOwner,
declaration: KtDeclaration
): PsiTypeParameterList {
val builder = KotlinLightTypeParameterListBuilder(owner)
if (declaration is KtTypeParameterListOwner) {
val parameters = declaration.typeParameters
for (i in parameters.indices) {
val jetTypeParameter = parameters[i]
val name = jetTypeParameter.name
val safeName = name ?: "__no_name__"
builder.addParameter(KtLightTypeParameter(owner, i, safeName))
}
}
return builder
}
class PropertyAccessorsPsiMethods(
val getter: PsiMethod?,
val setter: PsiMethod?,
@@ -1,70 +1,20 @@
/*
* Copyright 2000-2017 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.builder
import com.intellij.openapi.diagnostic.ControlFlowException
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiClassType
import com.intellij.psi.impl.DebugUtil
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.stubs.StubElement
import org.jetbrains.kotlin.asJava.LightClassUtil.findClass
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightFieldImpl
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.debugText.getDebugText
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
interface LightClassDataHolder {
val javaFileStub: PsiJavaFileStub
val extraDiagnostics: Diagnostics
fun findData(findDelegate: (PsiJavaFileStub) -> PsiClass): LightClassData
interface ForClass : LightClassDataHolder {
fun findDataForDefaultImpls(classOrObject: KtClassOrObject) = findData {
it.findDelegate(classOrObject).findInnerClassByName(JvmAbi.DEFAULT_IMPLS_CLASS_NAME, false)
?: throw IllegalStateException("Couldn't get delegate for $this\n in ${DebugUtil.stubTreeToString(it)}")
}
fun findDataForClassOrObject(classOrObject: KtClassOrObject): LightClassData = findData { it.findDelegate(classOrObject) }
}
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 {
val clsDelegate: PsiClass
val supertypes: Array<PsiClassType>
get() {
return clsDelegate.superTypes
}
fun getOwnFields(containingClass: KtLightClass): List<KtLightField>
fun getOwnMethods(containingClass: KtLightClass): List<KtLightMethod>
}
class LightClassDataImpl(override val clsDelegate: PsiClass) : LightClassData {
override fun getOwnFields(containingClass: KtLightClass) = KtLightFieldImpl.fromClsFields(clsDelegate, containingClass)
override fun getOwnMethods(containingClass: KtLightClass) = KtLightMethodImpl.fromClsMethods(clsDelegate, containingClass)
interface ForClass : LightClassDataHolder
interface ForFacade : LightClassDataHolder
interface ForScript : ForClass
}
object InvalidLightClassDataHolder : LightClassDataHolder.ForClass {
@@ -74,50 +24,10 @@ object InvalidLightClassDataHolder : LightClassDataHolder.ForClass {
override val extraDiagnostics: Diagnostics
get() = shouldNotBeCalled()
override fun findData(findDelegate: (PsiJavaFileStub) -> PsiClass) = shouldNotBeCalled()
private fun shouldNotBeCalled(): Nothing = throw UnsupportedOperationException("Should not be called")
}
class LightClassDataHolderImpl(
override val javaFileStub: PsiJavaFileStub,
override val extraDiagnostics: Diagnostics
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade, LightClassDataHolder.ForScript {
override fun findData(findDelegate: (PsiJavaFileStub) -> PsiClass) = findDelegate(javaFileStub).let(::LightClassDataImpl)
}
fun PsiJavaFileStub.findDelegate(classOrObject: KtClassOrObject): PsiClass {
findClass(this) {
ClsWrapperStubPsiFactory.getOriginalElement(it as StubElement<*>) == classOrObject
}?.let { return it }
val outermostClassOrObject = getOutermostClassOrObject(classOrObject)
val ktFileText: String? = try {
outermostClassOrObject.containingFile.text
} catch (e: Exception) {
if (e is ControlFlowException) throw e
"Can't get text for outermost class"
}
val stubFileText = DebugUtil.stubTreeToString(this)
throw KotlinExceptionWithAttachments("Couldn't get delegate for class")
.withAttachment(classOrObject.name ?: "unnamed class or object", classOrObject.getDebugText())
.withAttachment("file.kt", ktFileText)
.withAttachment("stub text", stubFileText)
}
fun PsiJavaFileStub.findDelegate(classFqName: FqName): PsiClass {
return findClass(this) {
classFqName.asString() == it.qualifiedName
} ?: throw IllegalStateException("Facade class $classFqName not found; classes in Java file stub: ${collectClassNames(this)}")
}
private fun collectClassNames(javaFileStub: PsiJavaFileStub): String {
val names = mutableListOf<String>()
findClass(javaFileStub) { cls ->
names.add(cls.qualifiedName ?: "<null>")
false
}
return names.joinToString(prefix = "[", postfix = "]")
}
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade, LightClassDataHolder.ForScript
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -11,15 +11,9 @@ import com.intellij.psi.*
import com.intellij.psi.impl.PsiClassImplUtil
import com.intellij.psi.impl.PsiImplUtil
import com.intellij.psi.impl.PsiSuperMethodImplUtil
import com.intellij.psi.impl.compiled.ClsClassImpl
import com.intellij.psi.impl.compiled.InnerClassSourceStrategy
import com.intellij.psi.impl.compiled.StubBuildingVisitor
import com.intellij.psi.impl.java.stubs.PsiClassStub
import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl
import com.intellij.psi.impl.light.*
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.*
import com.intellij.util.ArrayUtil
import com.intellij.util.IncorrectOperationException
@@ -31,10 +25,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightParameter
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.org.objectweb.asm.Opcodes
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
class KotlinClassInnerStuffCache(
private val myClass: KtExtensibleLightClass,
@@ -200,8 +191,6 @@ private class KotlinEnumSyntheticMethod(
val nameParameter = object : LightParameter("name", stringType, this, language, false), KtLightParameter {
override val method: KtLightMethod get() = this@KotlinEnumSyntheticMethod
override val kotlinOrigin: KtParameter? get() = null
override val clsDelegate: PsiParameter get() = this@KotlinEnumSyntheticMethod.clsDelegate.parameterList.parameters.single()
override fun getParent(): PsiElement = this@KotlinEnumSyntheticMethod
override fun getContainingFile(): PsiFile = this@KotlinEnumSyntheticMethod.containingFile
@@ -285,52 +274,7 @@ private class KotlinEnumSyntheticMethod(
override fun getText(): String = ""
override fun getTextRange(): TextRange = TextRange.EMPTY_RANGE
// As you can see, the implementation is quite dumb, yet it is still better than throwing an exception,
// as 'clsDelegate' is used for verifying light class consistency.
// See 'org.jetbrains.kotlin.idea.caches.resolve.LightClassLazinessChecker.LazinessInfo#checkConsistency' for more information.
override val clsDelegate: PsiMethod by lazy {
val emptyStrategy = object : InnerClassSourceStrategy<PsiClass> {
override fun findInnerClass(innerName: String, outerClass: PsiClass): PsiClass? = null
override fun accept(innerClass: PsiClass, visitor: StubBuildingVisitor<PsiClass>) {}
}
val containingFile = enumClass.containingFile as PsiJavaFile
var parent = PsiJavaFileStubImpl(containingFile, containingFile.packageName, null, true) as StubElement<*>
fun process(clazz: PsiClass): PsiClassStub<*> {
clazz.containingClass?.let { process(it) }
val access = getAccess(clazz)
val superName = clazz.superClass?.let { ClassUtil.getJVMClassName(it) } ?: "java/lang/Object"
val interfaceNames = clazz.interfaces.mapNotNull { ClassUtil.getJVMClassName(it) }.toTypedArray()
val stub = StubBuildingVisitor(clazz, emptyStrategy, parent, access, clazz.name).apply {
visit(Opcodes.V1_8, access, ClassUtil.getJVMClassName(clazz), null, superName, interfaceNames)
visitEnd()
}.result
parent = stub
return stub
}
ClsClassImpl(process(enumClass)).methods.single { it.name == name }
}
private companion object {
private fun getAccess(clazz: PsiClass): Int {
var result = 0
if (clazz.hasModifierProperty(PsiModifier.PUBLIC)) result = result or Opcodes.ACC_PUBLIC
if (clazz.hasModifierProperty(PsiModifier.PROTECTED)) result = result or Opcodes.ACC_PROTECTED
if (clazz.hasModifierProperty(PsiModifier.PRIVATE)) result = result or Opcodes.ACC_PRIVATE
if (clazz.hasModifierProperty(PsiModifier.FINAL)) result = result or Opcodes.ACC_FINAL
if (clazz.hasModifierProperty(PsiModifier.ABSTRACT)) result = result or Opcodes.ACC_ABSTRACT
if (clazz.isDeprecated) result = result or Opcodes.ACC_DEPRECATED
if (clazz.isEnum) result = result or Opcodes.ACC_ENUM
if (clazz.isAnnotationType) result = result or Opcodes.ACC_ANNOTATION
if (clazz.isInterface) result = result or Opcodes.ACC_INTERFACE
return result
}
private fun makeNotNullAnnotation(context: PsiClass): PsiAnnotation {
return PsiElementFactory.getInstance(context.project).createAnnotationFromText("@" + NotNull::class.java.name, context)
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -33,7 +33,6 @@ abstract class KtFakeLightClass(override val kotlinOrigin: KtClassOrObject) :
private val _delegate: PsiClass by lazy { DummyJavaPsiFactory.createDummyClass(kotlinOrigin.project) }
override val clsDelegate get() = _delegate
override val originKind get() = LightClassOriginKind.SOURCE
override fun getName(): String? = kotlinOrigin.name
@@ -93,7 +92,6 @@ class KtFakeLightMethod private constructor(
KotlinLanguage.INSTANCE
), KtLightElement<KtNamedDeclaration, PsiMethod> {
override val kotlinOrigin get() = ktDeclaration
override val clsDelegate get() = myMethod
override fun getName() = ktDeclaration.name ?: ""
@@ -1,30 +1,10 @@
/*
* 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.asJava.builder.LightClassData
abstract class KtLazyLightClass(manager: PsiManager) : KtLightClassBase(manager) {
abstract val lightClassData: LightClassData
override val clsDelegate: PsiClass by lazyPub { lightClassData.clsDelegate }
override fun getOwnFields() = lightClassData.getOwnFields(this)
override fun getOwnMethods() = lightClassData.getOwnMethods(this)
}
abstract class KtLazyLightClass(manager: PsiManager) : KtLightClassBase(manager)
@@ -1,28 +1,18 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.psi.*
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiField
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiMethod
import com.intellij.psi.impl.PsiClassImplUtil
import com.intellij.psi.impl.light.AbstractLightClass
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
import org.jetbrains.kotlin.asJava.elements.KtLightFieldImpl
import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl
import org.jetbrains.kotlin.idea.KotlinLanguage
abstract class KtLightClassBase protected constructor(
@@ -34,7 +24,7 @@ abstract class KtLightClassBase protected constructor(
lazyCreator = LightClassesLazyCreator(project)
)
override fun getDelegate() = clsDelegate
override fun getDelegate() = invalidAccess()
override fun getFields() = myInnersCache.fields
@@ -55,10 +45,8 @@ abstract class KtLightClassBase protected constructor(
override fun findMethodsByName(name: String, checkBases: Boolean) = myInnersCache.findMethodsByName(name, checkBases)
override fun findInnerClassByName(name: String, checkBases: Boolean) = myInnersCache.findInnerClassByName(name, checkBases)
override fun getOwnFields(): List<PsiField> = KtLightFieldImpl.fromClsFields(delegate, this)
override fun getOwnMethods(): List<PsiMethod> = KtLightMethodImpl.fromClsMethods(delegate, this)
abstract override fun getOwnFields(): List<PsiField>
abstract override fun getOwnMethods(): List<PsiMethod>
override fun getText(): String {
val origin = kotlinOrigin
@@ -1,110 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.*
import com.intellij.psi.impl.InheritanceImplUtil
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.reference.SoftReference
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.resolve.DescriptorUtils
internal open class KtLightClassForAnonymousDeclaration(classOrObject: KtClassOrObject) :
KtLightClassForLocalDeclaration(classOrObject), PsiAnonymousClass {
private var cachedBaseType: SoftReference<PsiClassType>? = null
override fun getBaseClassReference(): PsiJavaCodeReferenceElement {
return JavaPsiFacade.getElementFactory(classOrObject.project).createReferenceElementByType(baseClassType)
}
@Synchronized
override fun getBaseClassType(): PsiClassType {
var type: PsiClassType? = null
if (cachedBaseType != null) type = cachedBaseType!!.get()
if (type != null && type.isValid) return type
val firstSupertypeFQName = getFirstSupertypeFQNameForAnonymousDeclaration()
for (superType in superTypes) {
val superClass = superType.resolve()
if (superClass != null && firstSupertypeFQName == superClass.qualifiedName) {
type = superType
break
}
}
if (type == null) {
val project = classOrObject.project
type = PsiType.getJavaLangObject(PsiManager.getInstance(project), GlobalSearchScope.allScope(project))
}
cachedBaseType = SoftReference<PsiClassType>(type)
return type
}
override fun getArgumentList(): PsiExpressionList? = null
override fun isInQualifiedNew(): Boolean {
return false
}
override fun getName(): String? = null
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class.java != other::class.java) return false
val aClass = other as KtLightClassForAnonymousDeclaration
return classOrObject == aClass.classOrObject
}
override fun hashCode(): Int {
return classOrObject.hashCode()
}
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean {
if (baseClass is KtLightClassForSourceDeclaration) {
return super.isInheritor(baseClass, checkDeep)
}
return InheritanceImplUtil.isInheritor(this, baseClass, checkDeep)
}
override fun getNameIdentifier(): KtLightIdentifier? = null
override fun getModifierList(): PsiModifierList? = null
override fun hasModifierProperty(name: String): Boolean = name == PsiModifier.FINAL
override fun getExtendsList(): PsiReferenceList? = null
override fun getImplementsList(): PsiReferenceList? = null
override fun getContainingClass(): PsiClass? = null
override fun isInterface() = false
override fun isAnnotationType() = false
override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun isEnum() = false
override fun copy(): PsiElement = KtLightClassForAnonymousDeclaration(classOrObject)
companion object {
fun KtLightClassForSourceDeclaration.getFirstSupertypeFQNameForAnonymousDeclaration(): String {
val descriptor = getDescriptor() ?: return CommonClassNames.JAVA_LANG_OBJECT
val superTypes = descriptor.typeConstructor.supertypes
if (superTypes.isEmpty()) return CommonClassNames.JAVA_LANG_OBJECT
val superType = superTypes.iterator().next()
val superClassDescriptor = superType.constructor.declarationDescriptor
if (superClassDescriptor === null) {
// return java.lang.Object for recovery
return CommonClassNames.JAVA_LANG_OBJECT
}
return DescriptorUtils.getFqName(superClassDescriptor).asString()
}
}
}
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2016 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.psi.PsiEnumConstant
import com.intellij.psi.PsiEnumConstantInitializer
import org.jetbrains.kotlin.psi.KtEnumEntry
internal class KtLightClassForEnumEntry(
enumEntry: KtEnumEntry,
private val enumConstant: PsiEnumConstant
): KtLightClassForAnonymousDeclaration(enumEntry), PsiEnumConstantInitializer {
override fun getEnumConstant(): PsiEnumConstant = enumConstant
override fun copy() = KtLightClassForEnumEntry(classOrObject as KtEnumEntry, enumConstant)
override fun getParent() = enumConstant
}
@@ -9,17 +9,12 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.impl.PsiSuperMethodImplUtil
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.impl.light.LightEmptyImplementsList
import com.intellij.psi.impl.light.LightModifierList
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForFileFacade
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
@@ -35,21 +30,11 @@ import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.psi.psiUtil.siblings
import javax.swing.Icon
open class KtLightClassForFacadeImpl constructor(
abstract class KtLightClassForFacadeImpl constructor(
manager: PsiManager,
override val facadeClassFqName: FqName,
myLightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
override val files: Collection<KtFile>
) : KtLazyLightClass(manager), KtLightClassForFacade {
protected open val lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade> = myLightClassDataCache
protected open val javaFileStub: PsiJavaFileStub?
get() = lightClassDataCache.value.javaFileStub
override val lightClassData
get() = lightClassDataCache.value.findDataForFacade(facadeClassFqName)
private val firstFileInFacade by lazyPub { files.iterator().next() }
private val modifierList: PsiModifierList =
@@ -62,7 +47,7 @@ open class KtLightClassForFacadeImpl constructor(
FakeFileForLightClass(
firstFileInFacade,
lightClass = { this },
stub = { javaFileStub },
stub = { null },
packageFqName = facadeClassFqName.parent()
)
}
@@ -168,8 +153,7 @@ open class KtLightClassForFacadeImpl constructor(
override fun isValid() = files.all { it.isValid && it.hasTopLevelCallables() && facadeClassFqName == it.javaFileFacadeFqName }
override fun copy(): KtLightClassForFacade =
KtLightClassForFacadeImpl(manager, facadeClassFqName, lightClassDataCache, files)
abstract override fun copy(): KtLightClassForFacade
override fun getNavigationElement() = firstFileInFacade
@@ -231,22 +215,15 @@ open class KtLightClassForFacadeImpl constructor(
companion object {
fun createForFacadeNoCache(fqName: FqName, searchScope: GlobalSearchScope, project: Project): KtLightClassForFacade? {
val sources = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(fqName, searchScope)
.filterNot { it.isCompiled || it.isScript() }
if (sources.isEmpty()) return null
val stubProvider = LightClassDataProviderForFileFacade.ByProjectSource(project, fqName, searchScope)
val stubValue = CachedValuesManager.getManager(project)
.createCachedValue(stubProvider, false)
val manager = PsiManager.getInstance(project)
return LightClassGenerationSupport.getInstance(project).run {
if (canCreateUltraLightClassForFacade(sources)) createUltraLightClassForFacade(manager, fqName, stubValue, sources)
if (!canCreateUltraLightClassForFacade(sources)) return null
createUltraLightClassForFacade(manager, fqName, sources)
?: error("Unable to create UL class for facade: $fqName for ${sources.joinToString { it.virtualFilePath }}")
else KtLightClassForFacadeImpl(manager, fqName, stubValue, sources)
}
}
@@ -263,11 +240,10 @@ open class KtLightClassForFacadeImpl constructor(
file: KtFile
): KtLightClassForFacade {
val project = file.project
// TODO: refactor, using cached value doesn't make sense for this case
val cachedValue = CachedValuesManager.getManager(project).createCachedValue(
LightClassDataProviderForFileFacade.ByFile(project, facadeClassFqName, file), false
)
return KtLightClassForFacadeImpl(PsiManager.getInstance(project), facadeClassFqName, cachedValue, listOf(file))
val manager = PsiManager.getInstance(project)
return LightClassGenerationSupport.getInstance(project).run {
createUltraLightClassForFacade(manager, facadeClassFqName, listOf(file)) ?: error { "Unable to create UL class for facade" }
}
}
}
}
@@ -1,63 +0,0 @@
/*
* Copyright 2010-2016 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.psi.*
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtClassOrObject
class KtLightClassForInterfaceDefaultImpls(classOrObject: KtClassOrObject)
: KtLightClassForSourceDeclaration(classOrObject, JvmDefaultMode.DEFAULT) {
override fun getQualifiedName(): String? = containingClass?.qualifiedName?.let { it + ".${JvmAbi.DEFAULT_IMPLS_CLASS_NAME}" }
override fun getName() = JvmAbi.DEFAULT_IMPLS_CLASS_NAME
override fun getParent() = containingClass
override fun copy(): PsiElement {
return KtLightClassForInterfaceDefaultImpls(classOrObject.copy() as KtClassOrObject)
}
override fun findLightClassData(): LightClassData {
return getLightClassDataHolder().findDataForDefaultImpls(classOrObject)
}
override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray()
override fun computeModifiers() = publicStaticFinal
override fun isInterface(): Boolean = false
override fun isDeprecated(): Boolean = false
override fun isAnnotationType(): Boolean = false
override fun isEnum(): Boolean = false
override fun hasTypeParameters(): Boolean = false
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean = false
@Throws(IncorrectOperationException::class)
override fun setName(name: String): PsiElement {
throw IncorrectOperationException("Impossible to rename DefaultImpls")
}
override fun getContainingClass() = KtLightClassForSourceDeclaration.create(classOrObject, JvmDefaultMode.DEFAULT)
override fun getOwnInnerClasses() = emptyList<PsiClass>()
}
private val publicStaticFinal = setOf(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL)
@@ -1,103 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.impl.light.LightClass
import com.intellij.psi.impl.light.LightMethod
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
open class KtLightClassForLocalDeclaration(
classOrObject: KtClassOrObject
) : KtLightClassForSourceDeclaration(classOrObject, JvmDefaultMode.DEFAULT) {
override fun copy(): PsiElement = KtLightClassForLocalDeclaration(classOrObject.copy() as KtClassOrObject)
override fun getQualifiedName(): String? = null
override fun getParent() = _parent
private val _parent: PsiElement? by lazyPub { getParentForLocalDeclaration(classOrObject) }
companion object {
fun getParentForLocalDeclaration(classOrObject: KtClassOrObject): PsiElement? {
fun getParentByPsiMethod(method: PsiMethod?, name: String?, forceMethodWrapping: Boolean): PsiElement? {
if (method == null || name == null) return null
var containingClass: PsiClass? = method.containingClass ?: return null
val currentFileName = classOrObject.containingFile.name
var createWrapper = forceMethodWrapping
// Use PsiClass wrapper instead of package light class to avoid names like "FooPackage" in Type Hierarchy and related views
if (containingClass is KtLightClassForFacade) {
containingClass = object : LightClass(containingClass as KtLightClassForFacade, KotlinLanguage.INSTANCE) {
override fun getName(): String? = currentFileName
}
createWrapper = true
}
if (createWrapper) {
return object : LightMethod(classOrObject.manager, method, containingClass!!, KotlinLanguage.INSTANCE) {
override fun getParent(): PsiElement = getContainingClass()
override fun getName(): String = name
}
}
return method
}
var declaration: PsiElement? = KtPsiUtil.getTopmostParentOfTypes(
classOrObject,
KtNamedFunction::class.java,
KtConstructor::class.java,
KtProperty::class.java,
KtAnonymousInitializer::class.java,
KtParameter::class.java
)
if (declaration is KtParameter) {
declaration = declaration.getStrictParentOfType<KtNamedDeclaration>()
}
if (declaration is KtFunction) {
return getParentByPsiMethod(
LightClassUtil.getLightClassMethod(declaration),
declaration.name,
forceMethodWrapping = false
)
}
// Represent the property as a fake method with the same name
if (declaration is KtProperty) {
return getParentByPsiMethod(
LightClassUtil.getLightClassPropertyMethods(declaration).getter,
declaration.name,
forceMethodWrapping = true
)
}
if (declaration is KtAnonymousInitializer) {
val parent = declaration.parent
val grandparent = parent.parent
if (parent is KtClassBody && grandparent is KtClassOrObject) {
return grandparent.toLightClass()
}
}
return if (declaration is KtClass) declaration.toLightClass() else null
}
}
}
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.asJava.classes
import com.intellij.openapi.util.Key
import com.intellij.psi.*
import com.intellij.psi.impl.PsiSuperMethodImplUtil
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.impl.light.LightEmptyImplementsList
import com.intellij.psi.impl.light.LightModifierList
import com.intellij.psi.util.CachedValue
@@ -18,11 +17,9 @@ import com.intellij.util.IncorrectOperationException
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.LightClassData
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.config.JvmDefaultMode
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.name.FqName
@@ -31,17 +28,7 @@ import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtScript
import javax.swing.Icon
open class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script.manager) {
protected open fun getLightClassDataHolder(): LightClassDataHolder.ForScript =
getLightClassCachedValue(script).value
override val lightClassData: LightClassData
get() = getLightClassDataHolder().findDataForScript(script.fqName)
protected open val javaFileStub: PsiJavaFileStub?
get() = getLightClassDataHolder().javaFileStub
abstract class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script.manager) {
private val modifierList: PsiModifierList = LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC)
private val scriptImplementsList: LightEmptyImplementsList = LightEmptyImplementsList(manager)
@@ -56,7 +43,7 @@ open class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script
FakeFileForLightClass(
script.containingKtFile,
lightClass = { this },
stub = { javaFileStub },
stub = { null },
packageFqName = fqName.parent(),
)
}
@@ -103,7 +90,7 @@ open class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script
// 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, JvmDefaultMode.DEFAULT) }
.mapNotNull { KtLightClassForSourceDeclaration.create(it) }
}
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
@@ -114,7 +101,7 @@ open class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script
override fun isValid() = script.isValid
override fun copy() = KtLightClassForScript(script)
abstract override fun copy(): PsiElement
override fun getNavigationElement() = script
@@ -184,27 +171,21 @@ open class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script
CachedValuesManager.getCachedValue(script) {
CachedValueProvider.Result
.create(
createNoCache(script, KtUltraLightSupport.forceUsingOldLightClasses),
createNoCache(script),
KotlinModificationTrackerService.getInstance(script.project).outOfBlockModificationTracker,
)
}
fun createNoCache(script: KtScript, forceUsingOldLightClasses: Boolean): KtLightClassForScript? {
fun createNoCache(script: KtScript): KtLightClassForScript? {
val containingFile = script.containingFile
if (containingFile is KtCodeFragment) {
// Avoid building light classes for code fragments
return null
}
if (!forceUsingOldLightClasses) {
LightClassGenerationSupport.getInstance(script.project).run {
if (useUltraLightClasses) {
return createUltraLightClassForScript(script) ?: error("UL class cannot be created for script")
}
}
return LightClassGenerationSupport.getInstance(script.project).run {
createUltraLightClassForScript(script)
}
return KtLightClassForScript(script)
}
fun getLightClassCachedValue(script: KtScript): CachedValue<LightClassDataHolder.ForScript> {
@@ -24,21 +24,17 @@ import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiUtilCore
import com.intellij.util.IncorrectOperationException
import com.intellij.util.containers.ConcurrentFactoryMap
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
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.elements.FakeFileForLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
import org.jetbrains.kotlin.asJava.elements.KtLightPsiReferenceList
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.config.JvmDefaultMode
@@ -94,8 +90,8 @@ abstract class KtLightClassForSourceDeclaration(
private val _implementsList by lazyPub { createImplementsList() }
private val _deprecated by lazyPub { classOrObject.isDeprecated() }
protected open fun createExtendsList(): PsiReferenceList? = super.getExtendsList()?.let { KtLightPsiReferenceList(it, this) }
protected open fun createImplementsList(): PsiReferenceList? = super.getImplementsList()?.let { KtLightPsiReferenceList(it, this) }
protected abstract fun createExtendsList(): PsiReferenceList?
protected abstract fun createImplementsList(): PsiReferenceList?
override val kotlinOrigin: KtClassOrObject = classOrObject
@@ -103,11 +99,6 @@ abstract class KtLightClassForSourceDeclaration(
abstract override fun getParent(): PsiElement?
abstract override fun getQualifiedName(): String?
override val lightClassData: LightClassData
get() = findLightClassData()
protected open fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject)
private fun getJavaFileStub(): PsiJavaFileStub = getLightClassDataHolder().javaFileStub
fun getDescriptor() =
@@ -124,7 +115,7 @@ abstract class KtLightClassForSourceDeclaration(
private val _containingFile: PsiFile by lazyPub {
object : FakeFileForLightClass(
classOrObject.containingKtFile,
{ if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject), jvmDefaultMode)!! },
{ if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject))!! },
{ getJavaFileStub() }
) {
override fun findReferenceAt(offset: Int) = ktFile.findReferenceAt(offset)
@@ -181,7 +172,7 @@ abstract class KtLightClassForSourceDeclaration(
val containingClassOrObject = (classOrObject.parent as? KtClassBody)?.parent as? KtClassOrObject
if (containingClassOrObject != null) {
return create(containingClassOrObject, jvmDefaultMode)
return create(containingClassOrObject)
}
// TODO: should return null
@@ -190,7 +181,7 @@ abstract class KtLightClassForSourceDeclaration(
private val _typeParameterList: PsiTypeParameterList by lazyPub { buildTypeParameterList() }
protected open fun buildTypeParameterList() = LightClassUtil.buildLightTypeParameterList(this, classOrObject)
protected abstract fun buildTypeParameterList(): PsiTypeParameterList
override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList
@@ -309,10 +300,7 @@ abstract class KtLightClassForSourceDeclaration(
// we can't prohibit creating light classes with null names either since they can contain members
.filter { it.name != null }
.mapNotNullTo(result) {
if (!forceUsingOldLightClasses)
create(it, jvmDefaultMode)
else
createNoCache(it, jvmDefaultMode, forceUsingOldLightClasses = true)
create(it)
}
if (classOrObject.hasInterfaceDefaultImpls && jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE) {
@@ -322,7 +310,7 @@ abstract class KtLightClassForSourceDeclaration(
return result
}
protected open fun createClassForInterfaceDefaultImpls(): PsiClass = KtLightClassForInterfaceDefaultImpls(classOrObject)
protected abstract fun createClassForInterfaceDefaultImpls(): PsiClass
override fun getUseScope(): SearchScope = kotlinOrigin.useScope
@@ -348,21 +336,15 @@ abstract class KtLightClassForSourceDeclaration(
FINAL_KEYWORD to PsiModifier.FINAL
)
fun create(classOrObject: KtClassOrObject, jvmDefaultMode: JvmDefaultMode): KtLightClassForSourceDeclaration? =
fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? =
CachedValuesManager.getCachedValue(classOrObject) {
CachedValueProvider.Result.create(
ConcurrentFactoryMap.createMap { defaultMode: JvmDefaultMode ->
createNoCache(classOrObject, defaultMode, KtUltraLightSupport.forceUsingOldLightClasses)
},
createNoCache(classOrObject),
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker,
)
}[jvmDefaultMode]
}
fun createNoCache(
classOrObject: KtClassOrObject,
jvmDefaultMode: JvmDefaultMode,
forceUsingOldLightClasses: Boolean
): KtLightClassForSourceDeclaration? {
fun createNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
val containingFile = classOrObject.containingFile
if (containingFile is KtCodeFragment) {
// Avoid building light classes for code fragments
@@ -373,24 +355,8 @@ abstract class KtLightClassForSourceDeclaration(
return null
}
if (!forceUsingOldLightClasses) {
LightClassGenerationSupport.getInstance(classOrObject.project).run {
if (useUltraLightClasses) {
return createUltraLightClass(classOrObject)
?: error { "Unable to create UL class for ${classOrObject.javaClass.name}" }
}
}
}
return when {
classOrObject is KtObjectDeclaration && classOrObject.isObjectLiteral() ->
KtLightClassForAnonymousDeclaration(classOrObject)
classOrObject.safeIsLocal() ->
KtLightClassForLocalDeclaration(classOrObject)
else ->
KtLightClassImpl(classOrObject, jvmDefaultMode, forceUsingOldLightClasses)
return LightClassGenerationSupport.getInstance(classOrObject.project).run {
createUltraLightClass(classOrObject)
}
}
@@ -488,19 +454,9 @@ abstract class KtLightClassForSourceDeclaration(
private val LOG = Logger.getInstance(KtLightClassForSourceDeclaration::class.java)
}
override fun getSupers(): Array<PsiClass> {
if (classOrObject.superTypeListEntries.isEmpty()) {
return getSupertypeByPsi()?.let { arrayOf(it.resolve()!!) } ?: emptyArray()
}
return clsDelegate.supers
}
abstract override fun getSupers(): Array<PsiClass>
override fun getSuperTypes(): Array<PsiClassType> {
if (classOrObject.superTypeListEntries.isEmpty()) {
return getSupertypeByPsi()?.let { arrayOf<PsiClassType>(it) } ?: emptyArray()
}
return clsDelegate.superTypes
}
abstract override fun getSuperTypes(): Array<PsiClassType>
private fun getSupertypeByPsi(): PsiImmediateClassType? {
return classOrObject.defaultJavaAncestorQualifiedName()?.let { ancestorFqName ->
@@ -525,12 +481,7 @@ abstract class KtLightClassForSourceDeclaration(
override val originKind: LightClassOriginKind
get() = LightClassOriginKind.SOURCE
open fun isFinal(isFinalByPsi: Boolean): Boolean {
// annotations can make class open via 'allopen' plugin
if (!isPossiblyAffectedByAllOpen() || !isFinalByPsi) return isFinalByPsi
return clsDelegate.hasModifierProperty(PsiModifier.FINAL)
}
abstract fun isFinal(isFinalByPsi: Boolean): Boolean
}
fun KtLightClassForSourceDeclaration.isPossiblyAffectedByAllOpen() =
@@ -1,26 +1,16 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.psi.KtClassOrObject
// light class for top level or (inner/nested of top level) source declarations
open class KtLightClassImpl @JvmOverloads constructor(
abstract class KtLightClassImpl @JvmOverloads constructor(
classOrObject: KtClassOrObject,
jvmDefaultMode: JvmDefaultMode,
forceUsingOldLightClasses: Boolean = false
@@ -32,5 +22,5 @@ open class KtLightClassImpl @JvmOverloads constructor(
else
containingClass
override fun copy() = KtLightClassImpl(classOrObject.copy() as KtClassOrObject, jvmDefaultMode)
abstract override fun copy(): PsiElement
}
@@ -59,7 +59,7 @@ class KtUltraLightClassForInterfaceDefaultImpls(classOrObject: KtClassOrObject,
override fun setName(name: String): PsiElement =
throw IncorrectOperationException("Impossible to rename ${JvmAbi.DEFAULT_IMPLS_CLASS_NAME}")
override fun getContainingClass(): KtLightClassForSourceDeclaration? = create(classOrObject, jvmDefaultMode)
override fun getContainingClass(): KtLightClassForSourceDeclaration? = create(classOrObject)
override fun getOwnInnerClasses() = emptyList<PsiClass>()
override fun getOwnMethods(): List<KtLightMethod> = _ownMethods.value
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -22,7 +22,7 @@ class KtUltraLightClassForRepeatableAnnotationContainer(classOrObject: KtClassOr
override fun getParent() = containingClass
override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray()
override fun getContainingClass(): KtLightClassForSourceDeclaration? = create(classOrObject, jvmDefaultMode)
override fun getContainingClass(): KtLightClassForSourceDeclaration? = create(classOrObject)
override fun getScope(): PsiElement? = containingClass
override fun getOwnInnerClasses() = emptyList<PsiClass>()
override fun getOwnFields(): List<KtLightField> = emptyList()
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -16,11 +16,10 @@ class LightClassesLazyCreator(private val project: Project) : KotlinClassInnerSt
override fun <T : Any> get(initializer: () -> T, dependencies: List<Any>) = object : Lazy<T> {
private val lock = ReentrantLock()
private val holder = lazyPub {
PsiCachedValueImpl(PsiManager.getInstance(project),
CachedValueProvider<T> {
val v = initializer()
CachedValueProvider.Result.create(v, dependencies)
})
PsiCachedValueImpl(PsiManager.getInstance(project)) {
val v = initializer()
CachedValueProvider.Result.create(v, dependencies)
}
}
private fun computeValue(): T = holder.value.value ?: error("holder has not null in initializer")
@@ -1,16 +1,15 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.*
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiModifierList
import com.intellij.psi.impl.light.LightModifierList
import com.intellij.psi.util.CachedValue
import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil.findAnnotationEntryOnFileNoResolve
import org.jetbrains.kotlin.idea.KotlinLanguage
@@ -26,21 +25,9 @@ import org.jetbrains.kotlin.psi.psiUtil.isPrivate
class KtUltraLightClassForFacade(
manager: PsiManager,
facadeClassFqName: FqName,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
files: Collection<KtFile>,
private val filesWithSupports: Collection<Pair<KtFile, KtUltraLightSupport>>
) : KtLightClassForFacadeImpl(manager, facadeClassFqName, lightClassDataCache, files) {
override fun getDelegate(): PsiClass = invalidAccess()
override val lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade> get() = invalidAccess()
override val clsDelegate: PsiClass get() = invalidAccess()
override val lightClassData: LightClassData get() = invalidAccess()
override val javaFileStub: PsiJavaFileStub? = null
) : KtLightClassForFacadeImpl(manager, facadeClassFqName, files) {
private val _modifierList: PsiModifierList by lazyPub {
if (isMultiFileClass)
LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL)
@@ -59,8 +46,7 @@ class KtUltraLightClassForFacade(
name = entry.shortName?.identifier,
lazyQualifiedName = { entry.analyzeAnnotation()?.fqName?.asString() },
kotlinOrigin = entry,
parent = _modifierList,
lazyClsDelegate = null
parent = _modifierList
)
}
}
@@ -101,6 +87,7 @@ class KtUltraLightClassForFacade(
ktFunction = declaration,
forceStatic = true
)
is KtProperty -> {
if (!declaration.isPrivate() || declaration.accessors.isNotEmpty()) {
creator.propertyAccessors(
@@ -111,6 +98,7 @@ class KtUltraLightClassForFacade(
)
} else emptyList()
}
else -> emptyList()
}
result.addAll(methods)
@@ -148,5 +136,5 @@ class KtUltraLightClassForFacade(
override fun getOwnMethods() = _ownMethods
override fun copy(): KtLightClassForFacade =
KtUltraLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files, filesWithSupports)
KtUltraLightClassForFacade(manager, facadeClassFqName, files, filesWithSupports)
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -46,7 +46,7 @@ class KtUltraLightSimpleAnnotation(
private val ultraLightSupport: KtUltraLightSupport,
parent: PsiElement,
private val nameReferenceElementProvider: (() -> PsiJavaCodeReferenceElement?)? = null,
) : KtLightAbstractAnnotation(parent, computeDelegate = null) {
) : KtLightAbstractAnnotation(parent) {
override fun getNameReferenceElement(): PsiJavaCodeReferenceElement? = nameReferenceElementProvider?.invoke()
private val parameterList = ParameterListImpl()
@@ -15,7 +15,6 @@ import com.intellij.psi.impl.light.LightMethodBuilder
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.elements.KtUltraLightModifierList
@@ -79,10 +78,6 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
override fun isFinal(isFinalByPsi: Boolean) = isFinalByPsi
override fun findLightClassData(): LightClassData = invalidAccess()
override fun getDelegate(): PsiClass = invalidAccess()
private val _modifierList: PsiModifierList? by lazyPub {
KtUltraLightClassModifierList(this, support) { computeModifiers() }
}
@@ -300,6 +295,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
when (declaration) {
is KtNamedFunction ->
if (isJvmStatic(declaration)) result.addAll(membersBuilder.createMethods(declaration, forceStatic = true))
is KtProperty -> result.addAll(
membersBuilder.propertyAccessors(
declaration,
@@ -405,6 +401,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
declarationOriginKindForOrigin = JvmDeclarationOriginKind.DELEGATION
)
}
is FunctionDescriptor -> result.add(
createGeneratedMethodFromDescriptor(
descriptor = delegate,
@@ -486,7 +483,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
val containingBody = classOrObject.parent as? KtClassBody
val containingClass = containingBody?.parent as? KtClassOrObject
containingClass?.let { return create(it, jvmDefaultMode) }
containingClass?.let { return create(it) }
val containingBlock = classOrObject.parent as? KtBlockExpression
val containingScript = containingBlock?.parent as? KtScript
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.*
import com.intellij.psi.impl.InheritanceImplUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClassForAnonymousDeclaration.Companion.getFirstSupertypeFQNameForAnonymousDeclaration
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.resolve.DescriptorUtils
open class KtUltraLightClassForAnonymousDeclaration(classOrObject: KtClassOrObject, support: KtUltraLightSupport) :
KtUltraLightClassForLocalDeclaration(classOrObject, support), PsiAnonymousClass {
@@ -18,7 +18,6 @@ open class KtUltraLightClassForAnonymousDeclaration(classOrObject: KtClassOrObje
JavaPsiFacade.getElementFactory(classOrObject.project).createReferenceElementByType(baseClassType)
private val _baseClassType by lazyPub {
val firstSupertypeFQName = getFirstSupertypeFQNameForAnonymousDeclaration()
if (firstSupertypeFQName == CommonClassNames.JAVA_LANG_OBJECT) {
@@ -64,4 +63,22 @@ open class KtUltraLightClassForAnonymousDeclaration(classOrObject: KtClassOrObje
override fun isEnum() = false
override fun copy() = KtUltraLightClassForAnonymousDeclaration(classOrObject, support)
}
}
private fun KtLightClassForSourceDeclaration.getFirstSupertypeFQNameForAnonymousDeclaration(): String {
val descriptor = getDescriptor() ?: return CommonClassNames.JAVA_LANG_OBJECT
val superTypes = descriptor.typeConstructor.supertypes
if (superTypes.isEmpty()) return CommonClassNames.JAVA_LANG_OBJECT
val superType = superTypes.iterator().next()
val superClassDescriptor = superType.constructor.declarationDescriptor
if (superClassDescriptor === null) {
// return java.lang.Object for recovery
return CommonClassNames.JAVA_LANG_OBJECT
}
return DescriptorUtils.getFqName(superClassDescriptor).asString()
}
@@ -1,13 +1,20 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.asJava.classes.KtLightClassForLocalDeclaration.Companion.getParentForLocalDeclaration
import org.jetbrains.kotlin.psi.KtClassOrObject
import com.intellij.psi.PsiMethod
import com.intellij.psi.impl.light.LightClass
import com.intellij.psi.impl.light.LightMethod
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
open class KtUltraLightClassForLocalDeclaration(
classOrObject: KtClassOrObject,
@@ -21,4 +28,73 @@ open class KtUltraLightClassForLocalDeclaration(
override fun getQualifiedName(): String? = null
override fun getParent() = _parent
}
private fun getParentForLocalDeclaration(classOrObject: KtClassOrObject): PsiElement? {
fun getParentByPsiMethod(method: PsiMethod?, name: String?, forceMethodWrapping: Boolean): PsiElement? {
if (method == null || name == null) return null
var containingClass: PsiClass? = method.containingClass ?: return null
val currentFileName = classOrObject.containingFile.name
var createWrapper = forceMethodWrapping
// Use PsiClass wrapper instead of package light class to avoid names like "FooPackage" in Type Hierarchy and related views
if (containingClass is KtLightClassForFacade) {
containingClass = object : LightClass(containingClass as KtLightClassForFacade, KotlinLanguage.INSTANCE) {
override fun getName(): String = currentFileName
}
createWrapper = true
}
if (createWrapper) {
return object : LightMethod(classOrObject.manager, method, containingClass!!, KotlinLanguage.INSTANCE) {
override fun getParent(): PsiElement = getContainingClass()
override fun getName(): String = name
}
}
return method
}
var declaration: PsiElement? = KtPsiUtil.getTopmostParentOfTypes(
classOrObject,
KtNamedFunction::class.java,
KtConstructor::class.java,
KtProperty::class.java,
KtAnonymousInitializer::class.java,
KtParameter::class.java
)
if (declaration is KtParameter) {
declaration = declaration.getStrictParentOfType<KtNamedDeclaration>()
}
if (declaration is KtFunction) {
return getParentByPsiMethod(
LightClassUtil.getLightClassMethod(declaration),
declaration.name,
forceMethodWrapping = false
)
}
// Represent the property as a fake method with the same name
if (declaration is KtProperty) {
return getParentByPsiMethod(
LightClassUtil.getLightClassPropertyMethods(declaration).getter,
declaration.name,
forceMethodWrapping = true
)
}
if (declaration is KtAnonymousInitializer) {
val parent = declaration.parent
val grandparent = parent.parent
if (parent is KtClassBody && grandparent is KtClassOrObject) {
return grandparent.toLightClass()
}
}
return if (declaration is KtClass) declaration.toLightClass() else null
}
@@ -1,21 +1,17 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiType
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.impl.light.LightMethodBuilder
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.psi.KtNamedFunction
@@ -26,15 +22,6 @@ class KtUltraLightClassForScript(
script: KtScript,
private val support: KtUltraLightSupport,
) : KtLightClassForScript(script) {
override val clsDelegate: PsiClass get() = invalidAccess()
override val lightClassData: LightClassData get() = invalidAccess()
override fun getLightClassDataHolder(): LightClassDataHolder.ForScript = invalidAccess()
override val javaFileStub: PsiJavaFileStub? = null
private val membersBuilder by lazyPub {
UltraLightMembersCreator(
containingClass = this,
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -184,8 +184,6 @@ internal open class KtUltraLightFieldImpl protected constructor(
override val kotlinOrigin = declaration
override val clsDelegate: PsiField get() = invalidAccess()
override val lightMemberOrigin = LightMemberOriginForDeclaration(declaration, JvmDeclarationOriginKind.OTHER)
override fun setName(@NonNls name: String): PsiElement {
@@ -10,13 +10,14 @@ import com.intellij.psi.impl.PsiImplUtil
import com.intellij.psi.impl.PsiSuperMethodImplUtil
import com.intellij.psi.impl.light.LightMethodBuilder
import com.intellij.psi.impl.light.LightTypeParameterListBuilder
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.util.MethodSignature
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.builder.MemberIndex
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl
import org.jetbrains.kotlin.asJava.elements.KtUltraLightModifierList
import org.jetbrains.kotlin.codegen.FunctionCodegen
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
@@ -28,9 +29,11 @@ import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
import org.jetbrains.kotlin.psi.psiUtil.hasBody
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.types.RawType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
const val METHOD_INDEX_FOR_GETTER = 1
const val METHOD_INDEX_FOR_SETTER = 2
@@ -40,22 +43,45 @@ const val METHOD_INDEX_FOR_NON_ORIGIN_METHOD = 5
const val METHOD_INDEX_FOR_SCRIPT_MAIN = 6
const val METHOD_INDEX_BASE = 7
private class KtUltraLightMethodModifierList(
support: KtUltraLightSupport,
owner: KtUltraLightMethod,
val delegate: PsiMethod,
) : KtUltraLightModifierList<KtUltraLightMethod>(owner, support) {
override fun hasModifierProperty(name: String) = when {
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
// pretend this method behaves like a default method
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
name == PsiModifier.FINAL &&
(owner.containingClass.safeAs<KtLightClassForSourceDeclaration>()?.isPossiblyAffectedByAllOpen() == true)
-> delegate.hasModifierProperty(name)
else -> delegate.hasModifierProperty(name)
}
override fun hasExplicitModifier(name: String) =
// Kotlin methods can't be truly default atm, that way we can avoid being reported on by diagnostics, namely UAST
if (name == PsiModifier.DEFAULT) false else super.hasExplicitModifier(name)
private fun isImplementationInInterface() = owner.containingClass.isInterface && owner.kotlinOrigin?.hasBody() == true
override fun copy() = KtUltraLightMethodModifierList(support, owner, delegate)
}
internal abstract class KtUltraLightMethod(
internal val delegate: PsiMethod,
lightMemberOrigin: LightMemberOrigin?,
lightMemberOrigin: LightMemberOriginForDeclaration?,
protected val support: KtUltraLightSupport,
containingClass: KtLightClass,
private val methodIndex: Int
) : KtLightMethodImpl(
{ delegate },
lightMemberOrigin,
containingClass
), KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiMethod> {
private class KtUltraLightThrowsReferenceListBuilder(private val parentMethod: PsiMethod) :
KotlinLightReferenceListBuilder(parentMethod.manager, parentMethod.language, PsiReferenceList.Role.THROWS_LIST) {
override fun getParent() = parentMethod
override fun getContainingFile() = parentMethod.containingFile
override fun getParent(): PsiMethod = parentMethod
override fun getContainingFile(): PsiFile? = parentMethod.containingFile
}
protected fun computeThrowsList(methodDescriptor: FunctionDescriptor?): PsiReferenceList {
@@ -105,9 +131,18 @@ internal abstract class KtUltraLightMethod(
// While here we only set return type for LightMethodBuilder (see org.jetbrains.kotlin.asJava.classes.KtUltraLightClass.asJavaMethod)
override fun getReturnTypeElement(): PsiTypeElement? = null
override fun getReturnType(): PsiType? = clsDelegate.returnType
override fun getReturnType(): PsiType? = delegate.returnType
override fun buildParametersForList(): List<PsiParameter> = clsDelegate.parameterList.parameters.toList()
override fun buildParametersForList(): List<PsiParameter> = delegate.parameterList.parameters.toList()
private val _modifierList by lazyPub {
KtUltraLightMethodModifierList(support, this, delegate)
}
override fun hasModifierProperty(name: String): Boolean = _modifierList.hasModifierProperty(name)
override fun getModifierList(): PsiModifierList = _modifierList
override fun getDefaultValue(): PsiAnnotationMemberValue? = delegate.safeAs<PsiAnnotationMethod>()?.defaultValue
override fun getName(): String = delegate.name
// should be in super
override fun isVarArgs() = PsiImplUtil.isVarArgs(this)
@@ -142,11 +177,15 @@ internal abstract class KtUltraLightMethod(
override fun hashCode(): Int = super.hashCode().times(31).plus(methodIndex.hashCode())
override fun isDeprecated(): Boolean = _deprecated
override fun getDocComment(): PsiDocComment? = delegate.docComment
override fun isConstructor(): Boolean = delegate.isConstructor
}
internal class KtUltraLightMethodForSourceDeclaration(
delegate: PsiMethod,
lightMemberOrigin: LightMemberOrigin?,
lightMemberOrigin: LightMemberOriginForDeclaration?,
support: KtUltraLightSupport,
containingClass: KtLightClass,
private val forceToSkipNullabilityAnnotation: Boolean = false,
@@ -204,7 +243,7 @@ internal class KtUltraLightMethodForSourceDeclaration(
internal class KtUltraLightMethodForDescriptor(
methodDescriptor: FunctionDescriptor,
delegate: LightMethodBuilder,
lightMemberOrigin: LightMemberOrigin?,
lightMemberOrigin: LightMemberOriginForDeclaration?,
support: KtUltraLightSupport,
containingClass: KtUltraLightClass
) : KtUltraLightMethod(
@@ -44,7 +44,6 @@ internal class KtUltraLightSuspendContinuationParameter(
override val psiTypeForNullabilityAnnotation: PsiType? get() = psiType
override val kotlinOrigin: KtParameter? = null
override val clsDelegate: PsiParameter get() = invalidAccess()
private val ktType: KotlinType?
get() {
@@ -94,8 +93,6 @@ internal abstract class KtUltraLightParameter(
override fun isEquivalentTo(another: PsiElement?): Boolean = kotlinOrigin == another
override val clsDelegate: PsiParameter get() = invalidAccess()
private val lightModifierList by lazyPub { KtLightSimpleModifierList(this, emptySet()) }
override fun getModifierList(): PsiModifierList = lightModifierList
@@ -1,16 +1,15 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.classes
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
interface KtUltraLightSupport {
@@ -21,12 +20,4 @@ interface KtUltraLightSupport {
val languageVersionSettings: LanguageVersionSettings
fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean
companion object {
// This property may be removed once IntelliJ versions earlier than 2018.3 become unsupported
// And usages of that property may be replaced with relevant registry key
@Volatile
@get:TestOnly
var forceUsingOldLightClasses = false
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -601,7 +601,6 @@ internal fun List<KtAnnotationEntry>.toLightAnnotations(
name = entry.shortName?.identifier,
lazyQualifiedName = { entry.analyzeAnnotation()?.fqName?.asString() },
kotlinOrigin = entry,
parent = parent,
lazyClsDelegate = null
parent = parent
)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.elements
@@ -54,7 +43,7 @@ open class FakeFileForLightClass(
override fun getPackageName() = packageFqName.asString()
private fun createFakeJavaFileStub(): PsiJavaFileStub {
val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), /*compiled = */true)
val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), /* compiled = */true)
javaFileStub.psiFactory = ClsStubPsiFactory.INSTANCE
javaFileStub.psi = this
return javaFileStub
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.elements
@@ -35,8 +24,6 @@ interface KtLightElement<out T : KtElement, out D : PsiElement> : PsiElement {
* Probably, it's a bit dirty solution. But, for now it's not clear how to make it better
*/
val givenAnnotations: List<KtLightAbstractAnnotation>? get() = null
val clsDelegate: D
}
interface KtLightDeclaration<out T : KtDeclaration, out D : PsiElement> : KtLightElement<T, D>, PsiNamedElement
@@ -1,125 +0,0 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.elements
import com.intellij.psi.*
import com.intellij.psi.impl.PsiVariableEx
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForEnumEntry
import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtNamedDeclaration
sealed class KtLightFieldImpl<D : PsiField>(
override val lightMemberOrigin: LightMemberOrigin?,
computeRealDelegate: () -> D,
containingClass: KtLightClass,
dummyDelegate: PsiField?
) : KtLightMemberImpl<PsiField>(computeRealDelegate, lightMemberOrigin, containingClass, dummyDelegate), KtLightField {
override val clsDelegate: D
@Suppress("UNCHECKED_CAST")
get() = super.clsDelegate as D
override fun setInitializer(initializer: PsiExpression?) = cannotModify()
override fun getType() = clsDelegate.type
override fun getTypeElement() = clsDelegate.typeElement
override fun getInitializer() = clsDelegate.initializer
override fun hasInitializer() = clsDelegate.hasInitializer()
override fun normalizeDeclaration() = cannotModify()
override fun computeConstantValue() = clsDelegate.computeConstantValue()
override fun setName(@NonNls name: String): PsiElement {
(kotlinOrigin as? KtNamedDeclaration)?.setName(name)
return this
}
override fun equals(other: Any?): Boolean = this === other ||
other is KtLightFieldImpl<*> &&
this.name == other.name &&
this.containingClass == other.containingClass
override fun hashCode() = 31 * containingClass.hashCode() + name.hashCode()
override fun computeConstantValue(visitedVars: MutableSet<PsiVariable>?): Any? {
return (clsDelegate as PsiVariableEx).computeConstantValue(visitedVars)
}
override fun copy() = Factory.create(lightMemberOrigin?.copy(), clsDelegate, containingClass)
class KtLightEnumConstant(
origin: LightMemberOrigin?,
computeDelegate: () -> PsiEnumConstant,
containingClass: KtLightClass,
dummyDelegate: PsiField?
) : KtLightFieldImpl<PsiEnumConstant>(origin, computeDelegate, containingClass, dummyDelegate), PsiEnumConstant {
private val initializingClass by lazyPub {
val kotlinEnumEntry = (lightMemberOrigin as? LightMemberOriginForDeclaration)?.originalElement as? KtEnumEntry
if (kotlinEnumEntry != null && kotlinEnumEntry.declarations.isNotEmpty()) {
KtLightClassForEnumEntry(kotlinEnumEntry, clsDelegate)
} else null
}
// NOTE: we don't use "delegation by" because the compiler would generate method calls to ALL of PsiEnumConstant members,
// but we need only members whose implementations are not present in KotlinLightField
override fun getArgumentList() = clsDelegate.argumentList
override fun getInitializingClass(): PsiEnumConstantInitializer? = initializingClass
override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer {
return initializingClass ?: throw UnsupportedOperationException("Can't create enum constant body: ${clsDelegate.name}")
}
override fun resolveConstructor() = clsDelegate.resolveConstructor()
override fun resolveMethod() = clsDelegate.resolveMethod()
override fun resolveMethodGenerics() = clsDelegate.resolveMethodGenerics()
}
class KtLightFieldForSourceDeclaration(
origin: LightMemberOrigin?,
computeDelegate: () -> PsiField,
containingClass: KtLightClass,
dummyDelegate: PsiField?
) :
KtLightFieldImpl<PsiField>(origin, computeDelegate, containingClass, dummyDelegate),
KtLightFieldForSourceDeclarationSupport
companion object Factory {
fun create(origin: LightMemberOrigin?, delegate: PsiField, containingClass: KtLightClass): KtLightField = when (delegate) {
is PsiEnumConstant -> KtLightEnumConstant(origin, { delegate }, containingClass, null)
else -> KtLightFieldForSourceDeclaration(origin, { delegate }, containingClass, null)
}
fun lazy(
dummyDelegate: PsiField,
origin: LightMemberOriginForDeclaration?,
containingClass: KtLightClass,
computeRealDelegate: () -> PsiField
): KtLightField {
if (dummyDelegate is PsiEnumConstant) {
@Suppress("UNCHECKED_CAST")
return KtLightEnumConstant(origin, computeRealDelegate as () -> PsiEnumConstant, containingClass, dummyDelegate)
}
return KtLightFieldForSourceDeclaration(origin, computeRealDelegate, containingClass, dummyDelegate)
}
fun fromClsFields(delegateClass: PsiClass, containingClass: KtLightClass) = delegateClass.fields.map {
KtLightFieldImpl.create(getOrigin(it), it, containingClass)
}
fun getOrigin(field: PsiField) = getMemberOrigin(field)
}
}
@@ -1,25 +1,12 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.elements
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiCompiledElement
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.impl.light.LightIdentifier
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
@@ -35,7 +22,7 @@ abstract class KtLightIdentifierBase(
override fun getTextOffset(): Int = origin?.textOffset ?: -1
}
open class KtLightIdentifierWithOrigin(
open class KtLightIdentifier(
lightOwner: PsiElement,
private val ktDeclaration: KtDeclaration?
) : KtLightIdentifierBase(lightOwner, ktDeclaration?.name) {
@@ -45,16 +32,9 @@ open class KtLightIdentifierWithOrigin(
is KtPrimaryConstructor -> ktDeclaration.getConstructorKeyword()
?: ktDeclaration.valueParameterList
?: ktDeclaration.containingClassOrObject?.nameIdentifier
is KtPropertyAccessor -> ktDeclaration.namePlaceholder
is KtNamedDeclaration -> ktDeclaration.nameIdentifier
else -> null
}
}
class KtLightIdentifier(
private val lightOwner: PsiElement,
ktDeclaration: KtDeclaration?
) : KtLightIdentifierWithOrigin(lightOwner, ktDeclaration), PsiCompiledElement {
override fun getMirror() = ((lightOwner as? KtLightElement<*, *>)?.clsDelegate as? PsiNameIdentifierOwner)?.nameIdentifier
}
@@ -1,69 +1,44 @@
/*
* 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.elements
import com.intellij.openapi.util.UserDataHolder
import com.intellij.psi.*
import com.intellij.psi.impl.compiled.ClsRepositoryPsiElement
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory.ORIGIN
import org.jetbrains.kotlin.asJava.builder.LightElementOrigin
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiIdentifier
import com.intellij.psi.PsiMember
import com.intellij.psi.PsiModifierList
import com.intellij.psi.javadoc.PsiDocComment
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.classes.isPossiblyAffectedByAllOpen
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.psiUtil.hasBody
abstract class KtLightMemberImpl<out D : PsiMember>(
computeRealDelegate: () -> D,
override val lightMemberOrigin: LightMemberOrigin?,
override val lightMemberOrigin: LightMemberOriginForDeclaration?,
private val containingClass: KtLightClass,
private val dummyDelegate: D?
) : KtLightElementBase(containingClass), PsiMember, KtLightMember<D> {
override val clsDelegate by lazyPub(computeRealDelegate)
private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
private val _modifierList by lazyPub {
if (lightMemberOrigin is LightMemberOriginForDeclaration)
KtLightMemberModifierList(this, dummyDelegate?.modifierList)
else clsDelegate.modifierList!!
}
abstract override fun hasModifierProperty(name: String): Boolean
override fun hasModifierProperty(name: String) = _modifierList.hasModifierProperty(name)
override fun getModifierList(): PsiModifierList = _modifierList
abstract override fun getModifierList(): PsiModifierList?
override fun toString(): String = "${this::class.java.simpleName}:$name"
override fun getContainingClass() = containingClass
override fun getName(): String = dummyDelegate?.name ?: clsDelegate.name!!
abstract override fun getName(): String
override fun getNameIdentifier(): PsiIdentifier = lightIdentifier
override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin?.originalElement
override fun getDocComment() = (clsDelegate as PsiDocCommentOwner).docComment
abstract override fun getDocComment(): PsiDocComment?
override fun isDeprecated() = (clsDelegate as PsiDocCommentOwner).isDeprecated
abstract override fun isDeprecated(): Boolean
override fun isValid(): Boolean {
return parent.isValid && lightMemberOrigin?.isValid() != false
@@ -75,46 +50,3 @@ abstract class KtLightMemberImpl<out D : PsiMember>(
another is KtLightMember<*> && lightMemberOrigin?.isEquivalentTo(another.lightMemberOrigin) == true
}
}
internal fun getMemberOrigin(member: PsiMember): LightMemberOriginForDeclaration? {
if (member !is ClsRepositoryPsiElement<*>) return null
val stubElement = member.stub as? UserDataHolder ?: return null
return stubElement.getUserData<LightElementOrigin>(ORIGIN) as? LightMemberOriginForDeclaration ?: return null
}
private val visibilityModifiers = arrayOf(PsiModifier.PRIVATE, PsiModifier.PACKAGE_LOCAL, PsiModifier.PROTECTED, PsiModifier.PUBLIC)
private class KtLightMemberModifierList(
owner: KtLightMember<*>, private val dummyDelegate: PsiModifierList?
) : KtLightModifierList<KtLightMember<*>>(owner) {
override fun hasModifierProperty(name: String) = when {
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
// pretend this method behaves like a default method
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
name == PsiModifier.FINAL && ((owner.containingClass as? KtLightClassForSourceDeclaration)?.isPossiblyAffectedByAllOpen()
?: false) ->
clsDelegate.hasModifierProperty(name)
dummyDelegate != null -> {
when {
name in visibilityModifiers && isMethodOverride() ->
clsDelegate.hasModifierProperty(name)
else -> dummyDelegate.hasModifierProperty(name)
}
}
else -> clsDelegate.hasModifierProperty(name)
}
override fun hasExplicitModifier(name: String) =
// Kotlin methods can't be truly default atm, that way we can avoid being reported on by diagnostics, namely UAST
if (name == PsiModifier.DEFAULT) false else super.hasExplicitModifier(name)
private fun isMethodOverride() = owner is KtLightMethod && owner.kotlinOrigin?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false
private fun isImplementationInInterface() =
owner.containingClass.isInterface && owner is KtLightMethod && owner.kotlinOrigin?.hasBody() ?: false
override fun copy() = KtLightMemberModifierList(owner, dummyDelegate)
}
@@ -7,66 +7,38 @@ package org.jetbrains.kotlin.asJava.elements
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.impl.compiled.ClsTypeElementImpl
import com.intellij.psi.scope.PsiScopeProcessor
import com.intellij.psi.util.MethodSignature
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.asJava.*
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.builder.MemberIndex
import org.jetbrains.kotlin.asJava.builder.memberIndex
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
open class KtLightMethodImpl protected constructor(
computeRealDelegate: () -> PsiMethod,
lightMemberOrigin: LightMemberOrigin?,
abstract class KtLightMethodImpl protected constructor(
lightMemberOrigin: LightMemberOriginForDeclaration?,
containingClass: KtLightClass,
private val dummyDelegate: PsiMethod? = null
) : KtLightMemberImpl<PsiMethod>(computeRealDelegate, lightMemberOrigin, containingClass, dummyDelegate), KtLightMethod {
private val returnTypeElem by lazyPub {
val delegateTypeElement = clsDelegate.returnTypeElement as? ClsTypeElementImpl
delegateTypeElement?.let { ClsTypeElementImpl(this, it.canonicalText, /*ClsTypeElementImpl.VARIANCE_NONE */ 0.toChar()) }
}
) : KtLightMemberImpl<PsiMethod>(lightMemberOrigin, containingClass), KtLightMethod {
private val calculatingReturnType = ThreadLocal<Boolean>()
private val paramsList: PsiParameterList by lazyPub {
KtLightParameterList(this, dummyDelegate?.parameterList?.parametersCount ?: clsDelegate.parameterList.parametersCount) {
buildParametersForList()
val parameters = buildParametersForList()
KtLightParameterList(this, parameters.size) {
parameters
}
}
protected open fun buildParametersForList(): List<PsiParameter> {
val clsParameters by lazyPub { clsDelegate.parameterList.parameters }
return (dummyDelegate?.parameterList?.parameters ?: clsParameters).mapIndexed { index, dummyParameter ->
KtLightParameterImpl(
dummyParameter,
{ clsParameters.getOrNull(index) },
index,
this@KtLightMethodImpl
)
}
}
protected abstract fun buildParametersForList(): List<PsiParameter>
private val typeParamsList: PsiTypeParameterList? by lazyPub { buildTypeParameterList() }
protected open fun buildTypeParameterList(): PsiTypeParameterList? {
val origin = (lightMemberOrigin as? LightMemberOriginForDeclaration)?.originalElement
return when {
origin is KtClassOrObject -> KotlinLightTypeParameterListBuilder(this)
origin != null -> LightClassUtil.buildLightTypeParameterList(this, origin)
else -> clsDelegate.typeParameterList
}
}
protected abstract fun buildTypeParameterList(): PsiTypeParameterList?
override fun accept(visitor: PsiElementVisitor) {
if (visitor is JavaElementVisitor) {
@@ -104,12 +76,7 @@ open class KtLightMethodImpl protected constructor(
} ?: cannotModify()
}
override fun getModifierList(): PsiModifierList {
if (calculatingReturnType.get() == true) {
return KotlinJavaPsiFacade.getInstance(project).emptyModifierList
}
return super.getModifierList()
}
abstract override fun getModifierList(): PsiModifierList
override fun getParameterList() = paramsList
@@ -120,16 +87,7 @@ open class KtLightMethodImpl protected constructor(
override fun hasTypeParameters() = typeParameters.isNotEmpty()
override fun getSignature(substitutor: PsiSubstitutor): MethodSignature {
if (substitutor == PsiSubstitutor.EMPTY) {
return clsDelegate.getSignature(substitutor)
}
return MethodSignatureBackedByPsiMethod.create(this, substitutor)
}
override fun copy(): PsiElement {
return Factory.create(clsDelegate, lightMemberOrigin?.copy(), containingClass)
}
abstract override fun getSignature(substitutor: PsiSubstitutor): MethodSignature
override fun processDeclarations(
processor: PsiScopeProcessor,
@@ -140,8 +98,7 @@ open class KtLightMethodImpl protected constructor(
return typeParameters.all { processor.execute(it, state) }
}
protected open val memberIndex: MemberIndex?
get() = (dummyDelegate ?: clsDelegate).memberIndex
protected abstract val memberIndex: MemberIndex?
/* comparing origin and member index should be enough to determine equality:
for compiled elements origin contains delegate
@@ -158,11 +115,9 @@ open class KtLightMethodImpl protected constructor(
.times(31).plus(containingClass.hashCode())
.times(31).plus(memberIndex.hashCode())
override fun getDefaultValue() = (clsDelegate as? PsiAnnotationMethod)?.defaultValue
abstract override fun getDefaultValue(): PsiAnnotationMemberValue?
// override getReturnType() so return type resolves to type parameters of this method not delegate's
// which is relied upon by java type inference
override fun getReturnTypeElement(): PsiTypeElement? = returnTypeElem
abstract override fun getReturnTypeElement(): PsiTypeElement?
override fun getReturnType(): PsiType? {
calculatingReturnType.set(true)
@@ -191,67 +146,28 @@ open class KtLightMethodImpl protected constructor(
return super.getTextRange()
}
companion object Factory {
private fun adjustMethodOrigin(origin: LightMemberOriginForDeclaration?): LightMemberOriginForDeclaration? {
val originalElement = origin?.originalElement
if (originalElement is KtPropertyAccessor) {
return origin.copy(
originalElement = originalElement.getStrictParentOfType<KtProperty>()!!,
originKind = origin.originKind,
auxiliaryOriginalElement = originalElement
)
}
return origin
}
abstract override fun getThrowsList(): PsiReferenceList
fun create(
delegate: PsiMethod, origin: LightMemberOrigin?, containingClass: KtLightClass
): KtLightMethodImpl {
return KtLightMethodImpl({ delegate }, origin, containingClass)
}
abstract override fun isVarArgs(): Boolean
fun lazy(
dummyDelegate: PsiMethod?,
containingClass: KtLightClass,
origin: LightMemberOriginForDeclaration?,
computeRealDelegate: () -> PsiMethod
): KtLightMethodImpl {
return KtLightMethodImpl(computeRealDelegate, origin, containingClass, dummyDelegate)
}
abstract override fun isConstructor(): Boolean
fun fromClsMethods(delegateClass: PsiClass, containingClass: KtLightClass): List<KtLightMethodImpl> = buildList {
for (method in delegateClass.methods) {
if (isSyntheticValuesOrValueOfMethod(method)) continue
this += create(method, getOrigin(method), containingClass)
}
}
abstract override fun getHierarchicalMethodSignature(): HierarchicalMethodSignature
fun getOrigin(method: PsiMethod) = adjustMethodOrigin(getMemberOrigin(method))
}
override fun getThrowsList() = clsDelegate.throwsList
override fun isVarArgs() = (dummyDelegate ?: clsDelegate).isVarArgs
override fun isConstructor() = dummyDelegate?.isConstructor ?: clsDelegate.isConstructor
override fun getHierarchicalMethodSignature() = clsDelegate.hierarchicalMethodSignature
override fun findSuperMethodSignaturesIncludingStatic(checkAccess: Boolean) =
clsDelegate.findSuperMethodSignaturesIncludingStatic(checkAccess)
abstract override fun findSuperMethodSignaturesIncludingStatic(checkAccess: Boolean): List<MethodSignatureBackedByPsiMethod>
override fun getBody() = null
@Suppress("DEPRECATION")
override fun findDeepestSuperMethod() = clsDelegate.findDeepestSuperMethod()
abstract override fun findDeepestSuperMethod(): PsiMethod?
override fun findDeepestSuperMethods() = clsDelegate.findDeepestSuperMethods()
abstract override fun findDeepestSuperMethods(): Array<out PsiMethod>
override fun findSuperMethods() = clsDelegate.findSuperMethods()
abstract override fun findSuperMethods(): Array<out PsiMethod>
override fun findSuperMethods(checkAccess: Boolean) = clsDelegate.findSuperMethods(checkAccess)
abstract override fun findSuperMethods(checkAccess: Boolean): Array<out PsiMethod>
override fun findSuperMethods(parentClass: PsiClass?) = clsDelegate.findSuperMethods(parentClass)
abstract override fun findSuperMethods(parentClass: PsiClass?): Array<out PsiMethod>
}
fun KtLightMethod.isTraitFakeOverride(): Boolean {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.resolve.source.getPsi
abstract class KtLightModifierList<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
protected val owner: T
) : KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierList> {
override val clsDelegate by lazyPub { owner.clsDelegate.modifierList!! }
private val _annotations by lazyPub {
val annotations = computeAnnotations()
annotationsFilter?.let(annotations::filter) ?: annotations
@@ -39,9 +38,13 @@ abstract class KtLightModifierList<out T : KtLightElement<KtModifierListOwner, P
override fun hasExplicitModifier(name: String) = hasModifierProperty(name)
override fun setModifierProperty(name: String, value: Boolean) = clsDelegate.setModifierProperty(name, value)
override fun checkSetModifierProperty(name: String, value: Boolean) = clsDelegate.checkSetModifierProperty(name, value)
override fun addAnnotation(qualifiedName: String) = clsDelegate.addAnnotation(qualifiedName)
private fun throwInvalidOperation(): Nothing = throw IncorrectOperationException()
override fun setModifierProperty(name: String, value: Boolean): Unit = throwInvalidOperation()
override fun checkSetModifierProperty(name: String, value: Boolean): Unit = throwInvalidOperation()
override fun addAnnotation(qualifiedName: String): PsiAnnotation = throwInvalidOperation()
override fun getApplicableAnnotations(): Array<out PsiAnnotation> = annotations
@@ -55,14 +58,7 @@ abstract class KtLightModifierList<out T : KtLightElement<KtModifierListOwner, P
override fun toString() = "Light modifier list of $owner"
protected open fun nonSourceAnnotationsForAnnotationType(sourceAnnotations: List<PsiAnnotation>): List<KtLightAbstractAnnotation> {
val annotations = parent.clsDelegate.modifierList?.annotations
if (annotations.isNullOrEmpty()) return emptyList()
return annotations.map { KtLightNonSourceAnnotation(this, it) }
}
open fun nonSourceAnnotationsForAnnotationType(sourceAnnotations: List<PsiAnnotation>): List<KtLightAbstractAnnotation> = emptyList()
private fun computeAnnotations(): List<KtLightAbstractAnnotation> {
val annotationsForEntries = owner.givenAnnotations ?: lightAnnotationsForEntries(this)
@@ -138,21 +134,7 @@ abstract class KtUltraLightModifierList<out T : KtLightElement<KtModifierListOwn
abstract class KtUltraLightModifierListBase<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
owner: T
) : KtLightModifierList<T>(owner) {
override val clsDelegate: PsiModifierList get() = invalidAccess()
private fun throwInvalidOperation(): Nothing = throw IncorrectOperationException()
override fun setModifierProperty(name: String, value: Boolean): Unit = throwInvalidOperation()
override fun checkSetModifierProperty(name: String, value: Boolean): Unit = throwInvalidOperation()
override fun addAnnotation(qualifiedName: String): PsiAnnotation = throwInvalidOperation()
override fun nonSourceAnnotationsForAnnotationType(sourceAnnotations: List<PsiAnnotation>): List<KtLightAbstractAnnotation> =
emptyList()
}
) : KtLightModifierList<T>(owner)
class KtLightSimpleModifierList(
owner: KtLightElement<KtModifierListOwner, PsiModifierListOwner>, private val modifiers: Set<String>
@@ -181,23 +163,12 @@ private fun lightAnnotationsForEntries(lightModifierList: KtLightModifierList<*>
}
.groupBy({ it.first }) { it.second }
.flatMap { (fqName, entries) ->
entries.mapIndexed { index, entry ->
val lazyClsDelegate = if (lightModifierList !is KtUltraLightModifierList) {
lazyPub {
lightModifierList.clsDelegate.annotations
.filter { it.qualifiedName == fqName }
.getOrNull(index)
?: KtLightNonExistentAnnotation(lightModifierList)
}
} else null
entries.map { entry ->
KtLightAnnotationForSourceEntry(
name = entry.shortName?.identifier,
lazyQualifiedName = { fqName },
kotlinOrigin = entry,
parent = lightModifierList,
lazyClsDelegate = lazyClsDelegate
parent = lightModifierList
)
}
}
@@ -230,8 +201,8 @@ private fun getAnnotationDescriptors(
val annotatedDescriptor = when {
descriptor is ClassDescriptor && annotatedLightElement is KtLightMethod && annotatedLightElement.isConstructor ->
descriptor.unsubstitutedPrimaryConstructor
descriptor !is PropertyDescriptor -> descriptor
annotatedLightElement is KtLightFieldImpl.KtLightEnumConstant -> descriptor
annotatedLightElement is KtLightField -> descriptor.backingField
annotatedLightElement !is KtLightMethod -> descriptor
annotatedLightElement.isGetter -> descriptor.getter
@@ -1,118 +0,0 @@
/*
* Copyright 2000-2017 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.elements
import com.intellij.lang.Language
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.Computable
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.SearchScope
import com.intellij.util.IncorrectOperationException
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
internal class KtLightParameterImpl(
private val dummyDelegate: PsiParameter,
private val clsDelegateProvider: () -> PsiParameter?,
private val index: Int,
method: KtLightMethod
) : LightParameter(dummyDelegate.name, dummyDelegate.type, method, KotlinLanguage.INSTANCE),
KtLightDeclaration<KtParameter, PsiParameter>, KtLightParameter {
private val lazyDelegate by lazyPub { clsDelegateProvider() ?: dummyDelegate }
override val clsDelegate: PsiParameter get() = lazyDelegate
override fun getType(): PsiType = lazyDelegate.type
override fun getName(): String = dummyDelegate.name
private val lightModifierList by lazyPub { KtLightSimpleModifierList(this, emptySet()) }
private val lightIdentifier: KtLightIdentifier? by lazyPub {
KtLightIdentifier(this, kotlinOrigin)
}
override val kotlinOrigin: KtParameter?
get() {
val declaration = method.kotlinOrigin ?: return null
val jetIndex = if (declaration.isExtensionDeclaration()) index - 1 else index
if (jetIndex < 0) return null
if (declaration is KtFunction) {
val paramList = method.lightMemberOrigin?.parametersForJvmOverloads ?: declaration.valueParameters
return if (jetIndex < paramList.size) paramList[jetIndex] else null
}
if (jetIndex != 0) return null
val setter = when (declaration) {
is KtPropertyAccessor -> if (declaration.isSetter) declaration else null
is KtProperty -> declaration.setter
is KtParameter -> return declaration
else -> return null
}
return setter?.parameter
}
override fun getModifierList(): PsiModifierList = lightModifierList
override fun getNavigationElement(): PsiElement = kotlinOrigin ?: super.getNavigationElement()
override fun isValid(): Boolean = method.isValid
@Throws(IncorrectOperationException::class)
override fun setName(@NonNls name: String): PsiElement {
kotlinOrigin?.setName(name)
return this
}
override fun getContainingFile(): PsiFile = method.containingFile
override fun getLanguage(): Language = KotlinLanguage.INSTANCE
override fun getUseScope(): SearchScope {
return kotlinOrigin?.useScope ?: LocalSearchScope(this)
}
override fun getText(): String = kotlinOrigin?.text ?: ""
override fun getTextRange(): TextRange = kotlinOrigin?.textRange ?: TextRange.EMPTY_RANGE
override fun getNameIdentifier(): PsiIdentifier? = lightIdentifier
override fun getParent(): PsiElement = method.parameterList
override fun isEquivalentTo(another: PsiElement?): Boolean {
if (this === another) return true
return ApplicationManager.getApplication().runReadAction(Computable<Boolean> {
if (another is KtParameter) {
val kotlinOrigin = kotlinOrigin
if (kotlinOrigin?.isEquivalentTo(another) == true) return@Computable true
}
if (another is KtLightParameterImpl) {
return@Computable kotlinOrigin != null && kotlinOrigin == another.kotlinOrigin && clsDelegate == another.clsDelegate
}
false
})
}
override fun equals(other: Any?): Boolean {
return other is PsiElement && isEquivalentTo(other)
}
override fun hashCode(): Int = kotlinOrigin?.hashCode() ?: 0
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -14,37 +14,31 @@ import org.jetbrains.kotlin.asJava.classes.lazyPub
class KtLightPsiJavaCodeReferenceElement(
private val ktElement: PsiElement,
reference: () -> PsiReference?,
clsDelegateProvider: () -> PsiJavaCodeReferenceElement?,
private val customReferenceName: String? = null,
) :
PsiElement by ktElement,
PsiReference by LazyPsiReferenceDelegate(ktElement, reference),
PsiJavaCodeReferenceElement {
private val delegate by lazyPub(clsDelegateProvider)
override fun advancedResolve(incompleteCode: Boolean): JavaResolveResult = JavaResolveResult.EMPTY
override fun advancedResolve(incompleteCode: Boolean): JavaResolveResult =
delegate?.advancedResolve(incompleteCode) ?: JavaResolveResult.EMPTY
override fun getReferenceNameElement(): PsiElement? = null
override fun getReferenceNameElement(): PsiElement? = delegate?.referenceNameElement
override fun getTypeParameters(): Array<PsiType> = emptyArray()
override fun getTypeParameters(): Array<PsiType> = delegate?.typeParameters ?: emptyArray()
override fun getReferenceName(): String? = customReferenceName
override fun getReferenceName(): String? = customReferenceName ?: delegate?.referenceName
override fun isQualified(): Boolean = false
override fun isQualified(): Boolean = delegate?.isQualified ?: false
override fun processVariants(processor: PsiScopeProcessor) = Unit
override fun processVariants(processor: PsiScopeProcessor) {
delegate?.processVariants(processor)
}
override fun multiResolve(incompleteCode: Boolean): Array<JavaResolveResult> = emptyArray()
override fun multiResolve(incompleteCode: Boolean): Array<JavaResolveResult> = delegate?.multiResolve(incompleteCode) ?: emptyArray()
override fun getQualifiedName(): String? = null
override fun getQualifiedName(): String? = delegate?.qualifiedName
override fun getQualifier(): PsiElement? = null
override fun getQualifier(): PsiElement? = delegate?.qualifier
override fun getParameterList(): PsiReferenceParameterList? = delegate?.parameterList
override fun getParameterList(): PsiReferenceParameterList? = null
}
private class LazyPsiReferenceDelegate(
@@ -1,75 +0,0 @@
/*
* Copyright 2010-2016 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.elements
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiJavaCodeReferenceElement
import com.intellij.psi.PsiReferenceList
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.addSuperTypeEntry
import org.jetbrains.kotlin.asJava.classes.findEntry
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.psi.KtSuperTypeList
import org.jetbrains.kotlin.psi.KtSuperTypeListEntry
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
class KtLightPsiReferenceList(
override val clsDelegate: PsiReferenceList,
private val owner: KtLightClass
) : KtLightElement<KtSuperTypeList, PsiReferenceList>, PsiReferenceList by clsDelegate {
inner class KtLightSuperTypeReference(
override val clsDelegate: PsiJavaCodeReferenceElement
) : KtLightElement<KtSuperTypeListEntry, PsiJavaCodeReferenceElement>, PsiJavaCodeReferenceElement by clsDelegate {
override val kotlinOrigin by lazyPub {
clsDelegate.qualifiedName?.let { this@KtLightPsiReferenceList.kotlinOrigin?.findEntry(it) }
}
override fun getParent() = this@KtLightPsiReferenceList
override fun delete() {
val superTypeList = this@KtLightPsiReferenceList.kotlinOrigin ?: return
val entry = kotlinOrigin ?: return
superTypeList.removeEntry(entry)
}
override fun getTextRange(): TextRange? = kotlinOrigin?.typeReference?.textRange ?: TextRange.EMPTY_RANGE
}
override val kotlinOrigin: KtSuperTypeList?
get() = owner.kotlinOrigin?.getSuperTypeList()
private val _referenceElements by lazyPub {
clsDelegate.referenceElements.map { KtLightSuperTypeReference(it) }.toTypedArray()
}
override fun getParent() = owner
override fun getReferenceElements() = _referenceElements
override fun add(element: PsiElement): PsiElement? {
if (element !is KtLightSuperTypeReference) throw UnsupportedOperationException("Unexpected element: ${element.getElementTextWithContext()}")
val superTypeList = kotlinOrigin ?: return element
val entry = element.kotlinOrigin ?: return element
this.addSuperTypeEntry(superTypeList, entry, element)
return element
}
}
@@ -1,184 +0,0 @@
/*
* Copyright 2010-2016 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.elements;
import com.intellij.lang.Language;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.AbstractLightClass;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.asJava.LightClassUtilsKt;
import org.jetbrains.kotlin.asJava.classes.KtLightClass;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.psi.KtTypeParameter;
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner;
import java.util.List;
public class KtLightTypeParameter
extends AbstractLightClass implements PsiTypeParameter, KtLightDeclaration<KtTypeParameter, PsiTypeParameter> {
private final PsiTypeParameterListOwner owner;
private final int index;
private final String name;
public KtLightTypeParameter(
@NotNull PsiTypeParameterListOwner owner,
int index,
@NotNull String name
) {
super(owner.getManager(), KotlinLanguage.INSTANCE);
this.owner = owner;
this.index = index;
this.name = name;
}
@NotNull
@Override
public PsiTypeParameter getClsDelegate() {
return getOwnerDelegate().getTypeParameters()[index];
}
@NotNull
@Override
public PsiClass getDelegate() {
return getClsDelegate();
}
@NotNull
@Override
public KtTypeParameter getKotlinOrigin() {
KtTypeParameterListOwner jetOwner = (KtTypeParameterListOwner) LightClassUtilsKt.getUnwrapped(owner);
assert (jetOwner != null) : "Invalid type parameter owner: " + owner;
return jetOwner.getTypeParameters().get(index);
}
@NotNull
private PsiTypeParameterListOwner getOwnerDelegate() {
if (owner instanceof KtLightClass) return ((KtLightClass) owner).getClsDelegate();
if (owner instanceof KtLightMethod) return ((KtLightMethod) owner).getClsDelegate();
return owner;
}
@NotNull
@Override
public PsiElement copy() {
return new KtLightTypeParameter(owner, index, name);
}
@Override
public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof JavaElementVisitor) {
((JavaElementVisitor) visitor).visitTypeParameter(this);
}
else {
super.accept(visitor);
}
}
@Override
public String getText() {
return "";
}
@Nullable
@Override
public String getName() {
return name;
}
@Override
public PsiTypeParameterListOwner getOwner() {
return owner;
}
@Override
public int getIndex() {
return index;
}
@NotNull
@Override
public PsiAnnotation[] getAnnotations() {
return getClsDelegate().getAnnotations();
}
@NotNull
@Override
public PsiAnnotation[] getApplicableAnnotations() {
return getClsDelegate().getApplicableAnnotations();
}
@Override
public PsiAnnotation findAnnotation(@NotNull String qualifiedName) {
return getClsDelegate().findAnnotation(qualifiedName);
}
@NotNull
@Override
public PsiAnnotation addAnnotation(@NotNull String qualifiedName) {
return getClsDelegate().addAnnotation(qualifiedName);
}
@Override
public String toString() {
return "KotlinLightTypeParameter:" + getName();
}
@NotNull
@Override
public PsiElement getNavigationElement() {
return getKotlinOrigin();
}
@NotNull
@Override
public Language getLanguage() {
return KotlinLanguage.INSTANCE;
}
@NotNull
@Override
public SearchScope getUseScope() {
return getKotlinOrigin().getUseScope();
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
return obj instanceof KtLightTypeParameter && getKotlinOrigin().equals(((KtLightTypeParameter) obj).getKotlinOrigin());
}
@Override
public boolean isEquivalentTo(PsiElement another) {
if (another instanceof PsiTypeParameter) {
PsiTypeParameter anotherTypeParameter = (PsiTypeParameter) another;
PsiTypeParameterListOwner owner = getOwner();
if (owner != null) {
return owner.isEquivalentTo(anotherTypeParameter.getOwner()) && getIndex() == anotherTypeParameter.getIndex();
}
}
return false;
}
@Nullable
@Override
public List<KtLightAbstractAnnotation> getGivenAnnotations() {
return null;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -152,7 +152,6 @@ internal fun PsiAnnotation.tryConvertAsRepeatable(
KtLightPsiJavaCodeReferenceElement(
ktElement = it,
reference = { null },
clsDelegateProvider = { null },
customReferenceName = JAVA_LANG_ANNOTATION_REPEATABLE_SHORT_NAME,
)
}
@@ -1,17 +1,14 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava.elements
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub
@@ -28,12 +25,12 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.util.getType
import org.jetbrains.kotlin.resolve.calls.components.isVararg
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.util.getType
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.types.KotlinType
@@ -43,22 +40,14 @@ import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.types.typeUtil.nullability
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.asJava.elements.lightAnnotations")
abstract class KtLightAbstractAnnotation(parent: PsiElement, computeDelegate: Lazy<PsiAnnotation>?) :
abstract class KtLightAbstractAnnotation(parent: PsiElement) :
KtLightElementBase(parent), PsiAnnotation, KtLightElement<KtCallElement, PsiAnnotation> {
override val clsDelegate: PsiAnnotation by lazyPub {
if (!accessAnnotationsClsDelegateIsAllowed && ApplicationManager.getApplication().isUnitTestMode && this !is KtLightNonSourceAnnotation)
LOG.error("KtLightAbstractAnnotation clsDelegate requested for ${this.javaClass}")
computeDelegate?.value ?: throw IllegalStateException("Cannot get class delegate for annotation light class")
}
override fun getNameReferenceElement() = clsDelegate.nameReferenceElement
abstract override fun getNameReferenceElement(): PsiJavaCodeReferenceElement?
override fun getOwner(): PsiAnnotationOwner? = parent as? PsiAnnotationOwner
override fun getParameterList(): PsiAnnotationParameterList = clsDelegate.parameterList
abstract override fun getParameterList(): PsiAnnotationParameterList
open fun fqNameMatches(fqName: String): Boolean = qualifiedName == fqName
}
@@ -67,9 +56,8 @@ class KtLightAnnotationForSourceEntry(
private val name: String?,
private val lazyQualifiedName: () -> String?,
override val kotlinOrigin: KtCallElement,
parent: PsiElement,
private val lazyClsDelegate: Lazy<PsiAnnotation>?
) : KtLightAbstractAnnotation(parent, lazyClsDelegate) {
parent: PsiElement
) : KtLightAbstractAnnotation(parent) {
private val _qualifiedName: String? by lazyPub { lazyQualifiedName() }
@@ -101,6 +89,7 @@ class KtLightAnnotationForSourceEntry(
when (val psiElement = callEntry.key.source.getPsi()) {
is KtParameter ->
return psiElement.defaultValue?.let { convertToLightAnnotationMemberValue(this, it) }
is PsiAnnotationMethod ->
return psiElement.defaultValue
}
@@ -116,7 +105,6 @@ class KtLightAnnotationForSourceEntry(
(kotlinOrigin as? KtAnnotationEntry)?.typeReference?.reference
?: (kotlinOrigin.calleeExpression?.nameReference)?.references?.firstOrNull()
},
{ lazyClsDelegate?.value?.nameReferenceElement },
if (qualifiedName == CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE) JAVA_LANG_ANNOTATION_REPEATABLE_SHORT_NAME else null,
)
@@ -232,40 +220,13 @@ class KtLightAnnotationForSourceEntry(
override fun <T : PsiAnnotationMemberValue?> setDeclaredAttributeValue(attributeName: String?, value: T?) = cannotModify()
}
class KtLightNonSourceAnnotation(
parent: PsiElement, clsDelegate: PsiAnnotation
) : KtLightAbstractAnnotation(parent, lazyPub { clsDelegate }) {
override val kotlinOrigin: KtAnnotationEntry? get() = null
override fun getQualifiedName() = kotlinOrigin?.name ?: clsDelegate.qualifiedName
override fun <T : PsiAnnotationMemberValue?> setDeclaredAttributeValue(attributeName: String?, value: T?) = cannotModify()
override fun findAttributeValue(attributeName: String?) = clsDelegate.findAttributeValue(attributeName)
override fun findDeclaredAttributeValue(attributeName: String?) = clsDelegate.findDeclaredAttributeValue(attributeName)
}
class KtLightNonExistentAnnotation(parent: KtLightElement<*, *>) : KtLightElementBase(parent), PsiAnnotation {
override val kotlinOrigin: KtElement? get() = null
override fun toString(): String = this.javaClass.name
override fun <T : PsiAnnotationMemberValue?> setDeclaredAttributeValue(attributeName: String?, value: T?) = cannotModify()
override fun getNameReferenceElement(): PsiJavaCodeReferenceElement? = null
override fun findAttributeValue(attributeName: String?): PsiAnnotationMemberValue? = null
override fun getQualifiedName(): String? = null
override fun getOwner(): PsiAnnotationOwner? = parent as? PsiAnnotationOwner
override fun findDeclaredAttributeValue(attributeName: String?): PsiAnnotationMemberValue? = null
override fun getParameterList(): KtLightEmptyAnnotationParameterList = KtLightEmptyAnnotationParameterList(this)
}
class KtLightEmptyAnnotationParameterList(parent: PsiElement) : KtLightElementBase(parent), PsiAnnotationParameterList {
override val kotlinOrigin: KtElement? get() = null
override fun getAttributes(): Array<PsiNameValuePair> = emptyArray()
}
open class KtLightNullabilityAnnotation<D : KtLightElement<*, PsiModifierListOwner>>(val member: D, parent: PsiElement) :
KtLightAbstractAnnotation(parent, lazyPub {
// searching for last because nullability annotations are generated after backend generates source annotations
getClsNullabilityAnnotation(member) ?: KtLightNonExistentAnnotation(member)
}) {
KtLightAbstractAnnotation(parent) {
override fun fqNameMatches(fqName: String): Boolean {
if (!isNullabilityAnnotation(fqName)) return false
@@ -280,7 +241,7 @@ open class KtLightNullabilityAnnotation<D : KtLightElement<*, PsiModifierListOwn
private val _qualifiedName: String? by lazyPub {
val annotatedElement = member.takeIf(::isFromSources)?.kotlinOrigin
?: // it is out of our hands
return@lazyPub getClsNullabilityAnnotation(member)?.qualifiedName
return@lazyPub null
if (!fastCheckIsNullabilityApplied(member)) return@lazyPub null
@@ -362,14 +323,6 @@ open class KtLightNullabilityAnnotation<D : KtLightElement<*, PsiModifierListOwn
override fun findDeclaredAttributeValue(attributeName: String?): PsiAnnotationMemberValue? = null
}
private fun getClsNullabilityAnnotation(member: KtLightElement<*, PsiModifierListOwner>): PsiAnnotation? {
if (!accessAnnotationsClsDelegateIsAllowed && ApplicationManager.getApplication().isUnitTestMode && isFromSources(member) && member.kotlinOrigin != null)
LOG.error("nullability should be retrieved from `kotlinOrigin`")
return member.clsDelegate.modifierList?.annotations?.findLast {
isNullabilityAnnotation(it.qualifiedName)
}
}
internal fun isNullabilityAnnotation(qualifiedName: String?) = qualifiedName in backendNullabilityAnnotations
private val backendNullabilityAnnotations = arrayOf(Nullable::class.java.name, NotNull::class.java.name)
@@ -388,9 +341,11 @@ fun convertToLightAnnotationMemberValue(lightParent: PsiElement, argument: KtExp
is KtClassLiteralExpression -> {
return KtLightPsiClassObjectAccessExpression(argument, lightParent)
}
is KtStringTemplateExpression, is KtConstantExpression -> {
return KtLightPsiLiteral(argument, lightParent)
}
is KtCallExpression -> {
val arguments = argument.valueArguments
val annotationName = argument.calleeExpression?.let { getAnnotationName(it) }
@@ -399,8 +354,7 @@ fun convertToLightAnnotationMemberValue(lightParent: PsiElement, argument: KtExp
name = annotationName,
lazyQualifiedName = { annotationName },
kotlinOrigin = argument,
parent = lightParent,
lazyClsDelegate = null
parent = lightParent
)
}
val resolvedCall = argument.getResolvedCall()
@@ -414,6 +368,7 @@ fun convertToLightAnnotationMemberValue(lightParent: PsiElement, argument: KtExp
}
}
}
is KtCollectionLiteralExpression -> {
val arguments = argument.getInnerExpressions()
if (arguments.isNotEmpty())
@@ -451,17 +406,3 @@ private fun getAnnotationName(callee: KtExpression): String? {
}
return null
}
@get:TestOnly
var accessAnnotationsClsDelegateIsAllowed = false
@TestOnly
fun <T> withAllowedAnnotationsClsDelegate(body: () -> T): T {
val prev = accessAnnotationsClsDelegateIsAllowed
try {
accessAnnotationsClsDelegateIsAllowed = true
return body()
} finally {
accessAnnotationsClsDelegateIsAllowed = prev
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -229,9 +229,7 @@ fun KtLightMethod.checkIsMangled(): Boolean {
}
fun fastCheckIsNullabilityApplied(lightElement: KtLightElement<*, PsiModifierListOwner>): Boolean {
val elementIsApplicable =
(lightElement is KtLightMember<*> && lightElement !is KtLightFieldImpl.KtLightEnumConstant) || lightElement is LightParameter
val elementIsApplicable = lightElement is KtLightMember<*> || lightElement is LightParameter
if (!elementIsApplicable) return false
val annotatedElement = lightElement.kotlinOrigin ?: return true
@@ -1,215 +0,0 @@
/*
* Copyright 2010-2016 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;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.search.GlobalSearchScope;
import junit.framework.ComparisonFailure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.asJava.classes.KtLightClass;
import org.jetbrains.kotlin.asJava.classes.KtUltraLightSupport;
import org.jetbrains.kotlin.name.SpecialNames;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
public class KotlinLightClassCoherenceTest extends KotlinAsJavaTestBase {
@Override
protected List<File> getKotlinSourceRoots() {
return Lists.newArrayList(
new File("compiler/testData/asJava/lightClassStructure/Declared.kt"),
new File("compiler/testData/asJava/lightClassStructure/Package.kt"),
new File("compiler/testData/asJava/lightClassStructure/ClassObject.kt")
);
}
@NotNull
protected PsiClass doTest() {
return doTest("test." + getTestName(false));
}
@NotNull
protected PsiClass doTest(String qualifiedName) {
boolean forceFlag = KtUltraLightSupport.Companion.getForceUsingOldLightClasses();
KtLightClass psiClass;
try {
KtUltraLightSupport.Companion.setForceUsingOldLightClasses(true);
psiClass = (KtLightClass) finder.findClass(qualifiedName, GlobalSearchScope.allScope(getProject()));
} finally {
KtUltraLightSupport.Companion.setForceUsingOldLightClasses(forceFlag);
}
assertNotNull("Class not found: " + qualifiedName, psiClass);
Asserter asserter = new Asserter();
asserter.assertModifiersCoherent(psiClass);
asserter.assertPropertyCoherent(psiClass, "isInterface");
asserter.assertPropertyCoherent(psiClass, "isAnnotationType");
asserter.assertPropertyCoherent(psiClass, "isEnum");
asserter.assertPropertyCoherent(psiClass, "hasTypeParameters");
asserter.assertPropertyCoherent(psiClass, "isDeprecated");
asserter.reportFailures();
return psiClass;
}
static class Asserter {
private final List<ComparisonFailure> failures = Lists.newArrayList();
private void assertEquals(String message, Object expected, Object actual) {
if (!Comparing.equal(expected, actual)) {
failures.add(new ComparisonFailure(message, String.valueOf(expected), String.valueOf(actual)));
}
}
public void assertModifiersCoherent(KtLightClass lightClass) {
PsiClass delegate = lightClass.getClsDelegate();
for (String modifier : PsiModifier.MODIFIERS) {
assertEquals("Incoherent modifier: " + modifier,
delegate.hasModifierProperty(modifier),
lightClass.hasModifierProperty(modifier));
}
}
public void assertPropertyCoherent(KtLightClass lightClass, String methodName) {
try {
Method method = PsiClass.class.getMethod(methodName);
Object lightResult = method.invoke(lightClass);
Object delegateResult = method.invoke(lightClass.getClsDelegate());
assertEquals("Result of method " + methodName + "() differs in light class and its delegate", delegateResult, lightResult);
}
catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new AssertionError(e);
}
}
public void reportFailures() {
if (failures.size() == 1) {
throw failures.get(0);
}
if (!failures.isEmpty()) {
StringBuilder builder = new StringBuilder("\n");
for (ComparisonFailure failure : failures) {
builder.append(failure.getMessage()).append("\n");
}
fail(builder.toString());
}
}
}
public void testFileFacade() throws Exception {
doTest("test.PackageKt");
}
public void testNoModifiers() throws Exception {
doTest();
}
public void testPublic() throws Exception {
doTest();
}
public void testPrivate() throws Exception {
doTest();
}
public void testInternal() throws Exception {
doTest();
}
public void testNestedPublic() throws Exception {
doTest("test.Outer.Public");
}
public void testNestedProtected() throws Exception {
doTest("test.Outer.Protected");
}
public void testNestedInternal() throws Exception {
doTest("test.Outer.Internal");
}
public void testNestedPrivate() throws Exception {
doTest("test.Outer.Private");
}
public void testInner() throws Exception {
doTest("test.Outer.Inner");
}
public void testAbstract() throws Exception {
doTest();
}
public void testOpen() throws Exception {
doTest();
}
public void testFinal() throws Exception {
doTest();
}
public void testAnnotation() throws Exception {
doTest();
}
public void testEnum() throws Exception {
doTest();
}
public void testTrait() throws Exception {
doTest();
}
public void testDeprecatedClass() throws Exception {
doTest();
}
public void testDeprecatedFQN() throws Exception {
doTest();
}
public void testDeprecatedFQNSpaces() throws Exception {
doTest();
}
public void testDeprecatedWithBrackets() throws Exception {
doTest();
}
public void testDeprecatedWithBracketsFQN() throws Exception {
doTest();
}
public void testDeprecatedWithBracketsFQNSpaces() throws Exception {
doTest();
}
public void testClassObject() throws Exception {
doTest("test.WithClassObject." + SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.asString());
}
}
@@ -1,17 +1,6 @@
/*
* 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.
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.asJava
@@ -24,8 +13,8 @@ import java.io.File
class KotlinLightClassTest : KotlinAsJavaTestBase() {
override fun getKotlinSourceRoots(): List<File> = listOf(
File("compiler/testData/asJava/lightClassStructure/ClassObject.kt"),
File("compiler/testData/asJava/lightClasses/ideRegression/ImplementingMap.kt")
File("compiler/testData/asJava/lightClassStructure/ClassObject.kt"),
File("compiler/testData/asJava/lightClasses/ideRegression/ImplementingMap.kt")
)
private val key = Key.create<String>("testKey")