add ultra-light classes/members that work without backend in simple cases
This commit is contained in:
@@ -64,7 +64,7 @@ public abstract class AnnotationCodegen {
|
||||
|
||||
public static final List<JvmFlagAnnotation> FIELD_FLAGS = Arrays.asList(
|
||||
new JvmFlagAnnotation(JvmAnnotationUtilKt.VOLATILE_ANNOTATION_FQ_NAME.asString(), Opcodes.ACC_VOLATILE),
|
||||
new JvmFlagAnnotation("kotlin.jvm.Transient", Opcodes.ACC_TRANSIENT)
|
||||
new JvmFlagAnnotation(JvmAnnotationUtilKt.TRANSIENT_ANNOTATION_FQ_NAME.asString(), Opcodes.ACC_TRANSIENT)
|
||||
);
|
||||
|
||||
public static final List<JvmFlagAnnotation> METHOD_FLAGS = Arrays.asList(
|
||||
|
||||
@@ -1112,34 +1112,37 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull KotlinTypeMapper typeMapper) {
|
||||
public static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull KotlinTypeMapper mapper) {
|
||||
return ArrayUtil.toStringArray(CollectionsKt.map(getThrownExceptions(function), d -> mapper.mapClass(d).getInternalName()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<ClassDescriptor> getThrownExceptions(@NotNull FunctionDescriptor function) {
|
||||
AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(new FqName("kotlin.throws"));
|
||||
if (annotation == null) {
|
||||
annotation = function.getAnnotations().findAnnotation(new FqName("kotlin.jvm.Throws"));
|
||||
}
|
||||
|
||||
if (annotation == null) return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
if (annotation == null) return Collections.emptyList();
|
||||
|
||||
Collection<ConstantValue<?>> values = annotation.getAllValueArguments().values();
|
||||
if (values.isEmpty()) return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
if (values.isEmpty()) return Collections.emptyList();
|
||||
|
||||
Object value = values.iterator().next();
|
||||
if (!(value instanceof ArrayValue)) return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
if (!(value instanceof ArrayValue)) return Collections.emptyList();
|
||||
ArrayValue arrayValue = (ArrayValue) value;
|
||||
|
||||
List<String> strings = CollectionsKt.mapNotNull(
|
||||
return CollectionsKt.mapNotNull(
|
||||
arrayValue.getValue(),
|
||||
(ConstantValue<?> constant) -> {
|
||||
if (constant instanceof KClassValue) {
|
||||
ClassDescriptor classDescriptor = DescriptorUtils.getClassDescriptorForType(
|
||||
return DescriptorUtils.getClassDescriptorForType(
|
||||
((KClassValue) constant).getArgumentType(DescriptorUtilsKt.getModule(function))
|
||||
);
|
||||
return typeMapper.mapClass(classDescriptor).getInternalName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
return ArrayUtil.toStringArray(strings);
|
||||
}
|
||||
|
||||
void generateDefaultIfNeeded(
|
||||
|
||||
@@ -398,8 +398,8 @@ public class PropertyCodegen {
|
||||
modifiers |= ACC_SYNTHETIC;
|
||||
}
|
||||
|
||||
KotlinType kotlinType =
|
||||
isDelegate ? getDelegateTypeForProperty((KtProperty) element, propertyDescriptor) : propertyDescriptor.getType();
|
||||
KotlinType kotlinType = isDelegate ? getDelegateTypeForProperty((KtProperty) element, propertyDescriptor, bindingContext)
|
||||
: propertyDescriptor.getType();
|
||||
Type type = typeMapper.mapType(kotlinType);
|
||||
|
||||
ClassBuilder builder = v;
|
||||
@@ -438,7 +438,11 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private KotlinType getDelegateTypeForProperty(@NotNull KtProperty p, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||
public static KotlinType getDelegateTypeForProperty(
|
||||
@NotNull KtProperty p,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull BindingContext bindingContext
|
||||
) {
|
||||
KotlinType delegateType = null;
|
||||
|
||||
ResolvedCall<FunctionDescriptor> provideDelegateResolvedCall =
|
||||
|
||||
@@ -1419,7 +1419,7 @@ public class KotlinTypeMapper {
|
||||
* In that case the generated method's return type should be boxed: otherwise it's not possible to use
|
||||
* this class from Java since javac issues errors when loading the class (incompatible return types)
|
||||
*/
|
||||
private boolean forceBoxedReturnType(@NotNull FunctionDescriptor descriptor) {
|
||||
public boolean forceBoxedReturnType(@NotNull FunctionDescriptor descriptor) {
|
||||
if (isBoxMethodForInlineClass(descriptor)) return true;
|
||||
|
||||
//noinspection ConstantConditions
|
||||
|
||||
+2
@@ -39,6 +39,8 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
* To mitigate this, CliLightClassGenerationSupport hold a trace that is shared between the analyzer and JetLightClasses
|
||||
*/
|
||||
class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) : LightClassGenerationSupport() {
|
||||
override fun createUltraLightClass(element: KtClassOrObject) = null
|
||||
|
||||
override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {
|
||||
//force resolve companion for light class generation
|
||||
traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
|
||||
|
||||
+3
@@ -27,6 +27,9 @@ val STRICTFP_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.Strictfp")
|
||||
@JvmField
|
||||
val VOLATILE_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.Volatile")
|
||||
|
||||
@JvmField
|
||||
val TRANSIENT_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.Transient")
|
||||
|
||||
fun DeclarationDescriptor.findJvmOverloadsAnnotation(): AnnotationDescriptor? =
|
||||
annotations.findAnnotation(JVM_OVERLOADS_FQ_NAME)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassBuilderResult
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.classes.KtUltraLightClass
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -40,6 +41,8 @@ abstract class LightClassGenerationSupport {
|
||||
|
||||
abstract fun analyzeWithContent(element: KtClassOrObject): BindingContext
|
||||
|
||||
abstract fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass?
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getInstance(project: Project): LightClassGenerationSupport {
|
||||
|
||||
@@ -209,7 +209,7 @@ object LightClassUtil {
|
||||
fun buildLightTypeParameterList(
|
||||
owner: PsiTypeParameterListOwner,
|
||||
declaration: KtDeclaration): PsiTypeParameterList {
|
||||
val builder = KotlinLightTypeParameterListBuilder(owner.manager)
|
||||
val builder = KotlinLightTypeParameterListBuilder(owner)
|
||||
if (declaration is KtTypeParameterListOwner) {
|
||||
val parameters = declaration.typeParameters
|
||||
for (i in parameters.indices) {
|
||||
|
||||
+27
-27
@@ -22,6 +22,7 @@ import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Comparing
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.PsiSubstitutorImpl
|
||||
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
||||
@@ -37,6 +38,7 @@ import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
|
||||
import com.intellij.psi.util.PsiUtilCore
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import com.intellij.util.SystemProperties
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.asJava.ImpreciseResolveResult
|
||||
@@ -73,15 +75,11 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
: KtLazyLightClass(classOrObject.manager), StubBasedPsiElement<KotlinClassOrObjectStub<out KtClassOrObject>> {
|
||||
private val lightIdentifier = KtLightIdentifier(this, classOrObject)
|
||||
|
||||
private val _extendsList by lazyPub {
|
||||
val listDelegate = super.getExtendsList() ?: return@lazyPub null
|
||||
KtLightPsiReferenceList(listDelegate, this)
|
||||
}
|
||||
private val _extendsList by lazyPub { createExtendsList() }
|
||||
private val _implementsList by lazyPub { createImplementsList() }
|
||||
|
||||
private val _implementsList by lazyPub {
|
||||
val listDelegate = super.getImplementsList() ?: return@lazyPub null
|
||||
KtLightPsiReferenceList(listDelegate, this)
|
||||
}
|
||||
protected open fun createExtendsList(): PsiReferenceList? = super.getExtendsList()?.let { KtLightPsiReferenceList(it, this) }
|
||||
protected open fun createImplementsList(): PsiReferenceList? = super.getImplementsList()?.let { KtLightPsiReferenceList(it, this) }
|
||||
|
||||
override val kotlinOrigin: KtClassOrObject = classOrObject
|
||||
|
||||
@@ -92,7 +90,7 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
override val lightClassData: LightClassData
|
||||
get() = findLightClassData()
|
||||
|
||||
open protected fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject)
|
||||
protected open fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject)
|
||||
|
||||
private fun getJavaFileStub(): PsiJavaFileStub = getLightClassDataHolder().javaFileStub
|
||||
|
||||
@@ -110,9 +108,9 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
|
||||
private val _containingFile: PsiFile by lazyPub {
|
||||
object : FakeFileForLightClass(
|
||||
classOrObject.containingKtFile,
|
||||
{ if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject))!! },
|
||||
{ getJavaFileStub() }
|
||||
classOrObject.containingKtFile,
|
||||
{ if (classOrObject.isTopLevel()) this else create(getOutermostClassOrObject(classOrObject))!! },
|
||||
{ getJavaFileStub() }
|
||||
) {
|
||||
override fun findReferenceAt(offset: Int) = ktFile.findReferenceAt(offset)
|
||||
|
||||
@@ -173,9 +171,9 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
return super.getContainingClass()
|
||||
}
|
||||
|
||||
private val _typeParameterList: PsiTypeParameterList by lazyPub {
|
||||
LightClassUtil.buildLightTypeParameterList(this, classOrObject)
|
||||
}
|
||||
private val _typeParameterList: PsiTypeParameterList by lazyPub { buildTypeParameterList() }
|
||||
|
||||
open protected fun buildTypeParameterList() = LightClassUtil.buildLightTypeParameterList(this, classOrObject)
|
||||
|
||||
override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList
|
||||
|
||||
@@ -322,9 +320,8 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
|
||||
override fun getNameIdentifier(): KtLightIdentifier? = lightIdentifier
|
||||
|
||||
override fun getExtendsList() = _extendsList
|
||||
|
||||
override fun getImplementsList() = _implementsList
|
||||
override fun getExtendsList(): PsiReferenceList? = _extendsList
|
||||
override fun getImplementsList(): PsiReferenceList? = _implementsList
|
||||
|
||||
companion object {
|
||||
private val JAVA_API_STUB = Key.create<CachedValue<LightClassDataHolder.ForClass>>("JAVA_API_STUB")
|
||||
@@ -347,6 +344,10 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
return null
|
||||
}
|
||||
|
||||
if (Registry.`is`("kotlin.use.ultra.light.classes", false)) {
|
||||
LightClassGenerationSupport.getInstance(classOrObject.project).createUltraLightClass(classOrObject)?.let { return it }
|
||||
}
|
||||
|
||||
return when {
|
||||
classOrObject is KtObjectDeclaration && classOrObject.isObjectLiteral() ->
|
||||
KtLightClassForAnonymousDeclaration(classOrObject)
|
||||
@@ -456,17 +457,16 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
|
||||
|
||||
private val modifiers by lazyPub { containingClass.computeModifiers() }
|
||||
|
||||
override fun hasModifierProperty(name: String): Boolean {
|
||||
if (name != PsiModifier.FINAL) {
|
||||
return name in modifiers
|
||||
}
|
||||
override fun hasModifierProperty(name: String): Boolean =
|
||||
if (name != PsiModifier.FINAL) name in modifiers else owner.isFinal(PsiModifier.FINAL in modifiers)
|
||||
|
||||
val isFinalByPsi = PsiModifier.FINAL in modifiers
|
||||
// annotations can make class open via 'allopen' plugin
|
||||
if (!owner.isPossiblyAffectedByAllOpen() || !isFinalByPsi) return isFinalByPsi
|
||||
}
|
||||
|
||||
return clsDelegate.hasModifierProperty(PsiModifier.FINAL)
|
||||
}
|
||||
open fun isFinal(isFinalByPsi: Boolean): Boolean {
|
||||
// annotations can make class open via 'allopen' plugin
|
||||
if (!isPossiblyAffectedByAllOpen() || !isFinalByPsi) return isFinalByPsi
|
||||
|
||||
return clsDelegate.hasModifierProperty(PsiModifier.FINAL)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.asJava.classes
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
|
||||
// light class for top level or (inner/nested of top level) source declarations
|
||||
class KtLightClassImpl(classOrObject: KtClassOrObject) : KtLightClassForSourceDeclaration(classOrObject) {
|
||||
open class KtLightClassImpl(classOrObject: KtClassOrObject) : KtLightClassForSourceDeclaration(classOrObject) {
|
||||
override fun getQualifiedName() = classOrObject.fqName?.asString()
|
||||
|
||||
override fun getParent() = if (classOrObject.isTopLevel())
|
||||
|
||||
@@ -0,0 +1,657 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.google.common.annotations.VisibleForTesting
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.PsiClassImplUtil
|
||||
import com.intellij.psi.impl.PsiImplUtil
|
||||
import com.intellij.psi.impl.light.*
|
||||
import com.intellij.psi.util.TypeConversionUtil
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassData
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.codegen.FunctionCodegen
|
||||
import org.jetbrains.kotlin.codegen.PropertyCodegen
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.STRICTFP_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.SYNCHRONIZED_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.TRANSIENT_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.VOLATILE_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: UltraLightSupport) :
|
||||
KtLightClassImpl(classOrObject) {
|
||||
private val tooComplex: Boolean by lazyPub { support.isTooComplexForUltraLightGeneration(classOrObject) }
|
||||
|
||||
override fun isFinal(isFinalByPsi: Boolean) = if (tooComplex) super.isFinal(isFinalByPsi) else isFinalByPsi
|
||||
|
||||
@Volatile
|
||||
@VisibleForTesting
|
||||
var isClsDelegateLoaded = false
|
||||
|
||||
override fun findLightClassData(): LightClassData = super.findLightClassData().also {
|
||||
if (!isClsDelegateLoaded) {
|
||||
isClsDelegateLoaded = true
|
||||
check(tooComplex) { "Cls delegate shouldn't be loaded for not too complex ultra-light classes!" }
|
||||
}
|
||||
}
|
||||
|
||||
private fun allSuperTypes() =
|
||||
getDescriptor()?.typeConstructor?.supertypes?.mapNotNull {
|
||||
it.asPsiType(classOrObject, support, TypeMappingMode.SUPER_TYPE) as? PsiClassType
|
||||
}.orEmpty()
|
||||
|
||||
override fun createExtendsList(): PsiReferenceList? =
|
||||
if (tooComplex) super.createExtendsList()
|
||||
else LightReferenceListBuilder(manager, language, PsiReferenceList.Role.EXTENDS_LIST).also { list ->
|
||||
allSuperTypes()
|
||||
.filter { (isInterface || it.resolve()?.isInterface == false) && !it.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) }
|
||||
.forEach(list::addReference)
|
||||
}
|
||||
|
||||
override fun createImplementsList(): PsiReferenceList? =
|
||||
if (tooComplex) super.createImplementsList()
|
||||
else LightReferenceListBuilder(manager, language, PsiReferenceList.Role.IMPLEMENTS_LIST).also { list ->
|
||||
if (!isInterface) {
|
||||
allSuperTypes()
|
||||
.filter { it.resolve()?.isInterface == true }
|
||||
.forEach(list::addReference)
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildTypeParameterList(): PsiTypeParameterList =
|
||||
if (tooComplex) super.buildTypeParameterList() else buildTypeParameterList(classOrObject, this, support)
|
||||
|
||||
// the following logic should be in the platform (super), overrides can be removed once that happens
|
||||
override fun getInterfaces(): Array<PsiClass> = PsiClassImplUtil.getInterfaces(this)
|
||||
override fun getSuperClass(): PsiClass? = PsiClassImplUtil.getSuperClass(this)
|
||||
override fun getSupers(): Array<PsiClass> = PsiClassImplUtil.getSupers(this)
|
||||
override fun getSuperTypes(): Array<PsiClassType> = PsiClassImplUtil.getSuperTypes(this)
|
||||
|
||||
override fun getRBrace(): PsiElement? = null
|
||||
override fun getLBrace(): PsiElement? = null
|
||||
|
||||
private val _ownFields: List<KtLightField> by lazyPub {
|
||||
val result = arrayListOf<KtLightField>()
|
||||
val usedNames = hashSetOf<String>()
|
||||
|
||||
fun generateUniqueName(base: String): String {
|
||||
if (usedNames.add(base)) return base
|
||||
var i = 1
|
||||
while (true) {
|
||||
val suggestion = "$base$$i"
|
||||
if (usedNames.add(suggestion)) return suggestion
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (parameter in propertyParameters()) {
|
||||
val modifiers = hashSetOf<String>()
|
||||
modifiers.add(PsiModifier.PRIVATE)
|
||||
if (!parameter.isMutable) {
|
||||
modifiers.add(PsiModifier.FINAL)
|
||||
}
|
||||
result.add(KtUltraLightField(parameter, generateUniqueName(parameter.name.orEmpty()), this, support, modifiers))
|
||||
}
|
||||
|
||||
this.classOrObject.companionObjects.firstOrNull()?.let { companion ->
|
||||
result.add(
|
||||
KtUltraLightField(
|
||||
companion,
|
||||
generateUniqueName(companion.name.orEmpty()),
|
||||
this,
|
||||
support,
|
||||
setOf(PsiModifier.STATIC, PsiModifier.FINAL, PsiModifier.PUBLIC)
|
||||
)
|
||||
)
|
||||
|
||||
for (property in companion.declarations.filterIsInstance<KtProperty>()) {
|
||||
if (isInterface && !property.hasModifier(CONST_KEYWORD)) continue
|
||||
|
||||
propertyField(property, ::generateUniqueName, true)?.let(result::add)
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInterface &&
|
||||
!(this.classOrObject is KtObjectDeclaration && this.classOrObject.isCompanion() && containingClass?.isInterface == false)
|
||||
) {
|
||||
for (property in this.classOrObject.declarations.filterIsInstance<KtProperty>()) {
|
||||
propertyField(property, ::generateUniqueName, forceStatic = this.classOrObject is KtObjectDeclaration)?.let(result::add)
|
||||
}
|
||||
}
|
||||
|
||||
if (isNamedObject()) {
|
||||
result.add(
|
||||
KtUltraLightField(
|
||||
this.classOrObject,
|
||||
JvmAbi.INSTANCE_FIELD,
|
||||
this,
|
||||
support,
|
||||
setOf(PsiModifier.STATIC, PsiModifier.FINAL, PsiModifier.PUBLIC)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
private fun isNamedObject() = classOrObject is KtObjectDeclaration && !classOrObject.isCompanion()
|
||||
|
||||
private fun propertyField(property: KtProperty, generateUniqueName: (String) -> String, forceStatic: Boolean): KtLightField? {
|
||||
if (!hasBackingField(property)) return null
|
||||
|
||||
val hasDelegate = property.hasDelegate()
|
||||
val fieldName = generateUniqueName((property.name ?: "") + (if (hasDelegate) "\$delegate" else ""))
|
||||
|
||||
val visibility = when {
|
||||
property.hasModifier(PRIVATE_KEYWORD) -> PsiModifier.PRIVATE
|
||||
property.hasModifier(PROTECTED_KEYWORD) && property.hasModifier(LATEINIT_KEYWORD) -> PsiModifier.PROTECTED
|
||||
property.hasModifier(CONST_KEYWORD) || (property.hasModifier(LATEINIT_KEYWORD) && property.setter == null) -> PsiModifier.PUBLIC
|
||||
else -> PsiModifier.PRIVATE
|
||||
}
|
||||
val modifiers = hashSetOf(visibility)
|
||||
|
||||
if (!property.isVar || property.hasModifier(CONST_KEYWORD) || hasDelegate) {
|
||||
modifiers.add(PsiModifier.FINAL)
|
||||
}
|
||||
|
||||
if (forceStatic || isNamedObject() && isJvmStatic(property)) {
|
||||
modifiers.add(PsiModifier.STATIC)
|
||||
}
|
||||
|
||||
return KtUltraLightField(property, fieldName, this, support, modifiers)
|
||||
}
|
||||
|
||||
private fun hasBackingField(property: KtProperty): Boolean {
|
||||
if (property.hasModifier(ABSTRACT_KEYWORD)) return false
|
||||
if (property.hasModifier(LATEINIT_KEYWORD) || property.accessors.isEmpty()) return true
|
||||
|
||||
val context = LightClassGenerationSupport.getInstance(project).analyze(property)
|
||||
val descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, property)
|
||||
return descriptor is PropertyDescriptor && context[BindingContext.BACKING_FIELD_REQUIRED, descriptor] == true
|
||||
}
|
||||
|
||||
override fun getOwnFields(): List<KtLightField> = if (tooComplex) super.getOwnFields() else _ownFields
|
||||
|
||||
private fun propertyParameters() = classOrObject.primaryConstructorParameters.filter { it.hasValOrVar() }
|
||||
|
||||
private val _ownMethods: List<KtLightMethod> by lazyPub {
|
||||
val result = arrayListOf<KtLightMethod>()
|
||||
for (declaration in this.classOrObject.declarations.filterNot { isHiddenByDeprecation(it) }) {
|
||||
if (declaration.hasModifier(PRIVATE_KEYWORD) && isInterface) continue
|
||||
when (declaration) {
|
||||
is KtNamedFunction -> result.add(asJavaMethod(declaration, false))
|
||||
is KtProperty -> result.addAll(propertyAccessors(declaration, declaration.isVar, false))
|
||||
}
|
||||
}
|
||||
for (parameter in propertyParameters()) {
|
||||
result.addAll(propertyAccessors(parameter, parameter.isMutable, false))
|
||||
}
|
||||
if (!isInterface) {
|
||||
result.addAll(createConstructors())
|
||||
}
|
||||
this.classOrObject.companionObjects.firstOrNull()?.let { companion ->
|
||||
for (declaration in companion.declarations.filterNot { isHiddenByDeprecation(it) }) {
|
||||
when (declaration) {
|
||||
is KtNamedFunction -> if (isJvmStatic(declaration)) result.add(asJavaMethod(declaration, true))
|
||||
is KtProperty -> result.addAll(propertyAccessors(declaration, declaration.isVar, true))
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
private fun createConstructors(): List<KtLightMethod> {
|
||||
val result = arrayListOf<KtLightMethod>()
|
||||
val constructors = classOrObject.allConstructors
|
||||
if (constructors.isEmpty()) {
|
||||
result.add(defaultConstructor())
|
||||
}
|
||||
for (constructor in constructors.filterNot { isHiddenByDeprecation(it) }) {
|
||||
result.add(asJavaMethod(constructor, false))
|
||||
}
|
||||
val primary = classOrObject.primaryConstructor
|
||||
if (primary != null && shouldGenerateNoArgOverload(primary)) {
|
||||
result.add(noArgConstructor(simpleVisibility(primary), primary))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun shouldGenerateNoArgOverload(primary: KtPrimaryConstructor): Boolean {
|
||||
return !primary.hasModifier(PRIVATE_KEYWORD) &&
|
||||
primary.valueParameters.isNotEmpty() &&
|
||||
primary.valueParameters.all { it.defaultValue != null } &&
|
||||
classOrObject.allConstructors.none { it.valueParameters.isEmpty() }
|
||||
}
|
||||
|
||||
private fun defaultConstructor(): KtUltraLightMethod {
|
||||
val visibility =
|
||||
if (classOrObject is KtObjectDeclaration || classOrObject.hasModifier(SEALED_KEYWORD)) PsiModifier.PRIVATE
|
||||
else PsiModifier.PUBLIC
|
||||
return noArgConstructor(visibility, classOrObject)
|
||||
}
|
||||
|
||||
private fun simpleVisibility(declaration: KtDeclaration): String = when {
|
||||
declaration.hasModifier(PRIVATE_KEYWORD) -> PsiModifier.PRIVATE
|
||||
declaration.hasModifier(PROTECTED_KEYWORD) -> PsiModifier.PROTECTED
|
||||
else -> PsiModifier.PUBLIC
|
||||
}
|
||||
|
||||
private fun noArgConstructor(visibility: String, declaration: KtDeclaration): KtUltraLightMethod = KtUltraLightMethod(
|
||||
LightMethodBuilder(manager, language, name.orEmpty()).setConstructor(true).addModifier(visibility),
|
||||
declaration,
|
||||
support,
|
||||
this
|
||||
)
|
||||
|
||||
private fun isHiddenByDeprecation(declaration: KtDeclaration): Boolean {
|
||||
val deprecated = support.findAnnotation(declaration, FqName("kotlin.Deprecated"))?.second
|
||||
return (deprecated?.argumentValue("level") as? EnumValue)?.enumEntryName?.asString() == "HIDDEN"
|
||||
}
|
||||
|
||||
private fun isJvmStatic(declaration: KtAnnotated): Boolean = declaration.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME)
|
||||
|
||||
override fun getOwnMethods(): List<KtLightMethod> = if (tooComplex) super.getOwnMethods() else _ownMethods
|
||||
|
||||
private fun asJavaMethod(f: KtFunction, forceStatic: Boolean): KtLightMethod {
|
||||
val isConstructor = f is KtConstructor<*>
|
||||
val name = if (isConstructor) this.name else mangleIfNeeded(listOf(f), f.name ?: SpecialNames.NO_NAME_PROVIDED.asString())
|
||||
val method = lightMethod(name.orEmpty(), f, forceStatic)
|
||||
val wrapper = KtUltraLightMethod(method, f, support, this)
|
||||
addReceiverParameter(f, wrapper)
|
||||
for (parameter in f.valueParameters) {
|
||||
method.addParameter(KtUltraLightParameter(parameter.name.orEmpty(), parameter, support, wrapper, null))
|
||||
}
|
||||
val returnType: PsiType? by lazyPub {
|
||||
if (isConstructor) null
|
||||
else methodReturnType(f)
|
||||
}
|
||||
method.setMethodReturnType { returnType }
|
||||
return wrapper
|
||||
}
|
||||
|
||||
private fun addReceiverParameter(f: KtDeclaration, method: KtUltraLightMethod) {
|
||||
val receiver = (f as? KtCallableDeclaration)?.receiverTypeReference
|
||||
if (receiver != null) {
|
||||
method.delegate.addParameter(KtUltraLightParameter("\$self", f, support, method, receiver))
|
||||
}
|
||||
}
|
||||
|
||||
private fun methodReturnType(f: KtDeclaration): PsiType {
|
||||
val desc = f.resolve()?.let { if (it is PropertyDescriptor) it.getter else it }
|
||||
val kotlinType = (desc as? FunctionDescriptor)?.returnType ?: return PsiType.NULL
|
||||
val mode = when {
|
||||
typeMapper(support).forceBoxedReturnType(desc) -> TypeMappingMode.RETURN_TYPE_BOXED
|
||||
else -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
|
||||
}
|
||||
return kotlinType.asPsiType(f, support, mode)
|
||||
}
|
||||
|
||||
private fun lightMethod(name: String, declaration: KtDeclaration, forceStatic: Boolean): LightMethodBuilder {
|
||||
val accessedProperty = if (declaration is KtPropertyAccessor) declaration.property else null
|
||||
val outer = accessedProperty ?: declaration
|
||||
return LightMethodBuilder(
|
||||
manager, language, name,
|
||||
LightParameterListBuilder(manager, language),
|
||||
object : LightModifierList(manager, language) {
|
||||
override fun hasModifierProperty(name: String): Boolean {
|
||||
if (name == PsiModifier.PUBLIC || name == PsiModifier.PROTECTED || name == PsiModifier.PRIVATE) {
|
||||
if (declaration.isPrivate() || accessedProperty?.isPrivate() == true) {
|
||||
return name == PsiModifier.PRIVATE
|
||||
}
|
||||
if (declaration.hasModifier(PROTECTED_KEYWORD) || accessedProperty?.hasModifier(PROTECTED_KEYWORD) == true) {
|
||||
return name == PsiModifier.PROTECTED
|
||||
}
|
||||
|
||||
if (outer.hasModifier(OVERRIDE_KEYWORD)) {
|
||||
when ((outer.resolve() as? CallableDescriptor)?.visibility) {
|
||||
Visibilities.PUBLIC -> return name == PsiModifier.PUBLIC
|
||||
Visibilities.PRIVATE -> return name == PsiModifier.PRIVATE
|
||||
Visibilities.PROTECTED -> return name == PsiModifier.PROTECTED
|
||||
}
|
||||
}
|
||||
|
||||
return name == PsiModifier.PUBLIC
|
||||
}
|
||||
|
||||
return when (name) {
|
||||
PsiModifier.FINAL -> !isInterface && outer !is KtConstructor<*> && isFinal(outer)
|
||||
PsiModifier.ABSTRACT -> isInterface || outer.hasModifier(ABSTRACT_KEYWORD)
|
||||
PsiModifier.STATIC -> forceStatic || isNamedObject() && isJvmStatic(outer)
|
||||
PsiModifier.STRICTFP -> declaration is KtFunction && declaration.hasAnnotation(STRICTFP_ANNOTATION_FQ_NAME)
|
||||
PsiModifier.SYNCHRONIZED -> declaration is KtFunction && declaration.hasAnnotation(SYNCHRONIZED_ANNOTATION_FQ_NAME)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
fun KtDeclaration.isPrivate() =
|
||||
hasModifier(PRIVATE_KEYWORD) ||
|
||||
this is KtConstructor<*> && classOrObject.hasModifier(SEALED_KEYWORD) ||
|
||||
this is KtFunction && typeParameters.any { it.hasModifier(REIFIED_KEYWORD) }
|
||||
}
|
||||
).setConstructor(declaration is KtConstructor<*>)
|
||||
}
|
||||
|
||||
private fun mangleIfNeeded(declarations: List<KtDeclaration>, name: String): String {
|
||||
for (declaration in declarations) {
|
||||
if (declaration.hasModifier(PRIVATE_KEYWORD) ||
|
||||
declaration.hasModifier(PROTECTED_KEYWORD) ||
|
||||
declaration.hasModifier(PUBLIC_KEYWORD)
|
||||
) {
|
||||
return name
|
||||
}
|
||||
if (isInternal(declaration) && declaration.resolve()?.isPublishedApi() != true) {
|
||||
return KotlinTypeMapper.InternalNameMapper.mangleInternalName(name, support.moduleName)
|
||||
}
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
private fun KtAnnotated.hasAnnotation(name: FqName) = support.findAnnotation(this, name) != null
|
||||
|
||||
private fun isInternal(f: KtDeclaration): Boolean {
|
||||
if (f.hasModifier(OVERRIDE_KEYWORD)) {
|
||||
val desc = f.resolve()
|
||||
return desc is CallableDescriptor &&
|
||||
desc.visibility.effectiveVisibility(desc, false) == EffectiveVisibility.Internal
|
||||
}
|
||||
return f.hasModifier(INTERNAL_KEYWORD)
|
||||
}
|
||||
|
||||
private fun propertyAccessors(declaration: KtNamedDeclaration, mutable: Boolean, onlyJvmStatic: Boolean): List<KtLightMethod> {
|
||||
val propertyName = declaration.name
|
||||
if (declaration.hasModifier(CONST_KEYWORD) || propertyName == null) return emptyList()
|
||||
|
||||
val ktGetter = (declaration as? KtProperty)?.getter
|
||||
val ktSetter = (declaration as? KtProperty)?.setter
|
||||
|
||||
val isPrivate = declaration.hasModifier(PRIVATE_KEYWORD)
|
||||
if (isPrivate && declaration !is KtProperty) return emptyList()
|
||||
|
||||
fun needsAccessor(accessor: KtPropertyAccessor?): Boolean {
|
||||
if (!onlyJvmStatic || isJvmStatic(declaration) || accessor != null && isJvmStatic(accessor)) {
|
||||
if (declaration is KtProperty && declaration.hasDelegate()) {
|
||||
return true
|
||||
}
|
||||
if (accessor?.hasModifier(PRIVATE_KEYWORD) == true) {
|
||||
return false
|
||||
}
|
||||
if (!isPrivate || accessor?.hasBody() == true) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
val result = arrayListOf<KtLightMethod>()
|
||||
|
||||
if (needsAccessor(ktGetter)) {
|
||||
val getterName = mangleIfNeeded(listOfNotNull(ktGetter, declaration), JvmAbi.getterName(propertyName))
|
||||
val getterType: PsiType by lazyPub { methodReturnType(declaration) }
|
||||
val getterPrototype = lightMethod(getterName, ktGetter ?: declaration, onlyJvmStatic)
|
||||
.setMethodReturnType { getterType }
|
||||
val getterWrapper = KtUltraLightMethod(getterPrototype, declaration, support, this)
|
||||
addReceiverParameter(declaration, getterWrapper)
|
||||
result.add(getterWrapper)
|
||||
}
|
||||
|
||||
if (mutable && needsAccessor(ktSetter)) {
|
||||
val setterName = mangleIfNeeded(listOfNotNull(ktSetter, declaration), JvmAbi.setterName(propertyName))
|
||||
val setterPrototype = lightMethod(setterName, ktSetter ?: declaration, onlyJvmStatic)
|
||||
.setMethodReturnType(PsiType.VOID)
|
||||
val setterWrapper = KtUltraLightMethod(setterPrototype, declaration, support, this)
|
||||
addReceiverParameter(declaration, setterWrapper)
|
||||
val parameterOrigin = ktSetter?.parameter ?: declaration
|
||||
setterPrototype.addParameter(KtUltraLightParameter(propertyName, parameterOrigin, support, setterWrapper, null))
|
||||
result.add(setterWrapper)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun isFinal(declaration: KtDeclaration): Boolean {
|
||||
if (declaration.hasModifier(FINAL_KEYWORD)) return true
|
||||
return declaration !is KtPropertyAccessor &&
|
||||
!declaration.hasModifier(OPEN_KEYWORD) &&
|
||||
!declaration.hasModifier(OVERRIDE_KEYWORD) &&
|
||||
!declaration.hasModifier(ABSTRACT_KEYWORD)
|
||||
}
|
||||
|
||||
override fun getInitializers(): Array<PsiClassInitializer> = emptyArray()
|
||||
|
||||
override fun getContainingClass(): PsiClass? =
|
||||
if (tooComplex) super.getContainingClass() else classOrObject.containingClass()?.let(KtLightClassForSourceDeclaration::create)
|
||||
|
||||
override fun getParent(): PsiElement? = if (tooComplex) super.getParent() else containingClass ?: containingFile
|
||||
|
||||
override fun getScope(): PsiElement? = if (tooComplex) super.getScope() else parent
|
||||
override fun copy(): KtLightClassImpl = KtUltraLightClass(classOrObject.copy() as KtClassOrObject, support)
|
||||
}
|
||||
|
||||
private class KtUltraLightField(
|
||||
private val declaration: KtNamedDeclaration,
|
||||
name: String,
|
||||
private val containingClass: KtUltraLightClass,
|
||||
private val support: UltraLightSupport,
|
||||
modifiers: Set<String>
|
||||
) : LightFieldBuilder(name, PsiType.NULL, declaration), KtLightField {
|
||||
private val modList = object : KtLightSimpleModifierList(this, modifiers) {
|
||||
override fun hasModifierProperty(name: String): Boolean = when (name) {
|
||||
PsiModifier.VOLATILE -> hasFieldAnnotation(VOLATILE_ANNOTATION_FQ_NAME)
|
||||
PsiModifier.TRANSIENT -> hasFieldAnnotation(TRANSIENT_ANNOTATION_FQ_NAME)
|
||||
else -> super.hasModifierProperty(name)
|
||||
}
|
||||
|
||||
private fun hasFieldAnnotation(fqName: FqName): Boolean {
|
||||
val annotation = support.findAnnotation(declaration, fqName)?.first ?: return false
|
||||
val target = annotation.useSiteTarget?.getAnnotationUseSiteTarget() ?: return true
|
||||
val expectedTarget =
|
||||
if (declaration is KtProperty && declaration.hasDelegate()) AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
|
||||
else AnnotationUseSiteTarget.FIELD
|
||||
return target == expectedTarget
|
||||
}
|
||||
}
|
||||
|
||||
override fun getModifierList(): PsiModifierList = modList
|
||||
override fun hasModifierProperty(name: String): Boolean =
|
||||
modifierList.hasModifierProperty(name) //can be removed after IDEA platform does the same
|
||||
|
||||
override fun getLanguage(): Language = KotlinLanguage.INSTANCE
|
||||
|
||||
private val _type: PsiType by lazyPub {
|
||||
fun nonExistent() = JavaPsiFacade.getElementFactory(project).createTypeFromText("error.NonExistentClass", declaration)
|
||||
when {
|
||||
declaration is KtProperty && declaration.hasDelegate() ->
|
||||
(declaration.resolve() as? PropertyDescriptor)
|
||||
?.let {
|
||||
val context = LightClassGenerationSupport.getInstance(project).analyze(declaration)
|
||||
PropertyCodegen.getDelegateTypeForProperty(declaration, it, context)
|
||||
}
|
||||
?.let { it.asPsiType(declaration, support, TypeMappingMode.getOptimalModeForValueParameter(it), this) }
|
||||
?.let(TypeConversionUtil::erasure)
|
||||
?: nonExistent()
|
||||
declaration is KtObjectDeclaration ->
|
||||
KtLightClassForSourceDeclaration.create(declaration)?.let { JavaPsiFacade.getElementFactory(project).createType(it) }
|
||||
?: nonExistent()
|
||||
else ->
|
||||
declaration.getKotlinType()?.let {
|
||||
val mode = when {
|
||||
(declaration.resolve() as? PropertyDescriptor)?.isVar == true -> TypeMappingMode.getOptimalModeForValueParameter(it)
|
||||
else -> TypeMappingMode.getOptimalModeForReturnType(it, false)
|
||||
}
|
||||
it.asPsiType(declaration, support, mode, this)
|
||||
} ?: PsiType.NULL
|
||||
}
|
||||
}
|
||||
|
||||
override fun getType(): PsiType = _type
|
||||
|
||||
override fun getParent() = containingClass
|
||||
override fun getContainingClass() = containingClass
|
||||
override fun getContainingFile(): PsiFile? = containingClass.containingFile
|
||||
|
||||
override fun computeConstantValue(): Any? =
|
||||
if (hasModifierProperty(PsiModifier.FINAL) &&
|
||||
(TypeConversionUtil.isPrimitiveAndNotNull(_type) || _type.equalsToText(CommonClassNames.JAVA_LANG_STRING))
|
||||
)
|
||||
(declaration.resolve() as? VariableDescriptor)?.compileTimeInitializer?.value
|
||||
else null
|
||||
|
||||
override fun computeConstantValue(visitedVars: MutableSet<PsiVariable>?): Any? = computeConstantValue()
|
||||
|
||||
override val kotlinOrigin = declaration
|
||||
override val clsDelegate: PsiField
|
||||
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
|
||||
override val lightMemberOrigin = LightMemberOriginForDeclaration(declaration, JvmDeclarationOriginKind.OTHER)
|
||||
|
||||
override fun setName(@NonNls name: String): PsiElement {
|
||||
(kotlinOrigin as? KtNamedDeclaration)?.setName(name)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun setInitializer(initializer: PsiExpression?) = cannotModify()
|
||||
|
||||
}
|
||||
|
||||
internal class KtUltraLightMethod(
|
||||
internal val delegate: LightMethodBuilder,
|
||||
originalElement: KtDeclaration,
|
||||
private val support: UltraLightSupport,
|
||||
containingClass: KtUltraLightClass
|
||||
) : KtLightMethodImpl({ delegate }, LightMemberOriginForDeclaration(originalElement, JvmDeclarationOriginKind.OTHER), containingClass) {
|
||||
|
||||
override fun getReturnTypeElement(): PsiTypeElement? = null
|
||||
override fun getReturnType(): PsiType? = clsDelegate.returnType
|
||||
override fun getParameterList(): PsiParameterList = clsDelegate.parameterList
|
||||
|
||||
// should be in super
|
||||
override fun isVarArgs() = PsiImplUtil.isVarArgs(this)
|
||||
|
||||
override fun buildTypeParameterList(): PsiTypeParameterList {
|
||||
val origin = kotlinOrigin
|
||||
return if (origin is KtFunction || origin is KtProperty)
|
||||
buildTypeParameterList(origin as KtTypeParameterListOwner, this, support)
|
||||
else LightTypeParameterListBuilder(manager, language)
|
||||
}
|
||||
|
||||
private val _throwsList: PsiReferenceList by lazyPub {
|
||||
val list = LightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST)
|
||||
(kotlinOrigin?.resolve() as? FunctionDescriptor)?.let {
|
||||
for (ex in FunctionCodegen.getThrownExceptions(it)) {
|
||||
list.addReference(ex.fqNameSafe.asString())
|
||||
}
|
||||
}
|
||||
list
|
||||
}
|
||||
|
||||
override fun getThrowsList(): PsiReferenceList = _throwsList
|
||||
}
|
||||
|
||||
internal class KtUltraLightParameter(
|
||||
name: String,
|
||||
override val kotlinOrigin: KtDeclaration,
|
||||
private val support: UltraLightSupport,
|
||||
method: KtLightMethod,
|
||||
private val receiver: KtTypeReference?
|
||||
) : org.jetbrains.kotlin.asJava.elements.LightParameter(
|
||||
name,
|
||||
PsiType.NULL,
|
||||
method,
|
||||
method.language
|
||||
),
|
||||
KtLightDeclaration<KtDeclaration, PsiParameter> {
|
||||
|
||||
override val clsDelegate: PsiParameter
|
||||
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
|
||||
|
||||
private val lightModifierList by lazyPub { KtLightSimpleModifierList(this, emptySet()) }
|
||||
|
||||
override fun isVarArgs(): Boolean =
|
||||
kotlinOrigin is KtParameter && kotlinOrigin.isVarArg && method.parameterList.parameters.last() == this
|
||||
|
||||
override fun getModifierList(): PsiModifierList = lightModifierList
|
||||
|
||||
override fun getNavigationElement(): PsiElement = kotlinOrigin
|
||||
|
||||
private val kotlinType: KotlinType? by lazyPub {
|
||||
when {
|
||||
receiver != null -> (kotlinOrigin.resolve() as? CallableMemberDescriptor)?.extensionReceiverParameter?.type
|
||||
else -> kotlinOrigin.getKotlinType()
|
||||
}
|
||||
}
|
||||
private val _type: PsiType by lazyPub {
|
||||
kotlinType?.let { it.asPsiType(kotlinOrigin, support, TypeMappingMode.getOptimalModeForValueParameter(it), this) } ?: PsiType.NULL
|
||||
}
|
||||
|
||||
override fun getType(): PsiType = _type
|
||||
|
||||
override fun setName(@NonNls name: String): PsiElement {
|
||||
(kotlinOrigin as? KtVariableDeclaration)?.setName(name)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun getContainingFile(): PsiFile = method.containingFile
|
||||
override fun getParent(): PsiElement = method.parameterList
|
||||
|
||||
override fun equals(other: Any?): Boolean = other is KtUltraLightParameter && other.kotlinOrigin == this.kotlinOrigin
|
||||
override fun hashCode(): Int = kotlinOrigin.hashCode()
|
||||
|
||||
internal fun annotatedOrigin(): KtAnnotated? {
|
||||
if (receiver != null) return receiver
|
||||
|
||||
if (kotlinOrigin is KtProperty) {
|
||||
return null // we're a setter of a property with no explicit declaration, so we don't have annotation
|
||||
}
|
||||
return kotlinOrigin
|
||||
}
|
||||
|
||||
internal fun getTypeForNullability(): KotlinType? {
|
||||
if (receiver != null) return kotlinType
|
||||
if (kotlinOrigin is KtProperty) {
|
||||
if (kotlinOrigin.setter?.hasModifier(PRIVATE_KEYWORD) == true) return null
|
||||
return kotlinType
|
||||
}
|
||||
if (kotlinOrigin is KtParameter) {
|
||||
val reference = kotlinOrigin.typeReference
|
||||
if (kotlinOrigin.isVarArg && reference != null) {
|
||||
LightClassGenerationSupport.getInstance(project).analyze(reference)[BindingContext.TYPE, reference]?.let { return it }
|
||||
}
|
||||
if (reference != null || kotlinOrigin.parent?.parent is KtPropertyAccessor) {
|
||||
return kotlinType
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface UltraLightSupport {
|
||||
val moduleName: String
|
||||
fun findAnnotation(owner: KtAnnotated, fqName: FqName): Pair<KtAnnotationEntry, AnnotationDescriptor>?
|
||||
fun isTooComplexForUltraLightGeneration(element: KtClassOrObject): Boolean
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.cache.TypeInfo
|
||||
import com.intellij.psi.impl.compiled.ClsTypeElementImpl
|
||||
import com.intellij.psi.impl.compiled.SignatureParsing
|
||||
import com.intellij.psi.impl.compiled.StubBuildingVisitor
|
||||
import com.intellij.psi.impl.light.LightReferenceListBuilder
|
||||
import com.intellij.psi.impl.light.LightTypeParameterBuilder
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterListBuilder
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.text.StringCharacterIterator
|
||||
|
||||
internal fun buildTypeParameterList(
|
||||
declaration: KtTypeParameterListOwner,
|
||||
owner: PsiTypeParameterListOwner,
|
||||
support: UltraLightSupport
|
||||
): PsiTypeParameterList {
|
||||
val tpList = KotlinLightTypeParameterListBuilder(owner)
|
||||
for ((i, ktParam) in declaration.typeParameters.withIndex()) {
|
||||
tpList.addParameter(object : LightTypeParameterBuilder(ktParam.name.orEmpty(), owner, i) {
|
||||
private val superList: LightReferenceListBuilder by lazyPub {
|
||||
val boundList = LightReferenceListBuilder(manager, PsiReferenceList.Role.EXTENDS_BOUNDS_LIST)
|
||||
if (ktParam.extendsBound != null || declaration.typeConstraints.isNotEmpty()) {
|
||||
val boundTypes = (ktParam.resolve() as? TypeParameterDescriptor)?.upperBounds.orEmpty()
|
||||
.mapNotNull { it.asPsiType(ktParam, support, TypeMappingMode.DEFAULT, this) as? PsiClassType }
|
||||
val hasDefaultBound = boundTypes.size == 1 && boundTypes[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
|
||||
if (!hasDefaultBound) {
|
||||
boundTypes.forEach(boundList::addReference)
|
||||
}
|
||||
}
|
||||
boundList
|
||||
}
|
||||
|
||||
override fun getExtendsList(): LightReferenceListBuilder = superList
|
||||
|
||||
override fun getParent(): PsiElement = tpList
|
||||
override fun getContainingFile(): PsiFile = owner.containingFile
|
||||
})
|
||||
}
|
||||
return tpList
|
||||
}
|
||||
|
||||
internal fun KtDeclaration.getKotlinType(): KotlinType? {
|
||||
val descriptor = resolve()
|
||||
return when (descriptor) {
|
||||
is ValueDescriptor -> descriptor.type
|
||||
is CallableDescriptor -> descriptor.returnType
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
internal fun KtDeclaration.resolve() = LightClassGenerationSupport.getInstance(project).resolveToDescriptor(this)
|
||||
|
||||
// copy-pasted from kotlinInternalUastUtils.kt and post-processed
|
||||
internal fun KotlinType.asPsiType(
|
||||
declaration: KtDeclaration,
|
||||
support: UltraLightSupport,
|
||||
mode: TypeMappingMode,
|
||||
psiContext: PsiElement = declaration
|
||||
): PsiType {
|
||||
val typeFqName = constructor.declarationDescriptor?.fqNameSafe?.asString()
|
||||
if (typeFqName == "kotlin.Unit" && declaration is KtFunction) return PsiType.VOID
|
||||
|
||||
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.TYPE)
|
||||
typeMapper(support).mapType(this, signatureWriter, mode)
|
||||
val signature = StringCharacterIterator(signatureWriter.toString())
|
||||
|
||||
val javaType = SignatureParsing.parseTypeString(signature, StubBuildingVisitor.GUESSING_MAPPER)
|
||||
val typeInfo = TypeInfo.fromString(javaType, false)
|
||||
val typeText = TypeInfo.createTypeText(typeInfo) ?: return PsiType.NULL
|
||||
|
||||
val type = ClsTypeElementImpl(psiContext, typeText, '\u0000').type
|
||||
if (type is PsiArrayType && psiContext is KtUltraLightParameter && psiContext.isVarArgs) {
|
||||
return PsiEllipsisType(type.componentType, type.annotationProvider)
|
||||
}
|
||||
return type
|
||||
}
|
||||
|
||||
internal fun typeMapper(support: UltraLightSupport): KotlinTypeMapper = KotlinTypeMapper(
|
||||
BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES,
|
||||
IncompatibleClassTracker.DoNothing, support.moduleName,
|
||||
JvmTarget.JVM_1_8,
|
||||
true, false
|
||||
)
|
||||
+7
-2
@@ -17,16 +17,21 @@
|
||||
package org.jetbrains.kotlin.asJava.elements
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiTypeParameterListOwner
|
||||
import com.intellij.psi.ResolveState
|
||||
import com.intellij.psi.impl.light.LightTypeParameterListBuilder
|
||||
import com.intellij.psi.scope.PsiScopeProcessor
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
|
||||
class KotlinLightTypeParameterListBuilder(manager: PsiManager): LightTypeParameterListBuilder(manager, KotlinLanguage.INSTANCE) {
|
||||
class KotlinLightTypeParameterListBuilder(private val owner: PsiTypeParameterListOwner) :
|
||||
LightTypeParameterListBuilder(owner.manager, KotlinLanguage.INSTANCE) {
|
||||
override fun processDeclarations(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean {
|
||||
return typeParameters.all { processor.execute(it, state) }
|
||||
}
|
||||
|
||||
override fun getParent(): PsiElement = owner
|
||||
override fun getContainingFile(): PsiFile = owner.containingFile
|
||||
|
||||
override fun getText(): String? = ""
|
||||
}
|
||||
|
||||
+14
-22
@@ -19,7 +19,9 @@ package org.jetbrains.kotlin.asJava.elements
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.compiled.ClsTypeElementImpl
|
||||
import com.intellij.psi.scope.PsiScopeProcessor
|
||||
import com.intellij.psi.util.*
|
||||
import com.intellij.psi.util.MethodSignature
|
||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||
@@ -36,7 +38,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
|
||||
class KtLightMethodImpl private constructor(
|
||||
open class KtLightMethodImpl protected constructor(
|
||||
computeRealDelegate: () -> PsiMethod,
|
||||
lightMemberOrigin: LightMemberOrigin?,
|
||||
containingClass: KtLightClass,
|
||||
@@ -55,25 +57,15 @@ class KtLightMethodImpl private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val typeParamsList: CachedValue<PsiTypeParameterList> by lazyPub {
|
||||
val cacheManager = CachedValuesManager.getManager(clsDelegate.project)
|
||||
cacheManager.createCachedValue<PsiTypeParameterList>(
|
||||
{
|
||||
val origin = (lightMemberOrigin as? LightMemberOriginForDeclaration)?.originalElement
|
||||
val list = if (origin != null) {
|
||||
if (origin is KtClassOrObject) {
|
||||
KotlinLightTypeParameterListBuilder(manager)
|
||||
}
|
||||
else {
|
||||
LightClassUtil.buildLightTypeParameterList(this@KtLightMethodImpl, origin)
|
||||
}
|
||||
}
|
||||
else {
|
||||
clsDelegate.typeParameterList
|
||||
}
|
||||
CachedValueProvider.Result.create(list, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT)
|
||||
}, false
|
||||
)
|
||||
private val typeParamsList: PsiTypeParameterList? by lazyPub { buildTypeParameterList() }
|
||||
|
||||
protected open fun buildTypeParameterList(): PsiTypeParameterList? {
|
||||
val origin = (lightMemberOrigin as? LightMemberOriginForDeclaration)?.originalElement
|
||||
return when {
|
||||
origin is KtClassOrObject -> KotlinLightTypeParameterListBuilder(this)
|
||||
origin != null -> LightClassUtil.buildLightTypeParameterList(this, origin)
|
||||
else -> clsDelegate.typeParameterList
|
||||
}
|
||||
}
|
||||
|
||||
override fun accept(visitor: PsiElementVisitor) {
|
||||
@@ -128,7 +120,7 @@ class KtLightMethodImpl private constructor(
|
||||
|
||||
override fun getParameterList() = paramsList
|
||||
|
||||
override fun getTypeParameterList() = typeParamsList.value
|
||||
override fun getTypeParameterList() = typeParamsList
|
||||
|
||||
override fun getTypeParameters(): Array<PsiTypeParameter> =
|
||||
typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
|
||||
|
||||
+31
-26
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiModifierListOwner
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.KtUltraLightParameter
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
@@ -37,7 +38,7 @@ import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
abstract class KtLightModifierList<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(protected val owner: T)
|
||||
: KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierList> {
|
||||
override val clsDelegate by lazyPub { owner.clsDelegate.modifierList!! }
|
||||
private val _annotations by lazyPub { computeAnnotations(this) }
|
||||
private val _annotations by lazyPub { computeAnnotations() }
|
||||
|
||||
override val kotlinOrigin: KtModifierList?
|
||||
get() = owner.kotlinOrigin?.modifierList
|
||||
@@ -61,9 +62,28 @@ abstract class KtLightModifierList<out T : KtLightElement<KtModifierListOwner, P
|
||||
override fun isWritable() = false
|
||||
|
||||
override fun toString() = "Light modifier list of $owner"
|
||||
|
||||
protected open fun computeAnnotations(): List<KtLightAbstractAnnotation> {
|
||||
val annotationsForEntries = lightAnnotationsForEntries(this)
|
||||
val modifierListOwner = parent
|
||||
if (modifierListOwner is KtLightClassForSourceDeclaration && modifierListOwner.isAnnotationType) {
|
||||
val sourceAnnotationNames = annotationsForEntries.mapTo(mutableSetOf()) { it.qualifiedName }
|
||||
val specialAnnotationsOnAnnotationClass = modifierListOwner.clsDelegate.modifierList?.annotations.orEmpty().filter {
|
||||
it.qualifiedName !in sourceAnnotationNames
|
||||
}.map { KtLightNonSourceAnnotation(this, it) }
|
||||
return annotationsForEntries + specialAnnotationsOnAnnotationClass
|
||||
}
|
||||
if ((modifierListOwner is KtLightMember<*> && modifierListOwner !is KtLightFieldImpl.KtLightEnumConstant)
|
||||
|| modifierListOwner is LightParameter) {
|
||||
return annotationsForEntries +
|
||||
listOf(KtLightNullabilityAnnotation(modifierListOwner as KtLightElement<*, PsiModifierListOwner>, this))
|
||||
}
|
||||
return annotationsForEntries
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class KtLightSimpleModifierList(
|
||||
open class KtLightSimpleModifierList(
|
||||
owner: KtLightElement<KtModifierListOwner, PsiModifierListOwner>, private val modifiers: Set<String>
|
||||
) : KtLightModifierList<KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(owner) {
|
||||
override fun hasModifierProperty(name: String) = name in modifiers
|
||||
@@ -71,31 +91,14 @@ class KtLightSimpleModifierList(
|
||||
override fun copy() = KtLightSimpleModifierList(owner, modifiers)
|
||||
}
|
||||
|
||||
private fun computeAnnotations(lightModifierList: KtLightModifierList<*>): List<KtLightAbstractAnnotation> {
|
||||
val annotationsForEntries = lightAnnotationsForEntries(lightModifierList)
|
||||
val modifierListOwner = lightModifierList.parent
|
||||
if (modifierListOwner is KtLightClassForSourceDeclaration && modifierListOwner.isAnnotationType) {
|
||||
val sourceAnnotationNames = annotationsForEntries.mapTo(mutableSetOf()) { it.qualifiedName }
|
||||
val specialAnnotationsOnAnnotationClass = modifierListOwner.clsDelegate.modifierList?.annotations.orEmpty().filter {
|
||||
it.qualifiedName !in sourceAnnotationNames
|
||||
}.map { KtLightNonSourceAnnotation(lightModifierList, it) }
|
||||
return annotationsForEntries + specialAnnotationsOnAnnotationClass
|
||||
}
|
||||
if ((modifierListOwner is KtLightMember<*> && modifierListOwner !is KtLightFieldImpl.KtLightEnumConstant)
|
||||
|| modifierListOwner is KtLightParameter) {
|
||||
return annotationsForEntries +
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
listOf(KtLightNullabilityAnnotation(modifierListOwner as KtLightElement<*, PsiModifierListOwner>, lightModifierList))
|
||||
}
|
||||
return annotationsForEntries
|
||||
}
|
||||
|
||||
private fun lightAnnotationsForEntries(lightModifierList: KtLightModifierList<*>): List<KtLightAnnotationForSourceEntry> {
|
||||
val lightModifierListOwner = lightModifierList.parent
|
||||
|
||||
if (!isFromSources(lightModifierList)) return emptyList()
|
||||
|
||||
val annotatedKtDeclaration = lightModifierListOwner.kotlinOrigin as? KtDeclaration
|
||||
val annotatedKtDeclaration =
|
||||
if (lightModifierListOwner is KtUltraLightParameter) lightModifierListOwner.annotatedOrigin()
|
||||
else lightModifierListOwner.kotlinOrigin as? KtDeclaration
|
||||
|
||||
if (annotatedKtDeclaration == null || !annotatedKtDeclaration.isValid || !hasAnnotationsInSource(annotatedKtDeclaration)) {
|
||||
return emptyList()
|
||||
@@ -128,11 +131,11 @@ fun isFromSources(lightElement: KtLightElement<*, *>): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getAnnotationDescriptors(declaration: KtDeclaration, annotatedLightElement: KtLightElement<*, *>): List<AnnotationDescriptor> {
|
||||
private fun getAnnotationDescriptors(declaration: KtAnnotated, annotatedLightElement: KtLightElement<*, *>): List<AnnotationDescriptor> {
|
||||
val context = LightClassGenerationSupport.getInstance(declaration.project).analyze(declaration)
|
||||
|
||||
val descriptor = if (declaration is KtParameter && declaration.isPropertyParameter()) {
|
||||
if (annotatedLightElement is KtLightParameter && annotatedLightElement.method.isConstructor)
|
||||
if (annotatedLightElement is LightParameter && annotatedLightElement.method.isConstructor)
|
||||
context[BindingContext.VALUE_PARAMETER, declaration]
|
||||
else
|
||||
context[BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, declaration]
|
||||
@@ -145,7 +148,8 @@ private fun getAnnotationDescriptors(declaration: KtDeclaration, annotatedLightE
|
||||
descriptor is ClassDescriptor && annotatedLightElement is KtLightMethod && annotatedLightElement.isConstructor ->
|
||||
descriptor.unsubstitutedPrimaryConstructor
|
||||
descriptor !is PropertyDescriptor -> descriptor
|
||||
annotatedLightElement is KtLightFieldImpl.KtLightFieldForDeclaration -> descriptor.backingField
|
||||
annotatedLightElement is KtLightFieldImpl.KtLightEnumConstant -> descriptor
|
||||
annotatedLightElement is KtLightField -> descriptor.backingField
|
||||
annotatedLightElement !is KtLightMethod -> descriptor
|
||||
annotatedLightElement.isGetter -> descriptor.getter
|
||||
annotatedLightElement.isSetter -> descriptor.setter
|
||||
@@ -164,7 +168,7 @@ private fun getAnnotationDescriptors(declaration: KtDeclaration, annotatedLightE
|
||||
return annotations
|
||||
}
|
||||
|
||||
private fun hasAnnotationsInSource(declaration: KtDeclaration): Boolean {
|
||||
private fun hasAnnotationsInSource(declaration: KtAnnotated): Boolean {
|
||||
if (declaration.annotationEntries.isNotEmpty()) {
|
||||
return true
|
||||
}
|
||||
@@ -175,3 +179,4 @@ private fun hasAnnotationsInSource(declaration: KtDeclaration): Boolean {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
class KtLightParameter(
|
||||
override val clsDelegate: PsiParameter,
|
||||
private val index: Int,
|
||||
val method: KtLightMethod
|
||||
method: KtLightMethod
|
||||
) : LightParameter(clsDelegate.name ?: "p$index", clsDelegate.type, method, KotlinLanguage.INSTANCE),
|
||||
KtLightDeclaration<KtParameter, PsiParameter> {
|
||||
|
||||
|
||||
@@ -25,14 +25,14 @@ public class LightParameter extends LightVariableBuilder implements PsiParameter
|
||||
public static final LightParameter[] EMPTY_ARRAY = new LightParameter[0];
|
||||
|
||||
private final String myName;
|
||||
private final PsiElement myDeclarationScope;
|
||||
private final KtLightMethod myDeclarationScope;
|
||||
private final boolean myVarArgs;
|
||||
|
||||
public LightParameter(@NotNull String name, @NotNull PsiType type, PsiElement declarationScope, Language language) {
|
||||
public LightParameter(@NotNull String name, @NotNull PsiType type, @NotNull KtLightMethod declarationScope, Language language) {
|
||||
this(name, type, declarationScope, language, type instanceof PsiEllipsisType);
|
||||
}
|
||||
|
||||
public LightParameter(@NotNull String name, @NotNull PsiType type, PsiElement declarationScope, Language language, boolean isVarArgs) {
|
||||
public LightParameter(@NotNull String name, @NotNull PsiType type, @NotNull KtLightMethod declarationScope, Language language, boolean isVarArgs) {
|
||||
super(declarationScope.getManager(), name, type, language);
|
||||
myName = name;
|
||||
myDeclarationScope = declarationScope;
|
||||
@@ -41,7 +41,11 @@ public class LightParameter extends LightVariableBuilder implements PsiParameter
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getDeclarationScope() {
|
||||
public KtLightMethod getDeclarationScope() {
|
||||
return myDeclarationScope;
|
||||
}
|
||||
|
||||
public KtLightMethod getMethod() {
|
||||
return myDeclarationScope;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.annotations.Nullable
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.KtUltraLightParameter
|
||||
import org.jetbrains.kotlin.asJava.classes.cannotModify
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
@@ -298,6 +299,10 @@ class KtLightNullabilityAnnotation(val member: KtLightElement<*, PsiModifierList
|
||||
internal fun KtTypeReference.getType(): KotlinType? = analyze()[BindingContext.TYPE, this]
|
||||
|
||||
private fun getTargetType(annotatedElement: PsiElement): KotlinType? {
|
||||
if (member is KtUltraLightParameter) {
|
||||
return member.getTypeForNullability()
|
||||
}
|
||||
|
||||
if (annotatedElement is KtTypeReference) {
|
||||
annotatedElement.getType()?.let { return it }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/** should load cls */
|
||||
annotation class Anno(val p: String = "", val x: Array<Anno> = arrayOf(Anno(p="a"), Anno(p="b")))
|
||||
|
||||
/** should load cls */
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
|
||||
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@MustBeDocumented
|
||||
@Deprecated("This anno is deprecated, use === instead", ReplaceWith("this === other"))
|
||||
annotation class Fancy
|
||||
|
||||
/** should load cls */
|
||||
annotation class ReplaceWith(val expression: String)
|
||||
|
||||
/** should load cls */
|
||||
annotation class Deprecated(
|
||||
val message: String,
|
||||
val replaceWith: ReplaceWith = ReplaceWith(""))
|
||||
|
||||
/** should load cls */
|
||||
annotation class Ann(val arg1: KClass<*>, val arg2: KClass<out Any>)
|
||||
|
||||
|
||||
@Anno class F: Runnable {
|
||||
@Anno("f") fun f(@Anno p: String) {}
|
||||
@Anno("p") var prop = "x"
|
||||
}
|
||||
|
||||
|
||||
class Foo @Anno constructor(dependency: MyDependency) {
|
||||
var x: String? = null
|
||||
@Anno set
|
||||
|
||||
@Anno
|
||||
fun String.f4() {}
|
||||
}
|
||||
|
||||
@Ann(String::class, Int::class) class MyClass
|
||||
|
||||
class Example(@field:Ann val foo, // annotate Java field
|
||||
@get:Ann val bar, // annotate Java getter
|
||||
@param:Ann val quux) // annotate Java constructor parameter
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
package pkg
|
||||
|
||||
open class Open {
|
||||
private class Private: Open {}
|
||||
protected inner class Private2 {}
|
||||
internal class StaticInternal {}
|
||||
}
|
||||
internal class OuterInternal {}
|
||||
private class TopLevelPrivate {}
|
||||
|
||||
sealed class Season {
|
||||
class Nested: Season()
|
||||
}
|
||||
|
||||
sealed class SealedWithArgs(val a: Int)
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
class TestConstructor private constructor(p: Int = 1)
|
||||
class A(vararg a: Int, f: () -> Unit) {}
|
||||
|
||||
class B {
|
||||
@Deprecated("", level = DeprecationLevel.HIDDEN)
|
||||
constructor()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/** should load cls */
|
||||
class Foo {
|
||||
suspend fun doSomething(foo: Foo): Bar {}
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
class Bar {
|
||||
fun <T> async(block: suspend () -> T)
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
interface Base {
|
||||
suspend fun foo()
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
class Derived: Base {
|
||||
override suspend fun foo() { ... }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/** should load cls */
|
||||
data class User(val name: String = "", val age: Int = 0)
|
||||
|
||||
/** should load cls */
|
||||
data class Person(val name: String) {
|
||||
var age: Int = 0
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
interface Base {
|
||||
fun printMessage()
|
||||
fun printMessageLine()
|
||||
}
|
||||
|
||||
class BaseImpl(val x: Int) : Base {
|
||||
override fun printMessage() { print(x) }
|
||||
override fun printMessageLine() { println(x) }
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
class Derived(b: Base) : Base by b {
|
||||
override fun printMessage() { print("abc") }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
import java.util.function.*
|
||||
|
||||
/** should load cls */
|
||||
enum class Direction {
|
||||
NORTH, SOUTH, WEST, EAST
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
enum class Color(val rgb: Int) {
|
||||
RED(0xFF0000),
|
||||
GREEN(0x00FF00),
|
||||
BLUE(0x0000FF)
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
enum class ProtocolState {
|
||||
WAITING {
|
||||
override fun signal() = TALKING
|
||||
},
|
||||
|
||||
TALKING {
|
||||
override fun signal() = WAITING
|
||||
};
|
||||
|
||||
abstract fun signal(): ProtocolState
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
enum class IntArithmetics : BinaryOperator<Int>, IntBinaryOperator {
|
||||
PLUS {
|
||||
override fun apply(t: Int, u: Int): Int = t + u
|
||||
},
|
||||
TIMES {
|
||||
override fun apply(t: Int, u: Int): Int = t * u
|
||||
};
|
||||
|
||||
override fun applyAsInt(t: Int, u: Int) = apply(t, u)
|
||||
}
|
||||
|
||||
class C {
|
||||
val enumConst: Direction? = Direction.EAST
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
abstract class C<T>(var constructorParam: List<CharSequence>) {
|
||||
fun foo<V, U : V>(p1: V, p2: C<V>, p4: Sequence<V>): T {}
|
||||
|
||||
inline fun <reified T : Enum<T>> printAllValues() {
|
||||
print(enumValues<T>().joinToString { it.name })
|
||||
}
|
||||
|
||||
val <Q : T> Q.w: Q get() = null!!
|
||||
|
||||
var sListProp: List<String>?
|
||||
var sSetProp: Set<String>?
|
||||
var sMutableSetProp: MutableSet<String>?
|
||||
var sHashSetProp: HashSet<String>?
|
||||
var csListProp: List<CharSequence>?
|
||||
|
||||
abstract fun listCS(l: List<CharSequence>): List<CharSequence>
|
||||
abstract fun listS(l: List<String>): List<String>
|
||||
abstract fun mutables(cin: MutableCollection<in Number>, sOut: MutableList<out C<*>>): MutableSet<CharSequence>
|
||||
abstract fun nested(l: List<List<CharSequence>>): Collection<Collection<CharSequence>>
|
||||
|
||||
fun <T : Any?> max(p0 : Collection<T>?): T? where T : Comparable<T>? {}
|
||||
|
||||
}
|
||||
|
||||
open class K<out T: K<T>> { }
|
||||
class Sub: K<K<*>>()
|
||||
@@ -0,0 +1,27 @@
|
||||
import java.util.*
|
||||
|
||||
/** should load cls */
|
||||
class MyList : List<String> {
|
||||
override operator fun get(index: Int): String {}
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
interface ASet<T> : MutableCollection<T> {}
|
||||
|
||||
/** should load cls */
|
||||
abstract class MySet<T> : ASet<T> {
|
||||
override fun remove(elem: String): Boolean {}
|
||||
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
abstract class SmartSet<T> private constructor() : AbstractSet<T>() {
|
||||
override fun iterator(): MutableIterator<T> = unresolved
|
||||
|
||||
override fun add(element: T): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun contains(element: T): Boolean = true
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import kotlin.jvm.JvmStatic as JS
|
||||
|
||||
/** should load cls */
|
||||
object O {
|
||||
@JS fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/** should load cls */
|
||||
class Prop {
|
||||
private val someProp = object { }
|
||||
}
|
||||
|
||||
|
||||
/** should load cls */
|
||||
class Fun {
|
||||
private fun someFun() = object { }
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
class Array {
|
||||
val a1 = arrayOf(
|
||||
object { val fy = "text"}
|
||||
)
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
private class C(val y: Int) {
|
||||
val initChild = { ->
|
||||
object {
|
||||
override fun toString(): String {
|
||||
return "child" + y
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Super {
|
||||
val a: Any?
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
class Sub {
|
||||
override val a = arrayOf(
|
||||
object { val fy = "text"}
|
||||
)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
interface Intf {
|
||||
fun v(): Int
|
||||
}
|
||||
interface IntfWithProp : Intf {
|
||||
val x: Int
|
||||
}
|
||||
abstract class Base(p: Int) {
|
||||
open protected fun v(): Int? { }
|
||||
fun nv() { }
|
||||
abstract fun abs(): Int
|
||||
|
||||
internal open val x: Int get() { }
|
||||
open var y = 1
|
||||
open protected var z = 1
|
||||
}
|
||||
class Derived(p: Int) : Base(p), IntfWithProp {
|
||||
override fun v() = unknown()
|
||||
override val x = 3
|
||||
override fun abs() = 0
|
||||
}
|
||||
abstract class AnotherDerived(override val x: Int, override val y: Int, override val z: Int) : Base(2) {
|
||||
final override fun v() { }
|
||||
abstract fun noReturn(s: String)
|
||||
abstract val abstractProp: Int
|
||||
}
|
||||
|
||||
private class Private {
|
||||
override val overridesNothing: Boolean
|
||||
get() = false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/** should load cls */
|
||||
inline class UInt(private val value: Int) { }
|
||||
|
||||
/** should load cls */
|
||||
inline enum class Foo(val x: Int) {
|
||||
A(0), B(1);
|
||||
|
||||
fun example() { }
|
||||
}
|
||||
|
||||
/** should load cls */
|
||||
inline class InlinedDelegate<T>(var node: T) {
|
||||
operator fun setValue(thisRef: A, property: KProperty<*>, value: T) {
|
||||
if (node !== value) {
|
||||
thisRef.notify(node, value)
|
||||
}
|
||||
node = value
|
||||
}
|
||||
|
||||
operator fun getValue(thisRef: A, property: KProperty<*>): T {
|
||||
return node
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/** should load cls */
|
||||
class C {
|
||||
var rwProp: Int
|
||||
@JvmName("get_rwProp")
|
||||
get() = 0
|
||||
@JvmName("set_rwProp")
|
||||
set(v) {}
|
||||
|
||||
fun getRwProp(): Int = 123
|
||||
fun setRwProp(v: Int) {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/** should load cls */
|
||||
class C @JvmOverloads constructor(
|
||||
val type: String?,
|
||||
val p1: Boolean = false,
|
||||
val p2: String = type
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
class C {
|
||||
companion object {
|
||||
@JvmStatic fun foo() {}
|
||||
fun bar() {}
|
||||
@JvmStatic var x: String = ""
|
||||
|
||||
var I.c: String
|
||||
@JvmStatic get() = "OK"
|
||||
@JvmStatic set(t: String) {}
|
||||
|
||||
var c1: String
|
||||
get() = "OK"
|
||||
@JvmStatic set(t: String) {}
|
||||
}
|
||||
companion object Factory {}
|
||||
}
|
||||
|
||||
class C1 {
|
||||
private companion object {}
|
||||
}
|
||||
|
||||
interface I {
|
||||
companion object { }
|
||||
}
|
||||
|
||||
object Obj : java.lang.Runnable {
|
||||
@JvmStatic var x: String = ""
|
||||
override fun run() {}
|
||||
@JvmStatic fun zoo(): Int = 2
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class Foo(a: Int, val b:Foo, var c:Boolean, private val d: List, protected val e: Long = 2) {
|
||||
val f1 = 2
|
||||
|
||||
val intConst: dynamic = 30
|
||||
val arrayConst: Any = byteArrayOf(1,2)
|
||||
|
||||
protected var f2 = 3
|
||||
|
||||
var name: String = "x"
|
||||
|
||||
val isEmpty get() = false
|
||||
var isEmptyMutable: Boolean?
|
||||
var islowercase: Boolean?
|
||||
var isEmptyInt: Int?
|
||||
var getInt: Int?
|
||||
private var noAccessors: String
|
||||
|
||||
internal var stringRepresentation: String
|
||||
get() = this.toString()
|
||||
set(value) {
|
||||
setDataFromString(value)
|
||||
}
|
||||
|
||||
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
|
||||
|
||||
var counter = 0
|
||||
set(value) {
|
||||
if (value >= 0) field = value
|
||||
}
|
||||
var counter2 : Int?
|
||||
get() = field
|
||||
set(value) {
|
||||
if (value >= 0) field = value
|
||||
}
|
||||
|
||||
lateinit var subject: Unresolved
|
||||
internal lateinit var internalVarPrivateSet: String
|
||||
private set
|
||||
protected lateinit var protectedLateinitVar: String
|
||||
|
||||
var delegatedProp: String by Delegate()
|
||||
var delegatedProp2 by MyProperty()
|
||||
private var privateDelegated: Int by Delegate()
|
||||
var lazyProp: String by lazy { "abc" }
|
||||
|
||||
val Int.intProp: Int
|
||||
get() = 1
|
||||
|
||||
final internal var internalWithPrivateSet: Int = 1
|
||||
private set
|
||||
|
||||
protected var protectedWithPrivateSet: String = ""
|
||||
private set
|
||||
|
||||
private var privateVarWithPrivateSet = { 0 }()
|
||||
private set
|
||||
|
||||
private val privateValWithGet: String?
|
||||
get() = ""
|
||||
|
||||
private var privateVarWithGet: Object = Object()
|
||||
get
|
||||
|
||||
val sum: (Int)->Int = { x: Int -> sum(x - 1) + x }
|
||||
|
||||
companion object {
|
||||
public val prop3: Int = { 12 }()
|
||||
get() {
|
||||
return field
|
||||
}
|
||||
public var prop7 : Int = { 20 }()
|
||||
set(i: Int) {
|
||||
field++
|
||||
}
|
||||
private const val contextBean = Context.BEAN
|
||||
|
||||
val f1 = 4
|
||||
}
|
||||
}
|
||||
|
||||
class MyProperty<T> {
|
||||
operator fun getValue(t: T, p: KProperty<*>): Int = 42
|
||||
operator fun setValue(t: T, p: KProperty<*>, i: Int) {}
|
||||
}
|
||||
|
||||
class Modifiers {
|
||||
@delegate:Transient
|
||||
val plainField: Int = 1
|
||||
|
||||
@delegate:Transient
|
||||
val lazy by lazy { 1 }
|
||||
}
|
||||
|
||||
interface A {
|
||||
public var int1: Int
|
||||
private set
|
||||
protected get
|
||||
public var int2: Int
|
||||
public get
|
||||
internal set
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class Foo {
|
||||
open fun bar(a: Int, b:Any, c:Foo): Unit {}
|
||||
internal fun bar2(a: Sequence, b: Unresolved) {}
|
||||
private fun bar3(x: Foo.Inner, vararg y: Inner) = "str"
|
||||
fun bar4() = 42
|
||||
|
||||
public fun nullableVararg(vararg o: Any?): Unit
|
||||
|
||||
operator fun plus(increment: Int): Foo {}
|
||||
fun String.onString(a: (Int) -> Any?): Foo {}
|
||||
|
||||
class Inner {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
class MyException : Exception
|
||||
class C @Throws(Exception::class) constructor(a: Int = 1) {
|
||||
@Throws(java.io.IOException::class, MyException::class)
|
||||
fun readFile(name: String): String {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
typealias JO = JvmOverloads
|
||||
|
||||
/** should load cls */
|
||||
object O {
|
||||
@JO fun foo(a: Int = 1, b: String = "") {}
|
||||
}
|
||||
@@ -32,6 +32,8 @@ import org.jetbrains.kotlin.android.quickfix.AbstractAndroidQuickFixMultiFileTes
|
||||
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidBoxTest
|
||||
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidBytecodeShapeTest
|
||||
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidSyntheticPropertyDescriptorTest
|
||||
import org.jetbrains.kotlin.asJava.classes.AbstractUltraLightClassLoadingTest
|
||||
import org.jetbrains.kotlin.asJava.classes.AbstractUltraLightClassSanityTest
|
||||
import org.jetbrains.kotlin.checkers.AbstractJavaAgainstKotlinBinariesCheckerTest
|
||||
import org.jetbrains.kotlin.checkers.AbstractJavaAgainstKotlinSourceCheckerTest
|
||||
import org.jetbrains.kotlin.checkers.AbstractJsCheckerTest
|
||||
@@ -825,6 +827,13 @@ fun main(args: Array<String>) {
|
||||
model("asJava/lightClasses", excludeDirs = listOf("delegation"), pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME)
|
||||
}
|
||||
|
||||
testClass<AbstractUltraLightClassSanityTest> {
|
||||
model("asJava/lightClasses", pattern = KT_OR_KTS)
|
||||
}
|
||||
testClass<AbstractUltraLightClassLoadingTest> {
|
||||
model("asJava/ultraLightClasses", pattern = KT_OR_KTS)
|
||||
}
|
||||
|
||||
testClass<AbstractIdeCompiledLightClassTest> {
|
||||
model("asJava/lightClasses", excludeDirs = listOf("local", "compilationErrors", "ideRegression"), pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME)
|
||||
}
|
||||
|
||||
+149
-1
@@ -16,23 +16,171 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.caches.resolve
|
||||
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.containers.ConcurrentFactoryMap
|
||||
import org.jetbrains.kotlin.asJava.LightClassBuilder
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.classes.KtUltraLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.UltraLightSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.shouldNotBeVisibleAsLightClass
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.lightClasses.IDELightClassContexts
|
||||
import org.jetbrains.kotlin.idea.caches.lightClasses.LazyLightClassDataHolder
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||
import org.jetbrains.kotlin.idea.resolve.frontendService
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException
|
||||
import java.util.concurrent.ConcurrentMap
|
||||
|
||||
class IDELightClassGenerationSupport(private val project: Project) : LightClassGenerationSupport() {
|
||||
override fun createUltraLightClass(element: KtClassOrObject): KtUltraLightClass? {
|
||||
if (element.shouldNotBeVisibleAsLightClass() ||
|
||||
element is KtObjectDeclaration && element.isObjectLiteral() ||
|
||||
element.isLocal ||
|
||||
element is KtEnumEntry
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return null
|
||||
return KtUltraLightClass(element, object : UltraLightSupport {
|
||||
override fun isTooComplexForUltraLightGeneration(element: KtClassOrObject): Boolean {
|
||||
val facet = KotlinFacet.get(module)
|
||||
val pluginClasspath = facet?.configuration?.settings?.compilerArguments?.pluginClasspaths
|
||||
if (!pluginClasspath.isNullOrEmpty()) {
|
||||
LOG.debug { "Using heavy light classes for ${element.fqName?.asString()} because of compiler plugins $pluginClasspath" }
|
||||
return true
|
||||
}
|
||||
|
||||
val problem = findTooComplexDeclaration(element)
|
||||
if (problem != null) {
|
||||
LOG.debug {
|
||||
"Using heavy light classes for ${element.fqName?.asString()} because of ${StringUtil.trimLog(problem.text, 100)}"
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override val moduleName: String = module.name
|
||||
|
||||
override fun findAnnotation(owner: KtAnnotated, fqName: FqName): Pair<KtAnnotationEntry, AnnotationDescriptor>? {
|
||||
val candidates = owner.annotationEntries.filter { it.shortName == fqName.shortName() || hasAlias(owner, fqName.shortName()) }
|
||||
for (entry in candidates) {
|
||||
val descriptor = analyze(entry).get(BindingContext.ANNOTATION, entry)
|
||||
if (descriptor?.fqName == fqName) {
|
||||
return Pair(entry, descriptor)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun findTooComplexDeclaration(declaration: KtDeclaration): PsiElement? {
|
||||
fun KtAnnotationEntry.seemsNonTrivial(): Boolean {
|
||||
val name = shortName
|
||||
return name == null || hasAlias(declaration, name) || name.asString().startsWith("Jvm") && name.asString() != "JvmStatic"
|
||||
}
|
||||
|
||||
if (declaration.hasExpectModifier() ||
|
||||
declaration.hasModifier(KtTokens.ANNOTATION_KEYWORD) ||
|
||||
declaration.hasModifier(KtTokens.INLINE_KEYWORD) && declaration is KtClassOrObject ||
|
||||
declaration.hasModifier(KtTokens.DATA_KEYWORD) ||
|
||||
declaration.hasModifier(KtTokens.ENUM_KEYWORD) ||
|
||||
declaration.hasModifier(KtTokens.SUSPEND_KEYWORD)) {
|
||||
return declaration
|
||||
}
|
||||
|
||||
declaration.annotationEntries.find(KtAnnotationEntry::seemsNonTrivial)?.let { return it }
|
||||
|
||||
if (declaration is KtClassOrObject) {
|
||||
declaration.superTypeListEntries.find { it is KtDelegatedSuperTypeEntry }?.let { return it }
|
||||
|
||||
declaration.primaryConstructor?.let { findTooComplexDeclaration(it) }?.let { return it }
|
||||
|
||||
for (d in declaration.declarations) {
|
||||
if (d is KtClassOrObject && !(d is KtObjectDeclaration && d.isCompanion())) continue
|
||||
|
||||
findTooComplexDeclaration(d)?.let { return it }
|
||||
}
|
||||
|
||||
if (implementsKotlinCollection(declaration)) {
|
||||
return declaration.getSuperTypeList()
|
||||
}
|
||||
}
|
||||
if (declaration is KtCallableDeclaration) {
|
||||
declaration.valueParameters.mapNotNull { findTooComplexDeclaration(it) }.firstOrNull()?.let { return it }
|
||||
if (declaration.typeReference == null && (declaration as? KtFunction)?.hasBlockBody() != true) {
|
||||
findPotentiallyReturnedAnonymousObject(declaration)?.let { return it }
|
||||
}
|
||||
if (declaration.typeReference?.hasModifier(KtTokens.SUSPEND_KEYWORD) == true) {
|
||||
return declaration.typeReference
|
||||
}
|
||||
}
|
||||
if (declaration is KtProperty) {
|
||||
declaration.accessors.mapNotNull { findTooComplexDeclaration(it) }.firstOrNull()?.let { return it }
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
}
|
||||
|
||||
private fun findPotentiallyReturnedAnonymousObject(declaration: KtDeclaration): KtObjectDeclaration? {
|
||||
val spine = declaration.containingKtFile.stubbedSpine
|
||||
for (i in 0 until spine.stubCount) {
|
||||
if (spine.getStubType(i) == KtStubElementTypes.OBJECT_DECLARATION) {
|
||||
val obj = spine.getStubPsi(i) as KtObjectDeclaration
|
||||
if (obj.isObjectLiteral() && PsiTreeUtil.isContextAncestor(declaration, obj, true)) {
|
||||
return obj
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun implementsKotlinCollection(classOrObject: KtClassOrObject): Boolean {
|
||||
if (classOrObject.superTypeListEntries.isEmpty()) return false
|
||||
|
||||
return (resolveToDescriptor(classOrObject) as? ClassifierDescriptor)?.getAllSuperClassifiers()?.any {
|
||||
it.fqNameSafe.asString().startsWith("kotlin.collections.")
|
||||
} == true
|
||||
}
|
||||
|
||||
private fun hasAlias(element: KtElement, shortName: Name): Boolean = allAliases(element.containingKtFile)[shortName.asString()] == true
|
||||
|
||||
private fun allAliases(file: KtFile): ConcurrentMap<String, Boolean> = CachedValuesManager.getCachedValue(file) {
|
||||
val importAliases = file.importDirectives.mapNotNull { it.aliasName }.toSet()
|
||||
val map = ConcurrentFactoryMap.createMap<String, Boolean> { s ->
|
||||
s in importAliases || KotlinTypeAliasShortNameIndex.getInstance().get(s, project, file.resolveScope).isNotEmpty()
|
||||
}
|
||||
CachedValueProvider.Result.create<ConcurrentMap<String, Boolean>>(map, PsiModificationTracker.MODIFICATION_COUNT)
|
||||
}
|
||||
|
||||
class IDELightClassGenerationSupport(project: Project) : LightClassGenerationSupport() {
|
||||
private val scopeFileComparator = JavaElementFinder.byClasspathComparator(GlobalSearchScope.allScope(project))
|
||||
|
||||
override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.idea.perf
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.KtUltraLightClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.junit.Assert
|
||||
|
||||
@TestOnly
|
||||
object UltraLightChecker {
|
||||
fun checkClassEquivalence(file: KtFile) {
|
||||
for (ktClass in allClasses(file)) {
|
||||
checkClassEquivalence(ktClass)
|
||||
}
|
||||
}
|
||||
|
||||
fun allClasses(file: KtFile): List<KtClassOrObject> =
|
||||
SyntaxTraverser.psiTraverser(file).filter(KtClassOrObject::class.java).toList()
|
||||
|
||||
fun checkClassEquivalence(ktClass: KtClassOrObject): KtUltraLightClass? {
|
||||
val gold = KtLightClassForSourceDeclaration.create(ktClass)
|
||||
val ultraLightClass = LightClassGenerationSupport.getInstance(ktClass.project).createUltraLightClass(ktClass) ?: return null
|
||||
|
||||
if (gold != null) {
|
||||
Assert.assertFalse(gold.javaClass.name.contains("Ultra"))
|
||||
}
|
||||
|
||||
val goldText = gold?.renderClass().orEmpty()
|
||||
val ultraText = ultraLightClass.renderClass()
|
||||
|
||||
if (goldText != ultraText) {
|
||||
Assert.assertEquals(
|
||||
"// Classic implementation:\n$goldText",
|
||||
"// Ultra-light implementation:\n$ultraText"
|
||||
)
|
||||
}
|
||||
return ultraLightClass
|
||||
}
|
||||
|
||||
private fun PsiAnnotation.renderAnnotation() =
|
||||
"@" + qualifiedName + "(" + parameterList.attributes.joinToString { it.name + "=" + (it.value?.text ?: "?") } + ")"
|
||||
|
||||
private fun PsiModifierListOwner.renderModifiers(): String {
|
||||
val buffer = StringBuilder()
|
||||
for (annotation in annotations) {
|
||||
buffer.append(annotation.renderAnnotation())
|
||||
buffer.append(if (this is PsiParameter) " " else "\n")
|
||||
}
|
||||
for (modifier in PsiModifier.MODIFIERS.filter(::hasModifierProperty)) {
|
||||
buffer.append(modifier).append(" ")
|
||||
}
|
||||
return buffer.toString()
|
||||
}
|
||||
|
||||
private fun PsiType.renderType() = getCanonicalText(true)
|
||||
|
||||
private fun PsiReferenceList?.renderRefList(keyword: String): String {
|
||||
if (this == null || this.referencedTypes.isEmpty()) return ""
|
||||
return " " + keyword + " " + referencedTypes.joinToString { it.renderType() }
|
||||
}
|
||||
|
||||
private fun PsiVariable.renderVar(): String {
|
||||
var result = this.renderModifiers() + type.renderType() + " " + name
|
||||
if (this is PsiParameter && this.isVarArgs) {
|
||||
result += " /* vararg */"
|
||||
}
|
||||
computeConstantValue()?.let { result += " /* constant value $it */" }
|
||||
return result
|
||||
}
|
||||
|
||||
private fun PsiTypeParameterListOwner.renderTypeParams() =
|
||||
if (typeParameters.isEmpty()) ""
|
||||
else "<" + typeParameters.joinToString {
|
||||
val bounds =
|
||||
if (it.extendsListTypes.isNotEmpty())
|
||||
" extends " + it.extendsListTypes.joinToString(" & ", transform = { it.renderType() })
|
||||
else ""
|
||||
it.name!! + bounds
|
||||
} + "> "
|
||||
|
||||
private fun PsiMethod.renderMethod() =
|
||||
renderModifiers() +
|
||||
(if (isVarArgs) "/* vararg */ " else "") +
|
||||
renderTypeParams() +
|
||||
(returnType?.renderType() ?: "") + " " +
|
||||
name +
|
||||
"(" + parameterList.parameters.joinToString { it.renderModifiers() + it.type.renderType() } + ")" +
|
||||
(this as? PsiAnnotationMethod)?.defaultValue?.let { " default " + it.text }.orEmpty() +
|
||||
throwsList.referencedTypes.let { thrownTypes ->
|
||||
if (thrownTypes.isEmpty()) ""
|
||||
else " throws " + thrownTypes.joinToString { it.renderType() }
|
||||
} +
|
||||
";"
|
||||
|
||||
private fun PsiClass.renderClass(): String {
|
||||
val classWord = when {
|
||||
isAnnotationType -> "@interface"
|
||||
isInterface -> "interface"
|
||||
isEnum -> "enum"
|
||||
else -> "class"
|
||||
}
|
||||
|
||||
return renderModifiers() +
|
||||
classWord + " " +
|
||||
name + " /* " + qualifiedName + "*/" +
|
||||
renderTypeParams() +
|
||||
extendsList.renderRefList("extends") +
|
||||
implementsList.renderRefList("implements") +
|
||||
" {\n" +
|
||||
(if (isEnum) fields.filterIsInstance<PsiEnumConstant>().joinToString(",\n") { it.name } + ";\n\n" else "") +
|
||||
fields.filterNot { it is PsiEnumConstant }.map { it.renderVar().prependIndent(" ") + ";\n\n" }.sorted().joinToString("") +
|
||||
methods.map { it.renderMethod().prependIndent(" ") + "\n\n" }.sorted().joinToString("") +
|
||||
innerClasses.map { "class ${it.name} ...\n\n".prependIndent(" ") }.sorted().joinToString("") +
|
||||
"}"
|
||||
}
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.idea.perf
|
||||
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode
|
||||
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
||||
import java.util.*
|
||||
import kotlin.system.measureNanoTime
|
||||
|
||||
class WholeProjectLightClassTest : WholeProjectPerformanceTest(), WholeProjectKotlinFileProvider {
|
||||
|
||||
override fun doTest(file: VirtualFile): PerFileTestResult {
|
||||
val results = mutableMapOf<String, Long>()
|
||||
var totalNs = 0L
|
||||
|
||||
val psiFile = file.toPsiFile(project) ?: run {
|
||||
return WholeProjectPerformanceTest.PerFileTestResult(results, totalNs, listOf(AssertionError("PsiFile not found for $file")))
|
||||
}
|
||||
|
||||
val errors = mutableListOf<Throwable>()
|
||||
|
||||
fun buildAllLightClasses(name: String, predicate: (KtClassOrObject) -> Boolean) {
|
||||
val result = measureNanoTime {
|
||||
try {
|
||||
// Build light class by PsiFile
|
||||
psiFile.acceptRecursively(object : KtVisitorVoid() {
|
||||
override fun visitClassOrObject(classOrObject: KtClassOrObject) {
|
||||
if (!predicate(classOrObject)) return
|
||||
val lightClass = classOrObject.toLightClass() as? KtLightClassForSourceDeclaration ?: return
|
||||
Arrays.hashCode(lightClass.superTypes)
|
||||
Arrays.hashCode(lightClass.fields)
|
||||
Arrays.hashCode(lightClass.methods)
|
||||
// Just to be sure: access types
|
||||
lightClass.fields.map { it.type }.hashCode()
|
||||
lightClass.methods.map { it.returnType }.hashCode()
|
||||
lightClass.hashCode()
|
||||
}
|
||||
})
|
||||
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
errors += t
|
||||
}
|
||||
}
|
||||
results[name] = result
|
||||
totalNs += result
|
||||
}
|
||||
|
||||
buildAllLightClasses("LightClasses_Top") {
|
||||
it.containingDeclarationForPseudocode == null
|
||||
}
|
||||
|
||||
buildAllLightClasses("LightClasses_Members") {
|
||||
!it.isLocal && it.containingDeclarationForPseudocode is KtClassOrObject
|
||||
}
|
||||
|
||||
return PerFileTestResult(results, totalNs, errors)
|
||||
}
|
||||
|
||||
fun testUltraLightPerformance() {
|
||||
Registry.get("kotlin.use.ultra.light.classes").setValue(true, testRootDisposable)
|
||||
testWholeProjectPerformance()
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.idea.perf
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import kotlin.system.measureNanoTime
|
||||
|
||||
// abstract so that it doesn't run in CI until known issues (JDK absence in the test project, different module names in mangled methods) are addressed
|
||||
abstract class WholeProjectUltraLightClassTest : WholeProjectPerformanceTest(), WholeProjectKotlinFileProvider {
|
||||
|
||||
override fun doTest(file: VirtualFile): PerFileTestResult {
|
||||
val psiFile = file.toPsiFile(project) as? KtFile ?: run {
|
||||
return WholeProjectPerformanceTest.PerFileTestResult(mapOf(), 0, listOf(AssertionError("PsiFile not found for $file")))
|
||||
}
|
||||
|
||||
val errors = mutableListOf<Throwable>()
|
||||
val elapsed = measureNanoTime {
|
||||
try {
|
||||
UltraLightChecker.checkClassEquivalence(psiFile)
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
errors += t
|
||||
}
|
||||
}
|
||||
|
||||
return PerFileTestResult(mapOf("ultraLightEquivalence" to elapsed), elapsed, errors)
|
||||
}
|
||||
}
|
||||
@@ -170,5 +170,10 @@
|
||||
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
|
||||
|
||||
<registryKey key="kotlin.use.ultra.light.classes"
|
||||
description="Whether to use an experimental implementation of Kotlin-as-Java classes"
|
||||
defaultValue="false"
|
||||
restartRequired="false"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.perf.UltraLightChecker
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractUltraLightClassLoadingTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
|
||||
fun doTest(testDataPath: String) {
|
||||
val file = myFixture.addFileToProject(testDataPath, File(testDataPath).readText()) as KtFile
|
||||
for (ktClass in UltraLightChecker.allClasses(file)) {
|
||||
val clsLoadingExpected = ktClass.docComment?.text?.contains("should load cls") == true
|
||||
val ultraLightClass = UltraLightChecker.checkClassEquivalence(ktClass)
|
||||
if (ultraLightClass != null) {
|
||||
assertEquals(
|
||||
"Cls-loaded status differs from expected for ${ultraLightClass.qualifiedName}",
|
||||
clsLoadingExpected,
|
||||
ultraLightClass.isClsDelegateLoaded
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.perf.UltraLightChecker
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractUltraLightClassSanityTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
|
||||
fun doTest(testDataPath: String) {
|
||||
val ioFile = File(testDataPath)
|
||||
if (ioFile.name == "AllOpenAnnotatedClasses.kt") {
|
||||
return //tests allopen compiler plugin that we don't have in this test
|
||||
}
|
||||
|
||||
val file = myFixture.addFileToProject(testDataPath, ioFile.readText()) as KtFile
|
||||
UltraLightChecker.checkClassEquivalence(file)
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/asJava/ultraLightClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class UltraLightClassLoadingTestGenerated extends AbstractUltraLightClassLoadingTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUltraLightClasses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/ultraLightClasses"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotations.kt")
|
||||
public void testAnnotations() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/annotations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classModifiers.kt")
|
||||
public void testClassModifiers() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/classModifiers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("constructors.kt")
|
||||
public void testConstructors() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/constructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("coroutines.kt")
|
||||
public void testCoroutines() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/coroutines.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("dataClasses.kt")
|
||||
public void testDataClasses() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/dataClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegatingToInterfaces.kt")
|
||||
public void testDelegatingToInterfaces() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/delegatingToInterfaces.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enums.kt")
|
||||
public void testEnums() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/enums.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("generics.kt")
|
||||
public void testGenerics() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/generics.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implementingKotlinCollections.kt")
|
||||
public void testImplementingKotlinCollections() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/implementingKotlinCollections.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("importAliases.kt")
|
||||
public void testImportAliases() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/importAliases.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inferringAnonymousObjectTypes.kt")
|
||||
public void testInferringAnonymousObjectTypes() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/inferringAnonymousObjectTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritance.kt")
|
||||
public void testInheritance() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/inheritance.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClasses.kt")
|
||||
public void testInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/inlineClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmName.kt")
|
||||
public void testJvmName() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/jvmName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloads.kt")
|
||||
public void testJvmOverloads() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/jvmOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objects.kt")
|
||||
public void testObjects() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/objects.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("properties.kt")
|
||||
public void testProperties() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/properties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleFunctions.kt")
|
||||
public void testSimpleFunctions() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/simpleFunctions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("throwsAnnotation.kt")
|
||||
public void testThrowsAnnotation() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/throwsAnnotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliases.kt")
|
||||
public void testTypeAliases() throws Exception {
|
||||
runTest("compiler/testData/asJava/ultraLightClasses/typeAliases.kt");
|
||||
}
|
||||
}
|
||||
+548
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class UltraLightClassSanityTestGenerated extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInLightClasses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationClass.kt")
|
||||
public void testAnnotationClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/AnnotationClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DataClassWithCustomImplementedMembers.kt")
|
||||
public void testDataClassWithCustomImplementedMembers() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/DataClassWithCustomImplementedMembers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DelegatedNested.kt")
|
||||
public void testDelegatedNested() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/DelegatedNested.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Delegation.kt")
|
||||
public void testDelegation() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/Delegation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DeprecatedEnumEntry.kt")
|
||||
public void testDeprecatedEnumEntry() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/DeprecatedEnumEntry.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DeprecatedNotHiddenInClass.kt")
|
||||
public void testDeprecatedNotHiddenInClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/DeprecatedNotHiddenInClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DollarsInName.kt")
|
||||
public void testDollarsInName() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/DollarsInName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DollarsInNameNoPackage.kt")
|
||||
public void testDollarsInNameNoPackage() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/DollarsInNameNoPackage.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ExtendingInterfaceWithDefaultImpls.kt")
|
||||
public void testExtendingInterfaceWithDefaultImpls() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ExtendingInterfaceWithDefaultImpls.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("HiddenDeprecated.kt")
|
||||
public void testHiddenDeprecated() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/HiddenDeprecated.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("HiddenDeprecatedInClass.kt")
|
||||
public void testHiddenDeprecatedInClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/HiddenDeprecatedInClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("InheritingInterfaceDefaultImpls.kt")
|
||||
public void testInheritingInterfaceDefaultImpls() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/InheritingInterfaceDefaultImpls.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("JvmNameOnMember.kt")
|
||||
public void testJvmNameOnMember() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/JvmNameOnMember.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("JvmStatic.kt")
|
||||
public void testJvmStatic() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/JvmStatic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NestedObjects.kt")
|
||||
public void testNestedObjects() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/NestedObjects.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NonDataClassWithComponentFunctions.kt")
|
||||
public void testNonDataClassWithComponentFunctions() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/NonDataClassWithComponentFunctions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PublishedApi.kt")
|
||||
public void testPublishedApi() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/PublishedApi.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SpecialAnnotationsOnAnnotationClass.kt")
|
||||
public void testSpecialAnnotationsOnAnnotationClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/SpecialAnnotationsOnAnnotationClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("StubOrderForOverloads.kt")
|
||||
public void testStubOrderForOverloads() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VarArgs.kt")
|
||||
public void testVarArgs() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/VarArgs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/compilationErrors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CompilationErrors extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("ActualClass.kt")
|
||||
public void testActualClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/ActualClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ActualTypeAlias.kt")
|
||||
public void testActualTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/ActualTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ActualTypeAliasCustomJvmPackageName.kt")
|
||||
public void testActualTypeAliasCustomJvmPackageName() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/ActualTypeAliasCustomJvmPackageName.kt");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCompilationErrors() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/compilationErrors"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("AllInlineOnly.kt")
|
||||
public void testAllInlineOnly() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/AllInlineOnly.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationModifiers.kt")
|
||||
public void testAnnotationModifiers() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/AnnotationModifiers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ExpectClass.kt")
|
||||
public void testExpectClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/ExpectClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ExpectObject.kt")
|
||||
public void testExpectObject() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/ExpectObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ExpectedNestedClass.kt")
|
||||
public void testExpectedNestedClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/ExpectedNestedClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ExpectedNestedClassInObject.kt")
|
||||
public void testExpectedNestedClassInObject() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/ExpectedNestedClassInObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("JvmPackageName.kt")
|
||||
public void testJvmPackageName() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/JvmPackageName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("LocalInAnnotation.kt")
|
||||
public void testLocalInAnnotation() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/LocalInAnnotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PrivateInTrait.kt")
|
||||
public void testPrivateInTrait() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/PrivateInTrait.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("RepetableAnnotations.kt")
|
||||
public void testRepetableAnnotations() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/RepetableAnnotations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SameName.kt")
|
||||
public void testSameName() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/SameName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TopLevelDestructuring.kt")
|
||||
public void testTopLevelDestructuring() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/TopLevelDestructuring.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TraitClassObjectField.kt")
|
||||
public void testTraitClassObjectField() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/TraitClassObjectField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("WrongAnnotations.kt")
|
||||
public void testWrongAnnotations() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/compilationErrors/WrongAnnotations.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/delegation")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Delegation extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDelegation() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("Function.kt")
|
||||
public void testFunction() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/delegation/Function.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/delegation/Property.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("WithPlatformTypes.NoCompile.kt")
|
||||
public void testWithPlatformTypes_NoCompile() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/delegation/WithPlatformTypes.NoCompile.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/facades")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Facades extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFacades() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/facades"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("AllPrivate.kt")
|
||||
public void testAllPrivate() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/facades/AllPrivate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("EmptyFile.NoCompile.kt")
|
||||
public void testEmptyFile_NoCompile() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/facades/EmptyFile.NoCompile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MultiFile.kt")
|
||||
public void testMultiFile() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/facades/MultiFile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SingleFile.kt")
|
||||
public void testSingleFile() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/facades/SingleFile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SingleJvmClassName.kt")
|
||||
public void testSingleJvmClassName() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/facades/SingleJvmClassName.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/ideRegression")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class IdeRegression extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInIdeRegression() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/ideRegression"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("AllOpenAnnotatedClasses.kt")
|
||||
public void testAllOpenAnnotatedClasses() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/AllOpenAnnotatedClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ImplementingCharSequenceAndNumber.kt")
|
||||
public void testImplementingCharSequenceAndNumber() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/ImplementingCharSequenceAndNumber.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ImplementingMap.kt")
|
||||
public void testImplementingMap() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/ImplementingMap.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ImplementingMutableSet.kt")
|
||||
public void testImplementingMutableSet() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/ImplementingMutableSet.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("InheritingInterfaceDefaultImpls.kt")
|
||||
public void testInheritingInterfaceDefaultImpls() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/InheritingInterfaceDefaultImpls.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("OverridingFinalInternal.kt")
|
||||
public void testOverridingFinalInternal() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/OverridingFinalInternal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("OverridingFinalInternal.extra.kt")
|
||||
public void testOverridingFinalInternal_extra() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/OverridingFinalInternal.extra.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("OverridingInternal.kt")
|
||||
public void testOverridingInternal() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/OverridingInternal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("OverridingInternal.extra.kt")
|
||||
public void testOverridingInternal_extra() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/OverridingInternal.extra.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("OverridingProtected.kt")
|
||||
public void testOverridingProtected() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/OverridingProtected.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("OverridingProtected.extra.kt")
|
||||
public void testOverridingProtected_extra() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/ideRegression/OverridingProtected.extra.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/local")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Local extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInLocal() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/local"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("DollarsInNameLocal.kt")
|
||||
public void testDollarsInNameLocal() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/local/DollarsInNameLocal.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/nullabilityAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NullabilityAnnotations extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNullabilityAnnotations() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/nullabilityAnnotations"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("Class.kt")
|
||||
public void testClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/Class.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassObjectField.kt")
|
||||
public void testClassObjectField() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/ClassObjectField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithConstructor.kt")
|
||||
public void testClassWithConstructor() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/ClassWithConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithConstructorAndProperties.kt")
|
||||
public void testClassWithConstructorAndProperties() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/ClassWithConstructorAndProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FileFacade.kt")
|
||||
public void testFileFacade() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/FileFacade.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Generic.kt")
|
||||
public void testGeneric() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/Generic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("IntOverridesAny.kt")
|
||||
public void testIntOverridesAny() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/IntOverridesAny.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("JvmOverloads.kt")
|
||||
public void testJvmOverloads() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/JvmOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NullableUnitReturn.kt")
|
||||
public void testNullableUnitReturn() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/NullableUnitReturn.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("OverrideAnyWithUnit.kt")
|
||||
public void testOverrideAnyWithUnit() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/OverrideAnyWithUnit.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PlatformTypes.kt")
|
||||
public void testPlatformTypes() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/PlatformTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Primitives.kt")
|
||||
public void testPrimitives() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/Primitives.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PrivateInClass.kt")
|
||||
public void testPrivateInClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/PrivateInClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Synthetic.kt")
|
||||
public void testSynthetic() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/Synthetic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Trait.kt")
|
||||
public void testTrait() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/Trait.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UnitAsGenericArgument.kt")
|
||||
public void testUnitAsGenericArgument() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/UnitAsGenericArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UnitParameter.kt")
|
||||
public void testUnitParameter() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/UnitParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VoidReturn.kt")
|
||||
public void testVoidReturn() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/nullabilityAnnotations/VoidReturn.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/object")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Object extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInObject() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/object"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("SimpleObject.kt")
|
||||
public void testSimpleObject() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/object/SimpleObject.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/publicField")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PublicField extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPublicField() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/publicField"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/publicField/CompanionObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/publicField/Simple.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/asJava/lightClasses/script")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Script extends AbstractUltraLightClassSanityTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInScript() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/script"), Pattern.compile("^(.+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("HelloWorld.kts")
|
||||
public void testHelloWorld() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/script/HelloWorld.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("InnerClasses.kts")
|
||||
public void testInnerClasses() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/script/InnerClasses.kts");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user