idlize

Форк
0
/
typecheck.ts 
135 строк · 4.4 Кб
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 { IDLEntry, forEachChild, isCallback, isClass, isEnum, isInterface, isTypedef } from "./idl"
17

18
export enum TypeKind {
19
    Primitive,
20
    String,
21
    Container,
22
    Interface,
23
    Class,
24
    Enum,
25
    Callback,
26
    AnonymousInterface, // Do we need it?
27
    Typedef,
28
}
29

30
export class TypeInfo {
31
    constructor(
32
        public kind: TypeKind,
33
        public declaration: IDLEntry|undefined,
34
        public location: string|undefined = undefined
35
    ) {}
36
}
37

38
function createPrimitiveType(): TypeInfo {
39
    return new TypeInfo(TypeKind.Primitive, undefined, undefined)
40
}
41

42
function createContainerType(): TypeInfo {
43
    return new TypeInfo(TypeKind.Container, undefined, undefined)
44
}
45

46
function createReferenceType(idl: IDLEntry, kind: TypeKind): TypeInfo {
47
    return new TypeInfo(TypeKind.Interface, idl, idl.fileName)
48
}
49

50
export class TypeTable {
51
    table = new Map<string, TypeInfo[]>([
52
        ["undefined", [new TypeInfo(TypeKind.Primitive, undefined, undefined)]],
53
        ["boolean", [new TypeInfo(TypeKind.Primitive, undefined, undefined)]],
54
        ["DOMString", [new TypeInfo(TypeKind.String, undefined, undefined)]],
55
        ["number", [new TypeInfo(TypeKind.Primitive, undefined, undefined)]],
56
        ["Object", [new TypeInfo(TypeKind.Interface, undefined, undefined)]],
57
        ["Promise", [new TypeInfo(TypeKind.Interface, undefined, undefined)]],
58
        ["Date", [new TypeInfo(TypeKind.Interface, undefined, undefined)]],
59
        ["Function", [new TypeInfo(TypeKind.Interface, undefined, undefined)]],
60
        ["this", [new TypeInfo(TypeKind.Interface, undefined, undefined)]],
61
        ["sequence", [new TypeInfo(TypeKind.Container, undefined, undefined)]],
62
        ["record", [new TypeInfo(TypeKind.Container, undefined, undefined)]]
63
    ])
64

65
    put(name: string, typeInfo: TypeInfo) {
66
        const alreadyKnown = this.table.get(name)
67
        if (!alreadyKnown) {
68
            this.table.set(name, [typeInfo])
69
            return
70
        }
71
        if (alreadyKnown.length > 0) {
72
            // console.log(`Duplicate type declaration: ${name}`)
73
        }
74
        alreadyKnown.push(typeInfo)
75
    }
76
    get(name: string): TypeInfo[] {
77
        return this.table.get(name) ?? []
78
    }
79
}
80

81
export class TypeChecker {
82
    typeTable: TypeTable
83
    constructor(idls?: IDLEntry[], typeTable?: TypeTable) {
84
        this.typeTable = typeTable ?? new TypeTable()
85
        idls?.forEach(idl => this.typecheck(idl))
86
    }
87

88
    typecheck(idl: IDLEntry) {
89
        forEachChild(idl, it => this.recordType(it))
90
    }
91

92
    private createTypeInfo(idl: IDLEntry, typeKind: TypeKind) {
93
        if (!idl.name) {
94
            console.log("Trying to record type for an unnamed IDL entry: ", idl)
95
        }
96
        this.typeTable.put(idl.name!, new TypeInfo(typeKind, idl, idl.fileName))
97
    }
98

99
    find(name: string): TypeInfo[] {
100
        return this.typeTable.get(name)
101
    }
102

103
    recordType(idl: IDLEntry) {
104
        if (isInterface(idl)) {
105
            this.createTypeInfo(idl, TypeKind.Interface)
106
            return
107
        }
108
        if (isEnum(idl)) {
109
            this.createTypeInfo(idl, TypeKind.Enum)
110
            return
111
        }
112
        if (isClass(idl)) {
113
            this.createTypeInfo(idl, TypeKind.Class)
114
            return
115
        }
116
        if (isCallback(idl)) {
117
            this.createTypeInfo(idl, TypeKind.Callback)
118
            return
119
        }
120
        if (isTypedef(idl)) {
121
            this.createTypeInfo(idl, TypeKind.Typedef)
122
            return
123
        }
124
    }
125
}
126

127
export function testTypecheck(entries: IDLEntry[]) {
128
    const typeChecker = new TypeChecker(entries)
129
    typeChecker.typeTable.table.forEach((types, name) => {
130
        console.log(`${name}:`)
131
        types.forEach(type =>
132
            console.log(`\t${TypeKind[type.kind]} ${type.declaration ? `IDLEntry name is ${type.declaration.name}` : `NO DECL`} in ${type.location}`)
133
        )
134
    })
135
}
136

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

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

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

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