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

rokucommunity / brighterscript / #13111

30 Sep 2024 04:35PM UTC coverage: 86.842% (-1.4%) from 88.193%
#13111

push

web-flow
Merge 25fc06528 into 3a2dc7282

11525 of 14034 branches covered (82.12%)

Branch coverage included in aggregate %.

6990 of 7581 new or added lines in 100 files covered. (92.2%)

83 existing lines in 18 files now uncovered.

12691 of 13851 relevant lines covered (91.63%)

29449.4 hits per line

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

87.16
/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);
111,156✔
14
}
15

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

23
    public readonly kind = BscTypeKind.UnionType;
159,906✔
24

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

29
    isResolvable(): boolean {
30
        for (const type of this.types) {
62✔
31
            if (!type.isResolvable()) {
128✔
32
                return false;
7✔
33
            }
34
        }
35
        return true;
55✔
36
    }
37

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

42
    getMemberType(name: string, options: GetTypeOptions) {
43
        const innerTypesMemberTypes = this.getMemberTypeFromInnerTypes(name, options);
29✔
44
        if (!innerTypesMemberTypes || innerTypesMemberTypes.includes(undefined)) {
29✔
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 {
60✔
49
                    name: `UnionType MemberTable: '${this.__identifier}'`,
50
                    getSymbolType: (innerName: string, innerOptions: GetTypeOptions) => {
51
                        const referenceTypeInnerMemberTypes = this.getMemberTypeFromInnerTypes(name, options);
60✔
52
                        if (!innerTypesMemberTypes || innerTypesMemberTypes.includes(undefined)) {
60!
53
                            return undefined;
60✔
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
                };
61
            });
62
        }
63
        return getUniqueType(findTypeUnion(innerTypesMemberTypes), unionTypeFactory);
18✔
64
    }
65

66
    isTypeCompatible(targetType: BscType, data?: TypeCompatibilityData): boolean {
67
        if (isDynamicType(targetType) || isObjectType(targetType)) {
54✔
68
            return true;
5✔
69
        }
70
        if (isEnumTypeCompatible(this, targetType, data)) {
49!
NEW
71
            return true;
×
72
        }
73
        if (isUnionType(targetType)) {
49✔
74
            // check if this set of inner types is a SUPERSET of targetTypes's inner types
75
            for (const targetInnerType of targetType.types) {
13✔
76
                if (!this.isTypeCompatible(targetInnerType, data)) {
30✔
77
                    return false;
2✔
78
                }
79
            }
80
            return true;
11✔
81
        }
82
        for (const innerType of this.types) {
36✔
83
            const foundCompatibleInnerType = innerType.isTypeCompatible(targetType, data);
58✔
84
            if (foundCompatibleInnerType) {
58✔
85
                return true;
32✔
86
            }
87
        }
88

89

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

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

105
    isEqual(targetType: BscType): boolean {
106
        if (!isUnionType(targetType)) {
2✔
107
            return false;
1✔
108
        }
109
        return this.isTypeCompatible(targetType) && targetType.isTypeCompatible(this);
1✔
110
    }
111

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

125
            if (!allResolvableTypes) {
19✔
126
                continue;
16✔
127
            }
128
            const uniqueType = getUniqueType(findTypeUnion(foundType), unionTypeFactory);
3✔
129
            unionTable.addSymbol(symbol.name, {}, uniqueType, SymbolTypeFlag.runtime);
3✔
130
        }
131
        return unionTable;
4✔
132
    }
133
}
134

135

136
function joinTypesString(types: BscType[]) {
137
    return types.map(t => t.toString()).join(' or ');
320,176✔
138
}
139

140
BuiltInInterfaceAdder.unionTypeFactory = (types: BscType[]) => {
1✔
141
    return new UnionType(types);
48,662✔
142
};
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