Coverage Summary for Class: IrKDocUtilKt (com.kotlinorm.compiler.plugin.utils)
Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
IrKDocUtilKt |
100%
(1/1)
|
100%
(3/3)
|
78.8%
(52/66)
|
96.2%
(50/52)
|
97.6%
(362/371)
|
/**
* Copyright 2022-2025 kronos-orm
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.kotlinorm.compiler.plugin.utils
/**
* Calculates the real start offset of the source code, skipping over comments and annotations.
*
* This function iterates through the source code lines starting from the given offset and skips
* lines that are annotations, single-line comments, or multi-line comments. It returns the first
* line that is not a comment or annotation.
*
* @param source The list of source code lines.
* @param startOffset The initial offset to start checking from.
* @return The real start offset after skipping comments and annotations.
*/
fun realStartOffset(source: List<String>, startOffset: Int): Int {
var realStartOffset = startOffset
var multiLineCommentFlag = false
while (
source[realStartOffset].trimStart().startsWith("@") ||
source[realStartOffset].trimStart().startsWith("//") ||
source[realStartOffset].trimStart().startsWith("/*") ||
multiLineCommentFlag
) {
if (source[realStartOffset].trimStart().startsWith("/*")) {
multiLineCommentFlag = true
}
if (source[realStartOffset].trimStart().endsWith("*/")) {
multiLineCommentFlag = false
}
realStartOffset++
}
return realStartOffset
}
internal const val SOURCE_FILE_CACHE_SIZE = 128
internal val sourceFileCache: LRUCache<String, List<String>> = LRUCache(SOURCE_FILE_CACHE_SIZE)
/**
* Extract the comment content within the specified range.
*
* This function will extract single-line or multi-line comments within the specified range from the given list of lines.
* If no comments are found within the specified range, the function will search upwards to the beginning of the file to find possible comments.
*
* 提取指定范围内的注释内容。
*
* 此函数会从给定的行列表中提取位于指定范围内的单行或多行注释。
* 如果在指定范围内没有找到注释,函数将向上查找直到文件的开头,以获取可能的注释。
*
* @param lines a list of code lines 包含代码行的列表
* @param range the range of lines to check 指定要检查的行范围
* @return the extracted comment content, or null if no comment is found 找到的注释内容,如果没有找到则返回 null
*/
fun extractDeclarationComment(lines: List<String>, range: IntRange): String? {
val startIndex = range.first
val endIndex = range.last
var comment: String? = null
val commentIgnore = { char: Char -> char == '*' || char == ' ' }
// Find single-line or multi-line comments within the specified range
// 在指定范围内查找单行或多行注释
for (i in startIndex..endIndex) {
val line = lines.getOrNull(i)?.trim() ?: continue
// Extract single-line comments
// 提取单行注释
val singleLineComment = line.substringAfter("//", "").substringBefore("//").trim()
// Extract multi-line comments
// 查找多行注释的起始和结束位置
val multiLineCommentStart = line.indexOf("/*")
val multiLineCommentEnd = line.indexOf("*/")
// If a single-line comment is found
// 如果找到单行注释
if (singleLineComment.isNotEmpty()) {
comment = singleLineComment
break
}
// If a multi-line comment is found
// 如果找到多行注释
else if (multiLineCommentStart != -1 && multiLineCommentEnd != -1) {
comment = line.substring(multiLineCommentStart + 2, multiLineCommentEnd).trim(commentIgnore)
break
}
}
// If no comments are found within the specified range, search upwards
// 如果在指定范围内没有找到注释,向上查找
if (comment == null) {
var multiLineCommentFlag = false
var singleLineCommentFlag = false
for (i in (startIndex - 1) downTo 0) {
val line = lines.getOrNull(i)?.trim() ?: continue
if (line.startsWith("@")) continue
val singleLineComment = line.substringAfter("//", "").trim()
val multiLineCommentStart = line.indexOf("/*")
val multiLineCommentEnd = line.indexOf("*/")
// Handle single-line comments
// 处理单行注释
if (line.startsWith("//") && singleLineComment.isNotEmpty()) {
if (singleLineCommentFlag) {
comment = singleLineComment + comment
} else {
comment = singleLineComment
singleLineCommentFlag = true
}
continue
}
// Handle multi-line comments
// 处理多行注释
else if (multiLineCommentStart != -1 && multiLineCommentEnd != -1) {
comment = line.substring(multiLineCommentStart + 2, multiLineCommentEnd).trim(commentIgnore)
break
}
// Handle multi-line comments that start but do not end
// 处理多行注释开始但未结束的情况
else if (multiLineCommentStart != -1 && multiLineCommentFlag) {
comment = line.substring(multiLineCommentStart + 2).trim(commentIgnore) + comment
break
}
// Handle multi-line comments that end but do not start
// 处理多行注释结束的情况
else if (multiLineCommentEnd != -1) {
comment = line.substring(0, multiLineCommentEnd).trim(commentIgnore)
multiLineCommentFlag = true
continue
}
// Handle non-empty lines
// 处理非空行
else if (line.isNotBlank()) {
if (multiLineCommentFlag) {
comment = line.trim(commentIgnore) + comment
continue
}
if (line.startsWith("@")) { // 如果是注解
continue
}
break
}
}
}
return comment
}