Write ClassWrapper class to transmit information to lower FIR nodes

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