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

rokucommunity / brighterscript / #13234

28 Oct 2024 07:06PM UTC coverage: 89.066% (+2.2%) from 86.866%
#13234

push

web-flow
Merge 9bcb77aad into 9ec6f722c

7233 of 8558 branches covered (84.52%)

Branch coverage included in aggregate %.

34 of 34 new or added lines in 5 files covered. (100.0%)

543 existing lines in 53 files now uncovered.

9621 of 10365 relevant lines covered (92.82%)

1782.52 hits per line

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

88.52
/src/PluginInterface.ts
1
import type { CompilerPlugin } from './interfaces';
2
import { LogLevel, createLogger } from './logging';
1✔
3
import type { Logger } from './logging';
4
/*
5
 * we use `Required` everywhere here because we expect that the methods on plugin objects will
6
 * be optional, and we don't want to deal with `undefined`.
7
 * `extends (...args: any[]) => any` determines whether the thing we're dealing with is a function.
8
 * Returning `never` in the `as` clause of the `[key in object]` step deletes that key from the
9
 * resultant object.
10
 * on the right-hand side of the mapped type we are forced to use a conditional type a second time,
11
 * in order to be able to use the `Parameters` utility type on `Required<T>[K]`. This will always
12
 * be true because of the filtering done by the `[key in object]` clause, but TS requires the duplication.
13
 *
14
 * so put together: we iterate over all of the fields in T, deleting ones which are not (potentially
15
 * optional) functions. For the ones that are, we replace them with their parameters.
16
 *
17
 * this returns the type of an object whose keys are the names of the methods of T and whose values
18
 * are tuples containing the arguments that each method accepts.
19
 */
20
export type PluginEventArgs<T> = {
21
    [K in keyof Required<T> as Required<T>[K] extends (...args: any[]) => any ? K : never]:
22
    Required<T>[K] extends (...args: any[]) => any ? Parameters<Required<T>[K]> : never
23
};
24

25
export default class PluginInterface<T extends CompilerPlugin = CompilerPlugin> {
1✔
26

27
    constructor();
28
    /**
29
     * @deprecated use the `options` parameter pattern instead
30
     */
31
    constructor(
32
        plugins?: CompilerPlugin[],
33
        logger?: Logger
34
    );
35
    constructor(
36
        plugins?: CompilerPlugin[],
37
        options?: {
38
            logger?: Logger;
39
            suppressErrors?: boolean;
40
        }
41
    );
42
    constructor(
43
        private plugins?: CompilerPlugin[],
1,318✔
44
        options?: {
45
            logger?: Logger;
46
            suppressErrors?: boolean;
47
        } | Logger
48
    ) {
49
        this.plugins ??= [];
1,318✔
50
        if (options?.constructor.name === 'Logger') {
1,318!
UNCOV
51
            this.logger = options as unknown as Logger;
×
52
        } else {
53
            this.logger = (options as any)?.logger;
1,318✔
54
            this.suppressErrors = (options as any)?.suppressErrors === false ? false : true;
1,318✔
55
        }
56
        if (!this.logger) {
1,318✔
57
            this.logger = createLogger();
1✔
58
        }
59
    }
60

61
    private logger: Logger;
62

63
    /**
64
     * Should plugin errors cause the program to fail, or should they be caught and simply logged
65
     */
66
    private suppressErrors: boolean | undefined;
67

68
    /**
69
     * Call `event` on plugins
70
     */
71
    public emit<K extends keyof PluginEventArgs<T> & string>(event: K, ...args: PluginEventArgs<T>[K]) {
72
        for (let plugin of this.plugins) {
17,091✔
73
            if ((plugin as any)[event]) {
18,376✔
74
                try {
4,374✔
75
                    this.logger.time(LogLevel.debug, [plugin.name, event], () => {
4,374✔
76
                        (plugin as any)[event](...args);
4,374✔
77
                    });
78
                } catch (err) {
79
                    this.logger.error(`Error when calling plugin ${plugin.name}.${event}:`, err);
2✔
80
                    if (!this.suppressErrors) {
2!
UNCOV
81
                        throw err;
×
82
                    }
83
                }
84
            }
85
        }
86
    }
87

88
    /**
89
     * Add a plugin to the beginning of the list of plugins
90
     */
91
    public addFirst<T extends CompilerPlugin = CompilerPlugin>(plugin: T) {
92
        if (!this.has(plugin)) {
1,296!
93
            this.plugins.unshift(plugin);
1,296✔
94
        }
95
        return plugin;
1,296✔
96
    }
97

98
    /**
99
     * Add a plugin to the end of the list of plugins
100
     */
101
    public add<T extends CompilerPlugin = CompilerPlugin>(plugin: T) {
102
        if (!this.has(plugin)) {
105✔
103
            this.plugins.push(plugin);
104✔
104
        }
105
        return plugin;
105✔
106
    }
107

108
    public has(plugin: CompilerPlugin) {
109
        return this.plugins.includes(plugin);
1,406✔
110
    }
111

112
    public remove<T extends CompilerPlugin = CompilerPlugin>(plugin: T) {
113
        if (this.has(plugin)) {
2!
114
            this.plugins.splice(this.plugins.indexOf(plugin));
2✔
115
        }
116
        return plugin;
2✔
117
    }
118

119
    /**
120
     * Remove all plugins
121
     */
122
    public clear() {
UNCOV
123
        this.plugins = [];
×
124
    }
125
}
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

© 2025 Coveralls, Inc