diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/Converter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/Converter.kt index d0df6527e06..5c2f1f2622b 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/Converter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/Converter.kt @@ -22,9 +22,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.KtNodeTypes.* +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.lightTree.fir.modifier.* import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.nameAsSafeName import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.toDelegatedSelfType @@ -34,10 +35,12 @@ import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.joinTypeParameters import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.extractArgumentsFrom import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.fillEnumEntryConstructor import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.fillConstructors +import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.toFirUserType +import org.jetbrains.kotlin.fir.lightTree.DataClassUtil.generateComponentFunctions +import org.jetbrains.kotlin.fir.lightTree.DataClassUtil.generateCopyFunction import org.jetbrains.kotlin.fir.lightTree.FunctionUtil.removeLast import org.jetbrains.kotlin.fir.lightTree.fir.TypeConstraint import org.jetbrains.kotlin.fir.lightTree.fir.ValueParameter -import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType import org.jetbrains.kotlin.psi.stubs.elements.KtDotQualifiedExpressionElementType import org.jetbrains.kotlin.psi.stubs.elements.KtStringTemplateExpressionElementType @@ -48,19 +51,6 @@ class Converter( val stubMode: Boolean, private val tree: FlyweightCapableTreeStructure ) { - - private val CLASS_MODIFIER = TokenSet.create(ENUM_KEYWORD, ANNOTATION_KEYWORD, DATA_KEYWORD, INNER_KEYWORD, COMPANION_KEYWORD) - private val MEMBER_MODIFIER = TokenSet.create(OVERRIDE_KEYWORD, LATEINIT_KEYWORD) - private val VISIBILITY_MODIFIER = TokenSet.create(PUBLIC_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD) - private val VARIANCE_MODIFIER = TokenSet.create(IN_KEYWORD, OUT_KEYWORD) - private val FUNCTION_MODIFIER = - TokenSet.create(TAILREC_KEYWORD, OPERATOR_KEYWORD, INFIX_KEYWORD, INLINE_KEYWORD, EXTERNAL_KEYWORD, SUSPEND_KEYWORD) - private val PROPERTY_MODIFIER = TokenSet.create(CONST_KEYWORD) - private val INHERITANCE_MODIFIER = TokenSet.create(ABSTRACT_KEYWORD, FINAL_KEYWORD, OPEN_KEYWORD, SEALED_KEYWORD) - private val PARAMETER_MODIFIER = TokenSet.create(VARARG_KEYWORD, NOINLINE_KEYWORD, CROSSINLINE_KEYWORD) - private val REIFICATION_MODIFIER = TokenSet.create(REIFIED_KEYWORD) - private val PLATFORM_MODIFIER = TokenSet.create(EXPECT_KEYWORD, ACTUAL_KEYWORD) - private val implicitUnitType = FirImplicitUnitTypeRef(session, null) private val implicitAnyType = FirImplicitAnyTypeRef(session, null) private val implicitEnumType = FirImplicitEnumTypeRef(session, null) @@ -245,20 +235,19 @@ class Converter( } } - classKind = when (modifiers.classModifier) { - ClassModifier.ENUM -> ClassKind.ENUM_CLASS - ClassModifier.ANNOTATION -> ClassKind.ANNOTATION_CLASS + classKind = when { + modifiers.isEnum() -> ClassKind.ENUM_CLASS + modifiers.isAnnotation() -> ClassKind.ANNOTATION_CLASS else -> classKind } val hasSecondaryConstructor = classBody.hasSecondaryConstructor(classBody.getChildrenAsArray()) - val className = identifier.nameAsSafeName(if (modifiers.classModifier == ClassModifier.COMPANION) "Companion" else "") + val className = identifier.nameAsSafeName(if (modifiers.isCompanion()) "Companion" else "") val defaultDelegatedSuperTypeRef = when (classKind) { ClassKind.ENUM_CLASS -> implicitEnumType ClassKind.ANNOTATION_CLASS -> implicitAnnotationType else -> implicitAnyType } - val delegatedSelfTypeRef = className.toDelegatedSelfType(session) delegatedSuperTypeRef = delegatedSuperTypeRef ?: defaultDelegatedSuperTypeRef return ClassNameUtil.withChildClassName(className) { @@ -267,43 +256,47 @@ class Converter( null, FirClassSymbol(ClassNameUtil.currentClassId), className, - modifiers.visibilityModifier.toVisibility(), - modifiers.inheritanceModifier?.toModality(), - modifiers.platformModifier == PlatformModifier.EXPECT, - modifiers.platformModifier == PlatformModifier.ACTUAL, + if (FunctionUtil.firFunctions.isNotEmpty()) Visibilities.LOCAL else modifiers.getVisibility(), + modifiers.getModality(), + modifiers.hasExpect(), + modifiers.hasActual(), classKind, - isInner = modifiers.classModifier == ClassModifier.INNER, - isCompanion = modifiers.classModifier == ClassModifier.COMPANION, - isData = modifiers.classModifier == ClassModifier.DATA, - isInline = modifiers.functionModifier == FunctionModifier.INLINE + isInner = modifiers.isInner(), + isCompanion = modifiers.isCompanion(), + isData = modifiers.isDataClass(), + isInline = modifiers.hasInline() ) firClass.annotations += modifiers.annotations firClass.typeParameters += firTypeParameters firClass.joinTypeParameters(typeConstraints) firClass.superTypeRefs += superTypeRefs + if (firClass.superTypeRefs.isEmpty()) { + firClass.superTypeRefs += defaultDelegatedSuperTypeRef + } - var firPrimaryConstructor: FirConstructor? = null - if (classKind != ClassKind.INTERFACE && !(primaryConstructor == null && hasSecondaryConstructor)) { - val firDelegatedConstructorCall = convertConstructorDelegationCall(null) - .extractArgumentsFrom(superTypeCallEntry, stubMode) - firPrimaryConstructor = convertPrimaryConstructor(primaryConstructor) - .apply { - this.returnTypeRef = delegatedSelfTypeRef - this.delegatedConstructor = firDelegatedConstructorCall - firClass.declarations += this - } - } - getValueParameters(primaryConstructor).forEach { - if (it.hasValOrVar()) { - firClass.declarations += it.toFirProperty() - } + val delegatedSelfTypeRef = toDelegatedSelfType(firClass) + val firPrimaryConstructor: FirConstructor? = convertPrimaryConstructor( + primaryConstructor, + classKind, + modifiers, + hasSecondaryConstructor, + delegatedSelfTypeRef, + delegatedSuperTypeRef!!, + superTypeCallEntry + )?.apply { + firClass.declarations += this } + val properties = getValueParameters(primaryConstructor) + .filter { it.hasValOrVar() } + .map { it.toFirProperty() } + firClass.declarations += properties + classBody?.let { if (classKind == ClassKind.ENUM_CLASS) { // separate converter only for enum entries val firEnumEntries = convertEnumClassBody(it) //return enum entries list - firEnumEntries.fillEnumEntryConstructor(firPrimaryConstructor!!, stubMode) + firEnumEntries.fillEnumEntryConstructor(firPrimaryConstructor!!, className.identifier.toFirUserType(session), stubMode) firClass.declarations += firEnumEntries } firClass.declarations += convertClassBody(it) @@ -314,6 +307,12 @@ class Converter( .collect(Collectors.toList()) .fillConstructors(primaryConstructor != null, delegatedSelfTypeRef, delegatedSuperTypeRef!!) + if (modifiers.isDataClass() && firPrimaryConstructor != null) { + generateComponentFunctions(session, firClass, properties) + generateCopyFunction(session, firClass, firPrimaryConstructor, properties) + // TODO: equals, hashCode, toString + } + return@withChildClassName firClass } } @@ -333,8 +332,17 @@ class Converter( * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseClassOrObject * primaryConstructor branch */ - private fun convertPrimaryConstructor(primaryConstructor: LighterASTNode?): FirConstructorImpl { - //if (primaryConstructor == null && hasSecondaryConstructor) return null + private fun convertPrimaryConstructor( + primaryConstructor: LighterASTNode?, + classKind: ClassKind, + classModifiers: Modifier, + hasSecondaryConstructor: Boolean, + delegatedSelfTypeRef: FirTypeRef, + delegatedSuperTypeRef: FirTypeRef, + superTypeCallEntry: List + ): FirConstructorImpl? { + if (primaryConstructor == null && hasSecondaryConstructor) return null + if (classKind == ClassKind.INTERFACE) return null var modifiers = Modifier(session) val valueParameters = mutableListOf() @@ -345,17 +353,34 @@ class Converter( } } + val defaultVisibility = + if (classKind == ClassKind.OBJECT || + classModifiers.getModality() == Modality.SEALED || + classModifiers.isEnum() + ) + Visibilities.PRIVATE + else + Visibilities.UNKNOWN + + val firDelegatedCall = FirDelegatedConstructorCallImpl( + session, + null, + delegatedSuperTypeRef, + isThis = false + ).extractArgumentsFrom(superTypeCallEntry, stubMode) + return FirPrimaryConstructorImpl( session, null, FirFunctionSymbol(ClassNameUtil.callableIdForClassConstructor()), - modifiers.visibilityModifier.toVisibility(), - modifiers.platformModifier == PlatformModifier.EXPECT, - modifiers.platformModifier == PlatformModifier.ACTUAL, - implicitType, //must be initialized with "delegatedSelfTypeRef" outside of this method - null //must be initialized outside of this method + if (primaryConstructor != null) modifiers.getVisibility() else defaultVisibility, + modifiers.hasExpect(), + modifiers.hasActual(), + delegatedSelfTypeRef, + firDelegatedCall ).apply { annotations += modifiers.annotations + //this.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef) this.valueParameters += valueParameters.map { it.firValueParameter } } } @@ -388,6 +413,8 @@ class Converter( VAR_KEYWORD -> isVar = true IDENTIFIER -> identifier = it.toString() TYPE_REFERENCE -> firType = convertType(it) + DOT_QUALIFIED_EXPRESSION, + REFERENCE_EXPRESSION, is KtNodeType, is KtConstantExpressionElementType, is KtDotQualifiedExpressionElementType, @@ -398,12 +425,12 @@ class Converter( val firValueParameter = FirValueParameterImpl( session, null, - Name.identifier(identifier), + identifier.nameAsSafeName(), firType, firExpression, - isCrossinline = modifiers.parameterModifier == ParameterModifier.CROSSINLINE, - isNoinline = modifiers.parameterModifier == ParameterModifier.NOINLINE, - isVararg = modifiers.parameterModifier == ParameterModifier.VARARG + isCrossinline = modifiers.hasCrossinline(), + isNoinline = modifiers.hasNoinline(), + isVararg = modifiers.hasVararg() ).apply { annotations += modifiers.annotations } return ValueParameter(isVal, isVar, modifiers, firValueParameter) } @@ -466,6 +493,8 @@ class Converter( explicitDelegation.forEachChildren { when (it.tokenType) { TYPE_REFERENCE -> firTypeRef = convertType(it) + DOT_QUALIFIED_EXPRESSION, + REFERENCE_EXPRESSION, is KtNodeType, is KtConstantExpressionElementType, is KtDotQualifiedExpressionElementType, @@ -575,9 +604,9 @@ class Converter( session, null, FirFunctionSymbol(ClassNameUtil.callableIdForClassConstructor()), - modifiers.visibilityModifier.toVisibility(), - modifiers.platformModifier == PlatformModifier.EXPECT, - modifiers.platformModifier == PlatformModifier.ACTUAL, + modifiers.getVisibility(), + modifiers.hasExpect(), + modifiers.hasActual(), implicitType, //must be initialized with "delegatedSelfTypeRef" outside of this method constructorDelegationCall ) @@ -606,7 +635,7 @@ class Converter( } } - val enumEntryName = Name.identifier(identifier) + val enumEntryName = identifier.nameAsSafeName() return ClassNameUtil.withChildClassName(enumEntryName) { return@withChildClassName FirEnumEntryImpl( session, @@ -644,11 +673,12 @@ class Converter( TYPE_REFERENCE -> if (isReturnType) returnType = convertType(it) else receiverType = convertType(it) TYPE_CONSTRAINT_LIST -> typeConstraints += convertTypeConstraints(it) BLOCK -> firBlock = visitBlock(it) + DOT_QUALIFIED_EXPRESSION, + REFERENCE_EXPRESSION, is KtNodeType, is KtConstantExpressionElementType, is KtDotQualifiedExpressionElementType, - is KtStringTemplateExpressionElementType, - REFERENCE_EXPRESSION -> firExpression = visitExpression(it) //TODO implement + is KtStringTemplateExpressionElementType -> firExpression = visitExpression(it) //TODO implement } } @@ -658,23 +688,24 @@ class Converter( else implicitType } - val functionName = Name.identifier(identifier) + val functionName = identifier.nameAsSafeName() + val isLocal = FunctionUtil.firFunctions.isNotEmpty() val firFunction = FirMemberFunctionImpl( session, null, - FirFunctionSymbol(ClassNameUtil.callableIdForName(functionName)), + FirFunctionSymbol(ClassNameUtil.callableIdForName(functionName, isLocal)), functionName, - modifiers.visibilityModifier.toVisibility(), - modifiers.inheritanceModifier?.toModality(), - modifiers.platformModifier == PlatformModifier.EXPECT, - modifiers.platformModifier == PlatformModifier.ACTUAL, - modifiers.memberModifier == MemberModifier.OVERRIDE, - modifiers.functionModifier == FunctionModifier.OPERATOR, - modifiers.functionModifier == FunctionModifier.INFIX, - modifiers.functionModifier == FunctionModifier.INLINE, - modifiers.functionModifier == FunctionModifier.TAILREC, - modifiers.functionModifier == FunctionModifier.EXTERNAL, - modifiers.functionModifier == FunctionModifier.SUSPEND, + modifiers.getVisibility(), + modifiers.getModality(), + modifiers.hasExpect(), + modifiers.hasActual(), + modifiers.hasOverride(), + modifiers.hasOperator(), + modifiers.hasInfix(), + modifiers.hasInline(), + modifiers.hasTailrec(), + modifiers.hasExternal(), + modifiers.hasSuspend(), receiverType, returnType!! ) @@ -715,23 +746,24 @@ class Converter( MODIFIER_LIST -> modifiers = convertModifiers(it) IDENTIFIER -> identifier = it.toString() TYPE_REFERENCE -> firType = convertType(it) + DOT_QUALIFIED_EXPRESSION, + REFERENCE_EXPRESSION, is KtNodeType, is KtConstantExpressionElementType, is KtDotQualifiedExpressionElementType, - is KtStringTemplateExpressionElementType, - REFERENCE_EXPRESSION -> firExpression = visitExpression(it) //TODO implement + is KtStringTemplateExpressionElementType -> firExpression = visitExpression(it) //TODO implement } } return FirValueParameterImpl( session, null, - Name.identifier(identifier), + identifier.nameAsSafeName(), firType, firExpression, - isCrossinline = modifiers.parameterModifier == ParameterModifier.CROSSINLINE, - isNoinline = modifiers.parameterModifier == ParameterModifier.NOINLINE, - isVararg = modifiers.parameterModifier == ParameterModifier.VARARG + isCrossinline = modifiers.hasCrossinline(), + isNoinline = modifiers.hasNoinline(), + isVararg = modifiers.hasVararg() ).apply { annotations += modifiers.annotations } } @@ -752,7 +784,7 @@ class Converter( return FirValueParameterImpl( session, null, - identifier?.let { Name.identifier(it) } ?: SpecialNames.NO_NAME_PROVIDED, + identifier.nameAsSafeName(), firType ?: implicitType, null, isCrossinline = false, @@ -783,9 +815,9 @@ class Converter( firValueParameter.name, if (firValueParameter.returnTypeRef == implicitType) propertyTypeRef else firValueParameter.returnTypeRef, null,//TODO implement - isCrossinline = modifiers.parameterModifier == ParameterModifier.CROSSINLINE, - isNoinline = modifiers.parameterModifier == ParameterModifier.NOINLINE, - isVararg = modifiers.parameterModifier == ParameterModifier.VARARG + isCrossinline = modifiers.hasCrossinline(), + isNoinline = modifiers.hasNoinline(), + isVararg = modifiers.hasVararg() ).apply { annotations += modifiers.annotations } @@ -843,15 +875,16 @@ class Converter( getter = convertGetter(it, returnType) else setter = convertSetter(it, returnType) + DOT_QUALIFIED_EXPRESSION, + REFERENCE_EXPRESSION, is KtNodeType, is KtConstantExpressionElementType, is KtDotQualifiedExpressionElementType, - is KtStringTemplateExpressionElementType, - REFERENCE_EXPRESSION -> firExpression = visitExpression(it) //TODO implement + is KtStringTemplateExpressionElementType -> firExpression = visitExpression(it) //TODO implement } } - val propertyName = Name.identifier(identifier) + val propertyName = identifier.nameAsSafeName() return if (FunctionUtil.firFunctions.isNotEmpty()) { FirVariableImpl( @@ -873,19 +906,19 @@ class Converter( null, FirPropertySymbol(ClassNameUtil.callableIdForName(propertyName)), propertyName, - modifiers.visibilityModifier.toVisibility(), - modifiers.inheritanceModifier?.toModality(), - modifiers.platformModifier == PlatformModifier.EXPECT, - modifiers.platformModifier == PlatformModifier.ACTUAL, - modifiers.memberModifier == MemberModifier.OVERRIDE, - modifiers.propertyModifier == PropertyModifier.CONST, - modifiers.memberModifier == MemberModifier.LATEINIT, + modifiers.getVisibility(), + modifiers.getModality(), + modifiers.hasExpect(), + modifiers.hasActual(), + modifiers.hasOverride(), + modifiers.isConst(), + modifiers.hasLateinit(), receiverType, returnType, isVar, firExpression, - getter ?: FirDefaultPropertyGetter(session, null, returnType, modifiers.visibilityModifier.toVisibility()), - setter ?: FirDefaultPropertySetter(session, null, returnType, modifiers.visibilityModifier.toVisibility()), + getter ?: FirDefaultPropertyGetter(session, null, returnType, modifiers.getVisibility()), + setter ?: FirDefaultPropertySetter(session, null, returnType, modifiers.getVisibility()), if (isDelegate) { FirExpressionStub(session, null) //TODO("not implemented") @@ -913,11 +946,12 @@ class Converter( MODIFIER_LIST -> modifiers = convertModifiers(it) TYPE_REFERENCE -> returnType = convertType(it) BLOCK -> firBlock = visitBlock(it) + DOT_QUALIFIED_EXPRESSION, + REFERENCE_EXPRESSION, is KtNodeType, is KtConstantExpressionElementType, is KtDotQualifiedExpressionElementType, - is KtStringTemplateExpressionElementType, - REFERENCE_EXPRESSION -> firExpression = visitExpression(it) //TODO implement + is KtStringTemplateExpressionElementType -> firExpression = visitExpression(it) //TODO implement } } @@ -925,7 +959,7 @@ class Converter( session, null, true, - modifiers.visibilityModifier.toVisibility(), + modifiers.getVisibility(), returnType ?: propertyTypeRef ) FunctionUtil.firFunctions += firAccessor @@ -952,11 +986,12 @@ class Converter( TYPE_REFERENCE -> returnType = convertType(it) VALUE_PARAMETER_LIST -> firValueParameters += convertSetterParameter(it, propertyTypeRef) BLOCK -> firBlock = visitBlock(it) + DOT_QUALIFIED_EXPRESSION, + REFERENCE_EXPRESSION, is KtNodeType, is KtConstantExpressionElementType, is KtDotQualifiedExpressionElementType, - is KtStringTemplateExpressionElementType, - REFERENCE_EXPRESSION -> firExpression = visitExpression(it) //TODO implement + is KtStringTemplateExpressionElementType -> firExpression = visitExpression(it) //TODO implement } } @@ -964,7 +999,7 @@ class Converter( session, null, false, - modifiers.visibilityModifier.toVisibility(), + modifiers.getVisibility(), returnType ?: implicitUnitType ) FunctionUtil.firFunctions += firAccessor @@ -1002,16 +1037,16 @@ class Converter( } } - val typeAliasName = Name.identifier(identifier) + val typeAliasName = identifier.nameAsSafeName() return ClassNameUtil.withChildClassName(typeAliasName) { return@withChildClassName FirTypeAliasImpl( session, null, FirTypeAliasSymbol(ClassNameUtil.currentClassId), typeAliasName, - modifiers.visibilityModifier.toVisibility(), - modifiers.platformModifier == PlatformModifier.EXPECT, - modifiers.platformModifier == PlatformModifier.ACTUAL, + modifiers.getVisibility(), + modifiers.hasExpect(), + modifiers.hasActual(), firType ).apply { annotations += modifiers.annotations @@ -1051,8 +1086,8 @@ class Converter( null, FirTypeParameterSymbol(), identifier.nameAsSafeName(), - typeParameterModifiers.varianceModifier.toVariance(), - typeParameterModifiers.reificationModifier != null + typeParameterModifiers.getVariance(), + typeParameterModifiers.hasReified() ) firTypeParameter.annotations += typeParameterModifiers.annotations firType?.let { firTypeParameter.bounds += it } @@ -1066,12 +1101,10 @@ class Converter( private fun convertTypeParameterModifiers(typeParameterModifiers: LighterASTNode): TypeParameterModifier { val modifier = TypeParameterModifier(session) typeParameterModifiers.forEachChildren { - val tokenType = it.tokenType - when { - VARIANCE_MODIFIER.contains(tokenType) -> modifier.varianceModifier = convertVarianceModifier(it) - REIFICATION_MODIFIER.contains(tokenType) -> modifier.reificationModifier = convertReificationModifier(it) - tokenType == ANNOTATION -> modifier.annotations += convertAnnotation(it) - tokenType == ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null) + when (it.tokenType) { + ANNOTATION -> modifier.annotations += convertAnnotation(it) + ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null) + else -> modifier.addModifier(it) } } return modifier @@ -1103,11 +1136,10 @@ class Converter( private fun convertTypeModifiers(typeModifiers: LighterASTNode): TypeModifier { val modifier = TypeModifier(session) typeModifiers.forEachChildren { - val tokenType = it.tokenType - when { - it.toString() == SUSPEND_KEYWORD.value -> modifier.suspendModifier = SuspendModifier.SUSPEND - tokenType == ANNOTATION -> modifier.annotations += convertAnnotation(it) - tokenType == ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null) + when (it.tokenType) { + ANNOTATION -> modifier.annotations += convertAnnotation(it) + ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null) + else -> modifier.addModifier(it) } } return modifier @@ -1120,7 +1152,7 @@ class Converter( lateinit var firType: FirTypeRef nullableType.forEachChildren { when (it.tokenType) { - USER_TYPE -> firType = convertUserType(it, true) + USER_TYPE -> firType = convertUserType(it, true).also { firUserType -> (firUserType as FirUserTypeRefImpl).qualifier.reverse() } FUNCTION_TYPE -> firType = convertFunctionType(it, true) NULLABLE_TYPE -> firType = convertNullableType(it) DYNAMIC_TYPE -> firType = FirDynamicTypeRefImpl(session, null, true) @@ -1184,7 +1216,7 @@ class Converter( } val qualifier = FirQualifierPartImpl( - Name.identifier(identifier) + identifier.nameAsSafeName() ).apply { typeArguments += firTypeArguments } return FirUserTypeRefImpl( @@ -1281,7 +1313,7 @@ class Converter( else FirTypeProjectionWithVarianceImpl( session, null, - modifiers.varianceModifier.toVariance(), + modifiers.getVariance(), firType ) } @@ -1292,11 +1324,10 @@ class Converter( private fun convertTypeProjectionModifiers(modifiers: LighterASTNode): TypeProjectionModifier { val modifier = TypeProjectionModifier(session) modifiers.forEachChildren { - val tokenType = it.tokenType - when { - VARIANCE_MODIFIER.contains(tokenType) -> modifier.varianceModifier = convertVarianceModifier(it) - tokenType == ANNOTATION -> modifier.annotations += convertAnnotation(it) - tokenType == ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null) + when (it.tokenType) { + ANNOTATION -> modifier.annotations += convertAnnotation(it) + ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null) + else -> modifier.addModifier(it) } } return modifier @@ -1327,63 +1358,15 @@ class Converter( private fun convertModifiers(modifiers: LighterASTNode): Modifier { val modifier = Modifier(session) modifiers.forEachChildren { - val tokenType = it.tokenType - when { - CLASS_MODIFIER.contains(tokenType) -> modifier.classModifier = convertClassModifier(it) - MEMBER_MODIFIER.contains(tokenType) -> modifier.memberModifier = convertMemberModifier(it) - VISIBILITY_MODIFIER.contains(tokenType) -> modifier.visibilityModifier = convertVisibilityModifier(it) - FUNCTION_MODIFIER.contains(tokenType) -> modifier.functionModifier = convertFunctionModifier(it) - PROPERTY_MODIFIER.contains(tokenType) -> modifier.propertyModifier = convertPropertyModifier(it) - INHERITANCE_MODIFIER.contains(tokenType) -> modifier.inheritanceModifier = convertInheritanceModifier(it) - PARAMETER_MODIFIER.contains(tokenType) -> modifier.parameterModifier = convertParameterModifier(it) - PLATFORM_MODIFIER.contains(tokenType) -> modifier.platformModifier = convertPlatformModifier(it) - tokenType == ANNOTATION -> modifier.annotations += convertAnnotation(it) - tokenType == ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null) + when (it.tokenType) { + ANNOTATION -> modifier.annotations += convertAnnotation(it) + ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null) + else -> modifier.addModifier(it) } } return modifier } - private fun convertClassModifier(classModifier: LighterASTNode): ClassModifier { - return ClassModifier.valueOf(classModifier.toString().toUpperCase()) - } - - private fun convertMemberModifier(memberModifier: LighterASTNode): MemberModifier { - return MemberModifier.valueOf(memberModifier.toString().toUpperCase()) - } - - private fun convertVisibilityModifier(visibilityModifier: LighterASTNode): VisibilityModifier { - return VisibilityModifier.valueOf(visibilityModifier.toString().toUpperCase()) - } - - private fun convertVarianceModifier(varianceModifier: LighterASTNode): VarianceModifier { - return VarianceModifier.valueOf(varianceModifier.toString().toUpperCase()) - } - - private fun convertFunctionModifier(functionModifier: LighterASTNode): FunctionModifier { - return FunctionModifier.valueOf(functionModifier.toString().toUpperCase()) - } - - private fun convertPropertyModifier(propertyModifier: LighterASTNode): PropertyModifier { - return PropertyModifier.valueOf(propertyModifier.toString().toUpperCase()) - } - - private fun convertInheritanceModifier(inheritanceModifier: LighterASTNode): InheritanceModifier { - return InheritanceModifier.valueOf(inheritanceModifier.toString().toUpperCase()) - } - - private fun convertParameterModifier(parameterModifier: LighterASTNode): ParameterModifier { - return ParameterModifier.valueOf(parameterModifier.toString().toUpperCase()) - } - - private fun convertReificationModifier(reificationModifier: LighterASTNode): ReificationModifier { - return ReificationModifier.valueOf(reificationModifier.toString().toUpperCase()) - } - - private fun convertPlatformModifier(platformModifier: LighterASTNode): PlatformModifier { - return PlatformModifier.valueOf(platformModifier.toString().toUpperCase()) - } - private fun convertAnnotation(annotationNode: LighterASTNode): List { var annotationTarget: AnnotationUseSiteTarget? = null return annotationNode.forEachChildrenReturnList { node, container -> diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/ConverterUtil.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/ConverterUtil.kt index df4fcfccdd9..7324ac0b91b 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/ConverterUtil.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/ConverterUtil.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.lightTree import com.intellij.lang.LighterASTNode import org.jetbrains.kotlin.KtNodeTypes +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirFunctionTarget import org.jetbrains.kotlin.fir.FirSession @@ -16,34 +17,58 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirReturnExpression import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.lightTree.fir.TypeConstraint +import org.jetbrains.kotlin.fir.lightTree.fir.ValueParameter +import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol -import org.jetbrains.kotlin.fir.types.FirTypeRef -import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef -import org.jetbrains.kotlin.fir.types.impl.FirQualifierPartImpl -import org.jetbrains.kotlin.fir.types.impl.FirUserTypeRefImpl +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.types.Variance object ConverterUtil { fun String?.nameAsSafeName(defaultName: String = ""): Name { return when { - this != null -> Name.identifier(this) + this != null -> Name.identifier(this.replace("`", "")) defaultName.isNotEmpty() -> Name.identifier(defaultName) else -> SpecialNames.NO_NAME_PROVIDED } } - fun Name?.toDelegatedSelfType(session: FirSession): FirTypeRef = - FirUserTypeRefImpl(session, null, isMarkedNullable = false).apply { - qualifier.add( - FirQualifierPartImpl( - this@toDelegatedSelfType ?: SpecialNames.NO_NAME_PROVIDED - ) - ) + fun String.toFirUserType(session: FirSession): FirUserTypeRef { + val qualifier = FirQualifierPartImpl( + Name.identifier(this) + ) + + return FirUserTypeRefImpl( + session, + null, + false + ).apply { + this.qualifier.add(qualifier) } + } + + fun toDelegatedSelfType(firClass: FirRegularClass): FirTypeRef { + val typeParameters = firClass.typeParameters.map { + FirTypeParameterImpl(firClass.session, it.psi, FirTypeParameterSymbol(), it.name, Variance.INVARIANT, false).apply { + this.bounds += it.bounds + } + } + return FirResolvedTypeRefImpl( + firClass.session, + null, + ConeClassTypeImpl( + firClass.symbol.toLookupTag(), + typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(), + false + ) + ) + } fun LighterASTNode?.hasSecondaryConstructor(kidsArray: Array): Boolean { if (this == null) return false @@ -105,6 +130,13 @@ object ConverterUtil { } } + fun typeParametersFromSelfType(delegatedSelfTypeRef: FirTypeRef): List { + return delegatedSelfTypeRef.coneTypeSafe() + ?.typeArguments + ?.map { ((it as ConeTypeParameterType).lookupTag.symbol as FirTypeParameterSymbol).fir } + ?: emptyList() + } + fun T.extractArgumentsFrom(container: List, stubMode: Boolean): T { if (!stubMode) { //TODO("not implemented") @@ -115,20 +147,21 @@ object ConverterUtil { fun List.fillEnumEntryConstructor( firPrimaryConstructor: FirConstructor, + enumType: FirUserTypeRef, stubMode: Boolean ) { this.forEach { firEnumEntry -> - val enumDelegatedSelfTypeRef = firPrimaryConstructor.returnTypeRef + val enumDelegatedSelfTypeRef = toDelegatedSelfType(firEnumEntry) var enumDelegatedSuperTypeRef: FirTypeRef = FirImplicitAnyTypeRef(firEnumEntry.session, null) val enumSuperTypeCallEntry = mutableListOf() if (firPrimaryConstructor.valueParameters.isNotEmpty()) { - enumDelegatedSuperTypeRef = enumDelegatedSelfTypeRef - firEnumEntry.superTypeRefs += enumDelegatedSuperTypeRef + enumDelegatedSuperTypeRef = enumType//enumDelegatedSelfTypeRef enumSuperTypeCallEntry += firPrimaryConstructor.valueParameters.map { firValueParameter -> firValueParameter.toFirExpression(stubMode) } } + firEnumEntry.superTypeRefs += enumDelegatedSuperTypeRef val firDelegatedConstructorCall = FirDelegatedConstructorCallImpl( firEnumEntry.session, @@ -147,6 +180,7 @@ object ConverterUtil { enumDelegatedSelfTypeRef, firDelegatedConstructorCall ) + firEnumPrimaryConstructor.typeParameters += typeParametersFromSelfType(enumDelegatedSelfTypeRef) firEnumEntry.declarations.add(0, firEnumPrimaryConstructor) } } @@ -157,7 +191,9 @@ object ConverterUtil { delegatedSuperTypeRef: FirTypeRef ) { this.forEach { constructor -> - (constructor as FirConstructorImpl).returnTypeRef = delegatedSelfTypeRef + (constructor as FirConstructorImpl).typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef) + + constructor.returnTypeRef = delegatedSelfTypeRef val constructorDelegationCall = constructor.delegatedConstructor as? FirDelegatedConstructorCallImpl val isThis = (constructorDelegationCall == null && hasPrimaryConstructor) || constructorDelegationCall?.isThis == true @@ -188,9 +224,12 @@ object ClassNameUtil { val currentClassId get() = ClassId(packageFqName, className, false) - fun callableIdForName(name: Name) = - if (className == FqName.ROOT) CallableId(packageFqName, name) - else CallableId(packageFqName, className, name) + fun callableIdForName(name: Name, local: Boolean = false) = + when { + local -> CallableId(name) + className == FqName.ROOT -> CallableId(packageFqName, name) + else -> CallableId(packageFqName, className, name) + } fun callableIdForClassConstructor() = if (className == FqName.ROOT) CallableId(packageFqName, Name.special("")) @@ -215,4 +254,90 @@ object FunctionUtil { } } +object DataClassUtil { + fun generateComponentFunctions( + session: FirSession, firClass: FirClassImpl, properties: List + ) { + var componentIndex = 1 + for (property in properties) { + if (!property.isVal && !property.isVar) continue + val name = Name.identifier("component$componentIndex") + componentIndex++ + val symbol = FirFunctionSymbol( + CallableId( + ClassNameUtil.packageFqName, + ClassNameUtil.className, + name + ) + ) + firClass.addDeclaration( + FirMemberFunctionImpl( + session, null, symbol, name, + Visibilities.PUBLIC, Modality.FINAL, + isExpect = false, isActual = false, + isOverride = false, isOperator = false, + isInfix = false, isInline = false, + isTailRec = false, isExternal = false, + isSuspend = false, receiverTypeRef = null, + returnTypeRef = FirImplicitTypeRefImpl(session, null) + ).apply { + val componentFunction = this + body = FirSingleExpressionBlock( + session, + FirReturnExpressionImpl( + session, null, + FirQualifiedAccessExpressionImpl(session, null).apply { + val parameterName = property.name + calleeReference = FirResolvedCallableReferenceImpl( + session, null, + parameterName, property.symbol + ) + } + ).apply { + target = FirFunctionTarget(null) + target.bind(componentFunction) + } + ) + } + ) + } + } + + private val copyName = Name.identifier("copy") + + fun generateCopyFunction( + session: FirSession, firClass: FirClassImpl, + firPrimaryConstructor: FirConstructor, + properties: List + ) { + val symbol = FirFunctionSymbol(CallableId(ClassNameUtil.packageFqName, ClassNameUtil.className, copyName)) + firClass.addDeclaration( + FirMemberFunctionImpl( + session, null, symbol, copyName, + Visibilities.PUBLIC, Modality.FINAL, + isExpect = false, isActual = false, + isOverride = false, isOperator = false, + isInfix = false, isInline = false, + isTailRec = false, isExternal = false, + isSuspend = false, receiverTypeRef = null, + returnTypeRef = firPrimaryConstructor.returnTypeRef//FirImplicitTypeRefImpl(session, this) + ).apply { + val copyFunction = this + for (property in properties) { + val name = property.name + valueParameters += FirValueParameterImpl( + session, null, name, + property.returnTypeRef, + FirQualifiedAccessExpressionImpl(session, null).apply { + calleeReference = FirResolvedCallableReferenceImpl(session, null, name, property.symbol) + }, + isCrossinline = false, isNoinline = false, isVararg = false + ) + } + + body = FirEmptyExpressionBlock(session) + } + ) + } +} diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt index 25a6668b05c..905d9ce38b9 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.declarations.impl.FirMemberPropertyImpl import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl import org.jetbrains.kotlin.fir.lightTree.ClassNameUtil -import org.jetbrains.kotlin.fir.lightTree.fir.modifier.MemberModifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.PlatformModifier import org.jetbrains.kotlin.fir.references.FirPropertyFromParameterCallableReference @@ -21,7 +20,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol class ValueParameter( private val isVal: Boolean, private val isVar: Boolean, - private val modifier: Modifier, + private val modifiers: Modifier, val firValueParameter: FirValueParameter ) { fun hasValOrVar(): Boolean { @@ -37,11 +36,11 @@ class ValueParameter( null, FirPropertySymbol(ClassNameUtil.callableIdForName(name)), name, - modifier.visibilityModifier.toVisibility(), - modifier.inheritanceModifier?.toModality(), - modifier.platformModifier == PlatformModifier.EXPECT, - modifier.platformModifier == PlatformModifier.ACTUAL, - isOverride = modifier.memberModifier == MemberModifier.OVERRIDE, + modifiers.getVisibility(), + modifiers.getModality(), + modifiers.hasExpect(), + modifiers.hasActual(), + isOverride = modifiers.hasOverride(), isConst = false, isLateInit = false, receiverTypeRef = null, @@ -52,12 +51,12 @@ class ValueParameter( this@ValueParameter.firValueParameter.session, null, name, this@ValueParameter.firValueParameter.symbol ) }, - getter = FirDefaultPropertyGetter(this.firValueParameter.session, null, type, modifier.visibilityModifier.toVisibility()), + getter = FirDefaultPropertyGetter(this.firValueParameter.session, null, type, modifiers.getVisibility()), setter = if (this.isVar) FirDefaultPropertySetter( this.firValueParameter.session, null, type, - modifier.visibilityModifier.toVisibility() + modifiers.getVisibility() ) else null, delegate = null ).apply { annotations += this@ValueParameter.firValueParameter.annotations } diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/Modifier.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/Modifier.kt index 84f2978fd6f..1a7c4c57b1e 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/Modifier.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/Modifier.kt @@ -5,28 +5,137 @@ package org.jetbrains.kotlin.fir.lightTree.fir.modifier +import com.intellij.lang.LighterASTNode import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.expressions.impl.FirAbstractAnnotatedElement +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.CLASS_MODIFIER +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.FUNCTION_MODIFIER +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.INHERITANCE_MODIFIER +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.MEMBER_MODIFIER +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.PARAMETER_MODIFIER +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.PLATFORM_MODIFIER +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.PROPERTY_MODIFIER +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.VISIBILITY_MODIFIER class Modifier( session: FirSession, psi: PsiElement? = null, - var classModifier: ClassModifier? = null, - var memberModifier: MemberModifier? = null, - var visibilityModifier: VisibilityModifier = VisibilityModifier.UNKNOWN, - var functionModifier: FunctionModifier? = null, - var propertyModifier: PropertyModifier? = null, - var inheritanceModifier: InheritanceModifier? = null, - var parameterModifier: ParameterModifier? = null, - var platformModifier: PlatformModifier? = null -) : FirAbstractAnnotatedElement(session, psi) + private var classModifier: ClassModifier? = null, + private val memberModifiers: MutableList = mutableListOf(), + private var visibilityModifier: VisibilityModifier = VisibilityModifier.UNKNOWN, + private val functionModifiers: MutableList = mutableListOf(), + private var propertyModifier: PropertyModifier? = null, + private var inheritanceModifier: InheritanceModifier? = null, + private var parameterModifier: ParameterModifier? = null, + private var platformModifier: PlatformModifier? = null +) : FirAbstractAnnotatedElement(session, psi) { + fun addModifier(modifier: LighterASTNode) { + val tokenType = modifier.tokenType + when { + CLASS_MODIFIER.contains(tokenType) -> this.classModifier = ClassModifier.valueOf(modifier.toString().toUpperCase()) + MEMBER_MODIFIER.contains(tokenType) -> this.memberModifiers += MemberModifier.valueOf(modifier.toString().toUpperCase()) + VISIBILITY_MODIFIER.contains(tokenType) -> this.visibilityModifier = + VisibilityModifier.valueOf(modifier.toString().toUpperCase()) + FUNCTION_MODIFIER.contains(tokenType) -> this.functionModifiers += FunctionModifier.valueOf(modifier.toString().toUpperCase()) + PROPERTY_MODIFIER.contains(tokenType) -> this.propertyModifier = PropertyModifier.valueOf(modifier.toString().toUpperCase()) + INHERITANCE_MODIFIER.contains(tokenType) -> this.inheritanceModifier = + InheritanceModifier.valueOf(modifier.toString().toUpperCase()) + PARAMETER_MODIFIER.contains(tokenType) -> this.parameterModifier = ParameterModifier.valueOf(modifier.toString().toUpperCase()) + PLATFORM_MODIFIER.contains(tokenType) -> this.platformModifier = PlatformModifier.valueOf(modifier.toString().toUpperCase()) + } + } -enum class ClassModifier{ + fun isEnum(): Boolean { + return classModifier == ClassModifier.ENUM + } + + fun isAnnotation(): Boolean { + return classModifier == ClassModifier.ANNOTATION + } + + fun isDataClass(): Boolean { + return classModifier == ClassModifier.DATA + } + + fun isInner(): Boolean { + return classModifier == ClassModifier.INNER + } + + fun isCompanion(): Boolean { + return classModifier == ClassModifier.COMPANION + } + + fun hasOverride(): Boolean { + return memberModifiers.contains(MemberModifier.OVERRIDE) + } + + fun hasLateinit(): Boolean { + return memberModifiers.contains(MemberModifier.LATEINIT) + } + + fun getVisibility(): Visibility { + return visibilityModifier.toVisibility() + } + + fun hasTailrec(): Boolean { + return functionModifiers.contains(FunctionModifier.TAILREC) + } + + fun hasOperator(): Boolean { + return functionModifiers.contains(FunctionModifier.OPERATOR) + } + + fun hasInfix(): Boolean { + return functionModifiers.contains(FunctionModifier.INFIX) + } + + fun hasInline(): Boolean { + return functionModifiers.contains(FunctionModifier.INLINE) + } + + fun hasExternal(): Boolean { + return functionModifiers.contains(FunctionModifier.EXTERNAL) + } + + fun hasSuspend(): Boolean { + return functionModifiers.contains(FunctionModifier.SUSPEND) + } + + fun isConst(): Boolean { + return propertyModifier == PropertyModifier.CONST + } + + fun getModality(): Modality? { + return inheritanceModifier?.toModality() + } + + fun hasVararg(): Boolean { + return parameterModifier == ParameterModifier.VARARG + } + + fun hasNoinline(): Boolean { + return parameterModifier == ParameterModifier.NOINLINE + } + + fun hasCrossinline(): Boolean { + return parameterModifier == ParameterModifier.CROSSINLINE + } + + fun hasExpect(): Boolean { + return platformModifier == PlatformModifier.EXPECT + } + + fun hasActual(): Boolean { + return platformModifier == PlatformModifier.ACTUAL + } +} + +enum class ClassModifier { ENUM, ANNOTATION, DATA, @@ -34,33 +143,33 @@ enum class ClassModifier{ COMPANION } -enum class MemberModifier{ +enum class MemberModifier { OVERRIDE, LATEINIT } -enum class VisibilityModifier{ - PUBLIC{ +enum class VisibilityModifier { + PUBLIC { override fun toVisibility(): Visibility { return Visibilities.PUBLIC } }, - PRIVATE{ + PRIVATE { override fun toVisibility(): Visibility { return Visibilities.PRIVATE } }, - INTERNAL{ + INTERNAL { override fun toVisibility(): Visibility { return Visibilities.INTERNAL } }, - PROTECTED{ + PROTECTED { override fun toVisibility(): Visibility { return Visibilities.PROTECTED } }, - UNKNOWN{ + UNKNOWN { override fun toVisibility(): Visibility { return Visibilities.UNKNOWN } @@ -69,7 +178,7 @@ enum class VisibilityModifier{ abstract fun toVisibility(): Visibility } -enum class FunctionModifier{ +enum class FunctionModifier { TAILREC, OPERATOR, INFIX, @@ -78,27 +187,27 @@ enum class FunctionModifier{ SUSPEND } -enum class PropertyModifier{ +enum class PropertyModifier { CONST } -enum class InheritanceModifier{ - ABSTRACT{ +enum class InheritanceModifier { + ABSTRACT { override fun toModality(): Modality { return Modality.ABSTRACT } }, - FINAL{ + FINAL { override fun toModality(): Modality { return Modality.FINAL } }, - OPEN{ + OPEN { override fun toModality(): Modality { return Modality.OPEN } }, - SEALED{ + SEALED { override fun toModality(): Modality { return Modality.SEALED } @@ -113,7 +222,7 @@ enum class ParameterModifier { CROSSINLINE } -enum class PlatformModifier{ +enum class PlatformModifier { EXPECT, ACTUAL } diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/ModifierSets.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/ModifierSets.kt new file mode 100644 index 00000000000..39947a4e7c6 --- /dev/null +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/ModifierSets.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.lightTree.fir.modifier + +import com.intellij.psi.tree.TokenSet +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.lexer.KtTokens.* + +object ModifierSets { + val CLASS_MODIFIER = TokenSet.create( + ENUM_KEYWORD, + ANNOTATION_KEYWORD, + DATA_KEYWORD, + INNER_KEYWORD, + COMPANION_KEYWORD + ) + val MEMBER_MODIFIER = TokenSet.create(OVERRIDE_KEYWORD, LATEINIT_KEYWORD) + val VISIBILITY_MODIFIER = TokenSet.create( + PUBLIC_KEYWORD, + PRIVATE_KEYWORD, + INTERNAL_KEYWORD, + PROTECTED_KEYWORD + ) + val FUNCTION_MODIFIER = + TokenSet.create( + TAILREC_KEYWORD, + OPERATOR_KEYWORD, + INFIX_KEYWORD, + INLINE_KEYWORD, + EXTERNAL_KEYWORD, + SUSPEND_KEYWORD + ) + val PROPERTY_MODIFIER = TokenSet.create(CONST_KEYWORD) + val INHERITANCE_MODIFIER = TokenSet.create( + ABSTRACT_KEYWORD, + FINAL_KEYWORD, + OPEN_KEYWORD, + SEALED_KEYWORD + ) + val PARAMETER_MODIFIER = TokenSet.create(VARARG_KEYWORD, NOINLINE_KEYWORD, CROSSINLINE_KEYWORD) + val PLATFORM_MODIFIER = TokenSet.create(EXPECT_KEYWORD, ACTUAL_KEYWORD) + val VARIANCE_MODIFIER = TokenSet.create(IN_KEYWORD, OUT_KEYWORD) + val REIFICATION_MODIFIER = TokenSet.create(REIFIED_KEYWORD) +} \ No newline at end of file diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeModifier.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeModifier.kt index 7f49727af80..9199785f3d8 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeModifier.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeModifier.kt @@ -5,17 +5,29 @@ package org.jetbrains.kotlin.fir.lightTree.fir.modifier +import com.intellij.lang.LighterASTNode import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.expressions.impl.FirAbstractAnnotatedElement +import org.jetbrains.kotlin.lexer.KtTokens class TypeModifier( session: FirSession, psi: PsiElement? = null, - var suspendModifier: SuspendModifier? = null -) : FirAbstractAnnotatedElement(session, psi) + private var suspendModifier: SuspendModifier? = null +) : FirAbstractAnnotatedElement(session, psi) { + fun addModifier(modifier: LighterASTNode) { + if (modifier.toString() == KtTokens.SUSPEND_KEYWORD.value) { + this.suspendModifier = SuspendModifier.SUSPEND + } + } -enum class SuspendModifier{ + fun hasSuspend(): Boolean { + return suspendModifier == SuspendModifier.SUSPEND + } +} + +enum class SuspendModifier { SUSPEND } \ No newline at end of file diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeParameterModifier.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeParameterModifier.kt index 46519d692ea..ce8e802bbd9 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeParameterModifier.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeParameterModifier.kt @@ -5,20 +5,39 @@ package org.jetbrains.kotlin.fir.lightTree.fir.modifier +import com.intellij.lang.LighterASTNode import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.expressions.impl.FirAbstractAnnotatedElement +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.REIFICATION_MODIFIER +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.VARIANCE_MODIFIER import org.jetbrains.kotlin.types.Variance class TypeParameterModifier( session: FirSession, psi: PsiElement? = null, - var varianceModifier: VarianceModifier = VarianceModifier.INVARIANT, - var reificationModifier: ReificationModifier? = null -) : FirAbstractAnnotatedElement(session, psi) + private var varianceModifier: VarianceModifier = VarianceModifier.INVARIANT, + private var reificationModifier: ReificationModifier? = null +) : FirAbstractAnnotatedElement(session, psi) { + fun addModifier(modifier: LighterASTNode) { + val tokenType = modifier.tokenType + when { + VARIANCE_MODIFIER.contains(tokenType) -> this.varianceModifier = VarianceModifier.valueOf(modifier.toString().toUpperCase()) + REIFICATION_MODIFIER.contains(tokenType) -> this.reificationModifier = ReificationModifier.valueOf(modifier.toString().toUpperCase()) + } + } -enum class VarianceModifier{ + fun getVariance(): Variance { + return varianceModifier.toVariance() + } + + fun hasReified(): Boolean { + return reificationModifier == ReificationModifier.REIFIED + } +} + +enum class VarianceModifier { IN { override fun toVariance(): Variance { return Variance.IN_VARIANCE @@ -38,6 +57,6 @@ enum class VarianceModifier{ abstract fun toVariance(): Variance } -enum class ReificationModifier{ +enum class ReificationModifier { REIFIED } \ No newline at end of file diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeProjectionModifier.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeProjectionModifier.kt index 8956e388262..5a79b5f6c07 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeProjectionModifier.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/fir/modifier/TypeProjectionModifier.kt @@ -5,13 +5,27 @@ package org.jetbrains.kotlin.fir.lightTree.fir.modifier +import com.intellij.lang.LighterASTNode import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.expressions.impl.FirAbstractAnnotatedElement +import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierSets.VARIANCE_MODIFIER +import org.jetbrains.kotlin.types.Variance class TypeProjectionModifier( session: FirSession, psi: PsiElement? = null, - var varianceModifier: VarianceModifier = VarianceModifier.INVARIANT -) : FirAbstractAnnotatedElement(session, psi) + private var varianceModifier: VarianceModifier = VarianceModifier.INVARIANT +) : FirAbstractAnnotatedElement(session, psi) { + fun addModifier(modifier: LighterASTNode) { + val tokenType = modifier.tokenType + when { + VARIANCE_MODIFIER.contains(tokenType) -> this.varianceModifier = VarianceModifier.valueOf(modifier.toString().toUpperCase()) + } + } + + fun getVariance(): Variance { + return varianceModifier.toVariance() + } +}