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

rokucommunity / brighterscript / #13683

03 Feb 2025 04:19PM UTC coverage: 86.753% (-1.4%) from 88.185%
#13683

push

web-flow
Merge 34e72243e into 4afb6f658

12476 of 15203 branches covered (82.06%)

Branch coverage included in aggregate %.

7751 of 8408 new or added lines in 101 files covered. (92.19%)

85 existing lines in 17 files now uncovered.

13398 of 14622 relevant lines covered (91.63%)

34302.41 hits per line

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

85.96
/src/types/UnionType.ts
1
import type { GetTypeOptions, TypeCompatibilityData } from '../interfaces';
2
import { isDynamicType, isObjectType, isUnionType } from '../astUtils/reflection';
1✔
3
import { BscType } from './BscType';
1✔
4
import { ReferenceType } from './ReferenceType';
1✔
5
import { findTypeUnion, getUniqueType, isEnumTypeCompatible } from './helpers';
1✔
6
import { BscTypeKind } from './BscTypeKind';
1✔
7
import type { TypeCacheEntry } from '../SymbolTable';
8
import { SymbolTable } from '../SymbolTable';
1✔
9
import { SymbolTypeFlag } from '../SymbolTypeFlag';
1✔
10
import { BuiltInInterfaceAdder } from './BuiltInInterfaceAdder';
1✔
11

12
export function unionTypeFactory(types: BscType[]) {
1✔
13
    return new UnionType(types);
127,462✔
14
}
15

16
export class UnionType extends BscType {
1✔
17
    constructor(
18
        public types: BscType[]
197,525✔
19
    ) {
20
        super(joinTypesString(types));
197,525✔
21
    }
22

23
    public readonly kind = BscTypeKind.UnionType;
197,525✔
24

25
    public addType(type: BscType) {
26
        this.types.push(type);
1✔
27
    }
28

29
    isResolvable(): boolean {
30
        for (const type of this.types) {
184✔
31
            if (!type.isResolvable()) {
368✔
32
                return false;
12✔
33
            }
34
        }
35
        return true;
172✔
36
    }
37

38
    private getMemberTypeFromInnerTypes(name: string, options: GetTypeOptions) {
39
        return this.types.map((innerType) => innerType?.getMemberType(name, options));
363!
40
    }
41

42
    getMemberType(name: string, options: GetTypeOptions) {
43
        const innerTypesMemberTypes = this.getMemberTypeFromInnerTypes(name, options);
36✔
44
        if (!innerTypesMemberTypes || innerTypesMemberTypes.includes(undefined)) {
36✔
45
            // We don't have any members of any inner types that match
46
            // so instead, create reference type that will
47
            return new ReferenceType(name, name, options.flags, () => {
11✔
48
                return {
76✔
49
                    name: `UnionType MemberTable: '${this.__identifier}'`,
50
                    getSymbolType: (innerName: string, innerOptions: GetTypeOptions) => {
51
                        const referenceTypeInnerMemberTypes = this.getMemberTypeFromInnerTypes(name, options);
76✔
52
                        if (!innerTypesMemberTypes || innerTypesMemberTypes.includes(undefined)) {
76!
53
                            return undefined;
76✔
54
                        }
NEW
55
                        return getUniqueType(findTypeUnion(referenceTypeInnerMemberTypes), unionTypeFactory);
×
56
                    },
57
                    setCachedType: (innerName: string, innerCacheEntry: TypeCacheEntry, innerOptions: GetTypeOptions) => {
58
                        // TODO: is this even cachable? This is a NO-OP for now, and it shouldn't hurt anything
59
                    },
60
                    addSibling: (symbolTable: SymbolTable) => {
61
                        // TODO: I don't know what this means in this context?
62
                    }
63
                };
64
            });
65
        }
66
        return getUniqueType(findTypeUnion(innerTypesMemberTypes), unionTypeFactory);
25✔
67
    }
68

69
    isTypeCompatible(targetType: BscType, data?: TypeCompatibilityData): boolean {
70
        if (isDynamicType(targetType) || isObjectType(targetType) || this === targetType) {
875✔
71
            return true;
813✔
72
        }
73
        if (isEnumTypeCompatible(this, targetType, data)) {
62!
NEW
74
            return true;
×
75
        }
76
        if (isUnionType(targetType)) {
62✔
77
            // check if this set of inner types is a SUPERSET of targetTypes's inner types
78
            for (const targetInnerType of targetType.types) {
16✔
79
                if (!this.isTypeCompatible(targetInnerType, data)) {
36✔
80
                    return false;
2✔
81
                }
82
            }
83
            return true;
14✔
84
        }
85
        for (const innerType of this.types) {
46✔
86
            const foundCompatibleInnerType = innerType.isTypeCompatible(targetType, data);
67✔
87
            if (foundCompatibleInnerType) {
67✔
88
                return true;
42✔
89
            }
90
        }
91

92
        return false;
4✔
93
    }
94
    toString(): string {
95
        return joinTypesString(this.types);
174✔
96
    }
97
    toTypeString(): string {
NEW
98
        return 'dynamic';
×
99
    }
100

101
    checkAllMemberTypes(predicate: (BscType) => boolean) {
NEW
102
        return this.types.reduce((acc, type) => {
×
NEW
103
            return acc && predicate(type);
×
104
        }, true);
105
    }
106

107
    isEqual(targetType: BscType): boolean {
108
        if (!isUnionType(targetType)) {
10✔
109
            return false;
7✔
110
        }
111
        if (this === targetType) {
3!
112
            return true;
3✔
113
        }
NEW
114
        return this.isTypeCompatible(targetType) && targetType.isTypeCompatible(this);
×
115
    }
116

117
    getMemberTable(): SymbolTable {
118
        const unionTable = new SymbolTable(this.__identifier + ' UnionTable');
4✔
119
        const firstType = this.types[0];
4✔
120
        if (!firstType) {
4!
NEW
121
            return unionTable;
×
122
        }
123
        firstType.addBuiltInInterfaces();
4✔
124
        for (const symbol of firstType.getMemberTable().getAllSymbols(SymbolTypeFlag.runtime)) {
4✔
125
            const foundType = this.getMemberTypeFromInnerTypes(symbol.name, { flags: SymbolTypeFlag.runtime });
67✔
126
            const allResolvableTypes = foundType.reduce((acc, curType) => {
67✔
127
                return acc && curType?.isResolvable();
139✔
128
            }, true);
129

130
            if (!allResolvableTypes) {
67✔
131
                continue;
60✔
132
            }
133
            const uniqueType = getUniqueType(findTypeUnion(foundType), unionTypeFactory);
7✔
134
            unionTable.addSymbol(symbol.name, {}, uniqueType, SymbolTypeFlag.runtime);
7✔
135
        }
136
        return unionTable;
4✔
137
    }
138
}
139

140

141
function joinTypesString(types: BscType[]) {
142
    return [...new Set(types.map(t => t.toString()))].join(' or ');
395,427✔
143
}
144

145
BuiltInInterfaceAdder.unionTypeFactory = (types: BscType[]) => {
1✔
146
    return new UnionType(types);
69,971✔
147
};
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