idlize

Форк
0
/
Convertors.ts 
729 строк · 25.7 Кб
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
import { IndentedPrinter } from "../IndentedPrinter"
16
import { asString, identName, importTypeName, typeName } from "../util"
17
import { PeerGeneratorVisitor, RuntimeType } from "./PeerGeneratorVisitor"
18
import * as ts from "typescript"
19

20
let uniqueCounter = 0
21

22
export interface ArgConvertor {
23
    tsTypeName: string
24
    isScoped: boolean
25
    useArray: boolean
26
    runtimeTypes: RuntimeType[]
27
    estimateSize(): number
28
    scopeStart?(param: string): string
29
    scopeEnd?(param: string): string
30
    convertorTSArg(param: string): string
31
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void
32
    convertorCArg(param: string): string
33
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void
34
    interopType(ts: boolean): string
35
    nativeType(): string
36
    param: string
37
}
38

39
export abstract class BaseArgConvertor implements ArgConvertor {
40
    constructor(
41
        public tsTypeName: string,
42
        public runtimeTypes: RuntimeType[],
43
        public isScoped: boolean,
44
        public useArray: boolean,
45
        public param: string
46
    ) {}
47

48
    estimateSize(): number {
49
        return 0
50
    }
51
    nativeType(): string {
52
        return "Empty"
53
    }
54
    interopType(ts: boolean): string {
55
        return ts ? "object" : "void*"
56
    }
57

58
    scopeStart?(param: string): string
59
    scopeEnd?(param: string): string
60
    abstract convertorTSArg(param: string): string
61
    abstract convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void
62
    abstract convertorCArg(param: string): string
63
    abstract convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void
64
}
65

66

67
export class StringConvertor extends BaseArgConvertor {
68
    constructor(param: string) {
69
        super("string", [RuntimeType.STRING], false, false, param)
70
    }
71

72
    convertorTSArg(param: string): string {
73
        return param
74
    }
75
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
76
        printer.print(`${param}Serializer.writeString(${value})`)
77
    }
78
    convertorCArg(param: string): string {
79
        return `String(${param})`
80
    }
81
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
82
        printer.print(`${value} = ${param}Deserializer.readString();`)
83
    }
84

85
    nativeType(): string {
86
        return "String"
87
    }
88
    interopType(ts: boolean): string {
89
        return "KStringPtr"
90
    }
91
    estimateSize() {
92
        return 32
93
    }
94
}
95

96
export class BooleanConvertor extends BaseArgConvertor {
97
    constructor(param: string) {
98
        super("boolean", [RuntimeType.BOOLEAN, RuntimeType.NUMBER], false, false, param)
99
        // TODO: shall NUMBER be here?
100
    }
101

102
    convertorTSArg(param: string): string {
103
        return `+${param}`
104
    }
105
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
106
        printer.print(`${param}Serializer.writeBoolean(${value})`)
107
    }
108
    convertorCArg(param: string): string {
109
        return param
110
    }
111
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
112
        printer.print(`${value} = ${param}Deserializer.readBoolean();`)
113
    }
114

115
    nativeType(): string {
116
        return "KBoolean"
117
    }
118
    interopType(ts: boolean): string {
119
        return "KBoolean"
120
    }
121
    estimateSize() {
122
        return 1
123
    }
124
}
125

126
export class UndefinedConvertor extends BaseArgConvertor {
127
    constructor(param: string) {
128
        super("undefined", [RuntimeType.UNDEFINED], false, false, param)
129
    }
130

131
    convertorTSArg(param: string): string {
132
        return "nullptr"
133
    }
134
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
135
        printer.print(`${param}Serializer.writeUndefined()`)
136
    }
137
    convertorCArg(param: string): string {
138
        return param
139
    }
140
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
141
        printer.print(`${value} = ${param}Deserializer.readUndefined();`)
142
    }
143

144
    nativeType(): string {
145
        return "Undefined"
146
    }
147
    interopType(ts: boolean): string {
148
        return "KNativePointer"
149
    }
150

151
    estimateSize() {
152
        return 1
153
    }
154
}
155

156
export class EnumConvertor extends BaseArgConvertor {
157
    constructor(param: string, type: ts.TypeReferenceNode | ts.ImportTypeNode, visitor: PeerGeneratorVisitor) {
158
        // Enums are integers in runtime.
159
        super("number", [RuntimeType.NUMBER], false, false, param)
160
        const typeNameString = typeName(type)
161
        if (typeNameString) visitor.requestType(typeNameString, type)
162
    }
163

164
    convertorTSArg(param: string): string {
165
        // as unknown for non-int enums, so it wouldn't clutter compiler diagnostic
166
        return `${param} as unknown as int32`
167
    }
168
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
169
        // as unknown for non-int enums, so it wouldn't clutter compiler diagnostic
170
        printer.print(`${param}Serializer.writeInt32(${value} as unknown as int32)`)
171
    }
172
    convertorCArg(param: string): string {
173
        return param
174
    }
175
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
176
        printer.print(`${value} = ${param}Deserializer.readInt32();`)
177
    }
178

179
    nativeType(): string {
180
        return "KInt"
181
    }
182
    interopType(): string {
183
        return "KInt"
184
    }
185

186
    estimateSize() {
187
        return 4
188
    }
189
}
190

191
export class LengthConvertor extends BaseArgConvertor {
192
    constructor(param: string) {
193
        super("Length", [RuntimeType.NUMBER, RuntimeType.STRING, RuntimeType.OBJECT], false, true, param)
194
    }
195

196
    scopeStart(param: string): string {
197
        return `withLengthArray(${param}, (${param}Ptr) => {`
198
    }
199
    scopeEnd(param: string): string {
200
        return '})'
201
    }
202

203
    convertorTSArg(param: string): string {
204
        // return `${param}Ptr`
205
        throw new Error("Not used")
206
    }
207
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
208
        printer.print(`${param}Serializer.writeLength(${value})`)
209
    }
210
    convertorCArg(param: string): string {
211
        return `Length::fromArray(${param})`
212
    }
213
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
214
        printer.print(`${value} = ${param}Deserializer.readLength();`)
215
    }
216
    nativeType(): string {
217
        return "Length"
218
    }
219
    interopType(ts: boolean): string {
220
        return ts ? "Int32ArrayPtr" : "int32_t*"
221
    }
222
    estimateSize() {
223
        return 12
224
    }
225
}
226

227
export class UnionConvertor extends BaseArgConvertor {
228
    private memberConvertors: ArgConvertor[]
229

230
    constructor(param: string, visitor: PeerGeneratorVisitor, private type: ts.UnionTypeNode) {
231
        super(`any`, [], false, true, param)
232
        this.memberConvertors = type
233
            .types
234
            .map(member => visitor.typeConvertor(param, member))
235
        this.checkUniques(param, this.memberConvertors)
236
        this.runtimeTypes = this.memberConvertors.flatMap(it => it.runtimeTypes)
237
    }
238
    convertorTSArg(param: string): string {
239
        throw new Error("Do not use for union")
240
    }
241
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
242
        printer.print(`const ${value}_type = runtimeType(${value})`)
243
        // Save actual type being passed.
244
        printer.print(`${param}Serializer.writeInt8(${value}_type)`)
245
        this.memberConvertors.forEach((it, index) => {
246
                if (it.runtimeTypes.length == 0) {
247
                    console.log(`WARNING: branch for ${it.nativeType()} was consumed`)
248
                    return
249
                }
250
                let maybeElse = (index > 0 && this.memberConvertors[index - 1].runtimeTypes.length > 0) ? "else " : ""
251
                let maybeComma1 = (it.runtimeTypes.length > 1) ? "(" : ""
252
                let maybeComma2 = (it.runtimeTypes.length > 1) ? ")" : ""
253

254
                printer.print(`${maybeElse}if (${it.runtimeTypes.map(it => `${maybeComma1}RuntimeType.${RuntimeType[it]} == ${value}_type${maybeComma2}`).join(" || ")}) {`)
255
                printer.pushIndent()
256
                if (!(it instanceof UndefinedConvertor)) {
257
                    // TODO: `as unknown` is temporary to workaround for string enums.
258
                    let maybeAsUnknown = (it instanceof EnumConvertor) ? "as unknown " : ""
259
                    printer.print(`const ${value}_${index}: ${it.tsTypeName} = ${value} ${maybeAsUnknown}as ${it.tsTypeName}`)
260
                    it.convertorToTSSerial(param, `${value}_${index}`, printer)
261
                }
262
                printer.popIndent()
263
                printer.print(`}`)
264
            })
265
    }
266
    convertorCArg(param: string): string {
267
        throw new Error("Do not use for union")
268
    }
269
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
270
        // Save actual type being passed.
271
        let runtimeType = `runtimeType${uniqueCounter++}`;
272
        printer.print(`int32_t ${runtimeType} = ${param}Deserializer.readInt8();`)
273
        this.memberConvertors.forEach((it, index) => {
274
                if (it.runtimeTypes.length == 0) {
275
                    return
276
                }
277
                let maybeElse = (index > 0 && this.memberConvertors[index - 1].runtimeTypes.length > 0) ? "else " : ""
278
                let maybeComma1 = (it.runtimeTypes.length > 1) ? "(" : ""
279
                let maybeComma2 = (it.runtimeTypes.length > 1) ? ")" : ""
280

281
                printer.print(`${maybeElse}if (${it.runtimeTypes.map(it => `${maybeComma1}RUNTIME_${RuntimeType[it]} == ${runtimeType}${maybeComma2}`).join(" || ")}) {`)
282
                printer.pushIndent()
283
                it.convertorToCDeserial(param, `${value}.value${index}`, printer)
284
                printer.print(`${value}.selector = ${index};`)
285
                printer.popIndent()
286
                printer.print(`}`)
287
            })
288
    }
289
    nativeType(): string {
290
        return `Union<${this.memberConvertors.map(it => it.nativeType()).join(", ")}>`
291
    }
292
    interopType(ts: boolean): string {
293
        throw new Error("Union")
294
    }
295
    estimateSize() {
296
        return 12
297
    }
298
    checkUniques(param: string, convertors: ArgConvertor[]): void {
299
        for (let i = 0; i < convertors.length; i++) {
300
            for (let j = i + 1; j < convertors.length; j++) {
301
                let first = convertors[i].runtimeTypes
302
                let second = convertors[j].runtimeTypes
303
                first.forEach(value => {
304
                    let index = second.findIndex(it => it == value)
305
                    if (index != -1) {
306
                        console.log(`WARNING: Runtime type conflict in ${param}: could be ${RuntimeType[value]}`)
307
                        second.splice(index, 1)
308
                    }
309
                })
310
            }
311
        }
312
    }
313
}
314

315
export class ImportTypeConvertor extends BaseArgConvertor {
316
    private importedName: string
317
    constructor(param: string, visitor: PeerGeneratorVisitor, type: ts.ImportTypeNode) {
318
        super("Object", [RuntimeType.OBJECT], false, true, param)
319
        this.importedName = importTypeName(type)
320
        visitor.requestType(this.importedName, type)
321
    }
322

323
    convertorTSArg(param: string): string {
324
        throw new Error("Must never be used")
325
    }
326
    convertorCArg(param: string): string {
327
        throw new Error("Must never be used")
328
    }
329
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
330
        printer.print(`${param}Serializer.writeCustom("${this.importedName}", ${value})`)
331
    }
332
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
333
        printer.print(`${value} = ${param}Deserializer.readCustom("${this.importedName}");`)
334
    }
335
    nativeType(): string {
336
        return this.importedName
337
    }
338
    interopType(ts: boolean): string {
339
        throw new Error("Must never be used")
340
    }
341
    estimateSize() {
342
        return 32
343
    }
344
}
345

346
export class CustomTypeConvertor extends BaseArgConvertor {
347
    private customName: string
348
    constructor(param: string, visitor: PeerGeneratorVisitor, customName: string) {
349
        super("Object", [RuntimeType.OBJECT], false, true, param)
350
        this.customName = customName
351
    }
352

353
    convertorTSArg(param: string): string {
354
        throw new Error("Must never be used")
355
    }
356
    convertorCArg(param: string): string {
357
        throw new Error("Must never be used")
358
    }
359
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
360
        printer.print(`${param}Serializer.writeCustom("${this.customName}", ${value})`)
361
    }
362
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
363
        printer.print(`${value} = ${param}Deserializer.readCustom("${this.customName}");`)
364
    }
365
    nativeType(): string {
366
        return "CustomObject"
367
    }
368
    interopType(ts: boolean): string {
369
        throw new Error("Must never be used")
370
    }
371
    estimateSize() {
372
        return 32
373
    }
374
}
375

376
export class OptionConvertor extends BaseArgConvertor {
377
    private typeConvertor: ArgConvertor
378

379
    constructor(param: string, visitor: PeerGeneratorVisitor, type: ts.TypeNode) {
380
        let typeConvertor = visitor.typeConvertor(param, type)
381
        let runtimeTypes = typeConvertor.runtimeTypes;
382
        if (!runtimeTypes.includes(RuntimeType.UNDEFINED)) {
383
            runtimeTypes.push(RuntimeType.UNDEFINED)
384
        }
385
        super(`(${typeConvertor.tsTypeName})?`, runtimeTypes, typeConvertor.isScoped, true, param)
386
        this.typeConvertor = typeConvertor
387
    }
388

389
    convertorTSArg(param: string): string {
390
        throw new Error("Must never be used")
391
    }
392
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
393
        printer.print(`const ${value}_type = runtimeType(${value})`)
394
        printer.print(`${param}Serializer.writeInt8(${value}_type)`)
395
        printer.print(`if (${value}_type != RuntimeType.UNDEFINED) {`)
396
        printer.pushIndent()
397
        this.typeConvertor.convertorToTSSerial(param, value, printer)
398
        printer.popIndent()
399
        printer.print(`}`)
400
    }
401
    convertorCArg(param: string): string {
402
        throw new Error("Must never be used")
403
    }
404
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
405
        printer.print(`${value}.tag = ${param}Deserializer.readInt8() == RUNTIME_UNDEFINED ? TAG_UNDEFINED : TAG_OBJECT;`)
406
        printer.print(`if (${value}.tag != TAG_UNDEFINED) {`)
407
        printer.pushIndent()
408
        this.typeConvertor.convertorToCDeserial(param, `${value}.value`, printer)
409
        printer.popIndent()
410
        printer.print(`}`)
411
    }
412
    nativeType(): string {
413
        return `Tagged<${this.typeConvertor.nativeType()}>`
414
    }
415
    interopType(ts: boolean): string {
416
        return "KPointer"
417
    }
418
    estimateSize() {
419
        return this.typeConvertor.estimateSize()
420
    }
421
}
422

423
export class AggregateConvertor extends BaseArgConvertor {
424
    private memberConvertors: ArgConvertor[]
425
    private members: string[] = []
426

427
    constructor(param: string, visitor: PeerGeneratorVisitor, type: ts.TypeLiteralNode) {
428
        super(`any`, [RuntimeType.OBJECT], false, true, param)
429
        this.memberConvertors = type
430
            .members
431
            .filter(ts.isPropertySignature)
432
            .map((member, index) => {
433
            this.members[index] = identName(member.name)!
434
            return visitor.typeConvertor(param, member.type!, member.questionToken != undefined)
435
        })
436
    }
437

438
    convertorTSArg(param: string): string {
439
        throw new Error("Do not use for aggregates")
440
    }
441
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
442
        this.memberConvertors.forEach((it, index) => {
443
            let memberName = this.members[index]
444
            printer.print(`const ${value}_${memberName} = ${value}?.${memberName}`)
445
            it.convertorToTSSerial(param, `${value}_${memberName}`, printer)
446
        })
447
    }
448
    convertorCArg(param: string): string {
449
        throw new Error("Do not use")
450
    }
451
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
452
        this.memberConvertors.forEach((it, index) => {
453
            it.convertorToCDeserial(param, `${value}.value${index}`, printer)
454
        })
455
    }
456

457
    nativeType(): string {
458
        return `Compound<${this.memberConvertors.map(it => it.nativeType()).join(", ")}>`
459
    }
460
    interopType(): string {
461
        return "KNativePointer"
462
    }
463
    estimateSize() {
464
        return 4
465
    }
466
}
467

468
export class TypedConvertor extends BaseArgConvertor {
469
    constructor(
470
        name: string,
471
        private type: ts.TypeReferenceNode | undefined,
472
        param: string, protected visitor: PeerGeneratorVisitor) {
473
        super(name, [RuntimeType.OBJECT, RuntimeType.FUNCTION, RuntimeType.UNDEFINED], false, true, param)
474
        visitor.requestType(name, type)
475
    }
476

477
    convertorTSArg(param: string): string {
478
        throw new Error("Must never be used")
479
    }
480
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
481
        printer.print(`${param}Serializer.${this.visitor.serializerName(this.tsTypeName, this.type)}(${value})`)
482
    }
483
    convertorCArg(param: string): string {
484
        throw new Error("Must never be used")
485
    }
486
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
487
        printer.print(`${value} = ${param}Deserializer.${this.visitor.deserializerName(this.tsTypeName, this.type)}();`)
488
    }
489
    nativeType(): string {
490
        return this.tsTypeName
491
    }
492
    interopType(): string {
493
        throw new Error("Must never be used")
494
    }
495
    estimateSize() {
496
        return 12
497
    }
498
}
499

500
export class InterfaceConvertor extends TypedConvertor {
501
    constructor(name: string, param: string, visitor: PeerGeneratorVisitor, type: ts.TypeReferenceNode) {
502
        super(name, type, param, visitor)
503
    }
504
}
505

506
export class FunctionConvertor extends TypedConvertor {
507
    constructor(param: string, visitor: PeerGeneratorVisitor) {
508
        super("Function", undefined, param, visitor)
509
    }
510
}
511

512
export class TupleConvertor extends BaseArgConvertor {
513
    memberConvertors: ArgConvertor[]
514

515
    constructor(param: string, protected visitor: PeerGeneratorVisitor, private elementType: ts.TupleTypeNode) {
516
        super(`[${elementType.elements.map(it => visitor.mapType(it)).join(",")}]`, [RuntimeType.OBJECT], false, true, param)
517
        this.memberConvertors = elementType
518
            .elements
519
            .map(element => visitor.typeConvertor(param, element))
520
    }
521

522
    convertorTSArg(param: string): string {
523
        throw new Error("Must never be used")
524
    }
525

526
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
527
        printer.print(`${param}Serializer.writeInt8(runtimeType(${value}))`)
528
        printer.print(`if (${value} !== undefined) {`)
529
        printer.pushIndent()
530
        this.memberConvertors.forEach((it, index) => {
531
            printer.print(`const ${value}_${index} = ${value}[${index}]`)
532
            it.convertorToTSSerial(param, `${value}_${index}`, printer)
533
        })
534
        printer.popIndent()
535
        printer.print(`}`)
536
    }
537

538
    convertorCArg(param: string): string {
539
        throw new Error("Must never be used")
540
    }
541

542
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
543
        printer.print(`if ( ${param}Deserializer.readInt8() != RUNTIME_UNDEFINED) {`) // TODO: `else value = nullptr` ?
544
        printer.pushIndent()
545
        this.memberConvertors.forEach((it, index) => {
546
            it.convertorToCDeserial(param, `${value}.value${index}`, printer)
547
        })
548
        printer.popIndent()
549
        printer.print(`}`)
550
    }
551
    nativeType(): string {
552
        return mapCType(this.elementType)
553
    }
554
    interopType(ts: boolean): string {
555
        return "KNativePointer"
556
    }
557

558
    estimateSize() {
559
        return this.memberConvertors
560
            .map(it => it.estimateSize())
561
            .reduce((sum, current) => sum + current, 0)
562
    }
563
}
564

565
export class ArrayConvertor extends BaseArgConvertor {
566
    elementConvertor: ArgConvertor
567
    constructor(param: string, protected visitor: PeerGeneratorVisitor, private elementType: ts.TypeNode) {
568
        super(`Array<${visitor.mapType(elementType)}>`, [RuntimeType.OBJECT], false, true, param)
569
        this.elementConvertor = visitor.typeConvertor(param, elementType)
570
    }
571

572
    convertorTSArg(param: string): string {
573
        throw new Error("Must never be used")
574
    }
575
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
576
        // Array length.
577
        printer.print(`${param}Serializer.writeInt8(runtimeType(${value}))`)
578
        printer.print(`if (${value} !== undefined) {`)
579
        printer.pushIndent()
580
        printer.print(`${param}Serializer.writeInt32(${value}.length)`)
581
        printer.print(`for (let i = 0; i < ${value}.length; i++) {`)
582
        printer.pushIndent()
583
        printer.print(`const ${value}_element = ${value}[i]`)
584
        this.elementConvertor.convertorToTSSerial(param, `${value}_element`, printer)
585
        printer.popIndent()
586
        printer.print(`}`)
587
        printer.popIndent()
588
        printer.print(`}`)
589
    }
590
    convertorCArg(param: string): string {
591
        throw new Error("Must never be used")
592
    }
593
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
594
        // Array length.
595
        let runtimeType = `runtimeType${uniqueCounter++}`;
596
        let arrayLength = `arrayLength${uniqueCounter++}`;
597

598
        printer.print(`auto ${runtimeType} = ${param}Deserializer.readInt8();`)
599
        printer.print(`if (${runtimeType} != RUNTIME_UNDEFINED) {`) // TODO: `else value = nullptr` ?
600
        printer.pushIndent()
601
        printer.print(`auto ${arrayLength} = ${param}Deserializer.readInt32();`)
602
        printer.print(`${value}.resize(${arrayLength});`);
603
        printer.print(`for (int i = 0; i < ${arrayLength}; i++) {`)
604
        printer.pushIndent()
605
        this.elementConvertor.convertorToCDeserial(param, `${value}[i]`, printer)
606
        printer.popIndent()
607
        printer.print(`}`)
608
        printer.popIndent()
609
        printer.print(`}`)
610

611
    }
612
    nativeType(): string {
613
        return `Array<${mapCType(this.elementType)}>`
614
    }
615
    interopType(ts: boolean): string {
616
        return "KNativePointer"
617
    }
618
    estimateSize() {
619
        return 12
620
    }
621
}
622
export class NumberConvertor extends BaseArgConvertor {
623
    constructor(param: string) {
624
        // Enums are integers in runtime.
625
        super("number", [RuntimeType.NUMBER], false, false, param)
626
    }
627

628
    convertorTSArg(param: string): string {
629
        return param
630
    }
631
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
632
        printer.print(`${param}Serializer.writeNumber(${value})`)
633
    }
634
    convertorCArg(param: string): string {
635
        return `Number(${param})`
636
    }
637
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
638
        printer.print(`${value} = ${param}Deserializer.readNumber();`)
639
    }
640

641
    nativeType(): string {
642
        return "Number"
643
    }
644

645
    interopType(): string {
646
        return "KInt"
647
    }
648
    estimateSize() {
649
        return 4
650
    }
651
}
652

653
export class AnimationRangeConvertor extends BaseArgConvertor {
654
    constructor(param: string) {
655
        super("AnimationRange<number>", [RuntimeType.OBJECT, RuntimeType.UNDEFINED], false, true, param)
656
    }
657

658
    convertorTSArg(param: string): string {
659
        throw new Error("unused")
660
    }
661
    convertorToTSSerial(param: string, value: string, printer: IndentedPrinter): void {
662
        printer.print(`${param}Serializer.writeAnimationRange(${value});`)
663
    }
664
    convertorCArg(param: string): string {
665
        throw new Error("unused")
666
    }
667
    convertorToCDeserial(param: string, value: string, printer: IndentedPrinter): void {
668
        printer.print(`${value} = ${param}Deserializer.readAnimationRange();`)
669
    }
670
    nativeType(): string {
671
        return "Compound<Number, Number>" // TODO: figure out how to pass real type args
672
    }
673
    interopType(ts: boolean): string {
674
        return ts ? "Int32ArrayPtr" : "int32_t*"
675
    }
676
    estimateSize() {
677
        return 8
678
    }
679
}
680

681
function mapCType(type: ts.TypeNode): string {
682
    if (ts.isTypeReferenceNode(type)) {
683
        return identName(type.typeName)!
684
    }
685
    if (ts.isUnionTypeNode(type)) {
686
        return `Union<${type.types.map(it => mapCType(it)).join(", ")}>`
687
    }
688
    if (ts.isTypeLiteralNode(type)) {
689
        return `Compound<${type
690
            .members
691
            .filter(ts.isPropertySignature)
692
            .map(it => mapCType(it.type!))
693
            .join(", ")}>`
694
    }
695
    if (ts.isTupleTypeNode(type)) {
696
        return `Compound<${type
697
            .elements
698
            .map(it => mapCType(it))
699
            .join(", ")}>`
700
    }
701
    if (ts.isOptionalTypeNode(type)) {
702
        return `Tagged<${mapCType(type.type)}>`
703
    }
704
    if (ts.isFunctionTypeNode(type)) {
705
        return "Function"
706
    }
707
    if (ts.isParenthesizedTypeNode(type)) {
708
        return `${mapCType(type.type)}`
709
    }
710
    if (ts.isNamedTupleMember(type)) {
711
        return `${mapCType(type.type)}`
712
    }
713
    if (type.kind == ts.SyntaxKind.NumberKeyword) {
714
        return "Number"
715
    }
716
    if (type.kind == ts.SyntaxKind.StringKeyword) {
717
        return "String"
718
    }
719
    if (type.kind == ts.SyntaxKind.ObjectKeyword) {
720
        return "Object"
721
    }
722
    if (type.kind == ts.SyntaxKind.BooleanKeyword) {
723
        return "KBoolean"
724
    }
725
    if (type.kind == ts.SyntaxKind.AnyKeyword) {
726
        return "Any"
727
    }
728
    throw new Error(`Cannot map ${type.getText()}: ${type.kind}`)
729
}
730

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

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

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

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