idlize

Форк
0
/
NativeModulePrinter.ts 
133 строки · 6.0 Кб
1
/*
2
 * Copyright (c) 2024 Huawei Device Co., Ltd.
3
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * you may not use this file except in compliance with the License.
5
 * You may obtain a copy of the License at
6
 *
7
 * http://www.apache.org/licenses/LICENSE-2.0
8
 *
9
 * Unless required by applicable law or agreed to in writing, software
10
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * See the License for the specific language governing permissions and
13
 * limitations under the License.
14
 */
15

16
import { IndentedPrinter } from "../../IndentedPrinter";
17
import { generateEventsBridgeSignature } from "./EventsPrinter";
18
import { nativeModuleDeclaration, nativeModuleEmptyDeclaration } from "../FileGenerators";
19
import { LanguageWriter, Method, NamedMethodSignature, StringExpression, Type, createLanguageWriter } from "../LanguageWriters";
20
import { PeerClass, PeerClassBase } from "../PeerClass";
21
import { PeerLibrary } from "../PeerLibrary";
22
import { PeerMethod } from "../PeerMethod";
23

24
class NativeModuleVisitor {
25
    readonly nativeModule: LanguageWriter
26
    readonly nativeModuleEmpty: LanguageWriter
27

28
    constructor(
29
        private readonly library: PeerLibrary,
30
    ) {
31
        this.nativeModule = createLanguageWriter(library.declarationTable.language)
32
        this.nativeModuleEmpty = createLanguageWriter(library.declarationTable.language)
33
    }
34

35
    private printPeerMethods(peer: PeerClass) {
36
        peer.methods.forEach(it => printPeerMethod(peer, it, this.nativeModule, this.nativeModuleEmpty))
37
    }
38

39
    private printMaterializedMethods(nativeModule: LanguageWriter, nativeModuleEmpty: LanguageWriter) {
40
        this.library.materializedClasses.forEach(clazz => {
41
            printPeerMethod(clazz, clazz.ctor, nativeModule, nativeModuleEmpty, Type.Pointer)
42
            printPeerMethod(clazz, clazz.finalizer, nativeModule, nativeModuleEmpty, Type.Pointer)
43
            clazz.methods.forEach(method => {
44
                const returnType = method.tsReturnType()
45
                // TODO: DotIndicator and DigitIndicator implements Indicator
46
                const subType = returnType?.name.includes(method.originalParentName)
47
                printPeerMethod(clazz, method, nativeModule, nativeModuleEmpty,
48
                    returnType === Type.This || subType ? Type.Pointer : returnType)
49
            })
50
        })
51
    }
52

53
    private printEventMethods(nativeModule: LanguageWriter, nativeModuleEmpty: LanguageWriter) {
54
        let method = generateEventsBridgeSignature(nativeModule.language)
55
        method = new Method(`_${method.name}`, method.signature, method.modifiers)
56
        nativeModule.writeNativeMethodDeclaration(method.name, method.signature)
57
        nativeModuleEmpty.writeMethodImplementation(method, writer => {
58
            writer.writePrintLog(method.name)
59
            writer.writeStatement(writer.makeReturn(new StringExpression(`0`)))
60
        })
61
    }
62

63
    print(): void {
64
        console.log(`Materialized classes: ${this.library.materializedClasses.size}`)
65
        this.nativeModule.pushIndent()
66
        this.nativeModuleEmpty.pushIndent()
67
        for (const file of this.library.files) {
68
            for (const peer of file.peersToGenerate.values()) {
69
                this.printPeerMethods(peer)
70
            }
71
        }
72
        this.printMaterializedMethods(this.nativeModule, this.nativeModuleEmpty)
73
        this.printEventMethods(this.nativeModule, this.nativeModuleEmpty)
74
        this.nativeModule.popIndent()
75
        this.nativeModuleEmpty.popIndent()
76
    }
77
}
78

79
function printPeerMethod(clazz: PeerClassBase, method: PeerMethod, nativeModule: LanguageWriter, nativeModuleEmpty: LanguageWriter,
80
    returnType?: Type
81
) {
82
    const component = clazz.generatedName(method.isCallSignature)
83
    clazz.setGenerationContext(`${method.isCallSignature ? "" : method.overloadedName}()`)
84
    let serializerArgCreated = false
85
    let args: ({name: string, type: string})[] = []
86
    for (let i = 0; i < method.argConvertors.length; ++i) {
87
        let it = method.argConvertors[i]
88
        if (it.useArray) {
89
            if (!serializerArgCreated) {
90
                const array = `thisSerializer`
91
                args.push({ name: `thisArray`, type: 'Uint8Array' }, { name: `thisLength`, type: 'int32' })
92
                serializerArgCreated = true
93
            }
94
        } else {
95
            // TODO: use language as argument of interop type.
96
            args.push({ name: `${it.param}`, type: it.interopType(nativeModule.language) })
97
        }
98
    }
99
    let maybeReceiver = method.hasReceiver() ? [{ name: 'ptr', type: 'KPointer' }] : []
100
    const parameters = NamedMethodSignature.make(returnType?.name ?? 'void', maybeReceiver.concat(args))
101
    let name = `_${component}_${method.overloadedName}`
102
    nativeModule.writeNativeMethodDeclaration(name, parameters)
103
    nativeModuleEmpty.writeMethodImplementation(new Method(name, parameters), (printer) => {
104
        printer.writePrintLog(name)
105
        if (returnType !== undefined && returnType.name !== Type.Void.name) {
106
            printer.writeStatement(printer.makeReturn(printer.makeString(getReturnValue(returnType))))
107
        }
108
    })
109
    clazz.setGenerationContext(undefined)
110
}
111

112
export function printNativeModule(peerLibrary: PeerLibrary, nativeBridgePath: string): string {
113
    const lang = peerLibrary.declarationTable.language
114
    const visitor = new NativeModuleVisitor(peerLibrary)
115
    visitor.print()
116
    return nativeModuleDeclaration(visitor.nativeModule, nativeBridgePath, false, lang)
117
}
118

119
export function printNativeModuleEmpty(peerLibrary: PeerLibrary): string {
120
    const visitor = new NativeModuleVisitor(peerLibrary)
121
    visitor.print()
122
    return nativeModuleEmptyDeclaration(visitor.nativeModuleEmpty.getOutput())
123
}
124

125
function getReturnValue(type: Type): string {
126
    switch(type.name) {
127
        case Type.Boolean.name : return "false"
128
        case Type.Number.name: return "1"
129
        case Type.Pointer.name: return "-1"
130
        case "string": return `"some string"`
131
    }
132
    throw new Error(`Unknown return type: ${type.name}`)
133
}
134

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.