Analysis API: add isSubclassOf tests
This commit is contained in:
+50
-14
@@ -41,17 +41,22 @@ internal class ExpressionMarkersSourceFilePreprocessor(testServices: TestService
|
||||
}
|
||||
|
||||
private fun processCaretExpression(file: TestFile, content: String): String {
|
||||
val startCaretPosition = content.indexOfOrNull(TAGS.CARET) ?: return content
|
||||
|
||||
testServices.expressionMarkerProvider.addCaret(file, startCaretPosition)
|
||||
return content
|
||||
.replace(TAGS.CARET, "")
|
||||
var result = content
|
||||
var match = TAGS.CARET_REGEXP.find(result)
|
||||
while (match != null) {
|
||||
val startCaretPosition = match.range.first
|
||||
val tag = match.groups[2]?.value
|
||||
testServices.expressionMarkerProvider.addCaret(file, tag, startCaretPosition)
|
||||
result = result.removeRange(match.range)
|
||||
match = TAGS.CARET_REGEXP.find(result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
object TAGS {
|
||||
const val OPENING_EXPRESSION_TAG = "<expr>"
|
||||
const val CLOSING_EXPRESSION_TAG = "</expr>"
|
||||
const val CARET = "<caret>"
|
||||
val CARET_REGEXP = "<caret(_(\\w+))?>".toRegex()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,25 +64,29 @@ class ExpressionMarkerProvider : TestService {
|
||||
private val selected = mutableMapOf<String, TextRange>()
|
||||
|
||||
@PrivateForInline
|
||||
val atCaret = mutableMapOf<String, Int>()
|
||||
val carets = CaretProvider()
|
||||
|
||||
fun addSelectedExpression(file: TestFile, range: TextRange) {
|
||||
selected[file.relativePath] = range
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
fun addCaret(file: TestFile, caret: Int) {
|
||||
atCaret[file.relativePath] = caret
|
||||
fun addCaret(file: TestFile, caretTag: String?, caretOffset: Int) {
|
||||
carets.addCaret(file.name, caretTag, caretOffset)
|
||||
}
|
||||
|
||||
@OptIn(PrivateForInline::class)
|
||||
fun getCaretPosition(file: KtFile): Int {
|
||||
return atCaret[file.name]
|
||||
?: error("No caret found in file")
|
||||
fun getCaretPosition(file: KtFile, caretTag: String? = null): Int {
|
||||
return carets.getCaretOffset(file.name, caretTag)
|
||||
?: run {
|
||||
val caretName = "caret${caretTag?.let { "_$it" }.orEmpty()}"
|
||||
error("No <$caretName> found in file")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline fun <reified P : KtElement> getElementOfTypAtCaret(file: KtFile): P {
|
||||
val offset = getCaretPosition(file)
|
||||
inline fun <reified P : KtElement> getElementOfTypAtCaret(file: KtFile, caretName: String? = null): P {
|
||||
val offset = getCaretPosition(file, caretName)
|
||||
return file.findElementAt(offset)
|
||||
?.parentOfType<P>()
|
||||
?: error("No expression found at caret")
|
||||
@@ -98,6 +107,33 @@ class ExpressionMarkerProvider : TestService {
|
||||
.dropLastWhile { it is PsiWhiteSpace }
|
||||
}
|
||||
|
||||
@PrivateForInline
|
||||
class CaretProvider {
|
||||
private val caretToFile = mutableMapOf<String, CaretsInFile>()
|
||||
|
||||
fun getCaretOffset(filename: String, caretTag: String?): Int? {
|
||||
val cartsInFile = caretToFile[filename] ?: return null
|
||||
return cartsInFile.getCaretOffsetByTag(caretTag)
|
||||
}
|
||||
|
||||
fun addCaret(filename: String, caretTag: String?, caretOffset: Int) {
|
||||
val cartsInFile = caretToFile.getOrPut(filename) { CaretsInFile() }
|
||||
cartsInFile.addCaret(caretTag, caretOffset)
|
||||
}
|
||||
|
||||
private class CaretsInFile {
|
||||
private val carets = mutableMapOf<String, Int>()
|
||||
|
||||
fun getCaretOffsetByTag(tag: String?): Int? {
|
||||
return carets[tag.orEmpty()]
|
||||
}
|
||||
|
||||
fun addCaret(caretTag: String?, caretOffset: Int) {
|
||||
carets[caretTag.orEmpty()] = caretOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val TestServices.expressionMarkerProvider: ExpressionMarkerProvider by TestServices.testServiceAccessor()
|
||||
|
||||
fun String.indexOfOrNull(substring: String) =
|
||||
|
||||
Reference in New Issue
Block a user