Skip to content

Instantly share code, notes, and snippets.

@suhininalex
Created September 25, 2017 10:24
Show Gist options
  • Save suhininalex/39dec6ba76911a1c03015f09cfeac944 to your computer and use it in GitHub Desktop.
Save suhininalex/39dec6ba76911a1c03015f09cfeac944 to your computer and use it in GitHub Desktop.
mapNotNull (infer error)
package com.suhininalex.clones.index
import com.intellij.psi.PsiElement
import com.suhininalex.clones.core.utils.isNoiseElement
import com.suhininalex.clones.core.utils.nextLeafElement
import com.suhininalex.clones.core.utils.prevLeafElement
fun PsiElement.nextElements(): Sequence<PsiElement> =
generateSequence (this) { it.nextLeafElement() }
fun PsiElement.prevElements(): Sequence<PsiElement> =
generateSequence (this) {it.prevLeafElement() }
fun extendRight(main: PsiElement, duplicates: List<PsiElement>): Pair<PsiElement, List<PsiElement>>? {
val fragment = main.nextElements().filterNot(::isNoiseElement).iterator()
val others = duplicates.map { it.nextElements().filterNot(::isNoiseElement).iterator() }
return extender(fragment, others) { it.node.elementType.index}!!
}
fun extendLeft(main: PsiElement, duplicates: List<PsiElement>): Pair<PsiElement, List<PsiElement>>? {
val fragment = main.prevElements().filterNot(::isNoiseElement).iterator()
val others = duplicates.map { it.prevElements().filterNot(::isNoiseElement).iterator() }
return extender(fragment, others) { it.node.elementType.index}!!
}
fun <T, R> extendAndSafeFirst(main: Iterator<T>, elements: List<Iterator<T>>, by: (T) -> R){
}
fun <T, R> extender(main: Iterator<T>, elements: List<Iterator<T>>, by: (T) -> R): Pair<T, List<T>>?{
require(elements.size >= 2)
var others = elements.filter { it.hasNext() }
var results: Pair<T, List<T>>? = null
while (main.hasNext() && others.isNotEmpty()) {
val main_value = main.next()
val values = others.map{ it.next() to it }.filter { (value, _) -> by(main_value) == by(value) }
others = values.map{(_, iterator) -> iterator}
if (values.isNotEmpty()){
results = main_value to values.map { it.first }
}
}
return results
}
fun <T> extend(main: Iterator<T>, elements: List<Iterator<T>>){
var others: List<ExtendedIterator<T>> = elements.map { ExtendedIterator(it) }
var results: List<T>? = null
while(main.hasNext()){
val value = main.next()
others.forEach { it.matchNext(value) }
others = others.filter { it.valid }
results = others.mapNotNull { it.lastSucceed }
}
}
class ExtendedIterator<T>(val iterator: Iterator<T>, val minMatches: Int = 0, val maxMismatches: Int = 0){
var lastSucceed: T? = null
var mismatches = 0
var matches = minMatches
var valid = true
fun matchNext(other: T){
val next = if (iterator.hasNext()) iterator.next() else null
return match(next, other)
}
private fun match(current: T?, other: T){
if (! valid) return
if (current == other){
matches += 1
mismatches = 0
if (matches>=minMatches) lastSucceed = current
} else {
mismatches += 1
matches = 0
if (mismatches > maxMismatches) valid = false
}
}
}
data class ExtendableClass<out T>(val main: Extendable<T>, val duplicates: List<Extendable<T>>)
interface Extendable<out T>{
fun goLeft(): Iterator<T>
fun goRight(): Iterator<T>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment