diff --git a/README.md b/README.md index f7d44ec..6e1c56b 100644 --- a/README.md +++ b/README.md @@ -1,103 +1,11 @@ # 🐕 qq-tree **qq-tree** is a Kotlin library that can construct a tree structure. -- Just copy and paste 🟦 Single-File version [QTreeNode.kt](src-single/QTreeNode.kt) into your project. -- Or you can use 🟩 Split-File Jar version. See [Maven Dependency Section](#-split-file-jar-version-maven-dependency). -- Feel free to fork or copy to your own codebase. - -## Example - -### output -

- 001-num-unicode.png -002-num-ascii.png -

-

- 003-walk-tree.png -

-

- 004-string-tree.png -005-dir-tree.png -

- -### code - -Full Source [QTreeNodeExample.kt](src-example/QTreeNodeExample.kt) - -```kotlin -fun main() { - // First, you have to create the root node. - val root = QTreeNode(0) - - val node1 = root add 1 - val node2 = root add 2 - val node3 = node2 add 3 - val node4 = node2 add 4 - val node5 = node4 add 5 - val node6 = node4 add 6 - val node7 = node2 add 7 - - val unicodeTree = root.tree(color = QShColor.GREEN, style = QTreeStyle.UNICODE) - - println(unicodeTree) - - val asciiTree = root.tree(color = QShColor.BLUE, style = QTreeStyle.ASCII) - - println(asciiTree) - - println() - - val depthFirstResult = root.descendantsList(QSearchAlgo.DepthFirst).toString() - - println("DepthFirst : $depthFirstResult") // [0, 1, 2, 3, 4, 5, 6, 7] - val breadthFirstResult = root.descendantsList(QSearchAlgo.BreadthFirst).toString() - - println("BreadthFirst : $breadthFirstResult") // [0, 1, 2, 3, 4, 7, 5, 6] - - println() - - // node can store anything - val rootA = QTreeNode("A") - val nodeB = rootA add "B" - val nodeC = nodeB add "C" - val nodeD = nodeB add "D" - val nodeE = nodeD add "E" - val nodeF = nodeE add "F" - val nodeG = nodeC add "G" - - val textTree = rootA.tree(color = QShColor.CYAN, style = QTreeStyle.UNICODE) - - println(textTree) - - // You can implement QLazyNode for more complicated situations. - class QFileNode(override val value: Path) : QLazyTreeNode { - override fun hasChildNodesToFill(): Boolean { - return value.isDirectory() - } - - override fun fillChildNodes(): List = Files.walk(value, 1).filter { - it != value - }.map { - QFileNode(it) - }.toList() - - override fun toTreeNodeString(): String { - return value.name - } - } - - val rootDir = Paths.get("rsc-test/root-dir").toAbsolutePath() +- Just copy and paste 🟦 Single-File version [QTreeNode.kt](src-single/QTreeNode.kt) into your project.- Or you can use 🟩 Split-File Jar version. See [Maven Dependency Section](#-split-file-jar-version-maven-dependency). +- Feel free to fork or copy to your own codebase. - val fileTree = QFileNode(rootDir).fillTree(maxDepth = 2).tree() - println(fileTree) -} -``` - -Please see [QTreeNodeTest.kt](src-test-split/nyab/util/QTreeNodeTest.kt) for more code examples. -Single-File version [src-test-single/QTreeNodeTest.kt](src-test-single/QTreeNodeTest.kt) is a self-contained source code that includes a runnable main function. -You can easily copy and paste it into your codebase. ## 🟦 Single-File version Dependency @@ -126,7 +34,7 @@ repositories { } dependencies { - implementation 'com.github.nyabkun:qq-tree:v2023-05-22' + implementation 'com.github.nyabkun:qq-tree:v2023-05-28' } ``` @@ -138,7 +46,7 @@ repositories { } dependencies { - implementation("com.github.nyabkun:qq-tree:v2023-05-22") + implementation("com.github.nyabkun:qq-tree:v2023-05-28") } ``` @@ -157,16 +65,14 @@ dependencies { com.github.nyabkun qq-tree - v2023-05-22 + v2023-05-28 ``` ## How did I create this library -I created this library by developing a program within my own codebase that automatically resolves dependencies at the method or property level, extracts necessary code elements, and generates a compact, self-contained, single-file library. - -The program uses [PSI](https://plugins.jetbrains.com/docs/intellij/psi.html) to resolve dependencies for function calls and references to classes. - -Although my original repository is currently disorganized, I have been gradually extracting and publishing small libraries. I also plan to prepare the original repository for publication in the future +- I developed [qq-compact-lib](https://github.com/nyabkun/qq-compact-lib) that resolves dependencies and generates compact, self-contained libraries. +- It utilizes [PSI](https://plugins.jetbrains.com/docs/intellij/psi.html) to resolve function calls and class references. +- The original repository is currently being organized, and I'm gradually extracting and publishing smaller libraries. diff --git a/VERSION b/VERSION index 7ef8858..dbfca95 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ -v2023-05-22 -8a0b25a1ba01b5f4b9c4956d63687a5a55d231a8fa313cfac656fe3e116334433432dd1254fbf89cd8c881f93b13f2691ac4fb0ae661b01556a875dede926d0e \ No newline at end of file +v2023-05-28 +f5b4d712c22124fd15407d08997388b76e203043bd70d311e0d99743b371686862e5dc3710e95643d6996905b36afa739d1a85608de21f0974de692eb1475d3b \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 5586dfd..218388c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ plugins { group = "com.nyabkun.qol" -version = "v2023-05-22" +version = "v2023-05-28" repositories { mavenCentral() @@ -45,38 +45,37 @@ java { sourceSets.main { - java.srcDirs("src-split") + java.srcDirs("src-split") - resources.srcDirs("rsc") -} - -sourceSets.test { - java.srcDirs("src-test-split") - - resources.srcDirs("rsc-test") -} - -sourceSets.register("example") { - java.srcDirs("src-example") - - resources.srcDirs("rsc") - - val jarFile = "$buildDir/libs/$qMavenArtifactId-$version.jar" - compileClasspath += files(jarFile) - runtimeClasspath += files(jarFile) -} - -tasks.getByName("compileExampleKotlin").dependsOn("jar") - -val exampleImplementation: Configuration by configurations.getting { - extendsFrom(configurations.implementation.get()) -} + resources.srcDirs("rsc") + } -val exampleRuntimeOnly: Configuration by configurations.getting { - extendsFrom(configurations.runtimeOnly.get()) -} + sourceSets.test { + java.srcDirs("src-test-split") -sourceSets.register("single") { + resources.srcDirs("rsc-test") + } + + sourceSets.register("example") { + java.srcDirs("src-example") + val jarFile = "$buildDir/libs/$qMavenArtifactId-$version.jar" + compileClasspath += files(jarFile) + runtimeClasspath += files(jarFile) + + resources.srcDirs("rsc") + } + + tasks.getByName("compileExampleKotlin").dependsOn("jar") + + val exampleImplementation: Configuration by configurations.getting { + extendsFrom(configurations.implementation.get()) + } + + val exampleRuntimeOnly: Configuration by configurations.getting { + extendsFrom(configurations.runtimeOnly.get()) + } + + sourceSets.register("single") { java.srcDirs("src-single") } @@ -112,13 +111,13 @@ tasks { enabled = true archiveBaseName.set(qMavenArtifactId) - + from(sourceSets.main.get().output) - + manifest { attributes( - "Implementation-Title" to qMavenArtifactId, - "Implementation-Version" to project.version + "Implementation-Title" to qMavenArtifactId, + "Implementation-Version" to project.version ) } } @@ -128,7 +127,7 @@ tasks { archiveClassifier.set("sources") from(sourceSets.main.get().allSource) } - + artifacts { archives(qSrcJar) archives(jar) diff --git a/src-single/QTreeNode.kt b/src-single/QTreeNode.kt index af04425..fa2073a 100644 --- a/src-single/QTreeNode.kt +++ b/src-single/QTreeNode.kt @@ -1184,8 +1184,8 @@ private enum class QFetchStart { // CallChain[size=9] = QFetchRuleA <-[Call]- QFetchRule.SINGLE_LINE <-[Call]- QSrcCut.QSrcCut() <-[C ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private abstract class QFetchRuleA( - override val numLinesBeforeTargetLine: Int = 10, - override val numLinesAfterTargetLine: Int = 10, + override val numLinesBeforeTargetLine: Int = 10, + override val numLinesAfterTargetLine: Int = 10, ) : QFetchRule // CallChain[size=8] = QFetchRule <-[Ref]- QSrcCut.QSrcCut() <-[Call]- qLogStackFrames() <-[Call]- Q ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] @@ -1197,31 +1197,31 @@ private interface QFetchRule { // CallChain[size=9] = QFetchRule.fetchStartCheck() <-[Propag]- QFetchRule.SINGLE_LINE <-[Call]- QSr ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart // CallChain[size=9] = QFetchRule.fetchEndCheck() <-[Propag]- QFetchRule.SINGLE_LINE <-[Call]- QSrcC ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd companion object { // CallChain[size=8] = QFetchRule.SINGLE_LINE <-[Call]- QSrcCut.QSrcCut() <-[Call]- qLogStackFrames( ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] val SINGLE_LINE = object : QFetchRuleA(0, 0) { override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart = if (currentLineNumber == targetLineNumber) { QFetchStart.START_FROM_THIS_LINE } else { @@ -1229,11 +1229,11 @@ private interface QFetchRule { } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber == targetLineNumber) { QFetchEnd.END_WITH_THIS_LINE } else { @@ -1244,27 +1244,27 @@ private interface QFetchRule { // CallChain[size=7] = QFetchRule.SMART_FETCH <-[Call]- qLogStackFrames() <-[Call]- QException.mySrc ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] val SMART_FETCH = object : QFetchRuleA(10, 10) { override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() val trimmed = line.trimStart() return if (arrayOf( - "\"\"\".", - "}", - ")", - ".", - ",", - "?", - "//", - "/*", - "*" - ).any { trimmed.startsWith(it) } + "\"\"\".", + "}", + ")", + ".", + ",", + "?", + "//", + "/*", + "*" + ).any { trimmed.startsWith(it) } ) { QFetchStart.FETCH_THIS_LINE_AND_GO_TO_PREVIOUS_LINE } else if (nIndentThis <= nIndentTarget) { @@ -1275,17 +1275,17 @@ private interface QFetchRule { } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber >= targetLineNumber) { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() if (currentLineNumber == targetLineNumber && line.trimStart() - .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 + .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 ) { // """ <<< targetLine // some text @@ -1315,8 +1315,8 @@ private interface QFetchRule { // CallChain[size=12] = LineNumberReader.qFetchLinesBetween() <-[Call]- LineNumberReader.qFetchTarge ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun LineNumberReader.qFetchLinesBetween( - lineNumberStartInclusive: Int, - lineNumberEndInclusive: Int, + lineNumberStartInclusive: Int, + lineNumberEndInclusive: Int, ): List { var fetching = false val lines = mutableListOf() @@ -1342,12 +1342,12 @@ private fun LineNumberReader.qFetchLinesBetween( // CallChain[size=12] = TargetSurroundingLines <-[Ref]- LineNumberReader.qFetchTargetSurroundingLine ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private class TargetSurroundingLines( - val targetLineNumber: Int, - val startLineNumber: Int, - val endLineNumber: Int, - val targetLine: String, - val linesBeforeTargetLine: List, - val linesAfterTargetLine: List, + val targetLineNumber: Int, + val startLineNumber: Int, + val endLineNumber: Int, + val targetLine: String, + val linesBeforeTargetLine: List, + val linesAfterTargetLine: List, ) { // CallChain[size=11] = TargetSurroundingLines.linesBetween() <-[Call]- LineNumberReader.qFetchLines ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] fun linesBetween(lineNumberStartInclusive: Int, lineNumberEndInclusive: Int): List { @@ -1366,9 +1366,9 @@ private class TargetSurroundingLines( // CallChain[size=11] = LineNumberReader.qFetchTargetSurroundingLines() <-[Call]- LineNumberReader.q ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun LineNumberReader.qFetchTargetSurroundingLines( - targetLineNumber: Int, - numLinesBeforeTargetLine: Int = 10, - numLinesAfterTargetLine: Int = 10, + targetLineNumber: Int, + numLinesBeforeTargetLine: Int = 10, + numLinesAfterTargetLine: Int = 10, ): TargetSurroundingLines { val start = max(1, targetLineNumber - numLinesBeforeTargetLine) val end = targetLineNumber + numLinesAfterTargetLine @@ -1376,27 +1376,27 @@ private fun LineNumberReader.qFetchTargetSurroundingLines( val lines = qFetchLinesBetween(start, end) return TargetSurroundingLines( - targetLineNumber = targetLineNumber, - startLineNumber = start, - endLineNumber = end, - targetLine = lines[targetLineNumber - start], - linesBeforeTargetLine = lines.subList(0, targetLineNumber - start), - linesAfterTargetLine = lines.subList(targetLineNumber - start + 1, lines.size) + targetLineNumber = targetLineNumber, + startLineNumber = start, + endLineNumber = end, + targetLine = lines[targetLineNumber - start], + linesBeforeTargetLine = lines.subList(0, targetLineNumber - start), + linesAfterTargetLine = lines.subList(targetLineNumber - start + 1, lines.size) ) } // CallChain[size=10] = LineNumberReader.qFetchLinesAround() <-[Call]- Path.qFetchLinesAround() <-[C ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun LineNumberReader.qFetchLinesAround( - file: Path, - targetLineNumber: Int, - targetLine: String, - fetchRule: QFetchRule = QFetchRule.SMART_FETCH, - lineSeparator: QLineSeparator = QLineSeparator.LF, + file: Path, + targetLineNumber: Int, + targetLine: String, + fetchRule: QFetchRule = QFetchRule.SMART_FETCH, + lineSeparator: QLineSeparator = QLineSeparator.LF, ): String { val surroundingLines = qFetchTargetSurroundingLines( - targetLineNumber, - fetchRule.numLinesBeforeTargetLine, - fetchRule.numLinesAfterTargetLine + targetLineNumber, + fetchRule.numLinesBeforeTargetLine, + fetchRule.numLinesAfterTargetLine ) val context: MutableSet = mutableSetOf() @@ -1415,11 +1415,11 @@ private fun LineNumberReader.qFetchLinesAround( val curLineNumber = targetLineNumber - i val check = fetchRule.fetchStartCheck( - line, - curLineNumber, - targetLine, - targetLineNumber, - context + line, + curLineNumber, + targetLine, + targetLineNumber, + context ) when (check) { @@ -1451,11 +1451,11 @@ private fun LineNumberReader.qFetchLinesAround( val curLineNumber = targetLineNumber + i val check = fetchRule.fetchEndCheck( - line, - curLineNumber, - targetLine, - targetLineNumber, - context + line, + curLineNumber, + targetLine, + targetLineNumber, + context ) when (check) { @@ -1492,19 +1492,19 @@ private fun LineNumberReader.qFetchLinesAround( // CallChain[size=10] = Path.qReader() <-[Call]- Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtF ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun Path.qReader( - charset: Charset = Charsets.UTF_8, - buffSize: Int = qBUFFER_SIZE, - opts: QFlag = QFlag.none(), + charset: Charset = Charsets.UTF_8, + buffSize: Int = qBUFFER_SIZE, + opts: QFlag = QFlag.none(), ): LineNumberReader { return LineNumberReader(reader(charset, *opts.toOptEnums()), buffSize) } // CallChain[size=9] = Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtFrame() <-[Call]- qMySrcLin ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun Path.qFetchLinesAround( - lineNumber: Int, - fetchRule: QFetchRule = QFetchRule.SMART_FETCH, - charset: Charset = Charsets.UTF_8, - lineSeparator: QLineSeparator = this.qLineSeparator(charset), + lineNumber: Int, + fetchRule: QFetchRule = QFetchRule.SMART_FETCH, + charset: Charset = Charsets.UTF_8, + lineSeparator: QLineSeparator = this.qLineSeparator(charset), ): String { val reader = qReader(charset) @@ -1526,8 +1526,8 @@ private fun Path.qFetchLinesAround( // CallChain[size=10] = Path.qLineAt() <-[Call]- Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtF ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun Path.qLineAt( - lineNumber: Int, - charset: Charset = Charsets.UTF_8, + lineNumber: Int, + charset: Charset = Charsets.UTF_8, ): String { bufferedReader(charset).use { reader -> var n = 0 @@ -1602,13 +1602,13 @@ private fun Path.qFind(nameMatcher: QM, type: QFType = QFType.File, maxDepth: In // CallChain[size=8] = Path.qListByMatch() <-[Call]- QMyPath.src_root <-[Call]- qLogStackFrames() <- ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun Path.qListByMatch( - nameMatch: QM, - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, + nameMatch: QM, + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, ): List { return qList( - type, maxDepth = maxDepth, followSymLink = followSymLink + type, maxDepth = maxDepth, followSymLink = followSymLink ) { it.name.qMatches(nameMatch) } @@ -1616,32 +1616,32 @@ private fun Path.qListByMatch( // CallChain[size=12] = Path.qList() <-[Call]- Path.qFind() <-[Call]- Collection.qFind() <-[Ca ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun Path.qList( - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, - sortWith: ((Path, Path) -> Int)? = Path::compareTo, - filter: (Path) -> Boolean = { true }, - // TODO https://stackoverflow.com/a/66996768/5570400 - // errorContinue: Boolean = true + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, + sortWith: ((Path, Path) -> Int)? = Path::compareTo, + filter: (Path) -> Boolean = { true }, + // TODO https://stackoverflow.com/a/66996768/5570400 + // errorContinue: Boolean = true ): List { return qSeq( - type = type, - maxDepth = maxDepth, - followSymLink = followSymLink, - sortWith = sortWith, - filter = filter + type = type, + maxDepth = maxDepth, + followSymLink = followSymLink, + sortWith = sortWith, + filter = filter ).toList() } // CallChain[size=13] = Path.qSeq() <-[Call]- Path.qList() <-[Call]- Path.qFind() <-[Call]- Collecti ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun Path.qSeq( - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, - sortWith: ((Path, Path) -> Int)? = Path::compareTo, - filter: (Path) -> Boolean = { true }, - // TODO https://stackoverflow.com/a/66996768/5570400 - // errorContinue: Boolean = true + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, + sortWith: ((Path, Path) -> Int)? = Path::compareTo, + filter: (Path) -> Boolean = { true }, + // TODO https://stackoverflow.com/a/66996768/5570400 + // errorContinue: Boolean = true ): Sequence { if (!this.isDirectory()) return emptySequence() diff --git a/src-split/nyab/util/QFile.kt b/src-split/nyab/util/QFile.kt index 3a09362..8d56bce 100644 --- a/src-split/nyab/util/QFile.kt +++ b/src-split/nyab/util/QFile.kt @@ -139,8 +139,8 @@ internal enum class QFetchStart { // CallChain[size=9] = QFetchRuleA <-[Call]- QFetchRule.SINGLE_LINE <-[Call]- QSrcCut.QSrcCut() <-[C ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] internal abstract class QFetchRuleA( - override val numLinesBeforeTargetLine: Int = 10, - override val numLinesAfterTargetLine: Int = 10, + override val numLinesBeforeTargetLine: Int = 10, + override val numLinesAfterTargetLine: Int = 10, ) : QFetchRule // CallChain[size=8] = QFetchRule <-[Ref]- QSrcCut.QSrcCut() <-[Call]- qLogStackFrames() <-[Call]- Q ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] @@ -152,31 +152,31 @@ internal interface QFetchRule { // CallChain[size=9] = QFetchRule.fetchStartCheck() <-[Propag]- QFetchRule.SINGLE_LINE <-[Call]- QSr ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart // CallChain[size=9] = QFetchRule.fetchEndCheck() <-[Propag]- QFetchRule.SINGLE_LINE <-[Call]- QSrcC ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd companion object { // CallChain[size=8] = QFetchRule.SINGLE_LINE <-[Call]- QSrcCut.QSrcCut() <-[Call]- qLogStackFrames( ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] val SINGLE_LINE = object : QFetchRuleA(0, 0) { override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart = if (currentLineNumber == targetLineNumber) { QFetchStart.START_FROM_THIS_LINE } else { @@ -184,11 +184,11 @@ internal interface QFetchRule { } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber == targetLineNumber) { QFetchEnd.END_WITH_THIS_LINE } else { @@ -199,27 +199,27 @@ internal interface QFetchRule { // CallChain[size=7] = QFetchRule.SMART_FETCH <-[Call]- qLogStackFrames() <-[Call]- QException.mySrc ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] val SMART_FETCH = object : QFetchRuleA(10, 10) { override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() val trimmed = line.trimStart() return if (arrayOf( - "\"\"\".", - "}", - ")", - ".", - ",", - "?", - "//", - "/*", - "*" - ).any { trimmed.startsWith(it) } + "\"\"\".", + "}", + ")", + ".", + ",", + "?", + "//", + "/*", + "*" + ).any { trimmed.startsWith(it) } ) { QFetchStart.FETCH_THIS_LINE_AND_GO_TO_PREVIOUS_LINE } else if (nIndentThis <= nIndentTarget) { @@ -230,17 +230,17 @@ internal interface QFetchRule { } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber >= targetLineNumber) { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() if (currentLineNumber == targetLineNumber && line.trimStart() - .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 + .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 ) { // """ <<< targetLine // some text @@ -270,8 +270,8 @@ internal interface QFetchRule { // CallChain[size=12] = LineNumberReader.qFetchLinesBetween() <-[Call]- LineNumberReader.qFetchTarge ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun LineNumberReader.qFetchLinesBetween( - lineNumberStartInclusive: Int, - lineNumberEndInclusive: Int, + lineNumberStartInclusive: Int, + lineNumberEndInclusive: Int, ): List { var fetching = false val lines = mutableListOf() @@ -297,12 +297,12 @@ private fun LineNumberReader.qFetchLinesBetween( // CallChain[size=12] = TargetSurroundingLines <-[Ref]- LineNumberReader.qFetchTargetSurroundingLine ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] internal class TargetSurroundingLines( - val targetLineNumber: Int, - val startLineNumber: Int, - val endLineNumber: Int, - val targetLine: String, - val linesBeforeTargetLine: List, - val linesAfterTargetLine: List, + val targetLineNumber: Int, + val startLineNumber: Int, + val endLineNumber: Int, + val targetLine: String, + val linesBeforeTargetLine: List, + val linesAfterTargetLine: List, ) { // CallChain[size=11] = TargetSurroundingLines.linesBetween() <-[Call]- LineNumberReader.qFetchLines ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] fun linesBetween(lineNumberStartInclusive: Int, lineNumberEndInclusive: Int): List { @@ -321,9 +321,9 @@ internal class TargetSurroundingLines( // CallChain[size=11] = LineNumberReader.qFetchTargetSurroundingLines() <-[Call]- LineNumberReader.q ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun LineNumberReader.qFetchTargetSurroundingLines( - targetLineNumber: Int, - numLinesBeforeTargetLine: Int = 10, - numLinesAfterTargetLine: Int = 10, + targetLineNumber: Int, + numLinesBeforeTargetLine: Int = 10, + numLinesAfterTargetLine: Int = 10, ): TargetSurroundingLines { val start = max(1, targetLineNumber - numLinesBeforeTargetLine) val end = targetLineNumber + numLinesAfterTargetLine @@ -331,27 +331,27 @@ private fun LineNumberReader.qFetchTargetSurroundingLines( val lines = qFetchLinesBetween(start, end) return TargetSurroundingLines( - targetLineNumber = targetLineNumber, - startLineNumber = start, - endLineNumber = end, - targetLine = lines[targetLineNumber - start], - linesBeforeTargetLine = lines.subList(0, targetLineNumber - start), - linesAfterTargetLine = lines.subList(targetLineNumber - start + 1, lines.size) + targetLineNumber = targetLineNumber, + startLineNumber = start, + endLineNumber = end, + targetLine = lines[targetLineNumber - start], + linesBeforeTargetLine = lines.subList(0, targetLineNumber - start), + linesAfterTargetLine = lines.subList(targetLineNumber - start + 1, lines.size) ) } // CallChain[size=10] = LineNumberReader.qFetchLinesAround() <-[Call]- Path.qFetchLinesAround() <-[C ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] private fun LineNumberReader.qFetchLinesAround( - file: Path, - targetLineNumber: Int, - targetLine: String, - fetchRule: QFetchRule = QFetchRule.SMART_FETCH, - lineSeparator: QLineSeparator = QLineSeparator.LF, + file: Path, + targetLineNumber: Int, + targetLine: String, + fetchRule: QFetchRule = QFetchRule.SMART_FETCH, + lineSeparator: QLineSeparator = QLineSeparator.LF, ): String { val surroundingLines = qFetchTargetSurroundingLines( - targetLineNumber, - fetchRule.numLinesBeforeTargetLine, - fetchRule.numLinesAfterTargetLine + targetLineNumber, + fetchRule.numLinesBeforeTargetLine, + fetchRule.numLinesAfterTargetLine ) val context: MutableSet = mutableSetOf() @@ -370,11 +370,11 @@ private fun LineNumberReader.qFetchLinesAround( val curLineNumber = targetLineNumber - i val check = fetchRule.fetchStartCheck( - line, - curLineNumber, - targetLine, - targetLineNumber, - context + line, + curLineNumber, + targetLine, + targetLineNumber, + context ) when (check) { @@ -406,11 +406,11 @@ private fun LineNumberReader.qFetchLinesAround( val curLineNumber = targetLineNumber + i val check = fetchRule.fetchEndCheck( - line, - curLineNumber, - targetLine, - targetLineNumber, - context + line, + curLineNumber, + targetLine, + targetLineNumber, + context ) when (check) { @@ -447,19 +447,19 @@ private fun LineNumberReader.qFetchLinesAround( // CallChain[size=10] = Path.qReader() <-[Call]- Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtF ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] internal fun Path.qReader( - charset: Charset = Charsets.UTF_8, - buffSize: Int = qBUFFER_SIZE, - opts: QFlag = QFlag.none(), + charset: Charset = Charsets.UTF_8, + buffSize: Int = qBUFFER_SIZE, + opts: QFlag = QFlag.none(), ): LineNumberReader { return LineNumberReader(reader(charset, *opts.toOptEnums()), buffSize) } // CallChain[size=9] = Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtFrame() <-[Call]- qMySrcLin ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] internal fun Path.qFetchLinesAround( - lineNumber: Int, - fetchRule: QFetchRule = QFetchRule.SMART_FETCH, - charset: Charset = Charsets.UTF_8, - lineSeparator: QLineSeparator = this.qLineSeparator(charset), + lineNumber: Int, + fetchRule: QFetchRule = QFetchRule.SMART_FETCH, + charset: Charset = Charsets.UTF_8, + lineSeparator: QLineSeparator = this.qLineSeparator(charset), ): String { val reader = qReader(charset) @@ -481,8 +481,8 @@ internal fun Path.qFetchLinesAround( // CallChain[size=10] = Path.qLineAt() <-[Call]- Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtF ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] internal fun Path.qLineAt( - lineNumber: Int, - charset: Charset = Charsets.UTF_8, + lineNumber: Int, + charset: Charset = Charsets.UTF_8, ): String { bufferedReader(charset).use { reader -> var n = 0 @@ -557,13 +557,13 @@ internal fun Path.qFind(nameMatcher: QM, type: QFType = QFType.File, maxDepth: I // CallChain[size=8] = Path.qListByMatch() <-[Call]- QMyPath.src_root <-[Call]- qLogStackFrames() <- ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] internal fun Path.qListByMatch( - nameMatch: QM, - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, + nameMatch: QM, + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, ): List { return qList( - type, maxDepth = maxDepth, followSymLink = followSymLink + type, maxDepth = maxDepth, followSymLink = followSymLink ) { it.name.qMatches(nameMatch) } @@ -571,32 +571,32 @@ internal fun Path.qListByMatch( // CallChain[size=12] = Path.qList() <-[Call]- Path.qFind() <-[Call]- Collection.qFind() <-[Ca ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] internal fun Path.qList( - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, - sortWith: ((Path, Path) -> Int)? = Path::compareTo, - filter: (Path) -> Boolean = { true }, - // TODO https://stackoverflow.com/a/66996768/5570400 - // errorContinue: Boolean = true + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, + sortWith: ((Path, Path) -> Int)? = Path::compareTo, + filter: (Path) -> Boolean = { true }, + // TODO https://stackoverflow.com/a/66996768/5570400 + // errorContinue: Boolean = true ): List { return qSeq( - type = type, - maxDepth = maxDepth, - followSymLink = followSymLink, - sortWith = sortWith, - filter = filter + type = type, + maxDepth = maxDepth, + followSymLink = followSymLink, + sortWith = sortWith, + filter = filter ).toList() } // CallChain[size=13] = Path.qSeq() <-[Call]- Path.qList() <-[Call]- Path.qFind() <-[Call]- Collecti ... ckTrace() <-[Propag]- QException.QException() <-[Ref]- QE.throwIt() <-[Call]- N.depthFirst()[Root] internal fun Path.qSeq( - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, - sortWith: ((Path, Path) -> Int)? = Path::compareTo, - filter: (Path) -> Boolean = { true }, - // TODO https://stackoverflow.com/a/66996768/5570400 - // errorContinue: Boolean = true + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, + sortWith: ((Path, Path) -> Int)? = Path::compareTo, + filter: (Path) -> Boolean = { true }, + // TODO https://stackoverflow.com/a/66996768/5570400 + // errorContinue: Boolean = true ): Sequence { if (!this.isDirectory()) return emptySequence() diff --git a/src-test-single/QTreeNodeTest.kt b/src-test-single/QTreeNodeTest.kt index e996b28..f3eb439 100644 --- a/src-test-single/QTreeNodeTest.kt +++ b/src-test-single/QTreeNodeTest.kt @@ -786,7 +786,7 @@ private annotation class QTest(val testOnlyThis: Boolean = false) // CallChain[size=3] = QTestHumanCheckRequired <-[Ref]- qTest() <-[Call]- main()[Root] @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.FUNCTION) -private annotation class QTestHumanCheckRequired +private annotation class QTestHumanCheckRequired(val testOnlyThis: Boolean = false) // CallChain[size=3] = QBeforeEach <-[Ref]- qTest() <-[Call]- main()[Root] @Retention(AnnotationRetention.RUNTIME) @@ -809,13 +809,13 @@ private data class QTestResultElement(val method: Method, val cause: Throwable?) private val List.allTestedMethods: String get() = "\n[${"Tested".light_blue}]\n" + - this.joinToString("\n") { - if (it.success) { - it.method.qName().green - } else { - it.method.qName().light_red + this.joinToString("\n") { + if (it.success) { + it.method.qName().green + } else { + it.method.qName().light_red + } } - } // CallChain[size=3] = QTestResult <-[Ref]- qTest() <-[Call]- main()[Root] private class QTestResult(val elements: List, val time: Long) { @@ -882,7 +882,6 @@ private class QTestResult(val elements: List, val time: Long } } } else { -// qLog(qBracket("Target Class", targetClass.name.light_blue), stackDepth = 1, color) out.println("${"✨".yellow} ${" Success ".green} ${"✨".yellow}".green + "\n") out.println(str) out.println(elements.allTestedMethods) @@ -961,28 +960,28 @@ private fun qTest( targetMethodFilter: QMMethod = (QMMethod.annotation(QTest::class) or QMMethod.annotation("Test")) and - QMMethod.notAnnotation(QTestHumanCheckRequired::class) and + QMMethod.notAnnotation(QTestHumanCheckRequired::class) and // QMMethod.notAnnotation(QIgnore::class) and - QMMethod.DeclaredOnly and - QMMethod.NoParams and - QMMethod.nameNotExact("main"), + QMMethod.DeclaredOnly and + QMMethod.NoParams and + QMMethod.nameNotExact("main"), beforeMethodFilter: QMMethod = ( - QMMethod.annotation(QBeforeEach::class) or QMMethod.annotation("BeforeTest") - or QMMethod.annotation("BeforeEach") - or QMMethod.annotation("BeforeMethod") - ) - and QMMethod.DeclaredOnly and QMMethod.NoParams and QMMethod.nameNotExact( + QMMethod.annotation(QBeforeEach::class) or QMMethod.annotation("BeforeTest") + or QMMethod.annotation("BeforeEach") + or QMMethod.annotation("BeforeMethod") + ) + and QMMethod.DeclaredOnly and QMMethod.NoParams and QMMethod.nameNotExact( "main" ), afterMethodFilter: QMMethod = ( - QMMethod.annotation(QAfterEach::class) or QMMethod.annotation("AfterTest") - or QMMethod.annotation("AfterEach") - or QMMethod.annotation("AfterMethod") - ) and QMMethod.DeclaredOnly and QMMethod.NoParams and QMMethod.nameNotExact( + QMMethod.annotation(QAfterEach::class) or QMMethod.annotation("AfterTest") + or QMMethod.annotation("AfterEach") + or QMMethod.annotation("AfterMethod") + ) and QMMethod.DeclaredOnly and QMMethod.NoParams and QMMethod.nameNotExact( "main" ), @@ -998,9 +997,11 @@ private fun qTest( val methodsToTestImmediately = targetClasses.flatMap { cls -> cls.qMethods().filter { method -> - (QMMethod.DeclaredOnly and QMMethod.annotation(QTest::class) { anno -> - anno.testOnlyThis - }).matches(method) + (QMMethod.DeclaredOnly and ( + QMMethod.annotation(QTest::class) { it.testOnlyThis } or + QMMethod.annotation(QTestHumanCheckRequired::class) { it.testOnlyThis })).matches(method) + }.sortedBy { + it.name // TODO sort by line number } } @@ -1058,7 +1059,7 @@ private fun qFailMsg(actual: Any?, msg: String = "is not equals to", expected: A val actualStr = actual.qToLogString() + " " + "(actual)".light_green val expectedStr = expected.qToLogString() + " " + "(expected)".blue return "${QMyMark.WARN} ${actualStr.qWithNewLineSurround(onlyIf = QOnlyIfStr.Always)}$cMsg${ - expectedStr.qWithNewLinePrefix(onlyIf = QOnlyIfStr.Always) + expectedStr.qWithNewLinePrefix(onlyIf = QOnlyIfStr.Always) }" } @@ -1492,8 +1493,8 @@ private enum class QFetchStart { // CallChain[size=11] = QFetchRuleA <-[Call]- QFetchRule.SINGLE_LINE <-[Call]- QSrcCut.QSrcCut() <-[ ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private abstract class QFetchRuleA( - override val numLinesBeforeTargetLine: Int = 10, - override val numLinesAfterTargetLine: Int = 10, + override val numLinesBeforeTargetLine: Int = 10, + override val numLinesAfterTargetLine: Int = 10, ) : QFetchRule // CallChain[size=10] = QFetchRule <-[Ref]- QSrcCut.QSrcCut() <-[Call]- qLogStackFrames() <-[Call]- ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] @@ -1505,31 +1506,31 @@ private interface QFetchRule { // CallChain[size=11] = QFetchRule.fetchStartCheck() <-[Propag]- QFetchRule.SINGLE_LINE <-[Call]- QS ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart // CallChain[size=11] = QFetchRule.fetchEndCheck() <-[Propag]- QFetchRule.SINGLE_LINE <-[Call]- QSrc ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd companion object { // CallChain[size=10] = QFetchRule.SINGLE_LINE <-[Call]- QSrcCut.QSrcCut() <-[Call]- qLogStackFrames ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] val SINGLE_LINE = object : QFetchRuleA(0, 0) { override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart = if (currentLineNumber == targetLineNumber) { QFetchStart.START_FROM_THIS_LINE } else { @@ -1537,11 +1538,11 @@ private interface QFetchRule { } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber == targetLineNumber) { QFetchEnd.END_WITH_THIS_LINE } else { @@ -1558,27 +1559,27 @@ private interface QFetchRule { // """ override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart { return QFetchStart.START_FROM_THIS_LINE } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber >= targetLineNumber) { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() if (currentLineNumber == targetLineNumber && line.trimStart() - .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 + .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 ) { // """ // some text @@ -1601,27 +1602,27 @@ private interface QFetchRule { // CallChain[size=9] = QFetchRule.SMART_FETCH <-[Call]- qLogStackFrames() <-[Call]- QException.mySrc ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] val SMART_FETCH = object : QFetchRuleA(10, 10) { override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() val trimmed = line.trimStart() return if (arrayOf( - "\"\"\".", - "}", - ")", - ".", - ",", - "?", - "//", - "/*", - "*" - ).any { trimmed.startsWith(it) } + "\"\"\".", + "}", + ")", + ".", + ",", + "?", + "//", + "/*", + "*" + ).any { trimmed.startsWith(it) } ) { QFetchStart.FETCH_THIS_LINE_AND_GO_TO_PREVIOUS_LINE } else if (nIndentThis <= nIndentTarget) { @@ -1632,17 +1633,17 @@ private interface QFetchRule { } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber >= targetLineNumber) { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() if (currentLineNumber == targetLineNumber && line.trimStart() - .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 + .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 ) { // """ <<< targetLine // some text @@ -1672,8 +1673,8 @@ private interface QFetchRule { // CallChain[size=14] = LineNumberReader.qFetchLinesBetween() <-[Call]- LineNumberReader.qFetchTarge ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun LineNumberReader.qFetchLinesBetween( - lineNumberStartInclusive: Int, - lineNumberEndInclusive: Int, + lineNumberStartInclusive: Int, + lineNumberEndInclusive: Int, ): List { var fetching = false val lines = mutableListOf() @@ -1699,12 +1700,12 @@ private fun LineNumberReader.qFetchLinesBetween( // CallChain[size=14] = TargetSurroundingLines <-[Ref]- LineNumberReader.qFetchTargetSurroundingLine ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private class TargetSurroundingLines( - val targetLineNumber: Int, - val startLineNumber: Int, - val endLineNumber: Int, - val targetLine: String, - val linesBeforeTargetLine: List, - val linesAfterTargetLine: List, + val targetLineNumber: Int, + val startLineNumber: Int, + val endLineNumber: Int, + val targetLine: String, + val linesBeforeTargetLine: List, + val linesAfterTargetLine: List, ) { // CallChain[size=13] = TargetSurroundingLines.linesBetween() <-[Call]- LineNumberReader.qFetchLines ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] fun linesBetween(lineNumberStartInclusive: Int, lineNumberEndInclusive: Int): List { @@ -1723,9 +1724,9 @@ private class TargetSurroundingLines( // CallChain[size=13] = LineNumberReader.qFetchTargetSurroundingLines() <-[Call]- LineNumberReader.q ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun LineNumberReader.qFetchTargetSurroundingLines( - targetLineNumber: Int, - numLinesBeforeTargetLine: Int = 10, - numLinesAfterTargetLine: Int = 10, + targetLineNumber: Int, + numLinesBeforeTargetLine: Int = 10, + numLinesAfterTargetLine: Int = 10, ): TargetSurroundingLines { val start = max(1, targetLineNumber - numLinesBeforeTargetLine) val end = targetLineNumber + numLinesAfterTargetLine @@ -1733,27 +1734,27 @@ private fun LineNumberReader.qFetchTargetSurroundingLines( val lines = qFetchLinesBetween(start, end) return TargetSurroundingLines( - targetLineNumber = targetLineNumber, - startLineNumber = start, - endLineNumber = end, - targetLine = lines[targetLineNumber - start], - linesBeforeTargetLine = lines.subList(0, targetLineNumber - start), - linesAfterTargetLine = lines.subList(targetLineNumber - start + 1, lines.size) + targetLineNumber = targetLineNumber, + startLineNumber = start, + endLineNumber = end, + targetLine = lines[targetLineNumber - start], + linesBeforeTargetLine = lines.subList(0, targetLineNumber - start), + linesAfterTargetLine = lines.subList(targetLineNumber - start + 1, lines.size) ) } // CallChain[size=12] = LineNumberReader.qFetchLinesAround() <-[Call]- Path.qFetchLinesAround() <-[C ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun LineNumberReader.qFetchLinesAround( - file: Path, - targetLineNumber: Int, - targetLine: String, - fetchRule: QFetchRule = QFetchRule.SMART_FETCH, - lineSeparator: QLineSeparator = QLineSeparator.LF, + file: Path, + targetLineNumber: Int, + targetLine: String, + fetchRule: QFetchRule = QFetchRule.SMART_FETCH, + lineSeparator: QLineSeparator = QLineSeparator.LF, ): String { val surroundingLines = qFetchTargetSurroundingLines( - targetLineNumber, - fetchRule.numLinesBeforeTargetLine, - fetchRule.numLinesAfterTargetLine + targetLineNumber, + fetchRule.numLinesBeforeTargetLine, + fetchRule.numLinesAfterTargetLine ) val context: MutableSet = mutableSetOf() @@ -1772,11 +1773,11 @@ private fun LineNumberReader.qFetchLinesAround( val curLineNumber = targetLineNumber - i val check = fetchRule.fetchStartCheck( - line, - curLineNumber, - targetLine, - targetLineNumber, - context + line, + curLineNumber, + targetLine, + targetLineNumber, + context ) when (check) { @@ -1808,11 +1809,11 @@ private fun LineNumberReader.qFetchLinesAround( val curLineNumber = targetLineNumber + i val check = fetchRule.fetchEndCheck( - line, - curLineNumber, - targetLine, - targetLineNumber, - context + line, + curLineNumber, + targetLine, + targetLineNumber, + context ) when (check) { @@ -1849,19 +1850,19 @@ private fun LineNumberReader.qFetchLinesAround( // CallChain[size=12] = Path.qReader() <-[Call]- Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtF ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun Path.qReader( - charset: Charset = Charsets.UTF_8, - buffSize: Int = qBUFFER_SIZE, - opts: QFlag = QFlag.none(), + charset: Charset = Charsets.UTF_8, + buffSize: Int = qBUFFER_SIZE, + opts: QFlag = QFlag.none(), ): LineNumberReader { return LineNumberReader(reader(charset, *opts.toOptEnums()), buffSize) } // CallChain[size=11] = Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtFrame() <-[Call]- qMySrcLi ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun Path.qFetchLinesAround( - lineNumber: Int, - fetchRule: QFetchRule = QFetchRule.SMART_FETCH, - charset: Charset = Charsets.UTF_8, - lineSeparator: QLineSeparator = this.qLineSeparator(charset), + lineNumber: Int, + fetchRule: QFetchRule = QFetchRule.SMART_FETCH, + charset: Charset = Charsets.UTF_8, + lineSeparator: QLineSeparator = this.qLineSeparator(charset), ): String { val reader = qReader(charset) @@ -1883,8 +1884,8 @@ private fun Path.qFetchLinesAround( // CallChain[size=12] = Path.qLineAt() <-[Call]- Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtF ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun Path.qLineAt( - lineNumber: Int, - charset: Charset = Charsets.UTF_8, + lineNumber: Int, + charset: Charset = Charsets.UTF_8, ): String { bufferedReader(charset).use { reader -> var n = 0 @@ -1959,13 +1960,13 @@ private fun Path.qFind(nameMatcher: QM, type: QFType = QFType.File, maxDepth: In // CallChain[size=10] = Path.qListByMatch() <-[Call]- QMyPath.src_root <-[Call]- qLogStackFrames() < ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun Path.qListByMatch( - nameMatch: QM, - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, + nameMatch: QM, + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, ): List { return qList( - type, maxDepth = maxDepth, followSymLink = followSymLink + type, maxDepth = maxDepth, followSymLink = followSymLink ) { it.name.qMatches(nameMatch) } @@ -1973,32 +1974,32 @@ private fun Path.qListByMatch( // CallChain[size=14] = Path.qList() <-[Call]- Path.qFind() <-[Call]- Collection.qFind() <-[Ca ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun Path.qList( - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, - sortWith: ((Path, Path) -> Int)? = Path::compareTo, - filter: (Path) -> Boolean = { true }, - // TODO https://stackoverflow.com/a/66996768/5570400 - // errorContinue: Boolean = true + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, + sortWith: ((Path, Path) -> Int)? = Path::compareTo, + filter: (Path) -> Boolean = { true }, + // TODO https://stackoverflow.com/a/66996768/5570400 + // errorContinue: Boolean = true ): List { return qSeq( - type = type, - maxDepth = maxDepth, - followSymLink = followSymLink, - sortWith = sortWith, - filter = filter + type = type, + maxDepth = maxDepth, + followSymLink = followSymLink, + sortWith = sortWith, + filter = filter ).toList() } // CallChain[size=15] = Path.qSeq() <-[Call]- Path.qList() <-[Call]- Path.qFind() <-[Call]- Collecti ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun Path.qSeq( - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, - sortWith: ((Path, Path) -> Int)? = Path::compareTo, - filter: (Path) -> Boolean = { true }, - // TODO https://stackoverflow.com/a/66996768/5570400 - // errorContinue: Boolean = true + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, + sortWith: ((Path, Path) -> Int)? = Path::compareTo, + filter: (Path) -> Boolean = { true }, + // TODO https://stackoverflow.com/a/66996768/5570400 + // errorContinue: Boolean = true ): Sequence { if (!this.isDirectory()) return emptySequence() diff --git a/src-test-split/nyab/test/QTest.kt b/src-test-split/nyab/test/QTest.kt index 1443036..2b90459 100644 --- a/src-test-split/nyab/test/QTest.kt +++ b/src-test-split/nyab/test/QTest.kt @@ -72,7 +72,7 @@ internal annotation class QTest(val testOnlyThis: Boolean = false) // CallChain[size=3] = QTestHumanCheckRequired <-[Ref]- qTest() <-[Call]- main()[Root] @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.FUNCTION) -internal annotation class QTestHumanCheckRequired +internal annotation class QTestHumanCheckRequired(val testOnlyThis: Boolean = false) // CallChain[size=3] = QBeforeEach <-[Ref]- qTest() <-[Call]- main()[Root] @Retention(AnnotationRetention.RUNTIME) @@ -95,13 +95,13 @@ internal data class QTestResultElement(val method: Method, val cause: Throwable? internal val List.allTestedMethods: String get() = "\n[${"Tested".light_blue}]\n" + - this.joinToString("\n") { - if (it.success) { - it.method.qName().green - } else { - it.method.qName().light_red + this.joinToString("\n") { + if (it.success) { + it.method.qName().green + } else { + it.method.qName().light_red + } } - } // CallChain[size=3] = QTestResult <-[Ref]- qTest() <-[Call]- main()[Root] internal class QTestResult(val elements: List, val time: Long) { @@ -168,7 +168,6 @@ internal class QTestResult(val elements: List, val time: Lon } } } else { -// qLog(qBracket("Target Class", targetClass.name.light_blue), stackDepth = 1, color) out.println("${"✨".yellow} ${" Success ".green} ${"✨".yellow}".green + "\n") out.println(str) out.println(elements.allTestedMethods) @@ -247,28 +246,28 @@ internal fun qTest( targetMethodFilter: QMMethod = (QMMethod.annotation(QTest::class) or QMMethod.annotation("Test")) and - QMMethod.notAnnotation(QTestHumanCheckRequired::class) and + QMMethod.notAnnotation(QTestHumanCheckRequired::class) and // QMMethod.notAnnotation(QIgnore::class) and - QMMethod.DeclaredOnly and - QMMethod.NoParams and - QMMethod.nameNotExact("main"), + QMMethod.DeclaredOnly and + QMMethod.NoParams and + QMMethod.nameNotExact("main"), beforeMethodFilter: QMMethod = ( - QMMethod.annotation(QBeforeEach::class) or QMMethod.annotation("BeforeTest") - or QMMethod.annotation("BeforeEach") - or QMMethod.annotation("BeforeMethod") - ) - and QMMethod.DeclaredOnly and QMMethod.NoParams and QMMethod.nameNotExact( + QMMethod.annotation(QBeforeEach::class) or QMMethod.annotation("BeforeTest") + or QMMethod.annotation("BeforeEach") + or QMMethod.annotation("BeforeMethod") + ) + and QMMethod.DeclaredOnly and QMMethod.NoParams and QMMethod.nameNotExact( "main" ), afterMethodFilter: QMMethod = ( - QMMethod.annotation(QAfterEach::class) or QMMethod.annotation("AfterTest") - or QMMethod.annotation("AfterEach") - or QMMethod.annotation("AfterMethod") - ) and QMMethod.DeclaredOnly and QMMethod.NoParams and QMMethod.nameNotExact( + QMMethod.annotation(QAfterEach::class) or QMMethod.annotation("AfterTest") + or QMMethod.annotation("AfterEach") + or QMMethod.annotation("AfterMethod") + ) and QMMethod.DeclaredOnly and QMMethod.NoParams and QMMethod.nameNotExact( "main" ), @@ -284,9 +283,11 @@ internal fun qTest( val methodsToTestImmediately = targetClasses.flatMap { cls -> cls.qMethods().filter { method -> - (QMMethod.DeclaredOnly and QMMethod.annotation(QTest::class) { anno -> - anno.testOnlyThis - }).matches(method) + (QMMethod.DeclaredOnly and ( + QMMethod.annotation(QTest::class) { it.testOnlyThis } or + QMMethod.annotation(QTestHumanCheckRequired::class) { it.testOnlyThis })).matches(method) + }.sortedBy { + it.name // TODO sort by line number } } @@ -344,7 +345,7 @@ private fun qFailMsg(actual: Any?, msg: String = "is not equals to", expected: A val actualStr = actual.qToLogString() + " " + "(actual)".light_green val expectedStr = expected.qToLogString() + " " + "(expected)".blue return "${QMyMark.WARN} ${actualStr.qWithNewLineSurround(onlyIf = QOnlyIfStr.Always)}$cMsg${ - expectedStr.qWithNewLinePrefix(onlyIf = QOnlyIfStr.Always) + expectedStr.qWithNewLinePrefix(onlyIf = QOnlyIfStr.Always) }" } diff --git a/src-test-split/nyab/util/QFile.kt b/src-test-split/nyab/util/QFile.kt index 5c01b06..ee491f7 100644 --- a/src-test-split/nyab/util/QFile.kt +++ b/src-test-split/nyab/util/QFile.kt @@ -139,8 +139,8 @@ internal enum class QFetchStart { // CallChain[size=11] = QFetchRuleA <-[Call]- QFetchRule.SINGLE_LINE <-[Call]- QSrcCut.QSrcCut() <-[ ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] internal abstract class QFetchRuleA( - override val numLinesBeforeTargetLine: Int = 10, - override val numLinesAfterTargetLine: Int = 10, + override val numLinesBeforeTargetLine: Int = 10, + override val numLinesAfterTargetLine: Int = 10, ) : QFetchRule // CallChain[size=10] = QFetchRule <-[Ref]- QSrcCut.QSrcCut() <-[Call]- qLogStackFrames() <-[Call]- ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] @@ -152,31 +152,31 @@ internal interface QFetchRule { // CallChain[size=11] = QFetchRule.fetchStartCheck() <-[Propag]- QFetchRule.SINGLE_LINE <-[Call]- QS ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart // CallChain[size=11] = QFetchRule.fetchEndCheck() <-[Propag]- QFetchRule.SINGLE_LINE <-[Call]- QSrc ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd companion object { // CallChain[size=10] = QFetchRule.SINGLE_LINE <-[Call]- QSrcCut.QSrcCut() <-[Call]- qLogStackFrames ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] val SINGLE_LINE = object : QFetchRuleA(0, 0) { override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart = if (currentLineNumber == targetLineNumber) { QFetchStart.START_FROM_THIS_LINE } else { @@ -184,11 +184,11 @@ internal interface QFetchRule { } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber == targetLineNumber) { QFetchEnd.END_WITH_THIS_LINE } else { @@ -205,27 +205,27 @@ internal interface QFetchRule { // """ override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart { return QFetchStart.START_FROM_THIS_LINE } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber >= targetLineNumber) { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() if (currentLineNumber == targetLineNumber && line.trimStart() - .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 + .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 ) { // """ // some text @@ -248,27 +248,27 @@ internal interface QFetchRule { // CallChain[size=9] = QFetchRule.SMART_FETCH <-[Call]- qLogStackFrames() <-[Call]- QException.mySrc ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] val SMART_FETCH = object : QFetchRuleA(10, 10) { override fun fetchStartCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchStart { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() val trimmed = line.trimStart() return if (arrayOf( - "\"\"\".", - "}", - ")", - ".", - ",", - "?", - "//", - "/*", - "*" - ).any { trimmed.startsWith(it) } + "\"\"\".", + "}", + ")", + ".", + ",", + "?", + "//", + "/*", + "*" + ).any { trimmed.startsWith(it) } ) { QFetchStart.FETCH_THIS_LINE_AND_GO_TO_PREVIOUS_LINE } else if (nIndentThis <= nIndentTarget) { @@ -279,17 +279,17 @@ internal interface QFetchRule { } override fun fetchEndCheck( - line: String, - currentLineNumber: Int, - targetLine: String, - targetLineNumber: Int, - context: MutableSet, + line: String, + currentLineNumber: Int, + targetLine: String, + targetLineNumber: Int, + context: MutableSet, ): QFetchEnd = if (currentLineNumber >= targetLineNumber) { val nIndentThis = line.qCountLeftSpace() val nIndentTarget = targetLine.qCountLeftSpace() if (currentLineNumber == targetLineNumber && line.trimStart() - .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 + .startsWith("\"\"\"") && line.qCountOccurrence("\"\"\"") == 1 ) { // """ <<< targetLine // some text @@ -319,8 +319,8 @@ internal interface QFetchRule { // CallChain[size=14] = LineNumberReader.qFetchLinesBetween() <-[Call]- LineNumberReader.qFetchTarge ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun LineNumberReader.qFetchLinesBetween( - lineNumberStartInclusive: Int, - lineNumberEndInclusive: Int, + lineNumberStartInclusive: Int, + lineNumberEndInclusive: Int, ): List { var fetching = false val lines = mutableListOf() @@ -346,12 +346,12 @@ private fun LineNumberReader.qFetchLinesBetween( // CallChain[size=14] = TargetSurroundingLines <-[Ref]- LineNumberReader.qFetchTargetSurroundingLine ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] internal class TargetSurroundingLines( - val targetLineNumber: Int, - val startLineNumber: Int, - val endLineNumber: Int, - val targetLine: String, - val linesBeforeTargetLine: List, - val linesAfterTargetLine: List, + val targetLineNumber: Int, + val startLineNumber: Int, + val endLineNumber: Int, + val targetLine: String, + val linesBeforeTargetLine: List, + val linesAfterTargetLine: List, ) { // CallChain[size=13] = TargetSurroundingLines.linesBetween() <-[Call]- LineNumberReader.qFetchLines ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] fun linesBetween(lineNumberStartInclusive: Int, lineNumberEndInclusive: Int): List { @@ -370,9 +370,9 @@ internal class TargetSurroundingLines( // CallChain[size=13] = LineNumberReader.qFetchTargetSurroundingLines() <-[Call]- LineNumberReader.q ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun LineNumberReader.qFetchTargetSurroundingLines( - targetLineNumber: Int, - numLinesBeforeTargetLine: Int = 10, - numLinesAfterTargetLine: Int = 10, + targetLineNumber: Int, + numLinesBeforeTargetLine: Int = 10, + numLinesAfterTargetLine: Int = 10, ): TargetSurroundingLines { val start = max(1, targetLineNumber - numLinesBeforeTargetLine) val end = targetLineNumber + numLinesAfterTargetLine @@ -380,27 +380,27 @@ private fun LineNumberReader.qFetchTargetSurroundingLines( val lines = qFetchLinesBetween(start, end) return TargetSurroundingLines( - targetLineNumber = targetLineNumber, - startLineNumber = start, - endLineNumber = end, - targetLine = lines[targetLineNumber - start], - linesBeforeTargetLine = lines.subList(0, targetLineNumber - start), - linesAfterTargetLine = lines.subList(targetLineNumber - start + 1, lines.size) + targetLineNumber = targetLineNumber, + startLineNumber = start, + endLineNumber = end, + targetLine = lines[targetLineNumber - start], + linesBeforeTargetLine = lines.subList(0, targetLineNumber - start), + linesAfterTargetLine = lines.subList(targetLineNumber - start + 1, lines.size) ) } // CallChain[size=12] = LineNumberReader.qFetchLinesAround() <-[Call]- Path.qFetchLinesAround() <-[C ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] private fun LineNumberReader.qFetchLinesAround( - file: Path, - targetLineNumber: Int, - targetLine: String, - fetchRule: QFetchRule = QFetchRule.SMART_FETCH, - lineSeparator: QLineSeparator = QLineSeparator.LF, + file: Path, + targetLineNumber: Int, + targetLine: String, + fetchRule: QFetchRule = QFetchRule.SMART_FETCH, + lineSeparator: QLineSeparator = QLineSeparator.LF, ): String { val surroundingLines = qFetchTargetSurroundingLines( - targetLineNumber, - fetchRule.numLinesBeforeTargetLine, - fetchRule.numLinesAfterTargetLine + targetLineNumber, + fetchRule.numLinesBeforeTargetLine, + fetchRule.numLinesAfterTargetLine ) val context: MutableSet = mutableSetOf() @@ -419,11 +419,11 @@ private fun LineNumberReader.qFetchLinesAround( val curLineNumber = targetLineNumber - i val check = fetchRule.fetchStartCheck( - line, - curLineNumber, - targetLine, - targetLineNumber, - context + line, + curLineNumber, + targetLine, + targetLineNumber, + context ) when (check) { @@ -455,11 +455,11 @@ private fun LineNumberReader.qFetchLinesAround( val curLineNumber = targetLineNumber + i val check = fetchRule.fetchEndCheck( - line, - curLineNumber, - targetLine, - targetLineNumber, - context + line, + curLineNumber, + targetLine, + targetLineNumber, + context ) when (check) { @@ -496,19 +496,19 @@ private fun LineNumberReader.qFetchLinesAround( // CallChain[size=12] = Path.qReader() <-[Call]- Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtF ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] internal fun Path.qReader( - charset: Charset = Charsets.UTF_8, - buffSize: Int = qBUFFER_SIZE, - opts: QFlag = QFlag.none(), + charset: Charset = Charsets.UTF_8, + buffSize: Int = qBUFFER_SIZE, + opts: QFlag = QFlag.none(), ): LineNumberReader { return LineNumberReader(reader(charset, *opts.toOptEnums()), buffSize) } // CallChain[size=11] = Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtFrame() <-[Call]- qMySrcLi ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] internal fun Path.qFetchLinesAround( - lineNumber: Int, - fetchRule: QFetchRule = QFetchRule.SMART_FETCH, - charset: Charset = Charsets.UTF_8, - lineSeparator: QLineSeparator = this.qLineSeparator(charset), + lineNumber: Int, + fetchRule: QFetchRule = QFetchRule.SMART_FETCH, + charset: Charset = Charsets.UTF_8, + lineSeparator: QLineSeparator = this.qLineSeparator(charset), ): String { val reader = qReader(charset) @@ -530,8 +530,8 @@ internal fun Path.qFetchLinesAround( // CallChain[size=12] = Path.qLineAt() <-[Call]- Path.qFetchLinesAround() <-[Call]- qSrcFileLinesAtF ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] internal fun Path.qLineAt( - lineNumber: Int, - charset: Charset = Charsets.UTF_8, + lineNumber: Int, + charset: Charset = Charsets.UTF_8, ): String { bufferedReader(charset).use { reader -> var n = 0 @@ -606,13 +606,13 @@ internal fun Path.qFind(nameMatcher: QM, type: QFType = QFType.File, maxDepth: I // CallChain[size=10] = Path.qListByMatch() <-[Call]- QMyPath.src_root <-[Call]- qLogStackFrames() < ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] internal fun Path.qListByMatch( - nameMatch: QM, - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, + nameMatch: QM, + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, ): List { return qList( - type, maxDepth = maxDepth, followSymLink = followSymLink + type, maxDepth = maxDepth, followSymLink = followSymLink ) { it.name.qMatches(nameMatch) } @@ -620,32 +620,32 @@ internal fun Path.qListByMatch( // CallChain[size=14] = Path.qList() <-[Call]- Path.qFind() <-[Call]- Collection.qFind() <-[Ca ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] internal fun Path.qList( - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, - sortWith: ((Path, Path) -> Int)? = Path::compareTo, - filter: (Path) -> Boolean = { true }, - // TODO https://stackoverflow.com/a/66996768/5570400 - // errorContinue: Boolean = true + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, + sortWith: ((Path, Path) -> Int)? = Path::compareTo, + filter: (Path) -> Boolean = { true }, + // TODO https://stackoverflow.com/a/66996768/5570400 + // errorContinue: Boolean = true ): List { return qSeq( - type = type, - maxDepth = maxDepth, - followSymLink = followSymLink, - sortWith = sortWith, - filter = filter + type = type, + maxDepth = maxDepth, + followSymLink = followSymLink, + sortWith = sortWith, + filter = filter ).toList() } // CallChain[size=15] = Path.qSeq() <-[Call]- Path.qList() <-[Call]- Path.qFind() <-[Call]- Collecti ... [Call]- qBrackets() <-[Call]- Any?.shouldBe() <-[Call]- QTreeNodeTest.testDepthFirstSearch()[Root] internal fun Path.qSeq( - type: QFType = QFType.File, - maxDepth: Int = 1, - followSymLink: Boolean = false, - sortWith: ((Path, Path) -> Int)? = Path::compareTo, - filter: (Path) -> Boolean = { true }, - // TODO https://stackoverflow.com/a/66996768/5570400 - // errorContinue: Boolean = true + type: QFType = QFType.File, + maxDepth: Int = 1, + followSymLink: Boolean = false, + sortWith: ((Path, Path) -> Int)? = Path::compareTo, + filter: (Path) -> Boolean = { true }, + // TODO https://stackoverflow.com/a/66996768/5570400 + // errorContinue: Boolean = true ): Sequence { if (!this.isDirectory()) return emptySequence() diff --git a/src-test-split/nyab/util/QReflection.kt b/src-test-split/nyab/util/QReflection.kt index 4d1dc86..5e6f59e 100644 --- a/src-test-split/nyab/util/QReflection.kt +++ b/src-test-split/nyab/util/QReflection.kt @@ -13,7 +13,6 @@ package nyab.util import java.lang.StackWalker.StackFrame -import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method import java.nio.charset.Charset import java.nio.file.Path