[FIR] Implement checkers for FIR parcelize plugin

There is one of checks left unimplemented (FirParcelizePropertyChecker.checkParcelableClassProperty)
  because it requires huge commonization of detecting which type can be
  serialized and which not, which is not prioritized job for now
This commit is contained in:
Dmitriy Novozhilov
2021-10-26 16:04:14 +03:00
committed by teamcityserver
parent eac9a9fc79
commit 8cdddbfd9d
37 changed files with 1089 additions and 62 deletions
@@ -420,24 +420,9 @@ object LightTreePositioningStrategies {
val TAILREC_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.TAILREC_KEYWORD))
val FIELD_KEYWORD: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
val fieldKeyword = tree.fieldKeyword(node)
if (fieldKeyword != null) {
return markElement(fieldKeyword, startOffset, endOffset, tree, node)
}
return DEFAULT.mark(node, startOffset, endOffset, tree)
}
val OBJECT_KEYWORD: LightTreePositioningStrategy = keywordStrategy { objectKeyword(it) }
override fun isValid(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
return tree.fieldKeyword(node) != null
}
}
val FIELD_KEYWORD: LightTreePositioningStrategy = keywordStrategy { fieldKeyword(it) }
val PROPERTY_DELEGATE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
@@ -1053,6 +1038,22 @@ object LightTreePositioningStrategies {
KtTokens.SEALED_KEYWORD
)
)
val DELEGATED_SUPERTYPE_BY_KEYWORD: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
val parent = tree.getParent(node)
if (parent == null || parent.tokenType != KtNodeTypes.DELEGATED_SUPER_TYPE_ENTRY) {
return super.mark(node, startOffset, endOffset, tree)
}
val byKeyword = parent.getChildren(tree).firstOrNull { it.tokenType == KtTokens.BY_KEYWORD } ?: node
return markElement(byKeyword, startOffset, endOffset, tree, node)
}
}
}
fun KtSourceElement.hasValOrVar(): Boolean =
@@ -1235,6 +1236,27 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.receiverTypeReference(
}
}
private fun keywordStrategy(
keywordExtractor: FlyweightCapableTreeStructure<LighterASTNode>.(LighterASTNode) -> LighterASTNode?
): LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
val fieldKeyword = tree.keywordExtractor(node)
if (fieldKeyword != null) {
return markElement(fieldKeyword, startOffset, endOffset, tree, node)
}
return LightTreePositioningStrategies.DEFAULT.mark(node, startOffset, endOffset, tree)
}
override fun isValid(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
return tree.keywordExtractor(node) != null
}
}
private fun FlyweightCapableTreeStructure<LighterASTNode>.defaultValue(node: LighterASTNode): LighterASTNode? {
val childrenRef = Ref<Array<LighterASTNode?>>()
getChildren(node, childrenRef)
@@ -295,6 +295,13 @@ object PositioningStrategies {
@JvmField
val TAILREC_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.TAILREC_KEYWORD)
@JvmField
val OBJECT_KEYWORD: PositioningStrategy<KtObjectDeclaration> = object : PositioningStrategy<KtObjectDeclaration>() {
override fun mark(element: KtObjectDeclaration): List<TextRange> {
return markElement(element.getObjectKeyword() ?: element)
}
}
@JvmField
val FIELD_KEYWORD: PositioningStrategy<KtBackingField> = object : DeclarationHeader<KtBackingField>() {
override fun mark(element: KtBackingField): List<TextRange> {
@@ -893,6 +900,13 @@ object PositioningStrategies {
val NON_FINAL_MODIFIER_OR_NAME: PositioningStrategy<KtModifierListOwner> =
ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.ABSTRACT_KEYWORD, KtTokens.OPEN_KEYWORD, KtTokens.SEALED_KEYWORD))
val DELEGATED_SUPERTYPE_BY_KEYWORD: PositioningStrategy<KtTypeReference> = object : PositioningStrategy<KtTypeReference>() {
override fun mark(element: KtTypeReference): List<TextRange> {
val parent = element.parent as? KtDelegatedSuperTypeEntry ?: return super.mark(element)
return markElement(parent.byKeywordNode.psi ?: element)
}
}
/**
* @param locateReferencedName whether to remove any nested parentheses while locating the reference element. This is useful for
* diagnostics on super and unresolved references. For example, with the following, only the part inside the parentheses should be
@@ -123,6 +123,11 @@ object SourceElementPositioningStrategies {
PositioningStrategies.DATA_MODIFIER
)
val OBJECT_KEYWORD = SourceElementPositioningStrategy(
LightTreePositioningStrategies.OBJECT_KEYWORD,
PositioningStrategies.OBJECT_KEYWORD
)
val OPERATOR = SourceElementPositioningStrategy(
LightTreePositioningStrategies.OPERATOR,
PositioningStrategies.OPERATOR
@@ -344,4 +349,9 @@ object SourceElementPositioningStrategies {
LightTreePositioningStrategies.DECLARATION_START_TO_NAME,
PositioningStrategies.DECLARATION_START_TO_NAME
)
val DELEGATED_SUPERTYPE_BY_KEYWORD = SourceElementPositioningStrategy(
LightTreePositioningStrategies.DELEGATED_SUPERTYPE_BY_KEYWORD,
PositioningStrategies.DELEGATED_SUPERTYPE_BY_KEYWORD
)
}