Mmidwinter1993update to cj 1.0.0
df634dc6创建于 2025年7月3日历史提交
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 */
package magic.examples.doc_generator

import std.ast.*
import std.collection.ArrayList

private func isPublicDecl(decl: Decl): Bool {
    var isPublic = false
    for (m in decl.modifiers) {
        if (m.keyword.value == "public") {
            isPublic = true
        }
    }
    return isPublic
}

func isApiTypeDecl(decl: Decl): Bool {
    if (!isPublicDecl(decl)) {
        return false
    }
    if (decl.identifier.value.startsWith("__")) {
        return false
    }
    match (decl.keyword.value) {
        case "class" | "enum" | "struct" | "interface" => true
        case _ => false
    }
}

func isApiMemberDecl(decl: Decl): Bool {
    if (!isPublicDecl(decl)) {
        return false
    }
    match (decl.keyword.value) {
        case "func" | "prop" | "init" | "operator" | "let" | "var" => true
        case _ => false
    }
}

class AstFile {
    private let fileLines: Array<String>

    init(content: String) {
        // File line numbers starts from 1, so adding an empty line at the beginning
        this.fileLines = "\n${content}".split("\n")
    }

    operator func[](index: Int64): String {
        return fileLines[index]
    }

    func extractDeclComment(beginPos: Position): String {
        var beginLineNo = Int64(beginPos.line)
        // Check whether the decl has a comment prefix
        var curr = beginLineNo - 1
        if (fileLines[curr].trimAscii().endsWith("*/")) {
            while (!fileLines[curr].trimAscii().startsWith("/*")) {
                curr -= 1
            }
            // println("Decl comment: ${curr}, ${beginLineNo}")
            return String.join(fileLines[curr..beginLineNo], delimiter: "\n")
        } else if (fileLines[curr].trimAscii().startsWith("//")) {
            while (fileLines[curr].trimAscii().startsWith("//")) {
                curr -= 1
            }
            curr += 1
            // println("Decl comment: ${curr}, ${beginLineNo}")
            return String.join(fileLines[curr..beginLineNo], delimiter: "\n")
        }else {
            return ""
        }
    }

    func extractDeclComment(decl: Decl): String {
        return extractDeclComment(decl.beginPos)
    }

    private func extractDeclWithComment(decl: Decl): String {
        var beginLineNo = Int64(decl.beginPos.line)
        let endLineNo = Int64(decl.endPos.line)
        // println("Decl: ${beginLineNo}, ${endLineNo}")
        let comment = extractDeclComment(decl)
        let declContent = String.join(fileLines[beginLineNo..(endLineNo+1)], delimiter: "\n")
        if (comment.isEmpty()) {
            return declContent
        } else {
            return comment + "\n" + declContent
        }
    }

    func extractMemberDecls(body: Body, needCheck!: Bool): ArrayList<String> {
        return extractMemberDecls(body.decls, needCheck: needCheck)
    }

    func extractMemberDecls(decls: ArrayList<Decl>, needCheck!: Bool): ArrayList<String> {
        let buffer = ArrayList<String>()
        for (memberDecl in decls) {
            if (needCheck && !isApiMemberDecl(memberDecl)) {
                continue
            }
            let declContent = extractDeclWithComment(memberDecl)
            buffer.add(declContent)
            buffer.add("")
        }
        return buffer
    }

}