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

rokucommunity / brighterscript / #13385

29 Nov 2024 06:38PM UTC coverage: 86.828%. Remained the same
#13385

push

web-flow
Merge 346e2057f into 57fa2ad4d

12078 of 14711 branches covered (82.1%)

Branch coverage included in aggregate %.

378 of 406 new or added lines in 36 files covered. (93.1%)

244 existing lines in 22 files now uncovered.

13071 of 14253 relevant lines covered (91.71%)

33084.46 hits per line

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

81.22
/src/types/InheritableType.ts
1
import type { GetTypeOptions, TypeCompatibilityData } from '../interfaces';
2
import { isInheritableType, isReferenceType } from '../astUtils/reflection';
1✔
3
import { SymbolTypeFlag } from '../SymbolTypeFlag';
1✔
4
import { BscType } from './BscType';
1✔
5
import type { ReferenceType } from './ReferenceType';
6
import { DynamicType } from './DynamicType';
1✔
7

8
export abstract class InheritableType extends BscType {
1✔
9

10
    constructor(public name: string, public readonly parentType?: InheritableType | ReferenceType) {
486,927✔
11
        super(name);
486,927✔
12
        if (parentType) {
486,927✔
13
            this.memberTable.pushParentProvider(() => this.parentType.memberTable);
162,486✔
14
        }
15
    }
16

17
    changeUnknownMemberToDynamic = false;
486,927✔
18

19
    getMemberType(memberName: string, options: GetTypeOptions) {
20
        let hasRoAssociativeArrayAsAncestor = this.name.toLowerCase() === 'roassociativearray' || this.getAncestorTypeList()?.find(ancestorType => ancestorType.name.toLowerCase() === 'roassociativearray');
1,479!
21

22
        if (hasRoAssociativeArrayAsAncestor) {
1,479✔
23
            return super.getMemberType(memberName, options) ?? DynamicType.instance;
20✔
24
        }
25

26
        const resultType = super.getMemberType(memberName, { ...options, fullName: memberName, tableProvider: () => this.memberTable });
1,459✔
27

28
        if (this.changeUnknownMemberToDynamic && !resultType.isResolvable()) {
1,459✔
29
            return DynamicType.instance;
5✔
30
        }
31
        return resultType;
1,454✔
32
    }
33

34
    public toString() {
35
        return this.name;
30,167✔
36
    }
37

38
    public toTypeString(): string {
39
        return 'dynamic';
6✔
40
    }
41

42
    protected getAncestorTypeList(): InheritableType[] {
43
        const ancestors = [];
1,538✔
44
        let currentParentType = this.parentType;
1,538✔
45
        while (currentParentType) {
1,538✔
46
            if (isInheritableType(currentParentType)) {
496✔
47
                ancestors.push(currentParentType);
493✔
48
                currentParentType = currentParentType.parentType;
493✔
49
            } else {
50
                break;
3✔
51
            }
52
        }
53
        return ancestors;
1,538✔
54
    }
55

56
    /**
57
     *  Checks if other type is an ancestor of this
58
     */
59
    isTypeAncestor(otherType: BscType) {
60
        if (!isInheritableType(otherType)) {
43!
61
            return false;
×
62
        }
63
        // Check if targetType is an ancestor of this
64
        const ancestors = this.getAncestorTypeList();
43✔
65
        if (ancestors?.find(ancestorType => ancestorType.isEqual(otherType))) {
43!
66
            return true;
29✔
67
        }
68
        return false;
14✔
69
    }
70

71
    /**
72
     *  Checks if other type is an descendent of this
73
     */
74
    isTypeDescendent(otherType: BscType) {
75
        if (!isInheritableType(otherType)) {
43!
76
            return false;
×
77
        }
78
        return otherType.isTypeAncestor(this);
43✔
79
    }
80

81
    /**
82
     * Gets a string representation of the Interface that looks like javascript
83
     * Useful for debugging
84
     */
85
    private toJSString() {
86
        // eslint-disable-next-line no-bitwise
87
        const flags = 3 as SymbolTypeFlag; //SymbolTypeFlags.runtime | SymbolTypeFlags.typetime;
5✔
88
        let result = '{';
5✔
89
        const memberSymbols = (this.memberTable?.getAllSymbols(flags) || []).sort((a, b) => a.name.localeCompare(b.name));
5!
90
        for (const symbol of memberSymbols) {
5✔
91
            let symbolTypeString = symbol.type.toString();
6✔
92
            if (isInheritableType(symbol.type)) {
6✔
93
                symbolTypeString = symbol.type.toJSString();
1✔
94
            }
95
            result += ' ' + symbol.name + ': ' + symbolTypeString + ';';
6✔
96
        }
97
        if (memberSymbols.length > 0) {
5✔
98
            result += ' ';
4✔
99
        }
100
        return result + '}';
5✔
101
    }
102

103
    isEqual(targetType: BscType, data: TypeCompatibilityData = {}): boolean {
60✔
104
        if (this === targetType) {
124✔
105
            return true;
17✔
106
        }
107
        if (isReferenceType(targetType)) {
107✔
108
            const lowerTargetName = (targetType.memberKey ?? targetType.fullName).toLowerCase();
35!
109
            const myLowerName = this.name.toLowerCase();
35✔
110

111
            if (myLowerName === lowerTargetName) {
35✔
112
                return true;
19✔
113
            }
114
            //check non-namespaced version
115
            if (myLowerName.split('.').pop() === lowerTargetName) {
16✔
116
                return true;
8✔
117
            }
118
        }
119
        if (!isInheritableType(targetType)) {
80!
120
            return false;
×
121
        }
122
        if (!targetType) {
80!
123
            return false;
×
124
        }
125
        if (this === targetType) {
80!
126
            return true;
×
127
        }
128
        if (data?.allowNameEquality) {
80!
NEW
129
            const thisKind = (this as any).kind;
×
NEW
130
            if (thisKind && thisKind === (targetType as any).kind) {
×
NEW
131
                if (this.toString().toLowerCase() === targetType.toString().toLowerCase()) {
×
NEW
132
                    return true;
×
133
                }
134
            }
135
        }
136

137
        if (this.isAncestorUnresolvedReferenceType() || targetType.isAncestorUnresolvedReferenceType()) {
80✔
138
            return this.name.toLowerCase() === targetType.name?.toLowerCase() &&
2!
139
                this.isParentTypeEqual(targetType, data);
140
        }
141
        return this.name.toLowerCase() === targetType.name?.toLowerCase() &&
78!
142
            this.isParentTypeEqual(targetType, data) &&
143
            this.checkCompatibilityBasedOnMembers(targetType, SymbolTypeFlag.runtime, data) &&
144
            targetType.checkCompatibilityBasedOnMembers(this, SymbolTypeFlag.runtime, data);
145
    }
146

147
    protected isParentTypeEqual(targetType: BscType, data?: TypeCompatibilityData): boolean {
148
        if (isInheritableType(targetType)) {
176!
149
            const targetParent = targetType.parentType;
176✔
150
            if (this.parentType && !targetParent) {
176!
UNCOV
151
                return false;
×
152
            } else if (!this.parentType && !targetParent) {
176✔
153
                return true;
33✔
154
            } else if (!this.parentType && targetParent) {
143!
UNCOV
155
                return false;
×
156
            }
157
            if (isReferenceType(targetParent) || isReferenceType(this.parentType)) {
143✔
158
                let thisParentName = isReferenceType(this.parentType) ? this.parentType.memberKey ?? this.parentType.fullName : this.parentType.name;
6!
159
                let targetParentName = isReferenceType(targetParent) ? targetParent.memberKey ?? targetParent.fullName : targetParent.name;
6!
160
                return thisParentName.toLowerCase() === targetParentName.toLowerCase();
6✔
161
            }
162
            return this.parentType.isEqual(targetParent, data);
137✔
163
        }
164
        return false;
×
165
    }
166

167
    protected isAncestorUnresolvedReferenceType() {
168
        let p = this as InheritableType | ReferenceType;
158✔
169
        while (p) {
158✔
170
            if (isReferenceType(p) && !p.isResolvable()) {
198✔
171
                return true;
2✔
172
            }
173
            p = (p as InheritableType).parentType;
196✔
174

175
        }
176
        return false;
156✔
177
    }
178
}
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