Write ClassWrapper class to transmit information to lower FIR nodes
Additionally a number of further optimization in Converter class
This commit is contained in:
committed by
Mikhail Glukhikh
parent
b5d617492a
commit
5fc3367c25
@@ -7,44 +7,48 @@ package org.jetbrains.kotlin.fir.lightTree
|
||||
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.intellij.psi.tree.IFileElementType
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.KtNodeType
|
||||
import org.jetbrains.kotlin.KtNodeTypes.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
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.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.extractArgumentsFrom
|
||||
import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.getAsString
|
||||
import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.getAsStringWithoutBacktick
|
||||
import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.isExpression
|
||||
import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.joinTypeParameters
|
||||
import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.nameAsSafeName
|
||||
import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.toDelegatedSelfType
|
||||
import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.hasSecondaryConstructor
|
||||
import org.jetbrains.kotlin.fir.lightTree.ConverterUtil.toReturn
|
||||
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.ClassWrapper
|
||||
import org.jetbrains.kotlin.fir.lightTree.fir.TypeConstraint
|
||||
import org.jetbrains.kotlin.fir.lightTree.fir.ValueParameter
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtConstantExpressionElementType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtDotQualifiedExpressionElementType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStringTemplateExpressionElementType
|
||||
import java.util.stream.Collectors
|
||||
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
|
||||
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeModifier
|
||||
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeParameterModifier
|
||||
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeProjectionModifier
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.FirDelegatedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
class Converter(
|
||||
val session: FirSession,
|
||||
@@ -57,6 +61,14 @@ class Converter(
|
||||
private val implicitAnnotationType = FirImplicitAnnotationTypeRef(session, null)
|
||||
private val implicitType = FirImplicitTypeRefImpl(session, null)
|
||||
|
||||
private fun LighterASTNode?.getChildNodesByType(type: IElementType): List<LighterASTNode> {
|
||||
return this?.forEachChildrenReturnList { node, container ->
|
||||
when (node.tokenType) {
|
||||
type -> container += node
|
||||
}
|
||||
} ?: listOf()
|
||||
}
|
||||
|
||||
private fun LighterASTNode?.getChildrenAsArray(): Array<LighterASTNode?> {
|
||||
if (this == null) return arrayOf()
|
||||
|
||||
@@ -89,6 +101,10 @@ class Converter(
|
||||
return container
|
||||
}
|
||||
|
||||
/**
|
||||
* [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
|
||||
* [org.jetbrains.kotlin.parsing.KotlinParsing.parsePreamble]
|
||||
*/
|
||||
fun convertFile(file: LighterASTNode, fileName: String = ""): FirFile {
|
||||
val tokenType = file.tokenType
|
||||
if (tokenType !is IFileElementType) {
|
||||
@@ -133,6 +149,7 @@ class Converter(
|
||||
return fileAnnotationList.forEachChildrenReturnList { node, container ->
|
||||
when (node.tokenType) {
|
||||
ANNOTATION -> container += convertAnnotation(node)
|
||||
ANNOTATION_ENTRY -> container += convertUnescapedAnnotation(node, AnnotationUseSiteTarget.FILE)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,7 +161,8 @@ class Converter(
|
||||
var packageName: FqName = FqName.ROOT
|
||||
packageNode.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
DOT_QUALIFIED_EXPRESSION, REFERENCE_EXPRESSION -> packageName = FqName(it.toString())
|
||||
//TODO separate logic for both expression types
|
||||
DOT_QUALIFIED_EXPRESSION, REFERENCE_EXPRESSION -> packageName = FqName(it.getAsStringWithoutBacktick())
|
||||
}
|
||||
}
|
||||
return packageName
|
||||
@@ -166,15 +184,15 @@ class Converter(
|
||||
*/
|
||||
private fun convertImportDirective(importDirective: LighterASTNode): FirImport {
|
||||
var importedFqName: FqName? = null
|
||||
var isAllUnder: Boolean = false
|
||||
var isAllUnder = false
|
||||
var aliasName: String? = null
|
||||
importDirective.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
DOT_QUALIFIED_EXPRESSION, REFERENCE_EXPRESSION -> {
|
||||
val importName = it.toString()
|
||||
var importName = it.getAsString()
|
||||
if (importName.endsWith(".*")) {
|
||||
isAllUnder = true
|
||||
importName.replace(".*", "")
|
||||
importName = importName.replace(".*", "")
|
||||
}
|
||||
importedFqName = FqName(importName)
|
||||
}
|
||||
@@ -194,7 +212,7 @@ class Converter(
|
||||
private fun convertImportAlias(importAlias: LighterASTNode): String {
|
||||
importAlias.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
IDENTIFIER -> return it.toString()
|
||||
IDENTIFIER -> return it.getAsString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +240,7 @@ class Converter(
|
||||
CLASS_KEYWORD -> classKind = ClassKind.CLASS
|
||||
INTERFACE_KEYWORD -> classKind = ClassKind.INTERFACE
|
||||
OBJECT_KEYWORD -> classKind = ClassKind.OBJECT
|
||||
IDENTIFIER -> identifier = it.toString()
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
TYPE_PARAMETER_LIST -> firTypeParameters += convertTypeParameters(it)
|
||||
PRIMARY_CONSTRUCTOR -> primaryConstructor = it
|
||||
SUPER_TYPE_LIST -> convertDelegationSpecifiers(it).apply {
|
||||
@@ -240,15 +258,14 @@ class Converter(
|
||||
modifiers.isAnnotation() -> ClassKind.ANNOTATION_CLASS
|
||||
else -> classKind
|
||||
}
|
||||
val hasSecondaryConstructor = classBody.hasSecondaryConstructor(classBody.getChildrenAsArray())
|
||||
val className = identifier.nameAsSafeName(if (modifiers.isCompanion()) "Companion" else "")
|
||||
|
||||
val defaultDelegatedSuperTypeRef = when (classKind) {
|
||||
ClassKind.ENUM_CLASS -> implicitEnumType
|
||||
ClassKind.ANNOTATION_CLASS -> implicitAnnotationType
|
||||
val defaultDelegatedSuperTypeRef = when {
|
||||
modifiers.isEnum() -> implicitEnumType
|
||||
modifiers.isAnnotation() -> implicitAnnotationType
|
||||
else -> implicitAnyType
|
||||
}
|
||||
delegatedSuperTypeRef = delegatedSuperTypeRef ?: defaultDelegatedSuperTypeRef
|
||||
|
||||
val className = identifier.nameAsSafeName(if (modifiers.isCompanion()) "Companion" else "")
|
||||
superTypeRefs.ifEmpty { superTypeRefs += defaultDelegatedSuperTypeRef }
|
||||
|
||||
return ClassNameUtil.withChildClassName(className) {
|
||||
val firClass = FirClassImpl(
|
||||
@@ -270,43 +287,31 @@ class Converter(
|
||||
firClass.typeParameters += firTypeParameters
|
||||
firClass.joinTypeParameters(typeConstraints)
|
||||
firClass.superTypeRefs += superTypeRefs
|
||||
if (firClass.superTypeRefs.isEmpty()) {
|
||||
firClass.superTypeRefs += defaultDelegatedSuperTypeRef
|
||||
}
|
||||
|
||||
val delegatedSelfTypeRef = toDelegatedSelfType(firClass)
|
||||
val firPrimaryConstructor: FirConstructor? = convertPrimaryConstructor(
|
||||
primaryConstructor,
|
||||
classKind,
|
||||
modifiers,
|
||||
hasSecondaryConstructor,
|
||||
delegatedSelfTypeRef,
|
||||
delegatedSuperTypeRef!!,
|
||||
superTypeCallEntry
|
||||
)?.apply {
|
||||
firClass.declarations += this
|
||||
}
|
||||
val classWrapper = ClassWrapper(
|
||||
session, className, modifiers, classKind,
|
||||
primaryConstructor != null,
|
||||
classBody.getChildNodesByType(SECONDARY_CONSTRUCTOR).isNotEmpty(),
|
||||
toDelegatedSelfType(firClass), delegatedSuperTypeRef ?: defaultDelegatedSuperTypeRef, superTypeCallEntry
|
||||
)
|
||||
//parse primary constructor
|
||||
val firPrimaryConstructor = convertPrimaryConstructor(primaryConstructor, classWrapper)
|
||||
firPrimaryConstructor?.let { firClass.declarations += it }
|
||||
|
||||
val properties = getValueParameters(primaryConstructor)
|
||||
//parse properties
|
||||
val properties = primaryConstructor
|
||||
.getChildNodesByType(VALUE_PARAMETER_LIST)
|
||||
.flatMap { convertClassParameters(it) }
|
||||
.filter { it.hasValOrVar() }
|
||||
.map { it.toFirProperty() }
|
||||
firClass.declarations += properties
|
||||
firClass.addDeclarations(properties)
|
||||
|
||||
//parse declarations
|
||||
classBody?.let {
|
||||
if (classKind == ClassKind.ENUM_CLASS) {
|
||||
// separate converter only for enum entries
|
||||
val firEnumEntries = convertEnumClassBody(it) //return enum entries list
|
||||
firEnumEntries.fillEnumEntryConstructor(firPrimaryConstructor!!, className.identifier.toFirUserType(session), stubMode)
|
||||
firClass.declarations += firEnumEntries
|
||||
}
|
||||
firClass.declarations += convertClassBody(it)
|
||||
firClass.addDeclarations(convertClassBody(it, classWrapper))
|
||||
}
|
||||
|
||||
firClass.declarations.stream()
|
||||
.filter { it is FirConstructor }
|
||||
.collect(Collectors.toList())
|
||||
.fillConstructors(primaryConstructor != null, delegatedSelfTypeRef, delegatedSuperTypeRef!!)
|
||||
|
||||
//parse data class
|
||||
if (modifiers.isDataClass() && firPrimaryConstructor != null) {
|
||||
generateComponentFunctions(session, firClass, properties)
|
||||
generateCopyFunction(session, firClass, firPrimaryConstructor, properties)
|
||||
@@ -317,32 +322,13 @@ class Converter(
|
||||
}
|
||||
}
|
||||
|
||||
//TODO try to get rid of this method
|
||||
private fun getValueParameters(primaryConstructor: LighterASTNode?): List<ValueParameter> {
|
||||
if (primaryConstructor == null) return listOf()
|
||||
|
||||
return primaryConstructor.forEachChildrenReturnList { node, container ->
|
||||
when (node.tokenType) {
|
||||
VALUE_PARAMETER_LIST -> container += convertClassParameters(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseClassOrObject
|
||||
* primaryConstructor branch
|
||||
*/
|
||||
private fun convertPrimaryConstructor(
|
||||
primaryConstructor: LighterASTNode?,
|
||||
classKind: ClassKind,
|
||||
classModifiers: Modifier,
|
||||
hasSecondaryConstructor: Boolean,
|
||||
delegatedSelfTypeRef: FirTypeRef,
|
||||
delegatedSuperTypeRef: FirTypeRef,
|
||||
superTypeCallEntry: List<FirExpression>
|
||||
): FirConstructorImpl? {
|
||||
if (primaryConstructor == null && hasSecondaryConstructor) return null
|
||||
if (classKind == ClassKind.INTERFACE) return null
|
||||
private fun convertPrimaryConstructor(primaryConstructor: LighterASTNode?, classWrapper: ClassWrapper): FirConstructorImpl? {
|
||||
if (primaryConstructor == null && classWrapper.hasSecondaryConstructor) return null
|
||||
if (classWrapper.isInterface()) return null
|
||||
|
||||
var modifiers = Modifier(session)
|
||||
val valueParameters = mutableListOf<ValueParameter>()
|
||||
@@ -353,21 +339,13 @@ class Converter(
|
||||
}
|
||||
}
|
||||
|
||||
val defaultVisibility =
|
||||
if (classKind == ClassKind.OBJECT ||
|
||||
classModifiers.getModality() == Modality.SEALED ||
|
||||
classModifiers.isEnum()
|
||||
)
|
||||
Visibilities.PRIVATE
|
||||
else
|
||||
Visibilities.UNKNOWN
|
||||
|
||||
val defaultVisibility = classWrapper.defaultConstructorVisibility()
|
||||
val firDelegatedCall = FirDelegatedConstructorCallImpl(
|
||||
session,
|
||||
null,
|
||||
delegatedSuperTypeRef,
|
||||
classWrapper.delegatedSuperTypeRef,
|
||||
isThis = false
|
||||
).extractArgumentsFrom(superTypeCallEntry, stubMode)
|
||||
).extractArgumentsFrom(classWrapper.superTypeCallEntry, stubMode)
|
||||
|
||||
return FirPrimaryConstructorImpl(
|
||||
session,
|
||||
@@ -376,11 +354,11 @@ class Converter(
|
||||
if (primaryConstructor != null) modifiers.getVisibility() else defaultVisibility,
|
||||
modifiers.hasExpect(),
|
||||
modifiers.hasActual(),
|
||||
delegatedSelfTypeRef,
|
||||
classWrapper.delegatedSelfTypeRef,
|
||||
firDelegatedCall
|
||||
).apply {
|
||||
annotations += modifiers.annotations
|
||||
//this.typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
|
||||
this.typeParameters += ConverterUtil.typeParametersFromSelfType(classWrapper.delegatedSelfTypeRef)
|
||||
this.valueParameters += valueParameters.map { it.firValueParameter }
|
||||
}
|
||||
}
|
||||
@@ -411,14 +389,9 @@ class Converter(
|
||||
MODIFIER_LIST -> modifiers = convertModifiers(it)
|
||||
VAL_KEYWORD -> isVal = true
|
||||
VAR_KEYWORD -> isVar = true
|
||||
IDENTIFIER -> identifier = it.toString()
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
TYPE_REFERENCE -> firType = convertType(it)
|
||||
DOT_QUALIFIED_EXPRESSION,
|
||||
REFERENCE_EXPRESSION,
|
||||
is KtNodeType,
|
||||
is KtConstantExpressionElementType,
|
||||
is KtDotQualifiedExpressionElementType,
|
||||
is KtStringTemplateExpressionElementType -> firExpression = visitExpression(it)
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,6 +416,7 @@ class Converter(
|
||||
* SUPER_TYPE_CALL_ENTRY - constructorInvocation
|
||||
* DELEGATED_SUPER_TYPE_ENTRY - explicitDelegation
|
||||
*/
|
||||
//TODO make wrapper for result?
|
||||
private fun convertDelegationSpecifiers(delegationSpecifiers: LighterASTNode): Triple<FirTypeRef?, List<FirTypeRef>, List<FirExpression>> {
|
||||
val superTypeRefs = mutableListOf<FirTypeRef>()
|
||||
val superTypeCallEntry = mutableListOf<FirExpression>()
|
||||
@@ -489,39 +463,36 @@ class Converter(
|
||||
*/
|
||||
private fun convertExplicitDelegation(explicitDelegation: LighterASTNode): FirDelegatedTypeRef {
|
||||
lateinit var firTypeRef: FirTypeRef
|
||||
var expression: FirExpression? = null
|
||||
var firExpression: FirExpression? = null
|
||||
explicitDelegation.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
TYPE_REFERENCE -> firTypeRef = convertType(it)
|
||||
DOT_QUALIFIED_EXPRESSION,
|
||||
REFERENCE_EXPRESSION,
|
||||
is KtNodeType,
|
||||
is KtConstantExpressionElementType,
|
||||
is KtDotQualifiedExpressionElementType,
|
||||
is KtStringTemplateExpressionElementType -> expression = visitExpression(it) // TODO implement
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
return FirDelegatedTypeRefImpl(
|
||||
session,
|
||||
firTypeRef,
|
||||
expression
|
||||
firExpression
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseClassBody
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseEnumClassBody
|
||||
*/
|
||||
private fun convertClassBody(classBody: LighterASTNode): List<FirDeclaration> {
|
||||
private fun convertClassBody(classBody: LighterASTNode, classWrapper: ClassWrapper): List<FirDeclaration> {
|
||||
return classBody.forEachChildrenReturnList { node, container ->
|
||||
when (node.tokenType) {
|
||||
ENUM_ENTRY -> container += convertEnumEntry(node, classWrapper)
|
||||
CLASS -> container += convertClass(node)
|
||||
FUN -> container += convertFunctionDeclaration(node)
|
||||
PROPERTY -> container += convertPropertyDeclaration(node)
|
||||
TYPEALIAS -> container += convertTypeAlias(node)
|
||||
OBJECT_DECLARATION -> container += convertClass(node)
|
||||
CLASS_INITIALIZER -> container += convertAnonymousInitializer(node) //anonymousInitializer
|
||||
SECONDARY_CONSTRUCTOR -> container += convertSecondaryConstructor(node)
|
||||
SECONDARY_CONSTRUCTOR -> container += convertSecondaryConstructor(node, classWrapper)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -530,39 +501,33 @@ class Converter(
|
||||
* @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.convert(
|
||||
* KtConstructorDelegationCall, FirTypeRef, Boolean)
|
||||
*/
|
||||
private fun convertConstructorDelegationCall(constructorDelegationCall: LighterASTNode?): FirDelegatedConstructorCallImpl {
|
||||
var isThis: Boolean = false
|
||||
var isSuper: Boolean = false
|
||||
constructorDelegationCall?.forEachChildren {
|
||||
private fun convertConstructorDelegationCall(
|
||||
constructorDelegationCall: LighterASTNode,
|
||||
classWrapper: ClassWrapper
|
||||
): FirDelegatedConstructorCallImpl {
|
||||
var thisKeywordPresent = false
|
||||
constructorDelegationCall.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
CONSTRUCTOR_DELEGATION_REFERENCE -> {
|
||||
if (it.toString() == "this") isThis = true
|
||||
if (it.toString() == "super") isSuper = true
|
||||
}
|
||||
CONSTRUCTOR_DELEGATION_REFERENCE -> if (it.getAsString() == "this") thisKeywordPresent = true
|
||||
VALUE_ARGUMENT_LIST -> "" //TODO implement
|
||||
}
|
||||
}
|
||||
|
||||
val isImplicit = constructorDelegationCall.getAsString().isEmpty()
|
||||
val isThis = (isImplicit && classWrapper.hasPrimaryConstructor) || thisKeywordPresent
|
||||
val delegatedType = when {
|
||||
isThis -> classWrapper.delegatedSelfTypeRef
|
||||
else -> classWrapper.delegatedSuperTypeRef
|
||||
}
|
||||
|
||||
return FirDelegatedConstructorCallImpl(
|
||||
session,
|
||||
null,
|
||||
implicitType,
|
||||
delegatedType,
|
||||
isThis
|
||||
).extractArgumentsFrom(listOf(), stubMode) //TODO implement
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse only enum entries, without members
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseEnumClassBody
|
||||
*/
|
||||
private fun convertEnumClassBody(classBody: LighterASTNode): List<FirEnumEntryImpl> {
|
||||
return classBody.forEachChildrenReturnList { node, container ->
|
||||
when (node.tokenType) {
|
||||
ENUM_ENTRY -> container += convertEnumEntry(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseMemberDeclarationRest
|
||||
* at INIT keyword
|
||||
@@ -585,7 +550,7 @@ class Converter(
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseSecondaryConstructor
|
||||
*/
|
||||
private fun convertSecondaryConstructor(secondaryConstructor: LighterASTNode): FirConstructor {
|
||||
private fun convertSecondaryConstructor(secondaryConstructor: LighterASTNode, classWrapper: ClassWrapper): FirConstructor {
|
||||
var modifiers = Modifier(session)
|
||||
val firValueParameters = mutableListOf<FirValueParameter>()
|
||||
var constructorDelegationCall: FirDelegatedConstructorCall? = null
|
||||
@@ -595,7 +560,7 @@ class Converter(
|
||||
when (it.tokenType) {
|
||||
MODIFIER_LIST -> modifiers = convertModifiers(it)
|
||||
VALUE_PARAMETER_LIST -> firValueParameters += convertFunctionValueParameters(it)
|
||||
CONSTRUCTOR_DELEGATION_CALL -> constructorDelegationCall = convertConstructorDelegationCall(it)
|
||||
CONSTRUCTOR_DELEGATION_CALL -> constructorDelegationCall = convertConstructorDelegationCall(it, classWrapper)
|
||||
BLOCK -> firBlock = visitBlock(it)
|
||||
}
|
||||
}
|
||||
@@ -607,11 +572,13 @@ class Converter(
|
||||
modifiers.getVisibility(),
|
||||
modifiers.hasExpect(),
|
||||
modifiers.hasActual(),
|
||||
implicitType, //must be initialized with "delegatedSelfTypeRef" outside of this method
|
||||
classWrapper.delegatedSelfTypeRef,
|
||||
constructorDelegationCall
|
||||
)
|
||||
|
||||
FunctionUtil.firFunctions += firConstructor
|
||||
firConstructor.annotations += modifiers.annotations
|
||||
firConstructor.typeParameters += ConverterUtil.typeParametersFromSelfType(classWrapper.delegatedSelfTypeRef)
|
||||
firConstructor.valueParameters += firValueParameters
|
||||
firConstructor.body = visitFunctionBody(firBlock, null)
|
||||
FunctionUtil.firFunctions.removeLast()
|
||||
@@ -621,31 +588,47 @@ class Converter(
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseEnumEntry
|
||||
*/
|
||||
private fun convertEnumEntry(enumEntry: LighterASTNode): FirEnumEntryImpl {
|
||||
private fun convertEnumEntry(enumEntry: LighterASTNode, classWrapper: ClassWrapper): FirEnumEntryImpl {
|
||||
var modifiers = Modifier(session)
|
||||
lateinit var identifier: String
|
||||
var initializerList = null
|
||||
var hasInitializerList = false
|
||||
val enumSuperTypeCallEntry = mutableListOf<FirExpression>() //TODO get from INITIALIZER_LIST
|
||||
val firDeclarations = mutableListOf<FirDeclaration>()
|
||||
enumEntry.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
MODIFIER_LIST -> modifiers = convertModifiers(it)
|
||||
IDENTIFIER -> identifier = it.toString()
|
||||
INITIALIZER_LIST -> "" //TODO implement
|
||||
CLASS_BODY -> firDeclarations += convertClassBody(it)
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
INITIALIZER_LIST -> hasInitializerList = true //TODO implement
|
||||
/*enumSuperTypeCallEntry += initializerList.valueParameters.map { firValueParameter ->
|
||||
firValueParameter.toFirExpression(stubMode)
|
||||
}*/
|
||||
CLASS_BODY -> firDeclarations += convertClassBody(it, classWrapper)
|
||||
}
|
||||
}
|
||||
|
||||
val enumEntryName = identifier.nameAsSafeName()
|
||||
return ClassNameUtil.withChildClassName(enumEntryName) {
|
||||
return@withChildClassName FirEnumEntryImpl(
|
||||
val firEnumEntry = FirEnumEntryImpl(
|
||||
session,
|
||||
null,
|
||||
FirClassSymbol(ClassNameUtil.currentClassId),
|
||||
enumEntryName
|
||||
).apply {
|
||||
annotations += modifiers.annotations
|
||||
declarations += firDeclarations
|
||||
}
|
||||
)
|
||||
firEnumEntry.annotations += modifiers.annotations
|
||||
|
||||
val enumClassWrapper = ClassWrapper(
|
||||
session, enumEntryName, modifiers, ClassKind.ENUM_ENTRY,
|
||||
hasPrimaryConstructor = true, hasSecondaryConstructor = false,
|
||||
delegatedSelfTypeRef = toDelegatedSelfType(firEnumEntry),
|
||||
delegatedSuperTypeRef = if (hasInitializerList) classWrapper.getFirUserTypeFromClassName() else implicitAnyType,
|
||||
superTypeCallEntry = enumSuperTypeCallEntry
|
||||
)
|
||||
firEnumEntry.superTypeRefs += enumClassWrapper.delegatedSuperTypeRef
|
||||
val firEnumPrimaryConstructor = convertPrimaryConstructor(null, enumClassWrapper)!!
|
||||
firEnumEntry.addDeclaration(firEnumPrimaryConstructor)
|
||||
firDeclarations.forEach { firEnumEntry.addDeclaration(it) }
|
||||
|
||||
return@withChildClassName firEnumEntry
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,19 +649,14 @@ class Converter(
|
||||
functionDeclaration.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
MODIFIER_LIST -> modifiers = convertModifiers(it)
|
||||
IDENTIFIER -> identifier = it.toString()
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
TYPE_PARAMETER_LIST -> firTypeParameters += convertTypeParameters(it)
|
||||
VALUE_PARAMETER_LIST -> valueParametersList += convertFunctionValueParameters(it)
|
||||
COLON -> isReturnType = true
|
||||
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 -> firExpression = visitExpression(it) //TODO implement
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -744,14 +722,9 @@ class Converter(
|
||||
functionValueParameter.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
MODIFIER_LIST -> modifiers = convertModifiers(it)
|
||||
IDENTIFIER -> identifier = it.toString()
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
TYPE_REFERENCE -> firType = convertType(it)
|
||||
DOT_QUALIFIED_EXPRESSION,
|
||||
REFERENCE_EXPRESSION,
|
||||
is KtNodeType,
|
||||
is KtConstantExpressionElementType,
|
||||
is KtDotQualifiedExpressionElementType,
|
||||
is KtStringTemplateExpressionElementType -> firExpression = visitExpression(it) //TODO implement
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,7 +748,7 @@ class Converter(
|
||||
var firType: FirTypeRef? = null
|
||||
parameter.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
IDENTIFIER -> identifier = it.toString()
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
TYPE_REFERENCE -> firType = convertType(it)
|
||||
//TODO expression?
|
||||
}
|
||||
@@ -863,24 +836,18 @@ class Converter(
|
||||
property.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
MODIFIER_LIST -> modifiers = convertModifiers(it)
|
||||
IDENTIFIER -> identifier = it.toString()
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
TYPE_PARAMETER_LIST -> firTypeParameters += convertTypeParameters(it)
|
||||
COLON -> isReturnType = true
|
||||
TYPE_REFERENCE -> if (isReturnType) returnType = convertType(it) else receiverType = convertType(it)
|
||||
TYPE_CONSTRAINT_LIST -> typeConstraints += convertTypeConstraints(it)
|
||||
PROPERTY_DELEGATE -> isDelegate = true
|
||||
VAR_KEYWORD -> isVar = true
|
||||
PROPERTY_ACCESSOR ->
|
||||
if (it.toString().contains("get")) //TODO make it better
|
||||
getter = convertGetter(it, returnType)
|
||||
else
|
||||
setter = convertSetter(it, returnType)
|
||||
DOT_QUALIFIED_EXPRESSION,
|
||||
REFERENCE_EXPRESSION,
|
||||
is KtNodeType,
|
||||
is KtConstantExpressionElementType,
|
||||
is KtDotQualifiedExpressionElementType,
|
||||
is KtStringTemplateExpressionElementType -> firExpression = visitExpression(it) //TODO implement
|
||||
PROPERTY_ACCESSOR -> {
|
||||
val propertyAccessor = convertGetterOrSetter(it, returnType)
|
||||
if (propertyAccessor.isGetter) getter = propertyAccessor else setter = propertyAccessor
|
||||
}
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -918,7 +885,7 @@ class Converter(
|
||||
isVar,
|
||||
firExpression,
|
||||
getter ?: FirDefaultPropertyGetter(session, null, returnType, modifiers.getVisibility()),
|
||||
setter ?: FirDefaultPropertySetter(session, null, returnType, modifiers.getVisibility()),
|
||||
if (isVar) setter ?: FirDefaultPropertySetter(session, null, returnType, modifiers.getVisibility()) else null,
|
||||
if (isDelegate) {
|
||||
FirExpressionStub(session, null)
|
||||
//TODO("not implemented")
|
||||
@@ -935,86 +902,42 @@ class Converter(
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parsePropertyGetterOrSetter
|
||||
*/
|
||||
private fun convertGetter(getter: LighterASTNode, propertyTypeRef: FirTypeRef): FirPropertyAccessor {
|
||||
private fun convertGetterOrSetter(getterOrSetter: LighterASTNode, propertyTypeRef: FirTypeRef): FirPropertyAccessor {
|
||||
var modifiers = Modifier(session)
|
||||
|
||||
var isGetter = true
|
||||
var returnType: FirTypeRef? = null
|
||||
var firValueParameters: FirValueParameter = FirDefaultSetterValueParameter(session, null, propertyTypeRef)
|
||||
var firBlock: FirBlock? = null
|
||||
var firExpression: FirExpression? = null
|
||||
getter.forEachChildren {
|
||||
getterOrSetter.forEachChildren {
|
||||
if (it.getAsString() == "set") isGetter = false
|
||||
when (it.tokenType) {
|
||||
SET_KEYWORD -> isGetter = false
|
||||
MODIFIER_LIST -> modifiers = convertModifiers(it)
|
||||
TYPE_REFERENCE -> returnType = convertType(it)
|
||||
VALUE_PARAMETER_LIST -> {
|
||||
//isGetter = false
|
||||
firValueParameters = convertSetterParameter(it, propertyTypeRef)
|
||||
}
|
||||
BLOCK -> firBlock = visitBlock(it)
|
||||
DOT_QUALIFIED_EXPRESSION,
|
||||
REFERENCE_EXPRESSION,
|
||||
is KtNodeType,
|
||||
is KtConstantExpressionElementType,
|
||||
is KtDotQualifiedExpressionElementType,
|
||||
is KtStringTemplateExpressionElementType -> firExpression = visitExpression(it) //TODO implement
|
||||
else -> if (it.isExpression()) firExpression = visitExpression(it)
|
||||
}
|
||||
}
|
||||
|
||||
val firAccessor = FirPropertyAccessorImpl(
|
||||
session,
|
||||
null,
|
||||
true,
|
||||
isGetter,
|
||||
modifiers.getVisibility(),
|
||||
returnType ?: propertyTypeRef
|
||||
returnType ?: if (isGetter) propertyTypeRef else implicitUnitType
|
||||
)
|
||||
FunctionUtil.firFunctions += firAccessor
|
||||
firAccessor.annotations += modifiers.annotations
|
||||
|
||||
firAccessor.body = visitFunctionBody(firBlock, firExpression)
|
||||
FunctionUtil.firFunctions.removeLast()
|
||||
return firAccessor
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parsePropertyGetterOrSetter
|
||||
*/
|
||||
private fun convertSetter(setter: LighterASTNode, propertyTypeRef: FirTypeRef): FirPropertyAccessor {
|
||||
var modifiers = Modifier(session)
|
||||
|
||||
var returnType: FirTypeRef? = null
|
||||
val firValueParameters = mutableListOf<FirValueParameter>()
|
||||
var firBlock: FirBlock? = null
|
||||
var firExpression: FirExpression? = null
|
||||
setter.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
MODIFIER_LIST -> modifiers = convertModifiers(it)
|
||||
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 -> firExpression = visitExpression(it) //TODO implement
|
||||
}
|
||||
if (!isGetter) {
|
||||
firAccessor.valueParameters += firValueParameters
|
||||
}
|
||||
|
||||
val firAccessor = FirPropertyAccessorImpl(
|
||||
session,
|
||||
null,
|
||||
false,
|
||||
modifiers.getVisibility(),
|
||||
returnType ?: implicitUnitType
|
||||
)
|
||||
FunctionUtil.firFunctions += firAccessor
|
||||
firAccessor.annotations += modifiers.annotations
|
||||
|
||||
firValueParameters.ifEmpty {
|
||||
firValueParameters +=
|
||||
FirDefaultSetterValueParameter(
|
||||
session,
|
||||
null,
|
||||
propertyTypeRef
|
||||
)
|
||||
}
|
||||
firAccessor.valueParameters += firValueParameters
|
||||
|
||||
firAccessor.body = visitFunctionBody(firBlock, firExpression)
|
||||
FunctionUtil.firFunctions.removeLast()
|
||||
return firAccessor
|
||||
@@ -1031,7 +954,7 @@ class Converter(
|
||||
typeAlias.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
MODIFIER_LIST -> modifiers = convertModifiers(it)
|
||||
IDENTIFIER -> identifier = it.toString()
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
TYPE_PARAMETER_LIST -> firTypeParameters += convertTypeParameters(it)
|
||||
TYPE_REFERENCE -> firType = convertType(it)
|
||||
}
|
||||
@@ -1076,7 +999,7 @@ class Converter(
|
||||
typeParameter.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
MODIFIER_LIST -> typeParameterModifiers = convertTypeParameterModifiers(it)
|
||||
IDENTIFIER -> identifier = it.toString()
|
||||
IDENTIFIER -> identifier = it.getAsString()
|
||||
TYPE_REFERENCE -> firType = convertType(it)
|
||||
}
|
||||
}
|
||||
@@ -1104,7 +1027,7 @@ class Converter(
|
||||
when (it.tokenType) {
|
||||
ANNOTATION -> modifier.annotations += convertAnnotation(it)
|
||||
ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null)
|
||||
else -> modifier.addModifier(it)
|
||||
is KtModifierKeywordToken -> modifier.addModifier(it)
|
||||
}
|
||||
}
|
||||
return modifier
|
||||
@@ -1116,7 +1039,7 @@ class Converter(
|
||||
private fun convertType(type: LighterASTNode): FirTypeRef {
|
||||
var typeModifiers = TypeModifier(session) //TODO what with suspend?
|
||||
lateinit var firType: FirTypeRef
|
||||
type.forEachChildren { it ->
|
||||
type.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
TYPE_REFERENCE -> firType = convertType(it)
|
||||
MODIFIER_LIST -> typeModifiers = convertTypeModifiers(it)
|
||||
@@ -1139,7 +1062,7 @@ class Converter(
|
||||
when (it.tokenType) {
|
||||
ANNOTATION -> modifier.annotations += convertAnnotation(it)
|
||||
ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null)
|
||||
else -> modifier.addModifier(it)
|
||||
is KtModifierKeywordToken -> modifier.addModifier(it)
|
||||
}
|
||||
}
|
||||
return modifier
|
||||
@@ -1152,7 +1075,8 @@ class Converter(
|
||||
lateinit var firType: FirTypeRef
|
||||
nullableType.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
USER_TYPE -> firType = convertUserType(it, true).also { firUserType -> (firUserType as FirUserTypeRefImpl).qualifier.reverse() }
|
||||
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)
|
||||
@@ -1210,7 +1134,7 @@ class Converter(
|
||||
userType.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
USER_TYPE -> simpleFirUserType = convertUserType(it) //simple user type
|
||||
REFERENCE_EXPRESSION -> identifier = it.toString()
|
||||
REFERENCE_EXPRESSION -> identifier = it.getAsString()
|
||||
TYPE_ARGUMENT_LIST -> firTypeArguments += convertTypeArguments(it)
|
||||
}
|
||||
}
|
||||
@@ -1260,9 +1184,9 @@ class Converter(
|
||||
val annotations = mutableListOf<FirAnnotationCall>()
|
||||
typeConstraint.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
//TODO check annotations
|
||||
//TODO where save annotations
|
||||
ANNOTATION, ANNOTATION_ENTRY -> annotations += convertAnnotation(it)
|
||||
REFERENCE_EXPRESSION -> identifier = it.toString()
|
||||
REFERENCE_EXPRESSION -> identifier = it.getAsString()
|
||||
TYPE_REFERENCE -> firType = convertType(it)
|
||||
}
|
||||
}
|
||||
@@ -1327,7 +1251,7 @@ class Converter(
|
||||
when (it.tokenType) {
|
||||
ANNOTATION -> modifier.annotations += convertAnnotation(it)
|
||||
ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null)
|
||||
else -> modifier.addModifier(it)
|
||||
is KtModifierKeywordToken -> modifier.addModifier(it)
|
||||
}
|
||||
}
|
||||
return modifier
|
||||
@@ -1361,7 +1285,7 @@ class Converter(
|
||||
when (it.tokenType) {
|
||||
ANNOTATION -> modifier.annotations += convertAnnotation(it)
|
||||
ANNOTATION_ENTRY -> modifier.annotations += convertUnescapedAnnotation(it, null)
|
||||
else -> modifier.addModifier(it)
|
||||
is KtModifierKeywordToken -> modifier.addModifier(it)
|
||||
}
|
||||
}
|
||||
return modifier
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.lightTree
|
||||
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import org.jetbrains.kotlin.KtNodeType
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
@@ -28,9 +29,18 @@ 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.psi.stubs.elements.KtConstantExpressionElementType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStringTemplateExpressionElementType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
object ConverterUtil {
|
||||
private val expressionSet = listOf(
|
||||
KtNodeTypes.REFERENCE_EXPRESSION,
|
||||
KtNodeTypes.DOT_QUALIFIED_EXPRESSION,
|
||||
KtNodeTypes.LAMBDA_EXPRESSION,
|
||||
KtNodeTypes.FUN
|
||||
)
|
||||
|
||||
fun String?.nameAsSafeName(defaultName: String = ""): Name {
|
||||
return when {
|
||||
this != null -> Name.identifier(this.replace("`", ""))
|
||||
@@ -39,17 +49,21 @@ object ConverterUtil {
|
||||
}
|
||||
}
|
||||
|
||||
fun String.toFirUserType(session: FirSession): FirUserTypeRef {
|
||||
val qualifier = FirQualifierPartImpl(
|
||||
Name.identifier(this)
|
||||
)
|
||||
fun LighterASTNode.getAsStringWithoutBacktick(): String {
|
||||
return this.toString().replace("`", "")
|
||||
}
|
||||
|
||||
return FirUserTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
false
|
||||
).apply {
|
||||
this.qualifier.add(qualifier)
|
||||
fun LighterASTNode.getAsString(): String {
|
||||
return this.toString()
|
||||
}
|
||||
|
||||
fun LighterASTNode.isExpression(): Boolean {
|
||||
return when (this.tokenType) {
|
||||
is KtNodeType,
|
||||
is KtConstantExpressionElementType,
|
||||
is KtStringTemplateExpressionElementType,
|
||||
in expressionSet -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,19 +84,6 @@ object ConverterUtil {
|
||||
)
|
||||
}
|
||||
|
||||
fun LighterASTNode?.hasSecondaryConstructor(kidsArray: Array<LighterASTNode?>): Boolean {
|
||||
if (this == null) return false
|
||||
//TODO check if node isn't CLASS_BODY
|
||||
|
||||
for (kid in kidsArray) {
|
||||
if (kid == null) continue
|
||||
when (kid.tokenType) {
|
||||
KtNodeTypes.SECONDARY_CONSTRUCTOR -> return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun FirExpression.toReturn(labelName: String? = null): FirReturnExpression {
|
||||
return FirReturnExpressionImpl(
|
||||
session,
|
||||
@@ -145,66 +146,6 @@ object ConverterUtil {
|
||||
return this
|
||||
}
|
||||
|
||||
fun List<FirEnumEntryImpl>.fillEnumEntryConstructor(
|
||||
firPrimaryConstructor: FirConstructor,
|
||||
enumType: FirUserTypeRef,
|
||||
stubMode: Boolean
|
||||
) {
|
||||
this.forEach { firEnumEntry ->
|
||||
val enumDelegatedSelfTypeRef = toDelegatedSelfType(firEnumEntry)
|
||||
var enumDelegatedSuperTypeRef: FirTypeRef = FirImplicitAnyTypeRef(firEnumEntry.session, null)
|
||||
val enumSuperTypeCallEntry = mutableListOf<FirExpression>()
|
||||
|
||||
if (firPrimaryConstructor.valueParameters.isNotEmpty()) {
|
||||
enumDelegatedSuperTypeRef = enumType//enumDelegatedSelfTypeRef
|
||||
enumSuperTypeCallEntry += firPrimaryConstructor.valueParameters.map { firValueParameter ->
|
||||
firValueParameter.toFirExpression(stubMode)
|
||||
}
|
||||
}
|
||||
firEnumEntry.superTypeRefs += enumDelegatedSuperTypeRef
|
||||
|
||||
val firDelegatedConstructorCall = FirDelegatedConstructorCallImpl(
|
||||
firEnumEntry.session,
|
||||
null,
|
||||
enumDelegatedSuperTypeRef,
|
||||
false
|
||||
).extractArgumentsFrom(enumSuperTypeCallEntry, stubMode)
|
||||
|
||||
val firEnumPrimaryConstructor = FirPrimaryConstructorImpl(
|
||||
firEnumEntry.session,
|
||||
null,
|
||||
FirFunctionSymbol(ClassNameUtil.callableIdForClassConstructor()),
|
||||
Visibilities.UNKNOWN,
|
||||
false,
|
||||
false,
|
||||
enumDelegatedSelfTypeRef,
|
||||
firDelegatedConstructorCall
|
||||
)
|
||||
firEnumPrimaryConstructor.typeParameters += typeParametersFromSelfType(enumDelegatedSelfTypeRef)
|
||||
firEnumEntry.declarations.add(0, firEnumPrimaryConstructor)
|
||||
}
|
||||
}
|
||||
|
||||
fun List<FirDeclaration>.fillConstructors(
|
||||
hasPrimaryConstructor: Boolean,
|
||||
delegatedSelfTypeRef: FirTypeRef,
|
||||
delegatedSuperTypeRef: FirTypeRef
|
||||
) {
|
||||
this.forEach { constructor ->
|
||||
(constructor as FirConstructorImpl).typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
|
||||
|
||||
constructor.returnTypeRef = delegatedSelfTypeRef
|
||||
val constructorDelegationCall = constructor.delegatedConstructor as? FirDelegatedConstructorCallImpl
|
||||
val isThis =
|
||||
(constructorDelegationCall == null && hasPrimaryConstructor) || constructorDelegationCall?.isThis == true
|
||||
val delegatedType = when {
|
||||
isThis -> delegatedSelfTypeRef
|
||||
else -> delegatedSuperTypeRef
|
||||
}
|
||||
constructorDelegationCall?.constructedTypeRef = delegatedType
|
||||
}
|
||||
}
|
||||
|
||||
fun FirValueParameter.toFirExpression(stubMode: Boolean): FirExpression {
|
||||
return if (stubMode) FirExpressionStub(this.session, null)
|
||||
else TODO("not implemeted")
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
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.FirExpression
|
||||
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirQualifierPartImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirUserTypeRefImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class ClassWrapper(
|
||||
private val session: FirSession,
|
||||
private val className: Name,
|
||||
private val modifiers: Modifier,
|
||||
private val classKind: ClassKind,
|
||||
val hasPrimaryConstructor: Boolean,
|
||||
val hasSecondaryConstructor: Boolean,
|
||||
val delegatedSelfTypeRef: FirTypeRef,
|
||||
val delegatedSuperTypeRef: FirTypeRef,
|
||||
val superTypeCallEntry: MutableList<FirExpression>
|
||||
) {
|
||||
private fun isObject(): Boolean {
|
||||
return classKind == ClassKind.OBJECT
|
||||
}
|
||||
|
||||
private fun isSealed(): Boolean {
|
||||
return modifiers.getModality() == Modality.SEALED
|
||||
}
|
||||
|
||||
private fun isEnum(): Boolean {
|
||||
return modifiers.isEnum()
|
||||
}
|
||||
|
||||
fun isInterface(): Boolean {
|
||||
return classKind == ClassKind.INTERFACE
|
||||
}
|
||||
|
||||
fun defaultConstructorVisibility(): Visibility {
|
||||
return if (isObject() || isSealed() || isEnum())
|
||||
Visibilities.PRIVATE
|
||||
else
|
||||
Visibilities.UNKNOWN
|
||||
}
|
||||
|
||||
fun getFirUserTypeFromClassName(): FirUserTypeRef {
|
||||
val qualifier = FirQualifierPartImpl(
|
||||
className
|
||||
)
|
||||
|
||||
return FirUserTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
false
|
||||
).apply {
|
||||
this.qualifier.add(qualifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user