Created
September 25, 2017 10:24
-
-
Save suhininalex/39dec6ba76911a1c03015f09cfeac944 to your computer and use it in GitHub Desktop.
mapNotNull (infer error)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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