• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rokucommunity / brighterscript / #14177

10 Apr 2025 04:25PM UTC coverage: 87.111% (-2.0%) from 89.104%
#14177

push

web-flow
Merge 2bd224618 into 2b6cc17a0

13312 of 16151 branches covered (82.42%)

Branch coverage included in aggregate %.

7993 of 8671 new or added lines in 102 files covered. (92.18%)

84 existing lines in 22 files now uncovered.

14384 of 15643 relevant lines covered (91.95%)

19744.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.5
/src/types/ComponentType.ts
1
import type { BscSymbol, GetSymbolTypeOptions, SymbolTableProvider } from '../SymbolTable';
2
import { SymbolTypeFlag } from '../SymbolTypeFlag';
1✔
3
import { SymbolTable } from '../SymbolTable';
1✔
4
import { isAnyReferenceType, isComponentType, isDynamicType, isInvalidType, isObjectType, isPrimitiveType, isReferenceType, isTypedFunctionType } from '../astUtils/reflection';
1✔
5
import type { ExtraSymbolData, TypeCompatibilityData } from '../interfaces';
6
import type { BaseFunctionType } from './BaseFunctionType';
7
import type { BscType } from './BscType';
8
import { BscTypeKind } from './BscTypeKind';
1✔
9
import { BuiltInInterfaceAdder } from './BuiltInInterfaceAdder';
1✔
10
import { InheritableType } from './InheritableType';
1✔
11
import { isUnionTypeCompatible } from './helpers';
1✔
12
import util from '../util';
1✔
13

14
export class ComponentType extends InheritableType {
1✔
15

16
    constructor(public name: string, superComponent?: ComponentType) {
188,492✔
17
        super(name, superComponent);
188,492✔
18
        this.callFuncMemberTable = new SymbolTable(`${this.name}: CallFunc`, () => this.parentComponent?.callFuncMemberTable);
188,492✔
19
        this.callFuncAssociatedTypesTable = new SymbolTable(`${this.name}: CallFuncAssociatedTypes`, () => this.parentComponent?.callFuncAssociatedTypesTable);
188,492!
20
    }
21

22
    public readonly kind = BscTypeKind.ComponentType;
188,492✔
23

24
    public get parentComponent() {
25
        return this.parentType as ComponentType;
2,255✔
26
    }
27

28
    public isTypeCompatible(targetType: BscType, data?: TypeCompatibilityData) {
29
        if (this.isEqual(targetType)) {
2,547✔
30
            return true;
2,538✔
31
        } else if (isInvalidType(targetType) ||
9✔
32
            isDynamicType(targetType) ||
33
            isObjectType(targetType) ||
34
            isUnionTypeCompatible(this, targetType, data)) {
35
            return true;
1✔
36
        } else if (isComponentType(targetType)) {
8!
37
            return this.isTypeDescendent(targetType);
8✔
38
        }
NEW
39
        return false;
×
40
    }
41

42
    public static instance = new ComponentType('Node');
1✔
43

44
    isEqual(targetType: BscType, data: TypeCompatibilityData = {}): boolean {
2,565✔
45
        if (isReferenceType(targetType) && targetType.isResolvable()) {
3,231✔
46
            targetType = targetType.getTarget?.() ?? targetType;
2,910!
47
        }
48
        if (this === targetType) {
3,231✔
49
            return true;
3,064✔
50
        }
51
        if (!isComponentType(targetType)) {
167✔
52
            return false;
1✔
53
        }
54

55
        const thisNameLower = this.name.toLowerCase();
166✔
56
        const targetNameLower = targetType.name.toLowerCase();
166✔
57
        if (thisNameLower !== targetNameLower) {
166✔
58
            return false;
18✔
59
        }
60
        if (this.isBuiltIn && targetType.isBuiltIn) {
148✔
61
            return true;
2✔
62
        }
63

64
        if (!this.isParentTypeEqual(targetType, data)) {
146!
NEW
65
            return false;
×
66
        }
67
        if (!this.checkCompatibilityBasedOnMembers(targetType, SymbolTypeFlag.runtime, data) ||
146✔
68
            !targetType.checkCompatibilityBasedOnMembers(this, SymbolTypeFlag.runtime, data)) {
69
            return false;
5✔
70
        }
71
        if (!this.checkCompatibilityBasedOnMembers(targetType, SymbolTypeFlag.runtime, data, this.callFuncMemberTable, targetType.callFuncMemberTable) ||
141✔
72
            !targetType.checkCompatibilityBasedOnMembers(this, SymbolTypeFlag.runtime, data, targetType.callFuncMemberTable, this.callFuncMemberTable)) {
73
            return false;
3✔
74
        }
75

76
        return true;
138✔
77
    }
78

79
    public toString() {
80
        return util.getSgNodeTypeName(this.name);
621✔
81
    }
82

83
    private builtInMemberTable: SymbolTable;
84

85
    getBuiltInMemberTable(): SymbolTable {
86
        if (!this.parentType) {
188,490✔
87
            if (this.builtInMemberTable) {
13,734!
NEW
88
                return this.builtInMemberTable;
×
89
            }
90
            this.builtInMemberTable = new SymbolTable(`${this.__identifier} Built-in Members`);
13,734✔
91
            this.pushMemberProvider(() => this.builtInMemberTable);
23,558✔
92
            return this.builtInMemberTable;
13,734✔
93
        }
94
    }
95

96
    private hasStartedAddingBuiltInInterfaces = false;
188,492✔
97

98
    addBuiltInInterfaces() {
99
        if (!this.hasAddedBuiltInInterfaces && !this.hasStartedAddingBuiltInInterfaces) {
365,107✔
100
            this.hasStartedAddingBuiltInInterfaces = true;
188,490✔
101
            if (this.parentType) {
188,490✔
102
                this.parentType.addBuiltInInterfaces();
174,756✔
103
            }
104
            BuiltInInterfaceAdder.addBuiltInInterfacesToType(this);
188,490✔
105
        }
106
        this.hasAddedBuiltInInterfaces = true;
365,107✔
107
        this.addBuiltInFields();
365,107✔
108
    }
109

110
    private hasAddedBuiltInFields = false;
188,492✔
111
    private hasStartedAddingBuiltInFields = false;
188,492✔
112

113

114
    addBuiltInFields() {
115
        if (!this.hasAddedBuiltInFields && !this.hasStartedAddingBuiltInFields) {
539,840✔
116
            this.hasStartedAddingBuiltInFields = true;
188,490✔
117
            if (isComponentType(this.parentType)) {
188,490✔
118
                this.parentType.addBuiltInFields();
174,733✔
119
            }
120
            BuiltInInterfaceAdder.addBuiltInFieldsToNodeType(this);
188,490✔
121
        }
122
        this.hasAddedBuiltInFields = true;
539,840✔
123
    }
124

125
    public readonly callFuncMemberTable: SymbolTable;
126
    public readonly callFuncAssociatedTypesTable: SymbolTable;
127

128
    /**
129
     * Adds a function to the call func member table
130
     * Also adds any associated custom types to its own table, so they can be used through a callfunc
131
     */
132
    addCallFuncMember(name: string, data: ExtraSymbolData, funcType: BaseFunctionType, flags: SymbolTypeFlag, associatedTypesTableProvider?: SymbolTableProvider) {
133
        const originalTypesToCheck = new Set<BscType>();
59✔
134
        if (isTypedFunctionType(funcType)) {
59✔
135
            const paramTypes = (funcType.params ?? []).map(p => p.type);
64!
136
            for (const paramType of paramTypes) {
55✔
137
                originalTypesToCheck.add(paramType);
64✔
138
            }
139
        }
140
        if (funcType.returnType) {
59!
141
            originalTypesToCheck.add(funcType.returnType);
59✔
142
        }
143
        const additionalTypesToCheck = new Set<BscType>();
59✔
144

145
        for (const type of originalTypesToCheck) {
59✔
146
            if (!type.isBuiltIn) {
86✔
147
                util.getCustomTypesInSymbolTree(additionalTypesToCheck, type, (subSymbol: BscSymbol) => {
7✔
148
                    return !originalTypesToCheck.has(subSymbol.type);
3✔
149
                });
150
            }
151
        }
152

153
        for (const type of [...originalTypesToCheck.values(), ...additionalTypesToCheck.values()]) {
59✔
154
            if (!isPrimitiveType(type) && type.isResolvable()) {
89✔
155
                // This type is a reference type, but was able to be resolved here
156
                // add it to the table of associated types, so it can be used through a callfunc
157
                const extraData = {};
47✔
158
                if (associatedTypesTableProvider) {
47!
159
                    associatedTypesTableProvider().getSymbolType(type.toString(), { flags: SymbolTypeFlag.typetime, data: extraData });
47✔
160
                }
161
                let targetType = isAnyReferenceType(type) ? type.getTarget?.() : type;
47✔
162

163
                this.callFuncAssociatedTypesTable.addSymbol(type.toString(), { ...extraData, isFromCallFunc: true }, targetType, SymbolTypeFlag.typetime);
47✔
164
            }
165
        }
166

167
        // add this function to be available through callfunc
168
        this.callFuncMemberTable.addSymbol(name, data, funcType, flags);
59✔
169
    }
170

171
    getCallFuncTable() {
172
        return this.callFuncMemberTable;
3✔
173
    }
174

175
    getCallFuncType(name: string, options: GetSymbolTypeOptions) {
176
        const callFuncType = this.callFuncMemberTable.getSymbolType(name, options);
250✔
177

178
        const addAssociatedTypesTableAsSiblingToMemberTable = (type: BscType) => {
247✔
179
            if (isReferenceType(type) &&
453✔
180
                !type.isResolvable()) {
181
                // This param or return type is a reference - make sure the associated types are included
182
                type.tableProvider().addSibling(this.callFuncAssociatedTypesTable);
4✔
183

184
                // add this as a sister table to member tables too!
185
                const memberTable: SymbolTable = type.getMemberTable();
4✔
186
                if (memberTable.getAllSymbols) {
4!
187
                    for (const memberSymbol of memberTable.getAllSymbols(SymbolTypeFlag.runtime)) {
4✔
188
                        addAssociatedTypesTableAsSiblingToMemberTable(memberSymbol?.type);
6!
189
                    }
190
                }
191
            }
192
        };
193

194
        if (isTypedFunctionType(callFuncType)) {
247✔
195
            const typesToCheck = [...callFuncType.params.map(p => p.type), callFuncType.returnType];
241✔
196

197
            for (const type of typesToCheck) {
241✔
198
                addAssociatedTypesTableAsSiblingToMemberTable(type);
447✔
199
            }
200
        }
201

202
        return callFuncType;
247✔
203
    }
204
}
205

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc