jsii-reflect 1.116.0 → 1.118.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/jsii-query ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('./jsii-query.js');
@@ -0,0 +1,2 @@
1
+ import '@jsii/check-node/run';
2
+ //# sourceMappingURL=jsii-query.d.ts.map
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("@jsii/check-node/run");
4
+ const chalk = require("chalk");
5
+ const yargs = require("yargs");
6
+ const jsii_query_1 = require("../lib/jsii-query");
7
+ async function main() {
8
+ const argv = await yargs
9
+ .usage('$0 <FILE> [QUERY...]', 'Queries a jsii file for its entries.', (args) => args
10
+ .positional('FILE', {
11
+ type: 'string',
12
+ desc: 'path to a .jsii file or directory to load',
13
+ })
14
+ .positional('QUERY', {
15
+ type: 'string',
16
+ desc: 'a query or filter expression to include or exclude items',
17
+ }))
18
+ .option('types', {
19
+ type: 'boolean',
20
+ alias: 't',
21
+ desc: 'after selecting API elements, show all selected types, as well as types containing selected members',
22
+ default: false,
23
+ })
24
+ .option('members', {
25
+ type: 'boolean',
26
+ alias: 'm',
27
+ desc: 'after selecting API elements, show all selected members, as well as members of selected types',
28
+ default: false,
29
+ })
30
+ .options('docs', {
31
+ type: 'boolean',
32
+ alias: 'd',
33
+ desc: 'show documentation for selected elements',
34
+ default: false,
35
+ })
36
+ .option('closure', {
37
+ type: 'boolean',
38
+ alias: 'c',
39
+ default: false,
40
+ desc: 'Load dependencies of package without assuming its a JSII package itself',
41
+ })
42
+ .strict().epilogue(`
43
+ REMARKS
44
+ -------
45
+
46
+ There can be more than one QUERY part, which progressively filters from or adds
47
+ to the list of selected elements.
48
+
49
+ QUERY is of the format:
50
+
51
+ [<op>]<kind>[:<expression>]
52
+
53
+ Where:
54
+
55
+ <op> The type of operation to apply. Absent means '.'
56
+ + Adds new API elements matching the selector to the selection.
57
+ If this selects types, it also includes all type's members.
58
+ - Removes API elements from the current selection that match
59
+ the selector.
60
+ . Removes API elements from the current selection that do NOT
61
+ match the selector (i.e., retain only those that DO match
62
+ the selector) (default)
63
+ <kind> Type of API element to select. One of 'type' or 'member',
64
+ or any of its more specific sub-types such as 'class',
65
+ 'interface', 'struct', 'enum', 'property', 'method', etc.
66
+ Also supports aliases like 'c', 'm', 'mem', 's', 'p', etc.
67
+ <expression> A JavaScript expression that will be evaluated against
68
+ the member. Has access to a number of attributes like
69
+ kind, ancestors, abstract, base, datatype, docs, interfaces,
70
+ name, initializer, optional, overrides, protected, returns,
71
+ parameters, static, variadic, type. The types are the
72
+ same types as offered by the jsii-reflect class model.
73
+
74
+ If the first expression of the query has operator '+', then the query starts
75
+ empty and the selector determines the initial set. Otherwise the query starts
76
+ with all elements and the first expression is a filter on it.
77
+
78
+ This file evaluates the expressions as JavaScript, so this tool is not safe
79
+ against untrusted input!
80
+
81
+ Don't forget to mind your shell escaping rules when you write query expressions.
82
+
83
+ Don't forget to add -- to terminate option parsing if you write negative expressions.
84
+
85
+ EXAMPLES
86
+ -------
87
+
88
+ Select all enums:
89
+ $ jsii-query --types node_modules/aws-cdk-lib enum
90
+
91
+ Select all methods with "grant" in their name:
92
+ $ jsii-query --members node_modules/aws-cdk-lib 'method:name.includes("grant")'
93
+
94
+ Select all classes that have a grant method:
95
+ $ jsii-query --types node_modules/aws-cdk-lib class 'method:name.includes("grant")'
96
+ -or-
97
+ $ jsii-query --types -- node_modules/aws-cdk-lib -interface 'method:name.includes("grant")'
98
+ ^^^^ note this
99
+
100
+ Select all classes that have methods that are named either 'foo' or 'bar':
101
+ $ jsii-query --types node_modules/some-package '+method:name=="foo"' '+method:name=="bar"' .class
102
+
103
+ `).argv;
104
+ // Add some fields that we know are there but yargs typing doesn't know
105
+ const options = argv;
106
+ if (!(options.types || options.members)) {
107
+ throw new Error('At least --types or --members must be specified');
108
+ }
109
+ // Yargs is annoying; if the user uses '--' to terminate the option list,
110
+ // it will not parse positionals into `QUERY` but into `_`
111
+ const expressions = [...options.QUERY, ...options._]
112
+ .map(String)
113
+ .map(jsii_query_1.parseExpression);
114
+ const result = await (0, jsii_query_1.jsiiQuery)({
115
+ fileName: options.FILE,
116
+ expressions,
117
+ closure: options.closure,
118
+ returnTypes: options.types,
119
+ returnMembers: options.members,
120
+ });
121
+ for (const element of result) {
122
+ console.log((0, jsii_query_1.renderElement)(element));
123
+ if (options.docs) {
124
+ console.log(chalk.gray((0, jsii_query_1.renderDocs)(element)
125
+ .split('\n')
126
+ .map((line) => ` ${line}`)
127
+ .join('\n')));
128
+ console.log('');
129
+ }
130
+ }
131
+ process.exitCode = result.length > 0 ? 0 : 1;
132
+ }
133
+ main().catch((e) => {
134
+ console.log(e);
135
+ process.exit(1);
136
+ });
137
+ //# sourceMappingURL=jsii-query.js.map
package/bin/jsii-tree.js CHANGED
@@ -4,7 +4,10 @@ require("@jsii/check-node/run");
4
4
  const chalk = require("chalk");
5
5
  const yargs = require("yargs");
6
6
  const lib_1 = require("../lib");
7
- const JSII_TREE_SUPPORTED_FEATURES = ['intersection-types'];
7
+ const JSII_TREE_SUPPORTED_FEATURES = [
8
+ 'intersection-types',
9
+ 'class-covariant-overrides',
10
+ ];
8
11
  async function main() {
9
12
  const options = await yargs
10
13
  .usage('$0 [JSII-FILE | MODULE-DIR...]', 'Prints an ASCII tree representation of a jsii type system.', (args) => args
@@ -0,0 +1,17 @@
1
+ export type HierarchicalElement = string[];
2
+ export declare class HierarchicalSet {
3
+ private root;
4
+ constructor(elements?: Iterable<HierarchicalElement>);
5
+ addAll(elements: Iterable<HierarchicalElement>): this;
6
+ add(element: HierarchicalElement): this;
7
+ /**
8
+ * Remove every element from LHS that doesn't have a prefix in RHS
9
+ */
10
+ intersect(rhs: HierarchicalSet): this;
11
+ remove(rhs: Iterable<HierarchicalElement>): this;
12
+ get size(): number;
13
+ [Symbol.iterator](): Iterator<HierarchicalElement, HierarchicalElement, any>;
14
+ has(el: HierarchicalElement): boolean;
15
+ private findNode;
16
+ }
17
+ //# sourceMappingURL=hierarchical-set.d.ts.map
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HierarchicalSet = void 0;
4
+ class HierarchicalSet {
5
+ constructor(elements) {
6
+ this.root = {
7
+ exists: false,
8
+ children: {},
9
+ };
10
+ if (elements) {
11
+ this.addAll(elements);
12
+ }
13
+ }
14
+ addAll(elements) {
15
+ for (const element of elements) {
16
+ this.add(element);
17
+ }
18
+ return this;
19
+ }
20
+ add(element) {
21
+ if (element.length === 0) {
22
+ throw new Error('Elements may not be empty');
23
+ }
24
+ let node = this.root;
25
+ for (const segment of element) {
26
+ if (!(segment in node.children)) {
27
+ node.children[segment] = {
28
+ exists: false,
29
+ children: {},
30
+ };
31
+ }
32
+ node = node.children[segment];
33
+ }
34
+ node.exists = true;
35
+ return this;
36
+ }
37
+ /**
38
+ * Remove every element from LHS that doesn't have a prefix in RHS
39
+ */
40
+ intersect(rhs) {
41
+ const retainSet = new HierarchicalSet();
42
+ for (const el of Array.from(this)) {
43
+ let found = false;
44
+ for (let i = 0; i < el.length && !found; i++) {
45
+ found = found || rhs.has(el.slice(0, i + 1));
46
+ }
47
+ if (found) {
48
+ retainSet.add(el);
49
+ }
50
+ }
51
+ this.root = retainSet.root;
52
+ return this;
53
+ }
54
+ remove(rhs) {
55
+ for (const el of rhs) {
56
+ const found = this.findNode(el);
57
+ if (found) {
58
+ const [parent, key] = found;
59
+ delete parent.children[key];
60
+ }
61
+ }
62
+ return this;
63
+ }
64
+ get size() {
65
+ return Array.from(this).length;
66
+ }
67
+ [Symbol.iterator]() {
68
+ if (Object.keys(this.root.children).length === 0) {
69
+ return {
70
+ next() {
71
+ return { done: true };
72
+ },
73
+ };
74
+ }
75
+ const stack = [];
76
+ function cursorFrom(node) {
77
+ return {
78
+ trie: node.children,
79
+ keys: Object.keys(node.children),
80
+ index: 0,
81
+ };
82
+ }
83
+ stack.push(cursorFrom(this.root));
84
+ let done = false;
85
+ let cur = stack[stack.length - 1];
86
+ /**
87
+ * Move 'cur' to the next node in the trie
88
+ */
89
+ function advance() {
90
+ // If we can descend, let's
91
+ if (!isEmpty(cur.trie[cur.keys[cur.index]])) {
92
+ stack.push(cursorFrom(cur.trie[cur.keys[cur.index]]));
93
+ cur = stack[stack.length - 1];
94
+ return;
95
+ }
96
+ cur.index += 1;
97
+ while (cur.index >= cur.keys.length) {
98
+ stack.pop();
99
+ if (stack.length === 0) {
100
+ done = true;
101
+ break;
102
+ }
103
+ cur = stack[stack.length - 1];
104
+ // Advance the pointer after coming back.
105
+ cur.index += 1;
106
+ }
107
+ }
108
+ return {
109
+ next() {
110
+ while (!done && !cur.trie[cur.keys[cur.index]].exists) {
111
+ advance();
112
+ }
113
+ const value = !done ? stack.map((f) => f.keys[f.index]) : undefined;
114
+ // Node's Array.from doesn't quite correctly implement the iterator protocol.
115
+ // If we return { value: <something>, done: true } it will pretend to never
116
+ // have seen <something>, so we need to split this into 2 steps.
117
+ // The TypeScript typings don't agree, so 'as any' that away.
118
+ const ret = (value ? { value, done } : { done });
119
+ if (!done) {
120
+ advance();
121
+ }
122
+ return ret;
123
+ },
124
+ };
125
+ }
126
+ has(el) {
127
+ const found = this.findNode(el);
128
+ if (!found) {
129
+ return false;
130
+ }
131
+ const [node, last] = found;
132
+ return node.children?.[last]?.exists ?? false;
133
+ }
134
+ findNode(el) {
135
+ if (el.length === 0) {
136
+ throw new Error('Elements may not be empty');
137
+ }
138
+ const parts = [...el];
139
+ let parent = this.root;
140
+ while (parts.length > 1) {
141
+ const next = parts.splice(0, 1)[0];
142
+ parent = parent.children?.[next];
143
+ if (!parent) {
144
+ return undefined;
145
+ }
146
+ }
147
+ return [parent, parts[0]];
148
+ }
149
+ }
150
+ exports.HierarchicalSet = HierarchicalSet;
151
+ function isEmpty(node) {
152
+ return Object.keys(node.children).length === 0;
153
+ }
154
+ //# sourceMappingURL=hierarchical-set.js.map
@@ -0,0 +1,41 @@
1
+ import '@jsii/check-node/run';
2
+ import { Documentable } from '../lib';
3
+ export interface JsiiQueryOptions {
4
+ readonly fileName: string;
5
+ readonly expressions: QExpr[];
6
+ readonly closure?: boolean;
7
+ readonly returnTypes?: boolean;
8
+ readonly returnMembers?: boolean;
9
+ }
10
+ export declare function jsiiQuery(options: JsiiQueryOptions): Promise<ApiElement[]>;
11
+ export declare class Predicate {
12
+ private readonly fn;
13
+ constructor(expr?: string);
14
+ apply(context: Record<string, unknown>): boolean;
15
+ }
16
+ type QExpr = QSelect | QFilter;
17
+ /**
18
+ * Select adds elements
19
+ */
20
+ interface QSelect {
21
+ readonly op: 'select';
22
+ readonly kind: ApiKind;
23
+ readonly expression?: string;
24
+ }
25
+ /**
26
+ * Filter retains elements
27
+ */
28
+ interface QFilter {
29
+ readonly op: 'filter';
30
+ readonly remove: boolean;
31
+ readonly kind: ApiKind;
32
+ readonly expression?: string;
33
+ }
34
+ export declare function parseExpression(expr: string): QExpr;
35
+ export declare function renderElement(el: ApiElement): string;
36
+ export declare function renderDocs(el: ApiElement): string;
37
+ declare const VALID_KINDS: readonly ["type", "interface", "class", "enum", "struct", "member", "property", "method", "initializer"];
38
+ type ApiKind = (typeof VALID_KINDS)[number];
39
+ type ApiElement = Documentable;
40
+ export {};
41
+ //# sourceMappingURL=jsii-query.d.ts.map
@@ -0,0 +1,307 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Predicate = void 0;
4
+ exports.jsiiQuery = jsiiQuery;
5
+ exports.parseExpression = parseExpression;
6
+ exports.renderElement = renderElement;
7
+ exports.renderDocs = renderDocs;
8
+ /* eslint-disable @typescript-eslint/no-implied-eval */
9
+ require("@jsii/check-node/run");
10
+ const lib_1 = require("../lib");
11
+ const hierarchical_set_1 = require("./hierarchical-set");
12
+ const JSII_TREE_SUPPORTED_FEATURES = [
13
+ 'intersection-types',
14
+ 'class-covariant-overrides',
15
+ ];
16
+ async function jsiiQuery(options) {
17
+ const typesys = new lib_1.TypeSystem();
18
+ if (options.closure) {
19
+ await typesys.loadNpmDependencies(options.fileName, {
20
+ validate: false,
21
+ supportedFeatures: JSII_TREE_SUPPORTED_FEATURES,
22
+ });
23
+ }
24
+ else {
25
+ await typesys.load(options.fileName, {
26
+ validate: false,
27
+ supportedFeatures: JSII_TREE_SUPPORTED_FEATURES,
28
+ });
29
+ }
30
+ const universe = selectAll(typesys);
31
+ const selectedElements = selectApiElements(universe, options.expressions);
32
+ expandSelectToParentsAndChildren(universe, selectedElements, options);
33
+ // The keys are sortable, so sort them, then get the original API elements back
34
+ // and return only those that were asked for.
35
+ // Then retain only the kinds we asked for, and sort them
36
+ return Array.from(selectedElements)
37
+ .sort()
38
+ .map((key) => universe.get(stringFromKey(key)))
39
+ .filter((x) => (isType(x) && options.returnTypes) ||
40
+ (isMember(x) && options.returnMembers));
41
+ }
42
+ // - if we are asking for types, include any type that's a parent of any of the selected members
43
+ // - if we are asking for members, include all members that are a child of any of the selected types
44
+ function expandSelectToParentsAndChildren(universe, selected, options) {
45
+ if (options.returnTypes) {
46
+ // All type keys from either type keys or member keys
47
+ selected.addAll(Array.from(selected).map(typeKey));
48
+ }
49
+ if (options.returnMembers) {
50
+ const allElements = new hierarchical_set_1.HierarchicalSet(Array.from(universe.keys()).map(keyFromString));
51
+ // Add all member keys that are members of a selected type
52
+ selected.addAll(new hierarchical_set_1.HierarchicalSet(allElements).intersect(selected));
53
+ }
54
+ }
55
+ function isType(x) {
56
+ return (x instanceof lib_1.ClassType ||
57
+ x instanceof lib_1.InterfaceType ||
58
+ x instanceof lib_1.EnumType);
59
+ }
60
+ function isMember(x) {
61
+ return x instanceof lib_1.Callable || x instanceof lib_1.Property;
62
+ }
63
+ /**
64
+ * Returns a unique key per API element, used because the jsii-reflect members don't guarantee uniqueness at the object level
65
+ *
66
+ * Keys have the property that parent keys are a prefix of child keys, and that the keys are in sort order
67
+ */
68
+ function apiElementKey(x) {
69
+ if (isType(x)) {
70
+ return [`${x.fqn}`];
71
+ }
72
+ if (isMember(x)) {
73
+ const sort = x instanceof lib_1.Method && x.static
74
+ ? '000'
75
+ : x instanceof lib_1.Initializer
76
+ ? '001'
77
+ : '002';
78
+ return [`${x.parentType.fqn}`, `${sort}${x.name}`];
79
+ }
80
+ throw new Error('huh');
81
+ }
82
+ function stringFromKey(x) {
83
+ return x.map((s) => `${s}#`).join('');
84
+ }
85
+ function keyFromString(x) {
86
+ return x.split('#').slice(0, -1);
87
+ }
88
+ /**
89
+ * Given a type or member key, return the type key
90
+ */
91
+ function typeKey(x) {
92
+ return [x[0]];
93
+ }
94
+ function selectApiElements(universe, expressions) {
95
+ const allKeys = new hierarchical_set_1.HierarchicalSet(Array.from(universe.keys()).map(keyFromString));
96
+ const currentSelection = expressions.length === 0 || expressions[0].op === 'filter'
97
+ ? new hierarchical_set_1.HierarchicalSet(allKeys)
98
+ : new hierarchical_set_1.HierarchicalSet();
99
+ for (const expr of expressions) {
100
+ const thisQuery = Array.from(filterElements(universe, allKeys, expr.kind, expr.expression));
101
+ if (expr.op === 'filter' && expr.remove) {
102
+ currentSelection.remove(thisQuery);
103
+ }
104
+ else if (expr.op === 'filter') {
105
+ currentSelection.intersect(new hierarchical_set_1.HierarchicalSet(thisQuery));
106
+ }
107
+ else {
108
+ currentSelection.addAll(thisQuery);
109
+ }
110
+ }
111
+ return currentSelection;
112
+ }
113
+ function* filterElements(universe, elements, kind, expression) {
114
+ const pred = new Predicate(expression);
115
+ for (const key of elements) {
116
+ const el = universe.get(stringFromKey(key));
117
+ if (!el) {
118
+ throw new Error(`Key not in universe: ${stringFromKey(key)}`);
119
+ }
120
+ if (matches(el, kind, pred)) {
121
+ yield key;
122
+ }
123
+ }
124
+ }
125
+ class Predicate {
126
+ constructor(expr) {
127
+ if (!expr) {
128
+ this.fn = () => true;
129
+ }
130
+ else {
131
+ const args = API_ELEMENT_ATTRIBUTES.join(',');
132
+ const body = `return Boolean(${expr});`;
133
+ try {
134
+ this.fn = Function(args, body);
135
+ }
136
+ catch (e) {
137
+ throw new Error(`Syntax error in selector: ${body}: ${e}`);
138
+ }
139
+ }
140
+ }
141
+ apply(context) {
142
+ return this.fn(...API_ELEMENT_ATTRIBUTES.map((attr) => context[attr]));
143
+ }
144
+ }
145
+ exports.Predicate = Predicate;
146
+ /**
147
+ * Whether a given API element matches the filter
148
+ */
149
+ function matches(el, kind, pred) {
150
+ const context = {};
151
+ if (el instanceof lib_1.ClassType) {
152
+ if (!['type', 'class'].includes(kind))
153
+ return false;
154
+ context.kind = 'class';
155
+ }
156
+ if (el instanceof lib_1.InterfaceType) {
157
+ const moreSpecificInterfaceType = el.datatype ? 'struct' : 'interface';
158
+ if (!['type', moreSpecificInterfaceType].includes(kind))
159
+ return false;
160
+ context.kind = moreSpecificInterfaceType;
161
+ }
162
+ if (el instanceof lib_1.EnumType) {
163
+ if (!['type', 'enum'].includes(kind))
164
+ return false;
165
+ context.kind = 'enum';
166
+ }
167
+ if (el instanceof lib_1.Property) {
168
+ if (!['member', 'property'].includes(kind))
169
+ return false;
170
+ context.kind = 'property';
171
+ }
172
+ if (el instanceof lib_1.Callable) {
173
+ const moreSpecificCallable = el instanceof lib_1.Initializer ? 'initializer' : 'method';
174
+ if (!['member', moreSpecificCallable].includes(kind))
175
+ return false;
176
+ context.kind = moreSpecificCallable;
177
+ }
178
+ Object.assign(context, Object.fromEntries(API_ELEMENT_ATTRIBUTES.map((attr) => [attr, el[attr]])));
179
+ const ret = pred.apply(context);
180
+ return ret;
181
+ }
182
+ function selectAll(typesys) {
183
+ return new Map([
184
+ ...typesys.classes,
185
+ ...typesys.interfaces,
186
+ ...typesys.enums,
187
+ ...typesys.methods,
188
+ ...typesys.properties,
189
+ ].map((el) => [stringFromKey(apiElementKey(el)), el]));
190
+ }
191
+ const KIND_ALIASES = {
192
+ t: 'type',
193
+ c: 'class',
194
+ i: 'interface',
195
+ s: 'struct',
196
+ e: 'enum',
197
+ p: 'property',
198
+ prop: 'property',
199
+ mem: 'member',
200
+ m: 'method',
201
+ init: 'initializer',
202
+ ctr: 'initializer',
203
+ constructor: 'initializer',
204
+ };
205
+ function parseExpression(expr) {
206
+ let op;
207
+ if (expr[0].match(/[a-z]/i)) {
208
+ op = '.';
209
+ }
210
+ else {
211
+ op = expr[0];
212
+ expr = expr.slice(1);
213
+ }
214
+ if (!['-', '+', '.'].includes(op)) {
215
+ throw new Error(`Invalid operator: ${op} (must be +, - or .)`);
216
+ }
217
+ const operator = op;
218
+ const [kind_, ...expressionParts] = expr.split(':');
219
+ const kind = (KIND_ALIASES[kind_] ??
220
+ kind_);
221
+ if (!VALID_KINDS.includes(kind)) {
222
+ throw new Error(`Invalid kind: ${kind} (must be one of ${VALID_KINDS.join(', ')})`);
223
+ }
224
+ return {
225
+ op: operator === '+' ? 'select' : 'filter',
226
+ remove: operator === '-',
227
+ kind,
228
+ expression: expressionParts?.join(':'),
229
+ };
230
+ }
231
+ function renderElement(el) {
232
+ if (el instanceof lib_1.ClassType) {
233
+ return combine(el.abstract ? 'abstract' : '', 'class', el.fqn);
234
+ }
235
+ if (el instanceof lib_1.InterfaceType) {
236
+ if (el.spec.datatype) {
237
+ return combine('struct', el.fqn);
238
+ }
239
+ return combine('interface', el.fqn);
240
+ }
241
+ if (el instanceof lib_1.EnumType) {
242
+ return combine('enum', el.fqn);
243
+ }
244
+ if (el instanceof lib_1.Property) {
245
+ const opt = el.optional ? '?' : '';
246
+ return combine(el.static ? 'static' : '', el.immutable ? 'readonly' : '', `${el.parentType.fqn}#${el.name}${opt}: ${el.type.toString()}`);
247
+ }
248
+ if (el instanceof lib_1.Method) {
249
+ return combine(el.static ? 'static' : '', `${el.parentType.fqn}#${el.name}(${renderParams(el.parameters)}): ${el.returns.toString()}`);
250
+ }
251
+ if (el instanceof lib_1.Initializer) {
252
+ return `${el.parentType.fqn}(${renderParams(el.parameters)}`;
253
+ }
254
+ return '???';
255
+ }
256
+ function renderDocs(el) {
257
+ return el.docs.toString();
258
+ }
259
+ function renderParams(ps) {
260
+ return (ps ?? [])
261
+ .map((p) => {
262
+ const opt = p.optional ? '?' : '';
263
+ const varia = p.variadic ? '...' : '';
264
+ const arr = p.variadic ? '[]' : '';
265
+ return `${varia}${p.name}${opt}: ${p.type.toString()}${arr}`;
266
+ })
267
+ .join(', ');
268
+ }
269
+ function combine(...xs) {
270
+ return xs.filter((x) => x).join(' ');
271
+ }
272
+ // A list of all valid API element kinds
273
+ const VALID_KINDS = [
274
+ // Types
275
+ 'type',
276
+ 'interface',
277
+ 'class',
278
+ 'enum',
279
+ 'struct',
280
+ // Members
281
+ 'member',
282
+ 'property',
283
+ 'method',
284
+ 'initializer',
285
+ ];
286
+ const API_ELEMENT_ATTRIBUTES = [
287
+ 'kind',
288
+ // Types
289
+ 'ancestors',
290
+ 'abstract',
291
+ 'base',
292
+ 'datatype',
293
+ 'docs',
294
+ 'interfaces',
295
+ 'name',
296
+ // Members
297
+ 'initializer',
298
+ 'optional',
299
+ 'overrides',
300
+ 'protected',
301
+ 'returns',
302
+ 'parameters',
303
+ 'static',
304
+ 'variadic',
305
+ 'type',
306
+ ];
307
+ //# sourceMappingURL=jsii-query.js.map
package/lib/method.d.ts CHANGED
@@ -39,5 +39,9 @@ export declare class Method extends Callable implements Documentable, Overridabl
39
39
  * Indicates if this is a static method.
40
40
  */
41
41
  get static(): boolean;
42
+ /**
43
+ * The Method that this method overrides, if any
44
+ */
45
+ get overriddenMethod(): Method | undefined;
42
46
  }
43
47
  //# sourceMappingURL=method.d.ts.map
package/lib/method.js CHANGED
@@ -61,6 +61,16 @@ class Method extends callable_1.Callable {
61
61
  get static() {
62
62
  return !!this.spec.static;
63
63
  }
64
+ /**
65
+ * The Method that this method overrides, if any
66
+ */
67
+ get overriddenMethod() {
68
+ const o = this.overrides;
69
+ if (o && (o.isClassType() || o.isInterfaceType())) {
70
+ return o.ownMethods.find((m) => m.name === this.name);
71
+ }
72
+ return undefined;
73
+ }
64
74
  }
65
75
  exports.Method = Method;
66
76
  __decorate([
package/lib/property.d.ts CHANGED
@@ -51,5 +51,9 @@ export declare class Property extends OptionalValue implements Documentable, Ove
51
51
  * Return the location in the repository
52
52
  */
53
53
  get locationInRepository(): SourceLocation | undefined;
54
+ /**
55
+ * The Property that this property overrides, if any
56
+ */
57
+ get overriddenProperty(): Property | undefined;
54
58
  }
55
59
  //# sourceMappingURL=property.d.ts.map
package/lib/property.js CHANGED
@@ -76,6 +76,16 @@ class Property extends optional_value_1.OptionalValue {
76
76
  get locationInRepository() {
77
77
  return (0, source_1.locationInRepository)(this);
78
78
  }
79
+ /**
80
+ * The Property that this property overrides, if any
81
+ */
82
+ get overriddenProperty() {
83
+ const o = this.overrides;
84
+ if (o && (o.isClassType() || o.isInterfaceType())) {
85
+ return o.ownProperties.find((p) => p.name === this.name);
86
+ }
87
+ return undefined;
88
+ }
79
89
  }
80
90
  exports.Property = Property;
81
91
  //# sourceMappingURL=property.js.map
@@ -12,6 +12,10 @@ import { Type } from './type';
12
12
  * The features claimed by the user of jsii-reflect must be a subset of these.
13
13
  */
14
14
  export declare const JSII_REFLECT_SUPPORTED_ASSEMBLY_FEATURES: JsiiFeature[];
15
+ /**
16
+ * All supported features as a type
17
+ */
18
+ export type JsiiReflectSupportedAssemblyFeatures = (typeof JSII_REFLECT_SUPPORTED_ASSEMBLY_FEATURES)[number];
15
19
  export declare class TypeSystem {
16
20
  /**
17
21
  * The "root" assemblies (ones that loaded explicitly via a "load" call).
@@ -40,6 +44,7 @@ export declare class TypeSystem {
40
44
  */
41
45
  loadNpmDependencies(packageRoot: string, options?: {
42
46
  validate?: boolean;
47
+ supportedFeatures?: JsiiFeature[];
43
48
  }): Promise<void>;
44
49
  /**
45
50
  * Loads a jsii module or a single .jsii file into the type system.
@@ -16,6 +16,7 @@ const util_1 = require("./util");
16
16
  */
17
17
  exports.JSII_REFLECT_SUPPORTED_ASSEMBLY_FEATURES = [
18
18
  'intersection-types',
19
+ 'class-covariant-overrides',
19
20
  ];
20
21
  class TypeSystem {
21
22
  constructor() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsii-reflect",
3
- "version": "1.116.0",
3
+ "version": "1.118.0",
4
4
  "description": "strongly-typed reflection library and tools for jsii",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -27,26 +27,26 @@
27
27
  "scripts": {
28
28
  "build": "tsc --build && chmod +x bin/jsii-tree && yarn lint",
29
29
  "watch": "tsc --build -w",
30
- "lint": "ESLINT_USE_FLAT_CONFIG=false eslint . --ext .js,.ts --ignore-path=.gitignore",
30
+ "lint": "ESLINT_USE_FLAT_CONFIG=false NODE_OPTIONS='--disable-warning=ESLintRCWarning' eslint . --ext .js,.ts --ignore-path=.gitignore",
31
31
  "lint:fix": "yarn lint --fix",
32
32
  "test": "jest",
33
33
  "test:update": "jest -u",
34
34
  "package": "package-js"
35
35
  },
36
36
  "dependencies": {
37
- "@jsii/check-node": "1.116.0",
38
- "@jsii/spec": "1.116.0",
37
+ "@jsii/check-node": "1.118.0",
38
+ "@jsii/spec": "1.118.0",
39
39
  "chalk": "^4",
40
40
  "fs-extra": "^10.1.0",
41
- "oo-ascii-tree": "^1.116.0",
41
+ "oo-ascii-tree": "^1.118.0",
42
42
  "yargs": "^17.7.2"
43
43
  },
44
44
  "devDependencies": {
45
- "@scope/jsii-calc-lib": "^1.116.0",
45
+ "@scope/jsii-calc-lib": "^1.118.0",
46
46
  "@types/fs-extra": "^9.0.13",
47
47
  "@types/yargs": "^17.0.33",
48
- "jsii": "^5.9.6",
49
- "jsii-build-tools": "^1.116.0",
48
+ "jsii": "^5.9.10",
49
+ "jsii-build-tools": "^1.118.0",
50
50
  "jsii-calc": "^3.20.120"
51
51
  }
52
52
  }
@@ -174,6 +174,72 @@ exports[`jsii-tree --all 1`] = `
174
174
  │ │ │ └─┬ enum CompositionStringStyle (stable)
175
175
  │ │ │ ├── NORMAL (stable)
176
176
  │ │ │ └── DECORATED (stable)
177
+ │ │ ├─┬ covariantOverrides
178
+ │ │ │ ├─┬ submodules
179
+ │ │ │ │ └─┬ classOverrides
180
+ │ │ │ │ └─┬ types
181
+ │ │ │ │ ├─┬ class Base (stable)
182
+ │ │ │ │ │ ├── interfaces: IBase
183
+ │ │ │ │ │ └─┬ members
184
+ │ │ │ │ │ ├── <initializer>() initializer (stable)
185
+ │ │ │ │ │ ├─┬ createSomething() method (stable)
186
+ │ │ │ │ │ │ └── returns: jsii-calc.covariantOverrides.classOverrides.Superclass
187
+ │ │ │ │ │ ├─┬ list property (stable)
188
+ │ │ │ │ │ │ ├── immutable
189
+ │ │ │ │ │ │ └── type: Array<jsii-calc.covariantOverrides.classOverrides.Superclass>
190
+ │ │ │ │ │ └─┬ something property (stable)
191
+ │ │ │ │ │ ├── immutable
192
+ │ │ │ │ │ └── type: jsii-calc.covariantOverrides.classOverrides.Superclass
193
+ │ │ │ │ ├─┬ class Derived (stable)
194
+ │ │ │ │ │ ├── base: Middle
195
+ │ │ │ │ │ └─┬ members
196
+ │ │ │ │ │ ├── <initializer>() initializer (stable)
197
+ │ │ │ │ │ ├─┬ createSomething() method (stable)
198
+ │ │ │ │ │ │ └── returns: jsii-calc.covariantOverrides.classOverrides.SubSubclass
199
+ │ │ │ │ │ ├─┬ list property (stable)
200
+ │ │ │ │ │ │ ├── immutable
201
+ │ │ │ │ │ │ └── type: Array<jsii-calc.covariantOverrides.classOverrides.Superclass>
202
+ │ │ │ │ │ └─┬ something property (stable)
203
+ │ │ │ │ │ ├── immutable
204
+ │ │ │ │ │ └── type: jsii-calc.covariantOverrides.classOverrides.SubSubclass
205
+ │ │ │ │ ├─┬ class Middle (stable)
206
+ │ │ │ │ │ ├── base: Base
207
+ │ │ │ │ │ └─┬ members
208
+ │ │ │ │ │ ├── <initializer>() initializer (stable)
209
+ │ │ │ │ │ └─┬ addUnrelatedMember property (stable)
210
+ │ │ │ │ │ └── type: number
211
+ │ │ │ │ ├─┬ class SubSubclass (stable)
212
+ │ │ │ │ │ ├── base: Subclass
213
+ │ │ │ │ │ └─┬ members
214
+ │ │ │ │ │ ├── <initializer>() initializer (stable)
215
+ │ │ │ │ │ ├─┬ sayHello() method (stable)
216
+ │ │ │ │ │ │ └── returns: string
217
+ │ │ │ │ │ ├─┬ name property (stable)
218
+ │ │ │ │ │ │ └── type: string
219
+ │ │ │ │ │ └─┬ unique property (stable)
220
+ │ │ │ │ │ └── type: string
221
+ │ │ │ │ ├─┬ class Subclass (stable)
222
+ │ │ │ │ │ ├── base: Superclass
223
+ │ │ │ │ │ └─┬ members
224
+ │ │ │ │ │ ├── <initializer>() initializer (stable)
225
+ │ │ │ │ │ ├─┬ sayHello() method (stable)
226
+ │ │ │ │ │ │ └── returns: string
227
+ │ │ │ │ │ └─┬ name property (stable)
228
+ │ │ │ │ │ └── type: string
229
+ │ │ │ │ ├─┬ class Superclass (stable)
230
+ │ │ │ │ │ └─┬ members
231
+ │ │ │ │ │ ├── <initializer>() initializer (stable)
232
+ │ │ │ │ │ ├─┬ sayHello() method (stable)
233
+ │ │ │ │ │ │ └── returns: string
234
+ │ │ │ │ │ └─┬ name property (stable)
235
+ │ │ │ │ │ └── type: string
236
+ │ │ │ │ └─┬ interface IBase (stable)
237
+ │ │ │ │ └─┬ members
238
+ │ │ │ │ └─┬ something property (stable)
239
+ │ │ │ │ ├── abstract
240
+ │ │ │ │ ├── immutable
241
+ │ │ │ │ └── type: jsii-calc.covariantOverrides.classOverrides.Superclass
242
+ │ │ │ └── types
177
243
  │ │ ├─┬ homonymousForwardReferences
178
244
  │ │ │ ├─┬ submodules
179
245
  │ │ │ │ ├─┬ bar
@@ -3814,6 +3880,23 @@ exports[`jsii-tree --inheritance 1`] = `
3814
3880
  │ │ │ ├─┬ class CompositeOperation
3815
3881
  │ │ │ │ └── base: Operation
3816
3882
  │ │ │ └── enum CompositionStringStyle
3883
+ │ │ ├─┬ covariantOverrides
3884
+ │ │ │ ├─┬ submodules
3885
+ │ │ │ │ └─┬ classOverrides
3886
+ │ │ │ │ └─┬ types
3887
+ │ │ │ │ ├─┬ class Base
3888
+ │ │ │ │ │ └── interfaces: IBase
3889
+ │ │ │ │ ├─┬ class Derived
3890
+ │ │ │ │ │ └── base: Middle
3891
+ │ │ │ │ ├─┬ class Middle
3892
+ │ │ │ │ │ └── base: Base
3893
+ │ │ │ │ ├─┬ class SubSubclass
3894
+ │ │ │ │ │ └── base: Subclass
3895
+ │ │ │ │ ├─┬ class Subclass
3896
+ │ │ │ │ │ └── base: Superclass
3897
+ │ │ │ │ ├── class Superclass
3898
+ │ │ │ │ └── interface IBase
3899
+ │ │ │ └── types
3817
3900
  │ │ ├─┬ homonymousForwardReferences
3818
3901
  │ │ │ ├─┬ submodules
3819
3902
  │ │ │ │ ├─┬ bar
@@ -4419,6 +4502,46 @@ exports[`jsii-tree --members 1`] = `
4419
4502
  │ │ │ └─┬ enum CompositionStringStyle
4420
4503
  │ │ │ ├── NORMAL
4421
4504
  │ │ │ └── DECORATED
4505
+ │ │ ├─┬ covariantOverrides
4506
+ │ │ │ ├─┬ submodules
4507
+ │ │ │ │ └─┬ classOverrides
4508
+ │ │ │ │ └─┬ types
4509
+ │ │ │ │ ├─┬ class Base
4510
+ │ │ │ │ │ └─┬ members
4511
+ │ │ │ │ │ ├── <initializer>() initializer
4512
+ │ │ │ │ │ ├── createSomething() method
4513
+ │ │ │ │ │ ├── list property
4514
+ │ │ │ │ │ └── something property
4515
+ │ │ │ │ ├─┬ class Derived
4516
+ │ │ │ │ │ └─┬ members
4517
+ │ │ │ │ │ ├── <initializer>() initializer
4518
+ │ │ │ │ │ ├── createSomething() method
4519
+ │ │ │ │ │ ├── list property
4520
+ │ │ │ │ │ └── something property
4521
+ │ │ │ │ ├─┬ class Middle
4522
+ │ │ │ │ │ └─┬ members
4523
+ │ │ │ │ │ ├── <initializer>() initializer
4524
+ │ │ │ │ │ └── addUnrelatedMember property
4525
+ │ │ │ │ ├─┬ class SubSubclass
4526
+ │ │ │ │ │ └─┬ members
4527
+ │ │ │ │ │ ├── <initializer>() initializer
4528
+ │ │ │ │ │ ├── sayHello() method
4529
+ │ │ │ │ │ ├── name property
4530
+ │ │ │ │ │ └── unique property
4531
+ │ │ │ │ ├─┬ class Subclass
4532
+ │ │ │ │ │ └─┬ members
4533
+ │ │ │ │ │ ├── <initializer>() initializer
4534
+ │ │ │ │ │ ├── sayHello() method
4535
+ │ │ │ │ │ └── name property
4536
+ │ │ │ │ ├─┬ class Superclass
4537
+ │ │ │ │ │ └─┬ members
4538
+ │ │ │ │ │ ├── <initializer>() initializer
4539
+ │ │ │ │ │ ├── sayHello() method
4540
+ │ │ │ │ │ └── name property
4541
+ │ │ │ │ └─┬ interface IBase
4542
+ │ │ │ │ └─┬ members
4543
+ │ │ │ │ └── something property
4544
+ │ │ │ └── types
4422
4545
  │ │ ├─┬ homonymousForwardReferences
4423
4546
  │ │ │ ├─┬ submodules
4424
4547
  │ │ │ │ ├─┬ bar
@@ -6060,6 +6183,9 @@ exports[`jsii-tree --signatures 1`] = `
6060
6183
  │ │ └── donotimport
6061
6184
  │ ├── cdk22369
6062
6185
  │ ├── composition
6186
+ │ ├─┬ covariantOverrides
6187
+ │ │ └─┬ submodules
6188
+ │ │ └── classOverrides
6063
6189
  │ ├─┬ homonymousForwardReferences
6064
6190
  │ │ └─┬ submodules
6065
6191
  │ │ ├── bar
@@ -6149,6 +6275,18 @@ exports[`jsii-tree --types 1`] = `
6149
6275
  │ │ │ └─┬ types
6150
6276
  │ │ │ ├── class CompositeOperation
6151
6277
  │ │ │ └── enum CompositionStringStyle
6278
+ │ │ ├─┬ covariantOverrides
6279
+ │ │ │ ├─┬ submodules
6280
+ │ │ │ │ └─┬ classOverrides
6281
+ │ │ │ │ └─┬ types
6282
+ │ │ │ │ ├── class Base
6283
+ │ │ │ │ ├── class Derived
6284
+ │ │ │ │ ├── class Middle
6285
+ │ │ │ │ ├── class SubSubclass
6286
+ │ │ │ │ ├── class Subclass
6287
+ │ │ │ │ ├── class Superclass
6288
+ │ │ │ │ └── interface IBase
6289
+ │ │ │ └── types
6152
6290
  │ │ ├─┬ homonymousForwardReferences
6153
6291
  │ │ │ ├─┬ submodules
6154
6292
  │ │ │ │ ├─┬ bar
@@ -6571,6 +6709,9 @@ exports[`jsii-tree 1`] = `
6571
6709
  │ │ └── donotimport
6572
6710
  │ ├── cdk22369
6573
6711
  │ ├── composition
6712
+ │ ├─┬ covariantOverrides
6713
+ │ │ └─┬ submodules
6714
+ │ │ └── classOverrides
6574
6715
  │ ├─┬ homonymousForwardReferences
6575
6716
  │ │ └─┬ submodules
6576
6717
  │ │ ├── bar
@@ -14,6 +14,9 @@ exports[`defaults 1`] = `
14
14
  │ │ └── donotimport
15
15
  │ ├── cdk22369
16
16
  │ ├── composition
17
+ │ ├─┬ covariantOverrides
18
+ │ │ └─┬ submodules
19
+ │ │ └── classOverrides
17
20
  │ ├─┬ homonymousForwardReferences
18
21
  │ │ └─┬ submodules
19
22
  │ │ ├── bar
@@ -76,6 +79,9 @@ exports[`inheritance 1`] = `
76
79
  │ │ └── donotimport
77
80
  │ ├── cdk22369
78
81
  │ ├── composition
82
+ │ ├─┬ covariantOverrides
83
+ │ │ └─┬ submodules
84
+ │ │ └── classOverrides
79
85
  │ ├─┬ homonymousForwardReferences
80
86
  │ │ └─┬ submodules
81
87
  │ │ ├── bar
@@ -138,6 +144,9 @@ exports[`members 1`] = `
138
144
  │ │ └── donotimport
139
145
  │ ├── cdk22369
140
146
  │ ├── composition
147
+ │ ├─┬ covariantOverrides
148
+ │ │ └─┬ submodules
149
+ │ │ └── classOverrides
141
150
  │ ├─┬ homonymousForwardReferences
142
151
  │ │ └─┬ submodules
143
152
  │ │ ├── bar
@@ -360,6 +369,72 @@ exports[`showAll 1`] = `
360
369
  │ │ │ └─┬ enum CompositionStringStyle
361
370
  │ │ │ ├── NORMAL
362
371
  │ │ │ └── DECORATED
372
+ │ │ ├─┬ covariantOverrides
373
+ │ │ │ ├─┬ submodules
374
+ │ │ │ │ └─┬ classOverrides
375
+ │ │ │ │ └─┬ types
376
+ │ │ │ │ ├─┬ class Base
377
+ │ │ │ │ │ ├── interfaces: IBase
378
+ │ │ │ │ │ └─┬ members
379
+ │ │ │ │ │ ├── <initializer>() initializer
380
+ │ │ │ │ │ ├─┬ createSomething() method
381
+ │ │ │ │ │ │ └── returns: jsii-calc.covariantOverrides.classOverrides.Superclass
382
+ │ │ │ │ │ ├─┬ list property
383
+ │ │ │ │ │ │ ├── immutable
384
+ │ │ │ │ │ │ └── type: Array<jsii-calc.covariantOverrides.classOverrides.Superclass>
385
+ │ │ │ │ │ └─┬ something property
386
+ │ │ │ │ │ ├── immutable
387
+ │ │ │ │ │ └── type: jsii-calc.covariantOverrides.classOverrides.Superclass
388
+ │ │ │ │ ├─┬ class Derived
389
+ │ │ │ │ │ ├── base: Middle
390
+ │ │ │ │ │ └─┬ members
391
+ │ │ │ │ │ ├── <initializer>() initializer
392
+ │ │ │ │ │ ├─┬ createSomething() method
393
+ │ │ │ │ │ │ └── returns: jsii-calc.covariantOverrides.classOverrides.SubSubclass
394
+ │ │ │ │ │ ├─┬ list property
395
+ │ │ │ │ │ │ ├── immutable
396
+ │ │ │ │ │ │ └── type: Array<jsii-calc.covariantOverrides.classOverrides.Superclass>
397
+ │ │ │ │ │ └─┬ something property
398
+ │ │ │ │ │ ├── immutable
399
+ │ │ │ │ │ └── type: jsii-calc.covariantOverrides.classOverrides.SubSubclass
400
+ │ │ │ │ ├─┬ class Middle
401
+ │ │ │ │ │ ├── base: Base
402
+ │ │ │ │ │ └─┬ members
403
+ │ │ │ │ │ ├── <initializer>() initializer
404
+ │ │ │ │ │ └─┬ addUnrelatedMember property
405
+ │ │ │ │ │ └── type: number
406
+ │ │ │ │ ├─┬ class SubSubclass
407
+ │ │ │ │ │ ├── base: Subclass
408
+ │ │ │ │ │ └─┬ members
409
+ │ │ │ │ │ ├── <initializer>() initializer
410
+ │ │ │ │ │ ├─┬ sayHello() method
411
+ │ │ │ │ │ │ └── returns: string
412
+ │ │ │ │ │ ├─┬ name property
413
+ │ │ │ │ │ │ └── type: string
414
+ │ │ │ │ │ └─┬ unique property
415
+ │ │ │ │ │ └── type: string
416
+ │ │ │ │ ├─┬ class Subclass
417
+ │ │ │ │ │ ├── base: Superclass
418
+ │ │ │ │ │ └─┬ members
419
+ │ │ │ │ │ ├── <initializer>() initializer
420
+ │ │ │ │ │ ├─┬ sayHello() method
421
+ │ │ │ │ │ │ └── returns: string
422
+ │ │ │ │ │ └─┬ name property
423
+ │ │ │ │ │ └── type: string
424
+ │ │ │ │ ├─┬ class Superclass
425
+ │ │ │ │ │ └─┬ members
426
+ │ │ │ │ │ ├── <initializer>() initializer
427
+ │ │ │ │ │ ├─┬ sayHello() method
428
+ │ │ │ │ │ │ └── returns: string
429
+ │ │ │ │ │ └─┬ name property
430
+ │ │ │ │ │ └── type: string
431
+ │ │ │ │ └─┬ interface IBase
432
+ │ │ │ │ └─┬ members
433
+ │ │ │ │ └─┬ something property
434
+ │ │ │ │ ├── abstract
435
+ │ │ │ │ ├── immutable
436
+ │ │ │ │ └── type: jsii-calc.covariantOverrides.classOverrides.Superclass
437
+ │ │ │ └── types
363
438
  │ │ ├─┬ homonymousForwardReferences
364
439
  │ │ │ ├─┬ submodules
365
440
  │ │ │ │ ├─┬ bar
@@ -3970,6 +4045,9 @@ exports[`signatures 1`] = `
3970
4045
  │ │ └── donotimport
3971
4046
  │ ├── cdk22369
3972
4047
  │ ├── composition
4048
+ │ ├─┬ covariantOverrides
4049
+ │ │ └─┬ submodules
4050
+ │ │ └── classOverrides
3973
4051
  │ ├─┬ homonymousForwardReferences
3974
4052
  │ │ └─┬ submodules
3975
4053
  │ │ ├── bar
@@ -4059,6 +4137,18 @@ exports[`types 1`] = `
4059
4137
  │ │ │ └─┬ types
4060
4138
  │ │ │ ├── class CompositeOperation
4061
4139
  │ │ │ └── enum CompositionStringStyle
4140
+ │ │ ├─┬ covariantOverrides
4141
+ │ │ │ ├─┬ submodules
4142
+ │ │ │ │ └─┬ classOverrides
4143
+ │ │ │ │ └─┬ types
4144
+ │ │ │ │ ├── class Base
4145
+ │ │ │ │ ├── class Derived
4146
+ │ │ │ │ ├── class Middle
4147
+ │ │ │ │ ├── class SubSubclass
4148
+ │ │ │ │ ├── class Subclass
4149
+ │ │ │ │ ├── class Superclass
4150
+ │ │ │ │ └── interface IBase
4151
+ │ │ │ └── types
4062
4152
  │ │ ├─┬ homonymousForwardReferences
4063
4153
  │ │ │ ├─┬ submodules
4064
4154
  │ │ │ │ ├─┬ bar
@@ -174,6 +174,12 @@ exports[`TypeSystem.classes lists all the classes in the typesystem 1`] = `
174
174
  "jsii-calc.cdk16625.donotimport.UnimportedSubmoduleType",
175
175
  "jsii-calc.cdk22369.AcceptsPath",
176
176
  "jsii-calc.composition.CompositeOperation",
177
+ "jsii-calc.covariantOverrides.classOverrides.Base",
178
+ "jsii-calc.covariantOverrides.classOverrides.Derived",
179
+ "jsii-calc.covariantOverrides.classOverrides.Middle",
180
+ "jsii-calc.covariantOverrides.classOverrides.SubSubclass",
181
+ "jsii-calc.covariantOverrides.classOverrides.Subclass",
182
+ "jsii-calc.covariantOverrides.classOverrides.Superclass",
177
183
  "jsii-calc.homonymousForwardReferences.bar.Consumer",
178
184
  "jsii-calc.homonymousForwardReferences.foo.Consumer",
179
185
  "jsii-calc.intersection.ConsumesIntersection",
package/test/features.js CHANGED
@@ -1,5 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TEST_FEATURES = void 0;
4
- exports.TEST_FEATURES = ['intersection-types'];
4
+ exports.TEST_FEATURES = [
5
+ 'intersection-types',
6
+ 'class-covariant-overrides',
7
+ ];
5
8
  //# sourceMappingURL=features.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hierarchical-set.test.d.ts.map
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const hierarchical_set_1 = require("../lib/hierarchical-set");
4
+ test('empty set', () => {
5
+ expect(Array.from(new hierarchical_set_1.HierarchicalSet())).toEqual([]);
6
+ });
7
+ test('set iteration', () => {
8
+ const hs = new hierarchical_set_1.HierarchicalSet([
9
+ ['a'],
10
+ ['a', 'b', 'c'],
11
+ ['a', 'b', 'd'],
12
+ ['a', 'e'],
13
+ ['f'],
14
+ ]);
15
+ expect(Array.from(hs)).toEqual([
16
+ ['a'],
17
+ ['a', 'b', 'c'],
18
+ ['a', 'b', 'd'],
19
+ ['a', 'e'],
20
+ ['f'],
21
+ ]);
22
+ });
23
+ test('add prefix after child', () => {
24
+ const hs = new hierarchical_set_1.HierarchicalSet();
25
+ hs.addAll([['a', 'b']]);
26
+ hs.addAll([['a']]);
27
+ expect(Array.from(hs)).toEqual([['a'], ['a', 'b']]);
28
+ });
29
+ describe('remove', () => {
30
+ test('remove literals', () => {
31
+ const x = new hierarchical_set_1.HierarchicalSet([['a', 'b'], ['c'], ['d']]);
32
+ x.remove([['a', 'b'], ['c']]);
33
+ expect(Array.from(x)).toEqual([['d']]);
34
+ });
35
+ test('remove parents', () => {
36
+ const x = new hierarchical_set_1.HierarchicalSet([['a', 'b'], ['c'], ['d']]);
37
+ x.remove([['a']]);
38
+ expect(Array.from(x)).toEqual([['c'], ['d']]);
39
+ });
40
+ });
41
+ describe('intersect', () => {
42
+ test('retains literal elements', () => {
43
+ const x = new hierarchical_set_1.HierarchicalSet([['a', 'b'], ['c'], ['d']]);
44
+ x.intersect(new hierarchical_set_1.HierarchicalSet([['a', 'b'], ['c']]));
45
+ expect(Array.from(x)).toEqual([['a', 'b'], ['c']]);
46
+ });
47
+ test('retains children of parents', () => {
48
+ const x = new hierarchical_set_1.HierarchicalSet([['a', 'b'], ['c'], ['d']]);
49
+ x.intersect(new hierarchical_set_1.HierarchicalSet([['a']]));
50
+ expect(Array.from(x)).toEqual([['a', 'b']]);
51
+ });
52
+ test('parent and child only retains child', () => {
53
+ const x = new hierarchical_set_1.HierarchicalSet([['a'], ['a', 'b']]);
54
+ x.intersect(new hierarchical_set_1.HierarchicalSet([['a', 'b'], ['c']]));
55
+ expect(Array.from(x)).toEqual([['a', 'b']]);
56
+ });
57
+ });
58
+ //# sourceMappingURL=hierarchical-set.test.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=jsii-query.test.d.ts.map
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path = require("path");
4
+ const jsii_query_1 = require("../lib/jsii-query");
5
+ describe('parseExpression', () => {
6
+ test('+', () => {
7
+ expect((0, jsii_query_1.parseExpression)('+type')).toMatchObject({
8
+ op: 'select',
9
+ kind: 'type',
10
+ });
11
+ });
12
+ test('-', () => {
13
+ expect((0, jsii_query_1.parseExpression)('-type')).toMatchObject({
14
+ op: 'filter',
15
+ kind: 'type',
16
+ remove: true,
17
+ });
18
+ });
19
+ test('.', () => {
20
+ expect((0, jsii_query_1.parseExpression)('.type')).toMatchObject({
21
+ op: 'filter',
22
+ kind: 'type',
23
+ remove: false,
24
+ });
25
+ expect((0, jsii_query_1.parseExpression)('type')).toMatchObject({
26
+ op: 'filter',
27
+ kind: 'type',
28
+ remove: false,
29
+ });
30
+ });
31
+ test('with expression', () => {
32
+ expect((0, jsii_query_1.parseExpression)('.property:name.startsWith("x")')).toMatchObject({
33
+ op: 'filter',
34
+ kind: 'property',
35
+ remove: false,
36
+ expression: 'name.startsWith("x")',
37
+ });
38
+ });
39
+ });
40
+ describe('Predicate', () => {
41
+ test('Simple', () => {
42
+ const p = new jsii_query_1.Predicate('name.startsWith("ba")');
43
+ expect(p.apply({ name: 'banana' })).toBeTruthy();
44
+ expect(p.apply({ name: 'blob' })).toBeFalsy();
45
+ });
46
+ test('empty', () => {
47
+ const p = new jsii_query_1.Predicate();
48
+ expect(p.apply({ name: 'banana' })).toBeTruthy();
49
+ expect(p.apply({ name: 'blob' })).toBeTruthy();
50
+ });
51
+ });
52
+ describe('filtering', () => {
53
+ test('empty filter returns everything', async () => {
54
+ const result = await query([], 'members');
55
+ expect(result.length).toBeGreaterThan(700);
56
+ expect(result).toContainEqual('readonly jsii-calc.ExportedBaseClass#success: boolean');
57
+ });
58
+ test('filter on method name', async () => {
59
+ const result = await query([(0, jsii_query_1.parseExpression)('method:name.includes("con")')], 'members');
60
+ expect(result).toContainEqual('static @scope/jsii-calc-base-of-base.StaticConsumer#consume(..._args: any[]): void');
61
+ });
62
+ test('filter on methods but expect types', async () => {
63
+ const result = await query([(0, jsii_query_1.parseExpression)('method:name.includes("con")')], 'types');
64
+ expect(result).toContainEqual('class @scope/jsii-calc-base-of-base.StaticConsumer');
65
+ });
66
+ test('filter on type but expect members', async () => {
67
+ const result = await query([(0, jsii_query_1.parseExpression)('class:name == "StaticConsumer"')], 'members');
68
+ expect(result).toContainEqual('static @scope/jsii-calc-base-of-base.StaticConsumer#consume(..._args: any[]): void');
69
+ });
70
+ test('filter on classes with a separate expression', async () => {
71
+ const result = await query([
72
+ (0, jsii_query_1.parseExpression)('method:name.includes("con")'),
73
+ (0, jsii_query_1.parseExpression)('class'),
74
+ ], 'members');
75
+ expect(result).toContainEqual('static @scope/jsii-calc-base-of-base.StaticConsumer#consume(..._args: any[]): void');
76
+ });
77
+ });
78
+ async function query(exp, what = 'all') {
79
+ const jsiiCalcDir = path.dirname(require.resolve('jsii-calc/package.json'));
80
+ const result = await (0, jsii_query_1.jsiiQuery)({
81
+ fileName: jsiiCalcDir,
82
+ expressions: exp,
83
+ returnMembers: what !== 'types',
84
+ returnTypes: what !== 'members',
85
+ });
86
+ return result.map(jsii_query_1.renderElement);
87
+ }
88
+ //# sourceMappingURL=jsii-query.test.js.map
@@ -180,6 +180,8 @@ test('overridden member knows about both parent types', () => {
180
180
  expect(booMethod.parentType).toBe(subType);
181
181
  expect(booMethod.definingType).toBe(subType);
182
182
  expect(booMethod.overrides).toBe(superType);
183
+ const superBooMethod = superType.allMethods.find((m) => m.name === 'boo');
184
+ expect(booMethod.overriddenMethod).toEqual(superBooMethod);
183
185
  });
184
186
  describe('Stability', () => {
185
187
  test('can be read on an item', () => {