mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[extract duplicates] clean up: restrict depth by terminal nodes instead of complicated comparator
GitOrigin-RevId: 86e02e7bc54c7f615ab3aeda84143bbd535c5c16
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d854449386
commit
8e9330e280
+11
-8
@@ -9,7 +9,7 @@ data class ChangedExpression(val pattern: PsiExpression, val candidate: PsiExpre
|
||||
|
||||
data class Duplicate(val pattern: List<PsiElement>, val candidate: List<PsiElement>, val changedExpressions: List<ChangedExpression>)
|
||||
|
||||
class JavaDuplicatesFinder(pattern: List<PsiElement>) {
|
||||
class JavaDuplicatesFinder(pattern: List<PsiElement>, private val terminalNodes: Set<PsiElement> = emptySet()) {
|
||||
|
||||
companion object {
|
||||
fun textRangeOf(range: List<PsiElement>) = TextRange(range.first().textRange.startOffset, range.last().textRange.endOffset)
|
||||
@@ -17,6 +17,10 @@ class JavaDuplicatesFinder(pattern: List<PsiElement>) {
|
||||
|
||||
private val pattern: List<PsiElement> = pattern.filterNot(::isNoise)
|
||||
|
||||
fun withTerminalNodes(terminalNodes: Set<PsiElement>): JavaDuplicatesFinder {
|
||||
return JavaDuplicatesFinder(pattern, this.terminalNodes + terminalNodes)
|
||||
}
|
||||
|
||||
fun findDuplicates(scope: PsiElement): List<Duplicate> {
|
||||
val ignoredElements = pattern.toSet()
|
||||
val duplicates = mutableListOf<Duplicate>()
|
||||
@@ -73,11 +77,9 @@ class JavaDuplicatesFinder(pattern: List<PsiElement>) {
|
||||
?.copy(pattern = listOf(pattern), candidate = listOf(candidate))
|
||||
}
|
||||
|
||||
fun createDuplicate(pattern: List<PsiElement>,
|
||||
candidate: List<PsiElement>,
|
||||
equivalenceComparator: (PsiElement, PsiElement) -> Boolean = ::isEquivalent): Duplicate? {
|
||||
fun createDuplicate(pattern: List<PsiElement>, candidate: List<PsiElement>): Duplicate? {
|
||||
val changedExpressions = ArrayList<ChangedExpression>()
|
||||
if (!traverseAndCollectChanges(pattern, candidate, changedExpressions, equivalenceComparator)) return null
|
||||
if (!traverseAndCollectChanges(pattern, candidate, changedExpressions)) return null
|
||||
return removeInternalReferences(Duplicate(pattern, candidate, changedExpressions))
|
||||
}
|
||||
|
||||
@@ -99,11 +101,12 @@ class JavaDuplicatesFinder(pattern: List<PsiElement>) {
|
||||
|
||||
fun traverseAndCollectChanges(pattern: List<PsiElement>,
|
||||
candidate: List<PsiElement>,
|
||||
changedExpressions: MutableList<ChangedExpression>,
|
||||
equivalenceComparator: (PsiElement, PsiElement) -> Boolean): Boolean {
|
||||
changedExpressions: MutableList<ChangedExpression>): Boolean {
|
||||
if (candidate.size != pattern.size) return false
|
||||
val notEqualElements = pattern.zip(candidate).filterNot { (pattern, candidate) ->
|
||||
equivalenceComparator(pattern, candidate) && traverseAndCollectChanges(childrenOf(pattern), childrenOf(candidate), changedExpressions, equivalenceComparator)
|
||||
pattern !in terminalNodes &&
|
||||
isEquivalent(pattern, candidate) &&
|
||||
traverseAndCollectChanges(childrenOf(pattern), childrenOf(candidate), changedExpressions)
|
||||
}
|
||||
if (notEqualElements.any { (pattern, candidate) -> ! canBeReplaced(pattern, candidate) }) return false
|
||||
changedExpressions += notEqualElements.map { (pattern, candidate) -> ChangedExpression(pattern as PsiExpression, candidate as PsiExpression) }
|
||||
|
||||
+5
-4
@@ -74,10 +74,11 @@ class DuplicatesMethodExtractor: InplaceExtractMethodProvider {
|
||||
//TODO check same data output
|
||||
//TODO check same flow output (+ same return values)
|
||||
|
||||
val terminalExpressions: Set<PsiExpression> = options.inputParameters.flatMap { parameter -> parameter.references }.toSet()
|
||||
val changes = duplicates.flatMap { it.changedExpressions.map(ChangedExpression::pattern) }.toSet() + terminalExpressions
|
||||
fun isEquivalent(pattern: PsiElement, candidate: PsiElement) = pattern !in changes && finder.isEquivalent(pattern, candidate)
|
||||
duplicates = duplicates.mapNotNull { finder.createDuplicate(it.pattern, it.candidate, ::isEquivalent) }
|
||||
val parameterExpressions = options.inputParameters.flatMap { parameter -> parameter.references }
|
||||
val changedExpressions = duplicates.flatMap { it.changedExpressions.map(ChangedExpression::pattern) }
|
||||
val duplicatesFinder = finder.withTerminalNodes((parameterExpressions + changedExpressions).toSet())
|
||||
|
||||
duplicates = duplicates.mapNotNull { duplicatesFinder.createDuplicate(it.pattern, it.candidate) }
|
||||
|
||||
val updatedParameters: List<InputParameter> = findNewParameters(options.inputParameters, duplicates)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user