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

rokucommunity / brighterscript / #13664

28 Jan 2025 02:09PM UTC coverage: 86.757%. Remained the same
#13664

push

web-flow
Merge 62bbd6b91 into aa9aba86f

12553 of 15295 branches covered (82.07%)

Branch coverage included in aggregate %.

94 of 100 new or added lines in 13 files covered. (94.0%)

108 existing lines in 10 files now uncovered.

13423 of 14646 relevant lines covered (91.65%)

34160.83 hits per line

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

96.83
/src/types/TypedFunctionType.ts
1
import { isDynamicType, isObjectType, isTypedFunctionType } from '../astUtils/reflection';
1✔
2
import { BaseFunctionType } from './BaseFunctionType';
1✔
3
import type { BscType } from './BscType';
4
import { BscTypeKind } from './BscTypeKind';
1✔
5
import { isUnionTypeCompatible } from './helpers';
1✔
6
import { BuiltInInterfaceAdder } from './BuiltInInterfaceAdder';
1✔
7
import type { TypeCompatibilityData } from '../interfaces';
8
import { CallExpression } from '../parser/Expression';
1✔
9

10
export class TypedFunctionType extends BaseFunctionType {
1✔
11
    constructor(
12
        public returnType: BscType
4,057,759✔
13
    ) {
14
        super();
4,057,759✔
15
    }
16

17
    public readonly kind = BscTypeKind.TypedFunctionType;
4,057,759✔
18

19
    /**
20
     * The name of the function for this type. Can be null
21
     */
22
    public name: string;
23

24
    /**
25
     * Determines if this is a sub or not
26
     */
27
    public isSub = false;
4,057,759✔
28

29
    /**
30
     * Does this function accept more args than just those in this.params
31
     */
32
    public isVariadic = false;
4,057,759✔
33

34
    public params = [] as Array<{ name: string; type: BscType; isOptional: boolean }>;
4,057,759✔
35

36
    public setName(name: string) {
37
        this.name = name;
7,999✔
38
        return this;
7,999✔
39
    }
40

41
    public addParameter(name: string, type: BscType, isOptional = false) {
11✔
42
        this.params.push({
3,164,395✔
43
            name: name,
44
            type: type,
45
            isOptional: isOptional === true ? true : false
3,164,395✔
46
        });
47
        return this;
3,164,395✔
48
    }
49

50
    public setVariadic(variadic: boolean) {
51
        this.isVariadic = variadic;
1✔
52
        return this;
1✔
53
    }
54

55
    public isTypeCompatible(targetType: BscType, data: TypeCompatibilityData = {}) {
26✔
56
        if (
19,654✔
57
            isDynamicType(targetType) ||
58,960✔
58
            isObjectType(targetType) ||
59
            isUnionTypeCompatible(this, targetType, data)
60
        ) {
61
            return true;
1✔
62
        }
63
        if (isTypedFunctionType(targetType)) {
19,653✔
64
            return this.checkParamsAndReturnValue(targetType, true, (t1, t2, d) => t1.isTypeCompatible(t2, d), data);
38,088✔
65
        }
66
        return false;
2✔
67
    }
68

69
    public toString() {
70
        let paramTexts = [];
8,804✔
71
        for (let param of this.params) {
8,804✔
72
            paramTexts.push(`${param.name}${param.isOptional ? '?' : ''} as ${param.type.toString()}`);
11,424✔
73
        }
74
        let variadicText = '';
8,804✔
75
        if (this.isVariadic) {
8,804✔
76
            if (paramTexts.length > 0) {
11✔
77
                variadicText += ', ';
1✔
78
            }
79
            variadicText += '...';
11✔
80
        }
81
        return `${this.isSub ? 'sub' : 'function'} ${this.name ?? ''}(${paramTexts.join(', ')}${variadicText}) as ${this.returnType.toString()}`;
8,804✔
82
    }
83

84
    public toTypeString(): string {
UNCOV
85
        return 'Function';
×
86
    }
87

88
    isEqual(targetType: BscType, data: TypeCompatibilityData = {}) {
108✔
89
        if (isTypedFunctionType(targetType)) {
210!
90
            if (this.toString().toLowerCase() === targetType.toString().toLowerCase()) {
210✔
91
                // this function has the same param names and types and return type as the target
92
                return true;
149✔
93
            }
94
            return this.checkParamsAndReturnValue(targetType, false, (t1, t2, predData = {}) => {
61!
95
                return t1.isEqual(t2, { ...predData, allowNameEquality: true });
60✔
96
            }, data);
97
        }
UNCOV
98
        return false;
×
99
    }
100

101
    private checkParamsAndReturnValue(targetType: TypedFunctionType, allowOptionalParamDifferences: boolean, predicate: (type1: BscType, type2: BscType, data: TypeCompatibilityData) => boolean, data?: TypeCompatibilityData) {
102
        //compare all parameters
103
        let len = Math.max(this.params.length, targetType.params.length);
19,712✔
104
        for (let i = 0; i < len; i++) {
19,712✔
105
            let myParam = this.params[i];
18,495✔
106
            let targetParam = targetType.params[i];
18,495✔
107
            if (allowOptionalParamDifferences && !myParam && targetParam.isOptional) {
18,495✔
108
                // target func has MORE (optional) params... that's ok
109
                break;
1✔
110
            }
111

112
            if (!myParam || !targetParam || !predicate(targetParam.type, myParam.type, data)) {
18,494✔
113
                return false;
35✔
114
            }
115
            if (!allowOptionalParamDifferences && myParam.isOptional !== targetParam.isOptional) {
18,459✔
116
                return false;
1✔
117
            } else if (!myParam.isOptional && targetParam.isOptional) {
18,458✔
118
                return false;
1✔
119
            }
120
        }
121
        //compare return type
122
        if (!this.returnType || !targetType.returnType || !predicate(this.returnType, targetType.returnType, data)) {
19,675✔
123
            return false;
45✔
124
        }
125
        if (this.isVariadic !== targetType.isVariadic) {
19,630✔
126
            return false;
1✔
127
        }
128
        //made it here, all params and return type  pass predicate
129
        return true;
19,629✔
130
    }
131

132
    public getMinMaxParamCount(): { minParams: number; maxParams: number } {
133
        //get min/max parameter count for callable
134
        let minParams = 0;
736✔
135
        let maxParams = 0;
736✔
136
        for (let param of this.params) {
736✔
137
            maxParams++;
989✔
138
            //optional parameters must come last, so we can assume that minParams won't increase once we hit
139
            //the first isOptional
140
            if (param.isOptional !== true) {
989✔
141
                minParams++;
537✔
142
            }
143
        }
144
        if (this.isVariadic) {
736✔
145
            // function accepts variable number of arguments
146
            maxParams = CallExpression.MaximumArguments;
14✔
147
        }
148
        return { minParams: minParams, maxParams: maxParams };
736✔
149
    }
150
}
151

152
BuiltInInterfaceAdder.typedFunctionFactory = (returnType: BscType) => {
1✔
153
    return new TypedFunctionType(returnType);
4,053,156✔
154
};
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