[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 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 import org.jetbrains.kotlin.psi.KtClassOrObject
open class KtLightClassForDecompiledDeclaration( open class KtLightClassForDecompiledDeclaration(
override val clsDelegate: PsiClass, clsDelegate: PsiClass,
private val clsParent: PsiElement, private val clsParent: PsiElement,
private val file: KtClsFile, private val file: KtClsFile,
kotlinOrigin: KtClassOrObject? 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 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 import org.jetbrains.kotlin.psi.KtClassOrObject
abstract class KtLightClassForDecompiledDeclarationBase( abstract class KtLightClassForDecompiledDeclarationBase(
override val clsDelegate: PsiClass, val clsDelegate: PsiClass,
clsParent: PsiElement, clsParent: PsiElement,
final override val kotlinOrigin: KtClassOrObject? final override val kotlinOrigin: KtClassOrObject?
) : KtLightElementBase(clsParent), PsiClass, KtExtensibleLightClass ) : 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 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 fun toString(): String = "${this.javaClass.simpleName} of $fldParent"
override val clsDelegate: PsiField = fldDelegate
override fun isValid(): Boolean = parent.isValid 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 package org.jetbrains.kotlin.analysis.decompiled.light.classes
@@ -97,8 +100,6 @@ class KtLightMethodForDecompiledDeclaration(
override fun toString(): String = "${this.javaClass.simpleName} of $funParent" override fun toString(): String = "${this.javaClass.simpleName} of $funParent"
override val clsDelegate: PsiMethod = funDelegate
override fun isValid(): Boolean = parent.isValid 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. * 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, private val containingClass: KtLightClass,
) : KtLightElementBase(containingClass), PsiMember, KtLightMember<T> { ) : KtLightElementBase(containingClass), PsiMember, KtLightMember<T> {
override val clsDelegate: T
get() = invalidAccess()
override fun hasModifierProperty(name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false override fun hasModifierProperty(name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false
override fun toString(): String = "${this::class.java.simpleName}:$name" 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. * 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) : internal abstract class FirLightAbstractAnnotation(parent: PsiElement) :
KtLightElementBase(parent), PsiAnnotation, KtLightElement<KtCallElement, PsiAnnotation> { KtLightElementBase(parent), PsiAnnotation, KtLightElement<KtCallElement, PsiAnnotation> {
override val clsDelegate: PsiAnnotation
get() = invalidAccess()
override fun getOwner() = parent as? PsiAnnotationOwner override fun getOwner() = parent as? PsiAnnotationOwner
private val KtExpression.nameReference: KtNameReferenceExpression? private val KtExpression.nameReference: KtNameReferenceExpression?
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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.light.classes.symbol package org.jetbrains.kotlin.light.classes.symbol
@@ -30,19 +19,16 @@ import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.PsiUtil import com.intellij.psi.util.PsiUtil
import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt 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.api.lifetime.allowAnalysisOnEdt
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.asJava.classes.* import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.light.classes.symbol.classes.checkIsInheritor import org.jetbrains.kotlin.light.classes.symbol.classes.checkIsInheritor
import javax.swing.Icon import javax.swing.Icon
abstract class FirLightClassBase protected constructor( abstract class FirLightClassBase protected constructor(
manager: PsiManager manager: PsiManager
) : LightElement(manager, KotlinLanguage.INSTANCE), PsiClass, KtExtensibleLightClass { ) : LightElement(manager, KotlinLanguage.INSTANCE), PsiClass, KtExtensibleLightClass {
override val clsDelegate: PsiClass
get() = invalidAccess()
private class FirLightClassesLazyCreator(private val project: Project) : KotlinClassInnerStuffCache.LazyCreator() { private class FirLightClassesLazyCreator(private val project: Project) : KotlinClassInnerStuffCache.LazyCreator() {
@OptIn(KtAllowAnalysisOnEdt::class) @OptIn(KtAllowAnalysisOnEdt::class)
override fun <T : Any> get(initializer: () -> T, dependencies: List<Any>): Lazy<T> = object : Lazy<T> { 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. * 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.LightEmptyImplementsList
import com.intellij.psi.impl.light.LightModifierList import com.intellij.psi.impl.light.LightModifierList
import org.jetbrains.annotations.NonNls 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.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass 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.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.idea.KotlinLanguage 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.analyseForLightClasses
import org.jetbrains.kotlin.light.classes.symbol.classes.createField import org.jetbrains.kotlin.light.classes.symbol.classes.createField
import org.jetbrains.kotlin.light.classes.symbol.classes.createMethods import org.jetbrains.kotlin.light.classes.symbol.classes.createMethods
@@ -50,8 +50,6 @@ class FirLightClassForFacade(
private val firstFileInFacade by lazyPub { files.first() } private val firstFileInFacade by lazyPub { files.first() }
override val clsDelegate: PsiClass get() = invalidAccess()
private val fileSymbols by lazyPub { private val fileSymbols by lazyPub {
files.map { ktFile -> files.map { ktFile ->
analyseForLightClasses(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. * 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 import org.jetbrains.kotlin.psi.KtFile
internal class KtLightClassForDecompiledFacade( internal class KtLightClassForDecompiledFacade(
override val clsDelegate: PsiClass, clsDelegate: PsiClass,
clsParent: PsiElement, clsParent: PsiElement,
file: KtClsFile, file: KtClsFile,
kotlinOrigin: KtClassOrObject?, 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. * 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, private val containingClass: KtLightClass,
lightMemberOrigin: LightMemberOrigin?, lightMemberOrigin: LightMemberOrigin?,
) : FirLightMemberImpl<PsiField>(lightMemberOrigin, containingClass), KtLightField { ) : FirLightMemberImpl<PsiField>(lightMemberOrigin, containingClass), KtLightField {
override val clsDelegate: PsiField get() = invalidAccess()
override fun setInitializer(initializer: PsiExpression?) = cannotModify() override fun setInitializer(initializer: PsiExpression?) = cannotModify()
override fun isEquivalentTo(another: PsiElement?): Boolean = 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. * 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 protected val owner: T
) : KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierListOwner> { ) : KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierListOwner> {
override val clsDelegate: PsiModifierListOwner
get() = invalidAccess()
override val kotlinOrigin: KtModifierList? override val kotlinOrigin: KtModifierList?
get() = owner.kotlinOrigin?.modifierList 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. * 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, internal abstract class FirLightParameter(containingDeclaration: FirLightMethod) : PsiVariable, NavigationItem,
KtLightElement<KtParameter, PsiParameter>, KtLightParameter, KtLightElementBase(containingDeclaration) { KtLightElement<KtParameter, PsiParameter>, KtLightParameter, KtLightElementBase(containingDeclaration) {
override val clsDelegate: PsiParameter
get() = invalidAccess()
override val givenAnnotations: List<KtLightAbstractAnnotation> override val givenAnnotations: List<KtLightAbstractAnnotation>
get() = invalidAccess() 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. * 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.PsiParameter
import com.intellij.psi.PsiParameterList import com.intellij.psi.PsiParameterList
import com.intellij.psi.impl.light.LightParameterListBuilder 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.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightElementBase 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.KtFunction
import org.jetbrains.kotlin.psi.KtParameterList import org.jetbrains.kotlin.psi.KtParameterList
@@ -28,7 +28,7 @@ internal class FirLightParameterList(
override val kotlinOrigin: KtParameterList? override val kotlinOrigin: KtParameterList?
get() = (parent.kotlinOrigin as? KtFunction)?.valueParameterList get() = (parent.kotlinOrigin as? KtFunction)?.valueParameterList
override val clsDelegate: PsiParameterList by lazyPub { private val clsDelegate: PsiParameterList by lazyPub {
val builder = LightParameterListBuilder(manager, language) val builder = LightParameterListBuilder(manager, language)
callableSymbol?.let { 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. * 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, ) : LightElement(parent.manager, KotlinLanguage.INSTANCE), PsiTypeParameter,
KtLightDeclaration<KtTypeParameter, PsiTypeParameter> { KtLightDeclaration<KtTypeParameter, PsiTypeParameter> {
override val clsDelegate: PsiTypeParameter get() = invalidAccess()
override val givenAnnotations: List<KtLightAbstractAnnotation>? get() = invalidAccess() override val givenAnnotations: List<KtLightAbstractAnnotation>? get() = invalidAccess()
override val kotlinOrigin: KtTypeParameter? = typeParameterSymbol.psi as? KtTypeParameter 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. * 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 com.intellij.util.SmartList
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.asJava.classes.* import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer
@@ -109,11 +108,9 @@ class CliKotlinAsJavaSupport(
).mapNotNull { member -> (member as? PackageViewDescriptor)?.fqName } ).mapNotNull { member -> (member as? PackageViewDescriptor)?.fqName }
} }
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = KtLightClassForSourceDeclaration.create(classOrObject)
KtLightClassForSourceDeclaration.create(classOrObject, traceHolder.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode))
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
KtLightClassForScript.create(script)
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> { override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
return ResolveSessionUtils.getClassDescriptorsByFqName(traceHolder.module, fqName).mapNotNull { return ResolveSessionUtils.getClassDescriptorsByFqName(traceHolder.module, fqName).mapNotNull {
@@ -130,6 +127,5 @@ class CliKotlinAsJavaSupport(
}.orEmpty() }.orEmpty()
} }
override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass = override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass = error("Should not be called")
error("Should not be called")
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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.cli.jvm.compiler 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.ClassBuilderMode
import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -105,9 +93,6 @@ class CliLightClassGenerationSupport(
return ultraLightSupport return ultraLightSupport
} }
override val useUltraLightClasses: Boolean
get() = !KtUltraLightSupport.forceUsingOldLightClasses && !traceHolder.languageVersionSettings.getFlag(JvmAnalysisFlags.disableUltraLightClasses)
override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass { override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {
//force resolve companion for light class generation //force resolve companion for light class generation
traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
@@ -1,27 +1,13 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.asJava
import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project 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.PsiManager
import com.intellij.psi.util.CachedValue
import org.jetbrains.kotlin.asJava.builder.LightClassBuilderResult import org.jetbrains.kotlin.asJava.builder.LightClassBuilderResult
import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
@@ -59,18 +45,11 @@ abstract class LightClassGenerationSupport {
ConstantExpressionEvaluator(moduleDescriptor, languageVersionSettings, expression.project) ConstantExpressionEvaluator(moduleDescriptor, languageVersionSettings, expression.project)
} }
abstract val useUltraLightClasses: Boolean internal fun canCreateUltraLightClassForFacade(files: Collection<KtFile>): Boolean = files.none { it.isScript() }
internal fun canCreateUltraLightClassForFacade(
files: Collection<KtFile>,
): Boolean {
return useUltraLightClasses && files.none { it.isScript() }
}
fun createUltraLightClassForFacade( fun createUltraLightClassForFacade(
manager: PsiManager, manager: PsiManager,
facadeClassFqName: FqName, facadeClassFqName: FqName,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
files: Collection<KtFile>, files: Collection<KtFile>,
): KtUltraLightClassForFacade? { ): KtUltraLightClassForFacade? {
if (!canCreateUltraLightClassForFacade(files)) return null if (!canCreateUltraLightClassForFacade(files)) return null
@@ -82,16 +61,12 @@ abstract class LightClassGenerationSupport {
return KtUltraLightClassForFacade( return KtUltraLightClassForFacade(
manager, manager,
facadeClassFqName, facadeClassFqName,
lightClassDataCache,
files, files,
filesToSupports filesToSupports
) )
} }
fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? { fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? {
if (!useUltraLightClasses) return null
if (element.shouldNotBeVisibleAsLightClass()) { if (element.shouldNotBeVisibleAsLightClass()) {
return null return null
} }
@@ -117,8 +92,8 @@ abstract class LightClassGenerationSupport {
} }
} }
fun createUltraLightClassForScript(script: KtScript): KtUltraLightClassForScript? = fun createUltraLightClassForScript(script: KtScript): KtUltraLightClassForScript =
if (useUltraLightClasses) KtUltraLightClassForScript(script, support = getUltraLightClassSupport(script)) else null KtUltraLightClassForScript(script, support = getUltraLightClassSupport(script))
companion object { companion object {
@JvmStatic @JvmStatic
@@ -1,22 +1,14 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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 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.impl.java.stubs.PsiClassStub
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.PsiFileStub import com.intellij.psi.stubs.PsiFileStub
@@ -24,7 +16,10 @@ import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.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.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.load.java.JvmAbi 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( class PropertyAccessorsPsiMethods(
val getter: PsiMethod?, val getter: PsiMethod?,
val setter: 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. * 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 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.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.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
interface LightClassDataHolder { interface LightClassDataHolder {
val javaFileStub: PsiJavaFileStub val javaFileStub: PsiJavaFileStub
val extraDiagnostics: Diagnostics val extraDiagnostics: Diagnostics
fun findData(findDelegate: (PsiJavaFileStub) -> PsiClass): LightClassData interface ForClass : LightClassDataHolder
interface ForFacade : LightClassDataHolder
interface ForClass : LightClassDataHolder { interface ForScript : ForClass
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)
} }
object InvalidLightClassDataHolder : LightClassDataHolder.ForClass { object InvalidLightClassDataHolder : LightClassDataHolder.ForClass {
@@ -74,50 +24,10 @@ object InvalidLightClassDataHolder : LightClassDataHolder.ForClass {
override val extraDiagnostics: Diagnostics override val extraDiagnostics: Diagnostics
get() = shouldNotBeCalled() get() = shouldNotBeCalled()
override fun findData(findDelegate: (PsiJavaFileStub) -> PsiClass) = shouldNotBeCalled()
private fun shouldNotBeCalled(): Nothing = throw UnsupportedOperationException("Should not be called") private fun shouldNotBeCalled(): Nothing = throw UnsupportedOperationException("Should not be called")
} }
class LightClassDataHolderImpl( class LightClassDataHolderImpl(
override val javaFileStub: PsiJavaFileStub, override val javaFileStub: PsiJavaFileStub,
override val extraDiagnostics: Diagnostics override val extraDiagnostics: Diagnostics
) : LightClassDataHolder.ForClass, LightClassDataHolder.ForFacade, LightClassDataHolder.ForScript { ) : 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 = "]")
}
@@ -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. * 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.PsiClassImplUtil
import com.intellij.psi.impl.PsiImplUtil import com.intellij.psi.impl.PsiImplUtil
import com.intellij.psi.impl.PsiSuperMethodImplUtil 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.impl.light.*
import com.intellij.psi.javadoc.PsiDocComment import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.* import com.intellij.psi.util.*
import com.intellij.util.ArrayUtil import com.intellij.util.ArrayUtil
import com.intellij.util.IncorrectOperationException 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.KtDeclaration
import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.org.objectweb.asm.Opcodes
import java.util.* import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
class KotlinClassInnerStuffCache( class KotlinClassInnerStuffCache(
private val myClass: KtExtensibleLightClass, private val myClass: KtExtensibleLightClass,
@@ -200,8 +191,6 @@ private class KotlinEnumSyntheticMethod(
val nameParameter = object : LightParameter("name", stringType, this, language, false), KtLightParameter { val nameParameter = object : LightParameter("name", stringType, this, language, false), KtLightParameter {
override val method: KtLightMethod get() = this@KotlinEnumSyntheticMethod override val method: KtLightMethod get() = this@KotlinEnumSyntheticMethod
override val kotlinOrigin: KtParameter? get() = null 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 getParent(): PsiElement = this@KotlinEnumSyntheticMethod
override fun getContainingFile(): PsiFile = this@KotlinEnumSyntheticMethod.containingFile override fun getContainingFile(): PsiFile = this@KotlinEnumSyntheticMethod.containingFile
@@ -285,52 +274,7 @@ private class KotlinEnumSyntheticMethod(
override fun getText(): String = "" override fun getText(): String = ""
override fun getTextRange(): TextRange = TextRange.EMPTY_RANGE 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 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 { private fun makeNotNullAnnotation(context: PsiClass): PsiAnnotation {
return PsiElementFactory.getInstance(context.project).createAnnotationFromText("@" + NotNull::class.java.name, context) 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. * 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) } private val _delegate: PsiClass by lazy { DummyJavaPsiFactory.createDummyClass(kotlinOrigin.project) }
override val clsDelegate get() = _delegate
override val originKind get() = LightClassOriginKind.SOURCE override val originKind get() = LightClassOriginKind.SOURCE
override fun getName(): String? = kotlinOrigin.name override fun getName(): String? = kotlinOrigin.name
@@ -93,7 +92,6 @@ class KtFakeLightMethod private constructor(
KotlinLanguage.INSTANCE KotlinLanguage.INSTANCE
), KtLightElement<KtNamedDeclaration, PsiMethod> { ), KtLightElement<KtNamedDeclaration, PsiMethod> {
override val kotlinOrigin get() = ktDeclaration override val kotlinOrigin get() = ktDeclaration
override val clsDelegate get() = myMethod
override fun getName() = ktDeclaration.name ?: "" override fun getName() = ktDeclaration.name ?: ""
@@ -1,30 +1,10 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiManager import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.asJava.builder.LightClassData
abstract class KtLazyLightClass(manager: PsiManager) : KtLightClassBase(manager) { 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)
}
@@ -1,28 +1,18 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.asJava.classes
import com.intellij.navigation.ItemPresentationProviders 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.PsiClassImplUtil
import com.intellij.psi.impl.light.AbstractLightClass import com.intellij.psi.impl.light.AbstractLightClass
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService 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 import org.jetbrains.kotlin.idea.KotlinLanguage
abstract class KtLightClassBase protected constructor( abstract class KtLightClassBase protected constructor(
@@ -34,7 +24,7 @@ abstract class KtLightClassBase protected constructor(
lazyCreator = LightClassesLazyCreator(project) lazyCreator = LightClassesLazyCreator(project)
) )
override fun getDelegate() = clsDelegate override fun getDelegate() = invalidAccess()
override fun getFields() = myInnersCache.fields 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 findMethodsByName(name: String, checkBases: Boolean) = myInnersCache.findMethodsByName(name, checkBases)
override fun findInnerClassByName(name: String, checkBases: Boolean) = myInnersCache.findInnerClassByName(name, checkBases) override fun findInnerClassByName(name: String, checkBases: Boolean) = myInnersCache.findInnerClassByName(name, checkBases)
abstract override fun getOwnFields(): List<PsiField>
override fun getOwnFields(): List<PsiField> = KtLightFieldImpl.fromClsFields(delegate, this) abstract override fun getOwnMethods(): List<PsiMethod>
override fun getOwnMethods(): List<PsiMethod> = KtLightMethodImpl.fromClsMethods(delegate, this)
override fun getText(): String { override fun getText(): String {
val origin = kotlinOrigin 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.openapi.util.TextRange
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.impl.PsiSuperMethodImplUtil 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.LightEmptyImplementsList
import com.intellij.psi.impl.light.LightModifierList import com.intellij.psi.impl.light.LightModifierList
import com.intellij.psi.search.GlobalSearchScope 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.annotations.NonNls
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport 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.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
@@ -35,21 +30,11 @@ import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.psi.psiUtil.siblings import org.jetbrains.kotlin.psi.psiUtil.siblings
import javax.swing.Icon import javax.swing.Icon
open class KtLightClassForFacadeImpl constructor( abstract class KtLightClassForFacadeImpl constructor(
manager: PsiManager, manager: PsiManager,
override val facadeClassFqName: FqName, override val facadeClassFqName: FqName,
myLightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
override val files: Collection<KtFile> override val files: Collection<KtFile>
) : KtLazyLightClass(manager), KtLightClassForFacade { ) : 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 firstFileInFacade by lazyPub { files.iterator().next() }
private val modifierList: PsiModifierList = private val modifierList: PsiModifierList =
@@ -62,7 +47,7 @@ open class KtLightClassForFacadeImpl constructor(
FakeFileForLightClass( FakeFileForLightClass(
firstFileInFacade, firstFileInFacade,
lightClass = { this }, lightClass = { this },
stub = { javaFileStub }, stub = { null },
packageFqName = facadeClassFqName.parent() 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 isValid() = files.all { it.isValid && it.hasTopLevelCallables() && facadeClassFqName == it.javaFileFacadeFqName }
override fun copy(): KtLightClassForFacade = abstract override fun copy(): KtLightClassForFacade
KtLightClassForFacadeImpl(manager, facadeClassFqName, lightClassDataCache, files)
override fun getNavigationElement() = firstFileInFacade override fun getNavigationElement() = firstFileInFacade
@@ -231,22 +215,15 @@ open class KtLightClassForFacadeImpl constructor(
companion object { companion object {
fun createForFacadeNoCache(fqName: FqName, searchScope: GlobalSearchScope, project: Project): KtLightClassForFacade? { fun createForFacadeNoCache(fqName: FqName, searchScope: GlobalSearchScope, project: Project): KtLightClassForFacade? {
val sources = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(fqName, searchScope) val sources = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(fqName, searchScope)
.filterNot { it.isCompiled || it.isScript() } .filterNot { it.isCompiled || it.isScript() }
if (sources.isEmpty()) return null 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) val manager = PsiManager.getInstance(project)
return LightClassGenerationSupport.getInstance(project).run { 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 }}") ?: 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 file: KtFile
): KtLightClassForFacade { ): KtLightClassForFacade {
val project = file.project val project = file.project
// TODO: refactor, using cached value doesn't make sense for this case val manager = PsiManager.getInstance(project)
val cachedValue = CachedValuesManager.getManager(project).createCachedValue( return LightClassGenerationSupport.getInstance(project).run {
LightClassDataProviderForFileFacade.ByFile(project, facadeClassFqName, file), false createUltraLightClassForFacade(manager, facadeClassFqName, listOf(file)) ?: error { "Unable to create UL class for facade" }
) }
return KtLightClassForFacadeImpl(PsiManager.getInstance(project), facadeClassFqName, cachedValue, listOf(file))
} }
} }
} }
@@ -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.openapi.util.Key
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.impl.PsiSuperMethodImplUtil 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.LightEmptyImplementsList
import com.intellij.psi.impl.light.LightModifierList import com.intellij.psi.impl.light.LightModifierList
import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValue
@@ -18,11 +17,9 @@ import com.intellij.util.IncorrectOperationException
import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport 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.LightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForScript import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForScript
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -31,17 +28,7 @@ import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtScript import org.jetbrains.kotlin.psi.KtScript
import javax.swing.Icon import javax.swing.Icon
open class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script.manager) { abstract 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
private val modifierList: PsiModifierList = LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC) private val modifierList: PsiModifierList = LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC)
private val scriptImplementsList: LightEmptyImplementsList = LightEmptyImplementsList(manager) private val scriptImplementsList: LightEmptyImplementsList = LightEmptyImplementsList(manager)
@@ -56,7 +43,7 @@ open class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script
FakeFileForLightClass( FakeFileForLightClass(
script.containingKtFile, script.containingKtFile,
lightClass = { this }, lightClass = { this },
stub = { javaFileStub }, stub = { null },
packageFqName = fqName.parent(), 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 // 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 // we can't prohibit creating light classes with null names either since they can contain members
.filter { it.name != null } .filter { it.name != null }
.mapNotNull { KtLightClassForSourceDeclaration.create(it, JvmDefaultMode.DEFAULT) } .mapNotNull { KtLightClassForSourceDeclaration.create(it) }
} }
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY 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 isValid() = script.isValid
override fun copy() = KtLightClassForScript(script) abstract override fun copy(): PsiElement
override fun getNavigationElement() = script override fun getNavigationElement() = script
@@ -184,27 +171,21 @@ open class KtLightClassForScript(val script: KtScript) : KtLazyLightClass(script
CachedValuesManager.getCachedValue(script) { CachedValuesManager.getCachedValue(script) {
CachedValueProvider.Result CachedValueProvider.Result
.create( .create(
createNoCache(script, KtUltraLightSupport.forceUsingOldLightClasses), createNoCache(script),
KotlinModificationTrackerService.getInstance(script.project).outOfBlockModificationTracker, KotlinModificationTrackerService.getInstance(script.project).outOfBlockModificationTracker,
) )
} }
fun createNoCache(script: KtScript, forceUsingOldLightClasses: Boolean): KtLightClassForScript? { fun createNoCache(script: KtScript): KtLightClassForScript? {
val containingFile = script.containingFile val containingFile = script.containingFile
if (containingFile is KtCodeFragment) { if (containingFile is KtCodeFragment) {
// Avoid building light classes for code fragments // Avoid building light classes for code fragments
return null return null
} }
if (!forceUsingOldLightClasses) { return LightClassGenerationSupport.getInstance(script.project).run {
LightClassGenerationSupport.getInstance(script.project).run { createUltraLightClassForScript(script)
if (useUltraLightClasses) {
return createUltraLightClassForScript(script) ?: error("UL class cannot be created for script")
}
}
} }
return KtLightClassForScript(script)
} }
fun getLightClassCachedValue(script: KtScript): CachedValue<LightClassDataHolder.ForScript> { 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.CachedValuesManager
import com.intellij.psi.util.PsiUtilCore import com.intellij.psi.util.PsiUtilCore
import com.intellij.util.IncorrectOperationException import com.intellij.util.IncorrectOperationException
import com.intellij.util.containers.ConcurrentFactoryMap
import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult import org.jetbrains.kotlin.asJava.ImpreciseResolveResult
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder 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.LightClassDataHolder
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
import org.jetbrains.kotlin.asJava.elements.KtLightPsiReferenceList
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.config.JvmDefaultMode import org.jetbrains.kotlin.config.JvmDefaultMode
@@ -94,8 +90,8 @@ abstract class KtLightClassForSourceDeclaration(
private val _implementsList by lazyPub { createImplementsList() } private val _implementsList by lazyPub { createImplementsList() }
private val _deprecated by lazyPub { classOrObject.isDeprecated() } private val _deprecated by lazyPub { classOrObject.isDeprecated() }
protected open fun createExtendsList(): PsiReferenceList? = super.getExtendsList()?.let { KtLightPsiReferenceList(it, this) } protected abstract fun createExtendsList(): PsiReferenceList?
protected open fun createImplementsList(): PsiReferenceList? = super.getImplementsList()?.let { KtLightPsiReferenceList(it, this) } protected abstract fun createImplementsList(): PsiReferenceList?
override val kotlinOrigin: KtClassOrObject = classOrObject override val kotlinOrigin: KtClassOrObject = classOrObject
@@ -103,11 +99,6 @@ abstract class KtLightClassForSourceDeclaration(
abstract override fun getParent(): PsiElement? abstract override fun getParent(): PsiElement?
abstract override fun getQualifiedName(): String? abstract override fun getQualifiedName(): String?
override val lightClassData: LightClassData
get() = findLightClassData()
protected open fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject)
private fun getJavaFileStub(): PsiJavaFileStub = getLightClassDataHolder().javaFileStub private fun getJavaFileStub(): PsiJavaFileStub = getLightClassDataHolder().javaFileStub
fun getDescriptor() = fun getDescriptor() =
@@ -124,7 +115,7 @@ abstract class KtLightClassForSourceDeclaration(
private val _containingFile: PsiFile by lazyPub { private val _containingFile: PsiFile by lazyPub {
object : FakeFileForLightClass( object : FakeFileForLightClass(
classOrObject.containingKtFile, classOrObject.containingKtFile,
{ if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject), jvmDefaultMode)!! }, { if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject))!! },
{ getJavaFileStub() } { getJavaFileStub() }
) { ) {
override fun findReferenceAt(offset: Int) = ktFile.findReferenceAt(offset) override fun findReferenceAt(offset: Int) = ktFile.findReferenceAt(offset)
@@ -181,7 +172,7 @@ abstract class KtLightClassForSourceDeclaration(
val containingClassOrObject = (classOrObject.parent as? KtClassBody)?.parent as? KtClassOrObject val containingClassOrObject = (classOrObject.parent as? KtClassBody)?.parent as? KtClassOrObject
if (containingClassOrObject != null) { if (containingClassOrObject != null) {
return create(containingClassOrObject, jvmDefaultMode) return create(containingClassOrObject)
} }
// TODO: should return null // TODO: should return null
@@ -190,7 +181,7 @@ abstract class KtLightClassForSourceDeclaration(
private val _typeParameterList: PsiTypeParameterList by lazyPub { buildTypeParameterList() } 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 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 // we can't prohibit creating light classes with null names either since they can contain members
.filter { it.name != null } .filter { it.name != null }
.mapNotNullTo(result) { .mapNotNullTo(result) {
if (!forceUsingOldLightClasses) create(it)
create(it, jvmDefaultMode)
else
createNoCache(it, jvmDefaultMode, forceUsingOldLightClasses = true)
} }
if (classOrObject.hasInterfaceDefaultImpls && jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE) { if (classOrObject.hasInterfaceDefaultImpls && jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE) {
@@ -322,7 +310,7 @@ abstract class KtLightClassForSourceDeclaration(
return result return result
} }
protected open fun createClassForInterfaceDefaultImpls(): PsiClass = KtLightClassForInterfaceDefaultImpls(classOrObject) protected abstract fun createClassForInterfaceDefaultImpls(): PsiClass
override fun getUseScope(): SearchScope = kotlinOrigin.useScope override fun getUseScope(): SearchScope = kotlinOrigin.useScope
@@ -348,21 +336,15 @@ abstract class KtLightClassForSourceDeclaration(
FINAL_KEYWORD to PsiModifier.FINAL FINAL_KEYWORD to PsiModifier.FINAL
) )
fun create(classOrObject: KtClassOrObject, jvmDefaultMode: JvmDefaultMode): KtLightClassForSourceDeclaration? = fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? =
CachedValuesManager.getCachedValue(classOrObject) { CachedValuesManager.getCachedValue(classOrObject) {
CachedValueProvider.Result.create( CachedValueProvider.Result.create(
ConcurrentFactoryMap.createMap { defaultMode: JvmDefaultMode -> createNoCache(classOrObject),
createNoCache(classOrObject, defaultMode, KtUltraLightSupport.forceUsingOldLightClasses)
},
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker, KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker,
) )
}[jvmDefaultMode] }
fun createNoCache( fun createNoCache(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
classOrObject: KtClassOrObject,
jvmDefaultMode: JvmDefaultMode,
forceUsingOldLightClasses: Boolean
): KtLightClassForSourceDeclaration? {
val containingFile = classOrObject.containingFile val containingFile = classOrObject.containingFile
if (containingFile is KtCodeFragment) { if (containingFile is KtCodeFragment) {
// Avoid building light classes for code fragments // Avoid building light classes for code fragments
@@ -373,24 +355,8 @@ abstract class KtLightClassForSourceDeclaration(
return null return null
} }
if (!forceUsingOldLightClasses) { return LightClassGenerationSupport.getInstance(classOrObject.project).run {
LightClassGenerationSupport.getInstance(classOrObject.project).run { createUltraLightClass(classOrObject)
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)
} }
} }
@@ -488,19 +454,9 @@ abstract class KtLightClassForSourceDeclaration(
private val LOG = Logger.getInstance(KtLightClassForSourceDeclaration::class.java) private val LOG = Logger.getInstance(KtLightClassForSourceDeclaration::class.java)
} }
override fun getSupers(): Array<PsiClass> { abstract override fun getSupers(): Array<PsiClass>
if (classOrObject.superTypeListEntries.isEmpty()) {
return getSupertypeByPsi()?.let { arrayOf(it.resolve()!!) } ?: emptyArray()
}
return clsDelegate.supers
}
override fun getSuperTypes(): Array<PsiClassType> { abstract override fun getSuperTypes(): Array<PsiClassType>
if (classOrObject.superTypeListEntries.isEmpty()) {
return getSupertypeByPsi()?.let { arrayOf<PsiClassType>(it) } ?: emptyArray()
}
return clsDelegate.superTypes
}
private fun getSupertypeByPsi(): PsiImmediateClassType? { private fun getSupertypeByPsi(): PsiImmediateClassType? {
return classOrObject.defaultJavaAncestorQualifiedName()?.let { ancestorFqName -> return classOrObject.defaultJavaAncestorQualifiedName()?.let { ancestorFqName ->
@@ -525,12 +481,7 @@ abstract class KtLightClassForSourceDeclaration(
override val originKind: LightClassOriginKind override val originKind: LightClassOriginKind
get() = LightClassOriginKind.SOURCE get() = LightClassOriginKind.SOURCE
open fun isFinal(isFinalByPsi: Boolean): Boolean { abstract fun isFinal(isFinalByPsi: Boolean): Boolean
// annotations can make class open via 'allopen' plugin
if (!isPossiblyAffectedByAllOpen() || !isFinalByPsi) return isFinalByPsi
return clsDelegate.hasModifierProperty(PsiModifier.FINAL)
}
} }
fun KtLightClassForSourceDeclaration.isPossiblyAffectedByAllOpen() = fun KtLightClassForSourceDeclaration.isPossiblyAffectedByAllOpen() =
@@ -1,26 +1,16 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.JvmDefaultMode import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
// light class for top level or (inner/nested of top level) source declarations // 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, classOrObject: KtClassOrObject,
jvmDefaultMode: JvmDefaultMode, jvmDefaultMode: JvmDefaultMode,
forceUsingOldLightClasses: Boolean = false forceUsingOldLightClasses: Boolean = false
@@ -32,5 +22,5 @@ open class KtLightClassImpl @JvmOverloads constructor(
else else
containingClass 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 = override fun setName(name: String): PsiElement =
throw IncorrectOperationException("Impossible to rename ${JvmAbi.DEFAULT_IMPLS_CLASS_NAME}") 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 getOwnInnerClasses() = emptyList<PsiClass>()
override fun getOwnMethods(): List<KtLightMethod> = _ownMethods.value 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. * 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 getParent() = containingClass
override fun getTypeParameterList(): PsiTypeParameterList? = null override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray() 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 getScope(): PsiElement? = containingClass
override fun getOwnInnerClasses() = emptyList<PsiClass>() override fun getOwnInnerClasses() = emptyList<PsiClass>()
override fun getOwnFields(): List<KtLightField> = emptyList() 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. * 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> { override fun <T : Any> get(initializer: () -> T, dependencies: List<Any>) = object : Lazy<T> {
private val lock = ReentrantLock() private val lock = ReentrantLock()
private val holder = lazyPub { private val holder = lazyPub {
PsiCachedValueImpl(PsiManager.getInstance(project), PsiCachedValueImpl(PsiManager.getInstance(project)) {
CachedValueProvider<T> { val v = initializer()
val v = initializer() CachedValueProvider.Result.create(v, dependencies)
CachedValueProvider.Result.create(v, dependencies) }
})
} }
private fun computeValue(): T = holder.value.value ?: error("holder has not null in initializer") 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. * 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 package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.* import com.intellij.psi.PsiElement
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub 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.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.asJava.elements.*
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil.findAnnotationEntryOnFileNoResolve import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil.findAnnotationEntryOnFileNoResolve
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
@@ -26,21 +25,9 @@ import org.jetbrains.kotlin.psi.psiUtil.isPrivate
class KtUltraLightClassForFacade( class KtUltraLightClassForFacade(
manager: PsiManager, manager: PsiManager,
facadeClassFqName: FqName, facadeClassFqName: FqName,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
files: Collection<KtFile>, files: Collection<KtFile>,
private val filesWithSupports: Collection<Pair<KtFile, KtUltraLightSupport>> private val filesWithSupports: Collection<Pair<KtFile, KtUltraLightSupport>>
) : KtLightClassForFacadeImpl(manager, facadeClassFqName, lightClassDataCache, files) { ) : KtLightClassForFacadeImpl(manager, facadeClassFqName, 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
private val _modifierList: PsiModifierList by lazyPub { private val _modifierList: PsiModifierList by lazyPub {
if (isMultiFileClass) if (isMultiFileClass)
LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL) LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL)
@@ -59,8 +46,7 @@ class KtUltraLightClassForFacade(
name = entry.shortName?.identifier, name = entry.shortName?.identifier,
lazyQualifiedName = { entry.analyzeAnnotation()?.fqName?.asString() }, lazyQualifiedName = { entry.analyzeAnnotation()?.fqName?.asString() },
kotlinOrigin = entry, kotlinOrigin = entry,
parent = _modifierList, parent = _modifierList
lazyClsDelegate = null
) )
} }
} }
@@ -101,6 +87,7 @@ class KtUltraLightClassForFacade(
ktFunction = declaration, ktFunction = declaration,
forceStatic = true forceStatic = true
) )
is KtProperty -> { is KtProperty -> {
if (!declaration.isPrivate() || declaration.accessors.isNotEmpty()) { if (!declaration.isPrivate() || declaration.accessors.isNotEmpty()) {
creator.propertyAccessors( creator.propertyAccessors(
@@ -111,6 +98,7 @@ class KtUltraLightClassForFacade(
) )
} else emptyList() } else emptyList()
} }
else -> emptyList() else -> emptyList()
} }
result.addAll(methods) result.addAll(methods)
@@ -148,5 +136,5 @@ class KtUltraLightClassForFacade(
override fun getOwnMethods() = _ownMethods override fun getOwnMethods() = _ownMethods
override fun copy(): KtLightClassForFacade = 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. * 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, private val ultraLightSupport: KtUltraLightSupport,
parent: PsiElement, parent: PsiElement,
private val nameReferenceElementProvider: (() -> PsiJavaCodeReferenceElement?)? = null, private val nameReferenceElementProvider: (() -> PsiJavaCodeReferenceElement?)? = null,
) : KtLightAbstractAnnotation(parent, computeDelegate = null) { ) : KtLightAbstractAnnotation(parent) {
override fun getNameReferenceElement(): PsiJavaCodeReferenceElement? = nameReferenceElementProvider?.invoke() override fun getNameReferenceElement(): PsiJavaCodeReferenceElement? = nameReferenceElementProvider?.invoke()
private val parameterList = ParameterListImpl() 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.CachedValue
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager 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.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.elements.KtUltraLightModifierList 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 isFinal(isFinalByPsi: Boolean) = isFinalByPsi
override fun findLightClassData(): LightClassData = invalidAccess()
override fun getDelegate(): PsiClass = invalidAccess()
private val _modifierList: PsiModifierList? by lazyPub { private val _modifierList: PsiModifierList? by lazyPub {
KtUltraLightClassModifierList(this, support) { computeModifiers() } KtUltraLightClassModifierList(this, support) { computeModifiers() }
} }
@@ -300,6 +295,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
when (declaration) { when (declaration) {
is KtNamedFunction -> is KtNamedFunction ->
if (isJvmStatic(declaration)) result.addAll(membersBuilder.createMethods(declaration, forceStatic = true)) if (isJvmStatic(declaration)) result.addAll(membersBuilder.createMethods(declaration, forceStatic = true))
is KtProperty -> result.addAll( is KtProperty -> result.addAll(
membersBuilder.propertyAccessors( membersBuilder.propertyAccessors(
declaration, declaration,
@@ -405,6 +401,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
declarationOriginKindForOrigin = JvmDeclarationOriginKind.DELEGATION declarationOriginKindForOrigin = JvmDeclarationOriginKind.DELEGATION
) )
} }
is FunctionDescriptor -> result.add( is FunctionDescriptor -> result.add(
createGeneratedMethodFromDescriptor( createGeneratedMethodFromDescriptor(
descriptor = delegate, descriptor = delegate,
@@ -486,7 +483,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
val containingBody = classOrObject.parent as? KtClassBody val containingBody = classOrObject.parent as? KtClassBody
val containingClass = containingBody?.parent as? KtClassOrObject val containingClass = containingBody?.parent as? KtClassOrObject
containingClass?.let { return create(it, jvmDefaultMode) } containingClass?.let { return create(it) }
val containingBlock = classOrObject.parent as? KtBlockExpression val containingBlock = classOrObject.parent as? KtBlockExpression
val containingScript = containingBlock?.parent as? KtScript 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. * 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.*
import com.intellij.psi.impl.InheritanceImplUtil 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.asJava.elements.KtLightIdentifier
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.resolve.DescriptorUtils
open class KtUltraLightClassForAnonymousDeclaration(classOrObject: KtClassOrObject, support: KtUltraLightSupport) : open class KtUltraLightClassForAnonymousDeclaration(classOrObject: KtClassOrObject, support: KtUltraLightSupport) :
KtUltraLightClassForLocalDeclaration(classOrObject, support), PsiAnonymousClass { KtUltraLightClassForLocalDeclaration(classOrObject, support), PsiAnonymousClass {
@@ -18,7 +18,6 @@ open class KtUltraLightClassForAnonymousDeclaration(classOrObject: KtClassOrObje
JavaPsiFacade.getElementFactory(classOrObject.project).createReferenceElementByType(baseClassType) JavaPsiFacade.getElementFactory(classOrObject.project).createReferenceElementByType(baseClassType)
private val _baseClassType by lazyPub { private val _baseClassType by lazyPub {
val firstSupertypeFQName = getFirstSupertypeFQNameForAnonymousDeclaration() val firstSupertypeFQName = getFirstSupertypeFQNameForAnonymousDeclaration()
if (firstSupertypeFQName == CommonClassNames.JAVA_LANG_OBJECT) { if (firstSupertypeFQName == CommonClassNames.JAVA_LANG_OBJECT) {
@@ -64,4 +63,22 @@ open class KtUltraLightClassForAnonymousDeclaration(classOrObject: KtClassOrObje
override fun isEnum() = false override fun isEnum() = false
override fun copy() = KtUltraLightClassForAnonymousDeclaration(classOrObject, support) 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. * 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 package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.asJava.classes.KtLightClassForLocalDeclaration.Companion.getParentForLocalDeclaration import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.psi.KtClassOrObject 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( open class KtUltraLightClassForLocalDeclaration(
classOrObject: KtClassOrObject, classOrObject: KtClassOrObject,
@@ -21,4 +28,73 @@ open class KtUltraLightClassForLocalDeclaration(
override fun getQualifiedName(): String? = null override fun getQualifiedName(): String? = null
override fun getParent() = _parent 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. * 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 package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiModifier import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiType import com.intellij.psi.PsiType
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.impl.light.LightMethodBuilder import com.intellij.psi.impl.light.LightMethodBuilder
import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService 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.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
@@ -26,15 +22,6 @@ class KtUltraLightClassForScript(
script: KtScript, script: KtScript,
private val support: KtUltraLightSupport, private val support: KtUltraLightSupport,
) : KtLightClassForScript(script) { ) : 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 { private val membersBuilder by lazyPub {
UltraLightMembersCreator( UltraLightMembersCreator(
containingClass = this, 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. * 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 kotlinOrigin = declaration
override val clsDelegate: PsiField get() = invalidAccess()
override val lightMemberOrigin = LightMemberOriginForDeclaration(declaration, JvmDeclarationOriginKind.OTHER) override val lightMemberOrigin = LightMemberOriginForDeclaration(declaration, JvmDeclarationOriginKind.OTHER)
override fun setName(@NonNls name: String): PsiElement { 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.PsiSuperMethodImplUtil
import com.intellij.psi.impl.light.LightMethodBuilder import com.intellij.psi.impl.light.LightMethodBuilder
import com.intellij.psi.impl.light.LightTypeParameterListBuilder import com.intellij.psi.impl.light.LightTypeParameterListBuilder
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.util.MethodSignature import com.intellij.psi.util.MethodSignature
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod 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.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.builder.MemberIndex import org.jetbrains.kotlin.asJava.builder.MemberIndex
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl
import org.jetbrains.kotlin.asJava.elements.KtUltraLightModifierList
import org.jetbrains.kotlin.codegen.FunctionCodegen import org.jetbrains.kotlin.codegen.FunctionCodegen
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor 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.KtFunction
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
import org.jetbrains.kotlin.psi.psiUtil.hasBody
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.types.RawType 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_GETTER = 1
const val METHOD_INDEX_FOR_SETTER = 2 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_FOR_SCRIPT_MAIN = 6
const val METHOD_INDEX_BASE = 7 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 abstract class KtUltraLightMethod(
internal val delegate: PsiMethod, internal val delegate: PsiMethod,
lightMemberOrigin: LightMemberOrigin?, lightMemberOrigin: LightMemberOriginForDeclaration?,
protected val support: KtUltraLightSupport, protected val support: KtUltraLightSupport,
containingClass: KtLightClass, containingClass: KtLightClass,
private val methodIndex: Int private val methodIndex: Int
) : KtLightMethodImpl( ) : KtLightMethodImpl(
{ delegate },
lightMemberOrigin, lightMemberOrigin,
containingClass containingClass
), KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiMethod> { ), KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiMethod> {
private class KtUltraLightThrowsReferenceListBuilder(private val parentMethod: PsiMethod) : private class KtUltraLightThrowsReferenceListBuilder(private val parentMethod: PsiMethod) :
KotlinLightReferenceListBuilder(parentMethod.manager, parentMethod.language, PsiReferenceList.Role.THROWS_LIST) { KotlinLightReferenceListBuilder(parentMethod.manager, parentMethod.language, PsiReferenceList.Role.THROWS_LIST) {
override fun getParent() = parentMethod override fun getParent(): PsiMethod = parentMethod
override fun getContainingFile() = parentMethod.containingFile override fun getContainingFile(): PsiFile? = parentMethod.containingFile
} }
protected fun computeThrowsList(methodDescriptor: FunctionDescriptor?): PsiReferenceList { 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) // While here we only set return type for LightMethodBuilder (see org.jetbrains.kotlin.asJava.classes.KtUltraLightClass.asJavaMethod)
override fun getReturnTypeElement(): PsiTypeElement? = null 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 // should be in super
override fun isVarArgs() = PsiImplUtil.isVarArgs(this) 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 hashCode(): Int = super.hashCode().times(31).plus(methodIndex.hashCode())
override fun isDeprecated(): Boolean = _deprecated override fun isDeprecated(): Boolean = _deprecated
override fun getDocComment(): PsiDocComment? = delegate.docComment
override fun isConstructor(): Boolean = delegate.isConstructor
} }
internal class KtUltraLightMethodForSourceDeclaration( internal class KtUltraLightMethodForSourceDeclaration(
delegate: PsiMethod, delegate: PsiMethod,
lightMemberOrigin: LightMemberOrigin?, lightMemberOrigin: LightMemberOriginForDeclaration?,
support: KtUltraLightSupport, support: KtUltraLightSupport,
containingClass: KtLightClass, containingClass: KtLightClass,
private val forceToSkipNullabilityAnnotation: Boolean = false, private val forceToSkipNullabilityAnnotation: Boolean = false,
@@ -204,7 +243,7 @@ internal class KtUltraLightMethodForSourceDeclaration(
internal class KtUltraLightMethodForDescriptor( internal class KtUltraLightMethodForDescriptor(
methodDescriptor: FunctionDescriptor, methodDescriptor: FunctionDescriptor,
delegate: LightMethodBuilder, delegate: LightMethodBuilder,
lightMemberOrigin: LightMemberOrigin?, lightMemberOrigin: LightMemberOriginForDeclaration?,
support: KtUltraLightSupport, support: KtUltraLightSupport,
containingClass: KtUltraLightClass containingClass: KtUltraLightClass
) : KtUltraLightMethod( ) : KtUltraLightMethod(
@@ -44,7 +44,6 @@ internal class KtUltraLightSuspendContinuationParameter(
override val psiTypeForNullabilityAnnotation: PsiType? get() = psiType override val psiTypeForNullabilityAnnotation: PsiType? get() = psiType
override val kotlinOrigin: KtParameter? = null override val kotlinOrigin: KtParameter? = null
override val clsDelegate: PsiParameter get() = invalidAccess()
private val ktType: KotlinType? private val ktType: KotlinType?
get() { get() {
@@ -94,8 +93,6 @@ internal abstract class KtUltraLightParameter(
override fun isEquivalentTo(another: PsiElement?): Boolean = kotlinOrigin == another override fun isEquivalentTo(another: PsiElement?): Boolean = kotlinOrigin == another
override val clsDelegate: PsiParameter get() = invalidAccess()
private val lightModifierList by lazyPub { KtLightSimpleModifierList(this, emptySet()) } private val lightModifierList by lazyPub { KtLightSimpleModifierList(this, emptySet()) }
override fun getModifierList(): PsiModifierList = lightModifierList 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. * 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 package org.jetbrains.kotlin.asJava.classes
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
interface KtUltraLightSupport { interface KtUltraLightSupport {
@@ -21,12 +20,4 @@ interface KtUltraLightSupport {
val languageVersionSettings: LanguageVersionSettings val languageVersionSettings: LanguageVersionSettings
fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean 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. * 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, name = entry.shortName?.identifier,
lazyQualifiedName = { entry.analyzeAnnotation()?.fqName?.asString() }, lazyQualifiedName = { entry.analyzeAnnotation()?.fqName?.asString() },
kotlinOrigin = entry, kotlinOrigin = entry,
parent = parent, parent = parent
lazyClsDelegate = null
) )
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.asJava.elements
@@ -54,7 +43,7 @@ open class FakeFileForLightClass(
override fun getPackageName() = packageFqName.asString() override fun getPackageName() = packageFqName.asString()
private fun createFakeJavaFileStub(): PsiJavaFileStub { private fun createFakeJavaFileStub(): PsiJavaFileStub {
val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), /*compiled = */true) val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), /* compiled = */true)
javaFileStub.psiFactory = ClsStubPsiFactory.INSTANCE javaFileStub.psiFactory = ClsStubPsiFactory.INSTANCE
javaFileStub.psi = this javaFileStub.psi = this
return javaFileStub return javaFileStub
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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 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 * 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 givenAnnotations: List<KtLightAbstractAnnotation>? get() = null
val clsDelegate: D
} }
interface KtLightDeclaration<out T : KtDeclaration, out D : PsiElement> : KtLightElement<T, D>, PsiNamedElement 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. * 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.
* 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 package org.jetbrains.kotlin.asJava.elements
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiCompiledElement
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.impl.light.LightIdentifier import com.intellij.psi.impl.light.LightIdentifier
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
@@ -35,7 +22,7 @@ abstract class KtLightIdentifierBase(
override fun getTextOffset(): Int = origin?.textOffset ?: -1 override fun getTextOffset(): Int = origin?.textOffset ?: -1
} }
open class KtLightIdentifierWithOrigin( open class KtLightIdentifier(
lightOwner: PsiElement, lightOwner: PsiElement,
private val ktDeclaration: KtDeclaration? private val ktDeclaration: KtDeclaration?
) : KtLightIdentifierBase(lightOwner, ktDeclaration?.name) { ) : KtLightIdentifierBase(lightOwner, ktDeclaration?.name) {
@@ -45,16 +32,9 @@ open class KtLightIdentifierWithOrigin(
is KtPrimaryConstructor -> ktDeclaration.getConstructorKeyword() is KtPrimaryConstructor -> ktDeclaration.getConstructorKeyword()
?: ktDeclaration.valueParameterList ?: ktDeclaration.valueParameterList
?: ktDeclaration.containingClassOrObject?.nameIdentifier ?: ktDeclaration.containingClassOrObject?.nameIdentifier
is KtPropertyAccessor -> ktDeclaration.namePlaceholder is KtPropertyAccessor -> ktDeclaration.namePlaceholder
is KtNamedDeclaration -> ktDeclaration.nameIdentifier is KtNamedDeclaration -> ktDeclaration.nameIdentifier
else -> null 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. * 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.
* 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 package org.jetbrains.kotlin.asJava.elements
import com.intellij.openapi.util.UserDataHolder import com.intellij.psi.PsiElement
import com.intellij.psi.* import com.intellij.psi.PsiIdentifier
import com.intellij.psi.impl.compiled.ClsRepositoryPsiElement import com.intellij.psi.PsiMember
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory.ORIGIN import com.intellij.psi.PsiModifierList
import org.jetbrains.kotlin.asJava.builder.LightElementOrigin import com.intellij.psi.javadoc.PsiDocComment
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.classes.KtLightClass 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.asJava.classes.lazyPub
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.psiUtil.hasBody
abstract class KtLightMemberImpl<out D : PsiMember>( abstract class KtLightMemberImpl<out D : PsiMember>(
computeRealDelegate: () -> D, override val lightMemberOrigin: LightMemberOriginForDeclaration?,
override val lightMemberOrigin: LightMemberOrigin?,
private val containingClass: KtLightClass, private val containingClass: KtLightClass,
private val dummyDelegate: D?
) : KtLightElementBase(containingClass), PsiMember, KtLightMember<D> { ) : KtLightElementBase(containingClass), PsiMember, KtLightMember<D> {
override val clsDelegate by lazyPub(computeRealDelegate)
private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) } private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
private val _modifierList by lazyPub { abstract override fun hasModifierProperty(name: String): Boolean
if (lightMemberOrigin is LightMemberOriginForDeclaration)
KtLightMemberModifierList(this, dummyDelegate?.modifierList)
else clsDelegate.modifierList!!
}
override fun hasModifierProperty(name: String) = _modifierList.hasModifierProperty(name) abstract override fun getModifierList(): PsiModifierList?
override fun getModifierList(): PsiModifierList = _modifierList
override fun toString(): String = "${this::class.java.simpleName}:$name" override fun toString(): String = "${this::class.java.simpleName}:$name"
override fun getContainingClass() = containingClass override fun getContainingClass() = containingClass
override fun getName(): String = dummyDelegate?.name ?: clsDelegate.name!! abstract override fun getName(): String
override fun getNameIdentifier(): PsiIdentifier = lightIdentifier override fun getNameIdentifier(): PsiIdentifier = lightIdentifier
override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin?.originalElement 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 { override fun isValid(): Boolean {
return parent.isValid && lightMemberOrigin?.isValid() != false return parent.isValid && lightMemberOrigin?.isValid() != false
@@ -75,46 +50,3 @@ abstract class KtLightMemberImpl<out D : PsiMember>(
another is KtLightMember<*> && lightMemberOrigin?.isEquivalentTo(another.lightMemberOrigin) == true 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.openapi.util.TextRange
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.impl.compiled.ClsTypeElementImpl
import com.intellij.psi.scope.PsiScopeProcessor import com.intellij.psi.scope.PsiScopeProcessor
import com.intellij.psi.util.MethodSignature import com.intellij.psi.util.MethodSignature
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.asJava.* 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.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.builder.MemberIndex 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.KtLightClass
import org.jetbrains.kotlin.asJava.classes.cannotModify import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
open class KtLightMethodImpl protected constructor( abstract class KtLightMethodImpl protected constructor(
computeRealDelegate: () -> PsiMethod, lightMemberOrigin: LightMemberOriginForDeclaration?,
lightMemberOrigin: LightMemberOrigin?,
containingClass: KtLightClass, containingClass: KtLightClass,
private val dummyDelegate: PsiMethod? = null ) : KtLightMemberImpl<PsiMethod>(lightMemberOrigin, containingClass), KtLightMethod {
) : 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()) }
}
private val calculatingReturnType = ThreadLocal<Boolean>() private val calculatingReturnType = ThreadLocal<Boolean>()
private val paramsList: PsiParameterList by lazyPub { private val paramsList: PsiParameterList by lazyPub {
KtLightParameterList(this, dummyDelegate?.parameterList?.parametersCount ?: clsDelegate.parameterList.parametersCount) { val parameters = buildParametersForList()
buildParametersForList() KtLightParameterList(this, parameters.size) {
parameters
} }
} }
protected open fun buildParametersForList(): List<PsiParameter> { protected abstract 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
)
}
}
private val typeParamsList: PsiTypeParameterList? by lazyPub { buildTypeParameterList() } private val typeParamsList: PsiTypeParameterList? by lazyPub { buildTypeParameterList() }
protected open fun buildTypeParameterList(): PsiTypeParameterList? { protected abstract 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
}
}
override fun accept(visitor: PsiElementVisitor) { override fun accept(visitor: PsiElementVisitor) {
if (visitor is JavaElementVisitor) { if (visitor is JavaElementVisitor) {
@@ -104,12 +76,7 @@ open class KtLightMethodImpl protected constructor(
} ?: cannotModify() } ?: cannotModify()
} }
override fun getModifierList(): PsiModifierList { abstract override fun getModifierList(): PsiModifierList
if (calculatingReturnType.get() == true) {
return KotlinJavaPsiFacade.getInstance(project).emptyModifierList
}
return super.getModifierList()
}
override fun getParameterList() = paramsList override fun getParameterList() = paramsList
@@ -120,16 +87,7 @@ open class KtLightMethodImpl protected constructor(
override fun hasTypeParameters() = typeParameters.isNotEmpty() override fun hasTypeParameters() = typeParameters.isNotEmpty()
override fun getSignature(substitutor: PsiSubstitutor): MethodSignature { abstract 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)
}
override fun processDeclarations( override fun processDeclarations(
processor: PsiScopeProcessor, processor: PsiScopeProcessor,
@@ -140,8 +98,7 @@ open class KtLightMethodImpl protected constructor(
return typeParameters.all { processor.execute(it, state) } return typeParameters.all { processor.execute(it, state) }
} }
protected open val memberIndex: MemberIndex? protected abstract val memberIndex: MemberIndex?
get() = (dummyDelegate ?: clsDelegate).memberIndex
/* comparing origin and member index should be enough to determine equality: /* comparing origin and member index should be enough to determine equality:
for compiled elements origin contains delegate for compiled elements origin contains delegate
@@ -158,11 +115,9 @@ open class KtLightMethodImpl protected constructor(
.times(31).plus(containingClass.hashCode()) .times(31).plus(containingClass.hashCode())
.times(31).plus(memberIndex.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 abstract override fun getReturnTypeElement(): PsiTypeElement?
// which is relied upon by java type inference
override fun getReturnTypeElement(): PsiTypeElement? = returnTypeElem
override fun getReturnType(): PsiType? { override fun getReturnType(): PsiType? {
calculatingReturnType.set(true) calculatingReturnType.set(true)
@@ -191,67 +146,28 @@ open class KtLightMethodImpl protected constructor(
return super.getTextRange() return super.getTextRange()
} }
companion object Factory { abstract override fun getThrowsList(): PsiReferenceList
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
}
fun create( abstract override fun isVarArgs(): Boolean
delegate: PsiMethod, origin: LightMemberOrigin?, containingClass: KtLightClass
): KtLightMethodImpl {
return KtLightMethodImpl({ delegate }, origin, containingClass)
}
fun lazy( abstract override fun isConstructor(): Boolean
dummyDelegate: PsiMethod?,
containingClass: KtLightClass,
origin: LightMemberOriginForDeclaration?,
computeRealDelegate: () -> PsiMethod
): KtLightMethodImpl {
return KtLightMethodImpl(computeRealDelegate, origin, containingClass, dummyDelegate)
}
fun fromClsMethods(delegateClass: PsiClass, containingClass: KtLightClass): List<KtLightMethodImpl> = buildList { abstract override fun getHierarchicalMethodSignature(): HierarchicalMethodSignature
for (method in delegateClass.methods) {
if (isSyntheticValuesOrValueOfMethod(method)) continue
this += create(method, getOrigin(method), containingClass)
}
}
fun getOrigin(method: PsiMethod) = adjustMethodOrigin(getMemberOrigin(method)) abstract override fun findSuperMethodSignaturesIncludingStatic(checkAccess: Boolean): List<MethodSignatureBackedByPsiMethod>
}
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)
override fun getBody() = null override fun getBody() = null
@Suppress("DEPRECATION") @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 { 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. * 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>>( abstract class KtLightModifierList<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
protected val owner: T protected val owner: T
) : KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierList> { ) : KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierList> {
override val clsDelegate by lazyPub { owner.clsDelegate.modifierList!! }
private val _annotations by lazyPub { private val _annotations by lazyPub {
val annotations = computeAnnotations() val annotations = computeAnnotations()
annotationsFilter?.let(annotations::filter) ?: annotations 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 hasExplicitModifier(name: String) = hasModifierProperty(name)
override fun setModifierProperty(name: String, value: Boolean) = clsDelegate.setModifierProperty(name, value) private fun throwInvalidOperation(): Nothing = throw IncorrectOperationException()
override fun checkSetModifierProperty(name: String, value: Boolean) = clsDelegate.checkSetModifierProperty(name, value)
override fun addAnnotation(qualifiedName: String) = clsDelegate.addAnnotation(qualifiedName) 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 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" override fun toString() = "Light modifier list of $owner"
protected open fun nonSourceAnnotationsForAnnotationType(sourceAnnotations: List<PsiAnnotation>): List<KtLightAbstractAnnotation> { open fun nonSourceAnnotationsForAnnotationType(sourceAnnotations: List<PsiAnnotation>): List<KtLightAbstractAnnotation> = emptyList()
val annotations = parent.clsDelegate.modifierList?.annotations
if (annotations.isNullOrEmpty()) return emptyList()
return annotations.map { KtLightNonSourceAnnotation(this, it) }
}
private fun computeAnnotations(): List<KtLightAbstractAnnotation> { private fun computeAnnotations(): List<KtLightAbstractAnnotation> {
val annotationsForEntries = owner.givenAnnotations ?: lightAnnotationsForEntries(this) 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>>( abstract class KtUltraLightModifierListBase<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
owner: T owner: T
) : KtLightModifierList<T>(owner) { ) : 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()
}
class KtLightSimpleModifierList( class KtLightSimpleModifierList(
owner: KtLightElement<KtModifierListOwner, PsiModifierListOwner>, private val modifiers: Set<String> owner: KtLightElement<KtModifierListOwner, PsiModifierListOwner>, private val modifiers: Set<String>
@@ -181,23 +163,12 @@ private fun lightAnnotationsForEntries(lightModifierList: KtLightModifierList<*>
} }
.groupBy({ it.first }) { it.second } .groupBy({ it.first }) { it.second }
.flatMap { (fqName, entries) -> .flatMap { (fqName, entries) ->
entries.mapIndexed { index, entry -> entries.map { entry ->
val lazyClsDelegate = if (lightModifierList !is KtUltraLightModifierList) {
lazyPub {
lightModifierList.clsDelegate.annotations
.filter { it.qualifiedName == fqName }
.getOrNull(index)
?: KtLightNonExistentAnnotation(lightModifierList)
}
} else null
KtLightAnnotationForSourceEntry( KtLightAnnotationForSourceEntry(
name = entry.shortName?.identifier, name = entry.shortName?.identifier,
lazyQualifiedName = { fqName }, lazyQualifiedName = { fqName },
kotlinOrigin = entry, kotlinOrigin = entry,
parent = lightModifierList, parent = lightModifierList
lazyClsDelegate = lazyClsDelegate
) )
} }
} }
@@ -230,8 +201,8 @@ private fun getAnnotationDescriptors(
val annotatedDescriptor = when { val annotatedDescriptor = when {
descriptor is ClassDescriptor && annotatedLightElement is KtLightMethod && annotatedLightElement.isConstructor -> descriptor is ClassDescriptor && annotatedLightElement is KtLightMethod && annotatedLightElement.isConstructor ->
descriptor.unsubstitutedPrimaryConstructor descriptor.unsubstitutedPrimaryConstructor
descriptor !is PropertyDescriptor -> descriptor descriptor !is PropertyDescriptor -> descriptor
annotatedLightElement is KtLightFieldImpl.KtLightEnumConstant -> descriptor
annotatedLightElement is KtLightField -> descriptor.backingField annotatedLightElement is KtLightField -> descriptor.backingField
annotatedLightElement !is KtLightMethod -> descriptor annotatedLightElement !is KtLightMethod -> descriptor
annotatedLightElement.isGetter -> descriptor.getter 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. * 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( class KtLightPsiJavaCodeReferenceElement(
private val ktElement: PsiElement, private val ktElement: PsiElement,
reference: () -> PsiReference?, reference: () -> PsiReference?,
clsDelegateProvider: () -> PsiJavaCodeReferenceElement?,
private val customReferenceName: String? = null, private val customReferenceName: String? = null,
) : ) :
PsiElement by ktElement, PsiElement by ktElement,
PsiReference by LazyPsiReferenceDelegate(ktElement, reference), PsiReference by LazyPsiReferenceDelegate(ktElement, reference),
PsiJavaCodeReferenceElement { PsiJavaCodeReferenceElement {
private val delegate by lazyPub(clsDelegateProvider) override fun advancedResolve(incompleteCode: Boolean): JavaResolveResult = JavaResolveResult.EMPTY
override fun advancedResolve(incompleteCode: Boolean): JavaResolveResult = override fun getReferenceNameElement(): PsiElement? = null
delegate?.advancedResolve(incompleteCode) ?: JavaResolveResult.EMPTY
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) { override fun multiResolve(incompleteCode: Boolean): Array<JavaResolveResult> = emptyArray()
delegate?.processVariants(processor)
}
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? = null
override fun getParameterList(): PsiReferenceParameterList? = delegate?.parameterList
} }
private class LazyPsiReferenceDelegate( 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. * 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( KtLightPsiJavaCodeReferenceElement(
ktElement = it, ktElement = it,
reference = { null }, reference = { null },
clsDelegateProvider = { null },
customReferenceName = JAVA_LANG_ANNOTATION_REPEATABLE_SHORT_NAME, 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. * 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 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.*
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.annotations.NotNull import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable import org.jetbrains.annotations.Nullable
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.classes.cannotModify import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub 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.psi.psiUtil.hasSuspendModifier
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils 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.components.isVararg
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument 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.descriptorUtil.declaresOrInheritsDefaultValue
import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.types.KotlinType 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.isUnit
import org.jetbrains.kotlin.types.typeUtil.nullability import org.jetbrains.kotlin.types.typeUtil.nullability
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.asJava.elements.lightAnnotations") abstract class KtLightAbstractAnnotation(parent: PsiElement) :
abstract class KtLightAbstractAnnotation(parent: PsiElement, computeDelegate: Lazy<PsiAnnotation>?) :
KtLightElementBase(parent), PsiAnnotation, KtLightElement<KtCallElement, PsiAnnotation> { KtLightElementBase(parent), PsiAnnotation, KtLightElement<KtCallElement, PsiAnnotation> {
override val clsDelegate: PsiAnnotation by lazyPub { abstract override fun getNameReferenceElement(): PsiJavaCodeReferenceElement?
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
override fun getOwner(): PsiAnnotationOwner? = parent as? PsiAnnotationOwner 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 open fun fqNameMatches(fqName: String): Boolean = qualifiedName == fqName
} }
@@ -67,9 +56,8 @@ class KtLightAnnotationForSourceEntry(
private val name: String?, private val name: String?,
private val lazyQualifiedName: () -> String?, private val lazyQualifiedName: () -> String?,
override val kotlinOrigin: KtCallElement, override val kotlinOrigin: KtCallElement,
parent: PsiElement, parent: PsiElement
private val lazyClsDelegate: Lazy<PsiAnnotation>? ) : KtLightAbstractAnnotation(parent) {
) : KtLightAbstractAnnotation(parent, lazyClsDelegate) {
private val _qualifiedName: String? by lazyPub { lazyQualifiedName() } private val _qualifiedName: String? by lazyPub { lazyQualifiedName() }
@@ -101,6 +89,7 @@ class KtLightAnnotationForSourceEntry(
when (val psiElement = callEntry.key.source.getPsi()) { when (val psiElement = callEntry.key.source.getPsi()) {
is KtParameter -> is KtParameter ->
return psiElement.defaultValue?.let { convertToLightAnnotationMemberValue(this, it) } return psiElement.defaultValue?.let { convertToLightAnnotationMemberValue(this, it) }
is PsiAnnotationMethod -> is PsiAnnotationMethod ->
return psiElement.defaultValue return psiElement.defaultValue
} }
@@ -116,7 +105,6 @@ class KtLightAnnotationForSourceEntry(
(kotlinOrigin as? KtAnnotationEntry)?.typeReference?.reference (kotlinOrigin as? KtAnnotationEntry)?.typeReference?.reference
?: (kotlinOrigin.calleeExpression?.nameReference)?.references?.firstOrNull() ?: (kotlinOrigin.calleeExpression?.nameReference)?.references?.firstOrNull()
}, },
{ lazyClsDelegate?.value?.nameReferenceElement },
if (qualifiedName == CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE) JAVA_LANG_ANNOTATION_REPEATABLE_SHORT_NAME else null, 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() 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 { class KtLightEmptyAnnotationParameterList(parent: PsiElement) : KtLightElementBase(parent), PsiAnnotationParameterList {
override val kotlinOrigin: KtElement? get() = null override val kotlinOrigin: KtElement? get() = null
override fun getAttributes(): Array<PsiNameValuePair> = emptyArray() override fun getAttributes(): Array<PsiNameValuePair> = emptyArray()
} }
open class KtLightNullabilityAnnotation<D : KtLightElement<*, PsiModifierListOwner>>(val member: D, parent: PsiElement) : open class KtLightNullabilityAnnotation<D : KtLightElement<*, PsiModifierListOwner>>(val member: D, parent: PsiElement) :
KtLightAbstractAnnotation(parent, lazyPub { KtLightAbstractAnnotation(parent) {
// searching for last because nullability annotations are generated after backend generates source annotations
getClsNullabilityAnnotation(member) ?: KtLightNonExistentAnnotation(member)
}) {
override fun fqNameMatches(fqName: String): Boolean { override fun fqNameMatches(fqName: String): Boolean {
if (!isNullabilityAnnotation(fqName)) return false if (!isNullabilityAnnotation(fqName)) return false
@@ -280,7 +241,7 @@ open class KtLightNullabilityAnnotation<D : KtLightElement<*, PsiModifierListOwn
private val _qualifiedName: String? by lazyPub { private val _qualifiedName: String? by lazyPub {
val annotatedElement = member.takeIf(::isFromSources)?.kotlinOrigin val annotatedElement = member.takeIf(::isFromSources)?.kotlinOrigin
?: // it is out of our hands ?: // it is out of our hands
return@lazyPub getClsNullabilityAnnotation(member)?.qualifiedName return@lazyPub null
if (!fastCheckIsNullabilityApplied(member)) 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 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 internal fun isNullabilityAnnotation(qualifiedName: String?) = qualifiedName in backendNullabilityAnnotations
private val backendNullabilityAnnotations = arrayOf(Nullable::class.java.name, NotNull::class.java.name) private val backendNullabilityAnnotations = arrayOf(Nullable::class.java.name, NotNull::class.java.name)
@@ -388,9 +341,11 @@ fun convertToLightAnnotationMemberValue(lightParent: PsiElement, argument: KtExp
is KtClassLiteralExpression -> { is KtClassLiteralExpression -> {
return KtLightPsiClassObjectAccessExpression(argument, lightParent) return KtLightPsiClassObjectAccessExpression(argument, lightParent)
} }
is KtStringTemplateExpression, is KtConstantExpression -> { is KtStringTemplateExpression, is KtConstantExpression -> {
return KtLightPsiLiteral(argument, lightParent) return KtLightPsiLiteral(argument, lightParent)
} }
is KtCallExpression -> { is KtCallExpression -> {
val arguments = argument.valueArguments val arguments = argument.valueArguments
val annotationName = argument.calleeExpression?.let { getAnnotationName(it) } val annotationName = argument.calleeExpression?.let { getAnnotationName(it) }
@@ -399,8 +354,7 @@ fun convertToLightAnnotationMemberValue(lightParent: PsiElement, argument: KtExp
name = annotationName, name = annotationName,
lazyQualifiedName = { annotationName }, lazyQualifiedName = { annotationName },
kotlinOrigin = argument, kotlinOrigin = argument,
parent = lightParent, parent = lightParent
lazyClsDelegate = null
) )
} }
val resolvedCall = argument.getResolvedCall() val resolvedCall = argument.getResolvedCall()
@@ -414,6 +368,7 @@ fun convertToLightAnnotationMemberValue(lightParent: PsiElement, argument: KtExp
} }
} }
} }
is KtCollectionLiteralExpression -> { is KtCollectionLiteralExpression -> {
val arguments = argument.getInnerExpressions() val arguments = argument.getInnerExpressions()
if (arguments.isNotEmpty()) if (arguments.isNotEmpty())
@@ -451,17 +406,3 @@ private fun getAnnotationName(callee: KtExpression): String? {
} }
return null 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. * 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 { fun fastCheckIsNullabilityApplied(lightElement: KtLightElement<*, PsiModifierListOwner>): Boolean {
val elementIsApplicable = lightElement is KtLightMember<*> || lightElement is LightParameter
val elementIsApplicable =
(lightElement is KtLightMember<*> && lightElement !is KtLightFieldImpl.KtLightEnumConstant) || lightElement is LightParameter
if (!elementIsApplicable) return false if (!elementIsApplicable) return false
val annotatedElement = lightElement.kotlinOrigin ?: return true 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. * 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.
* 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 package org.jetbrains.kotlin.asJava
@@ -24,8 +13,8 @@ import java.io.File
class KotlinLightClassTest : KotlinAsJavaTestBase() { class KotlinLightClassTest : KotlinAsJavaTestBase() {
override fun getKotlinSourceRoots(): List<File> = listOf( override fun getKotlinSourceRoots(): List<File> = listOf(
File("compiler/testData/asJava/lightClassStructure/ClassObject.kt"), File("compiler/testData/asJava/lightClassStructure/ClassObject.kt"),
File("compiler/testData/asJava/lightClasses/ideRegression/ImplementingMap.kt") File("compiler/testData/asJava/lightClasses/ideRegression/ImplementingMap.kt")
) )
private val key = Key.create<String>("testKey") private val key = Key.create<String>("testKey")