jsii-diff 1.35.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/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +111 -0
- package/bin/jsii-diff +2 -0
- package/bin/jsii-diff.d.ts +1 -0
- package/bin/jsii-diff.js +230 -0
- package/lib/diagnostics.d.ts +17 -0
- package/lib/diagnostics.js +52 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +20 -0
- package/lib/stability.d.ts +3 -0
- package/lib/stability.js +52 -0
- package/lib/type-analysis.d.ts +39 -0
- package/lib/type-analysis.js +172 -0
- package/lib/type-comparison.d.ts +195 -0
- package/lib/type-comparison.js +508 -0
- package/lib/types.d.ts +46 -0
- package/lib/types.js +136 -0
- package/lib/util.d.ts +19 -0
- package/lib/util.js +117 -0
- package/lib/validations.d.ts +157 -0
- package/lib/validations.js +487 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.js +7 -0
- package/package.json +57 -0
- package/test/classes.test.d.ts +1 -0
- package/test/classes.test.js +542 -0
- package/test/diagnostics.test.d.ts +1 -0
- package/test/diagnostics.test.js +110 -0
- package/test/enums.test.d.ts +1 -0
- package/test/enums.test.js +41 -0
- package/test/structs.test.d.ts +1 -0
- package/test/structs.test.js +242 -0
- package/test/type-unions.test.d.ts +1 -0
- package/test/type-unions.test.js +101 -0
- package/test/util.d.ts +4 -0
- package/test/util.js +38 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.classifyDiagnostics = exports.hasErrors = exports.formatDiagnostic = exports.DiagLevel = void 0;
|
|
4
|
+
const spec_1 = require("@jsii/spec");
|
|
5
|
+
var DiagLevel;
|
|
6
|
+
(function (DiagLevel) {
|
|
7
|
+
DiagLevel[DiagLevel["Error"] = 0] = "Error";
|
|
8
|
+
DiagLevel[DiagLevel["Warning"] = 1] = "Warning";
|
|
9
|
+
DiagLevel[DiagLevel["Skipped"] = 2] = "Skipped";
|
|
10
|
+
})(DiagLevel = exports.DiagLevel || (exports.DiagLevel = {}));
|
|
11
|
+
const LEVEL_PREFIX = {
|
|
12
|
+
[DiagLevel.Error]: 'err ',
|
|
13
|
+
[DiagLevel.Warning]: 'warn',
|
|
14
|
+
[DiagLevel.Skipped]: 'skip',
|
|
15
|
+
};
|
|
16
|
+
function formatDiagnostic(diag, includeSuppressionKey = false) {
|
|
17
|
+
return [
|
|
18
|
+
LEVEL_PREFIX[diag.level],
|
|
19
|
+
'-',
|
|
20
|
+
diag.message,
|
|
21
|
+
...(includeSuppressionKey ? [`[${diag.suppressionKey}]`] : []),
|
|
22
|
+
].join(' ');
|
|
23
|
+
}
|
|
24
|
+
exports.formatDiagnostic = formatDiagnostic;
|
|
25
|
+
function hasErrors(diags) {
|
|
26
|
+
return diags.some((diag) => diag.level === DiagLevel.Error);
|
|
27
|
+
}
|
|
28
|
+
exports.hasErrors = hasErrors;
|
|
29
|
+
/**
|
|
30
|
+
* Classify API mismatches into a set of warnings and errors
|
|
31
|
+
*/
|
|
32
|
+
function classifyDiagnostics(mismatches, experimentalErrors, skipFilter) {
|
|
33
|
+
const ret = mismatches.mismatches.map((mis) => ({
|
|
34
|
+
level: level(mis),
|
|
35
|
+
message: mis.message,
|
|
36
|
+
suppressionKey: mis.violationKey,
|
|
37
|
+
}));
|
|
38
|
+
ret.sort((a, b) => a.level - b.level);
|
|
39
|
+
return ret;
|
|
40
|
+
function level(mis) {
|
|
41
|
+
if (skipFilter.has(mis.violationKey)) {
|
|
42
|
+
return DiagLevel.Skipped;
|
|
43
|
+
}
|
|
44
|
+
if (mis.stability === spec_1.Stability.Stable ||
|
|
45
|
+
(mis.stability === spec_1.Stability.Experimental && experimentalErrors)) {
|
|
46
|
+
return DiagLevel.Error;
|
|
47
|
+
}
|
|
48
|
+
return DiagLevel.Warning;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.classifyDiagnostics = classifyDiagnostics;
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhZ25vc3RpY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkaWFnbm9zdGljcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxQ0FBdUM7QUFJdkMsSUFBWSxTQUlYO0FBSkQsV0FBWSxTQUFTO0lBQ25CLDJDQUFTLENBQUE7SUFDVCwrQ0FBVyxDQUFBO0lBQ1gsK0NBQVcsQ0FBQTtBQUNiLENBQUMsRUFKVyxTQUFTLEdBQVQsaUJBQVMsS0FBVCxpQkFBUyxRQUlwQjtBQUVELE1BQU0sWUFBWSxHQUFHO0lBQ25CLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLE1BQU07SUFDekIsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTTtJQUMzQixDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxNQUFNO0NBQzVCLENBQUM7QUFRRixTQUFnQixnQkFBZ0IsQ0FDOUIsSUFBZ0IsRUFDaEIscUJBQXFCLEdBQUcsS0FBSztJQUU3QixPQUFPO1FBQ0wsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDeEIsR0FBRztRQUNILElBQUksQ0FBQyxPQUFPO1FBQ1osR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUMvRCxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLENBQUM7QUFWRCw0Q0FVQztBQUVELFNBQWdCLFNBQVMsQ0FBQyxLQUFtQjtJQUMzQyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzlELENBQUM7QUFGRCw4QkFFQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsbUJBQW1CLENBQ2pDLFVBQXNCLEVBQ3RCLGtCQUEyQixFQUMzQixVQUF1QjtJQUV2QixNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM5QyxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQztRQUNqQixPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU87UUFDcEIsY0FBYyxFQUFFLEdBQUcsQ0FBQyxZQUFZO0tBQ2pDLENBQUMsQ0FBQyxDQUFDO0lBQ0osR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3RDLE9BQU8sR0FBRyxDQUFDO0lBRVgsU0FBUyxLQUFLLENBQUMsR0FBZ0I7UUFDN0IsSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsRUFBRTtZQUNwQyxPQUFPLFNBQVMsQ0FBQyxPQUFPLENBQUM7U0FDMUI7UUFDRCxJQUNFLEdBQUcsQ0FBQyxTQUFTLEtBQUssZ0JBQVMsQ0FBQyxNQUFNO1lBQ2xDLENBQUMsR0FBRyxDQUFDLFNBQVMsS0FBSyxnQkFBUyxDQUFDLFlBQVksSUFBSSxrQkFBa0IsQ0FBQyxFQUNoRTtZQUNBLE9BQU8sU0FBUyxDQUFDLEtBQUssQ0FBQztTQUN4QjtRQUNELE9BQU8sU0FBUyxDQUFDLE9BQU8sQ0FBQztJQUMzQixDQUFDO0FBQ0gsQ0FBQztBQXpCRCxrREF5QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdGFiaWxpdHkgfSBmcm9tICdAanNpaS9zcGVjJztcblxuaW1wb3J0IHsgQXBpTWlzbWF0Y2gsIE1pc21hdGNoZXMgfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGVudW0gRGlhZ0xldmVsIHtcbiAgRXJyb3IgPSAwLFxuICBXYXJuaW5nID0gMSxcbiAgU2tpcHBlZCA9IDIsXG59XG5cbmNvbnN0IExFVkVMX1BSRUZJWCA9IHtcbiAgW0RpYWdMZXZlbC5FcnJvcl06ICdlcnIgJyxcbiAgW0RpYWdMZXZlbC5XYXJuaW5nXTogJ3dhcm4nLFxuICBbRGlhZ0xldmVsLlNraXBwZWRdOiAnc2tpcCcsXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIERpYWdub3N0aWMge1xuICBsZXZlbDogRGlhZ0xldmVsO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIHN1cHByZXNzaW9uS2V5OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXREaWFnbm9zdGljKFxuICBkaWFnOiBEaWFnbm9zdGljLFxuICBpbmNsdWRlU3VwcHJlc3Npb25LZXkgPSBmYWxzZSxcbikge1xuICByZXR1cm4gW1xuICAgIExFVkVMX1BSRUZJWFtkaWFnLmxldmVsXSxcbiAgICAnLScsXG4gICAgZGlhZy5tZXNzYWdlLFxuICAgIC4uLihpbmNsdWRlU3VwcHJlc3Npb25LZXkgPyBbYFske2RpYWcuc3VwcHJlc3Npb25LZXl9XWBdIDogW10pLFxuICBdLmpvaW4oJyAnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0Vycm9ycyhkaWFnczogRGlhZ25vc3RpY1tdKSB7XG4gIHJldHVybiBkaWFncy5zb21lKChkaWFnKSA9PiBkaWFnLmxldmVsID09PSBEaWFnTGV2ZWwuRXJyb3IpO1xufVxuXG4vKipcbiAqIENsYXNzaWZ5IEFQSSBtaXNtYXRjaGVzIGludG8gYSBzZXQgb2Ygd2FybmluZ3MgYW5kIGVycm9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2xhc3NpZnlEaWFnbm9zdGljcyhcbiAgbWlzbWF0Y2hlczogTWlzbWF0Y2hlcyxcbiAgZXhwZXJpbWVudGFsRXJyb3JzOiBib29sZWFuLFxuICBza2lwRmlsdGVyOiBTZXQ8c3RyaW5nPixcbik6IERpYWdub3N0aWNbXSB7XG4gIGNvbnN0IHJldCA9IG1pc21hdGNoZXMubWlzbWF0Y2hlcy5tYXAoKG1pcykgPT4gKHtcbiAgICBsZXZlbDogbGV2ZWwobWlzKSxcbiAgICBtZXNzYWdlOiBtaXMubWVzc2FnZSxcbiAgICBzdXBwcmVzc2lvbktleTogbWlzLnZpb2xhdGlvbktleSxcbiAgfSkpO1xuICByZXQuc29ydCgoYSwgYikgPT4gYS5sZXZlbCAtIGIubGV2ZWwpO1xuICByZXR1cm4gcmV0O1xuXG4gIGZ1bmN0aW9uIGxldmVsKG1pczogQXBpTWlzbWF0Y2gpIHtcbiAgICBpZiAoc2tpcEZpbHRlci5oYXMobWlzLnZpb2xhdGlvbktleSkpIHtcbiAgICAgIHJldHVybiBEaWFnTGV2ZWwuU2tpcHBlZDtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgbWlzLnN0YWJpbGl0eSA9PT0gU3RhYmlsaXR5LlN0YWJsZSB8fFxuICAgICAgKG1pcy5zdGFiaWxpdHkgPT09IFN0YWJpbGl0eS5FeHBlcmltZW50YWwgJiYgZXhwZXJpbWVudGFsRXJyb3JzKVxuICAgICkge1xuICAgICAgcmV0dXJuIERpYWdMZXZlbC5FcnJvcjtcbiAgICB9XG4gICAgcmV0dXJuIERpYWdMZXZlbC5XYXJuaW5nO1xuICB9XG59XG4iXX0=
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as reflect from 'jsii-reflect';
|
|
2
|
+
import { ComparisonOptions, Mismatches } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compare two assemblies
|
|
5
|
+
*
|
|
6
|
+
* We currently only check for compatibility (a full diff is
|
|
7
|
+
* harder :). The only thing we have to do is check for every API
|
|
8
|
+
* item whether it's still available and has the same shape (or
|
|
9
|
+
* bigger) in the new API.
|
|
10
|
+
*/
|
|
11
|
+
export declare function compareAssemblies(original: reflect.Assembly, updated: reflect.Assembly, options?: ComparisonOptions): Mismatches;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compareAssemblies = void 0;
|
|
4
|
+
const type_comparison_1 = require("./type-comparison");
|
|
5
|
+
/**
|
|
6
|
+
* Compare two assemblies
|
|
7
|
+
*
|
|
8
|
+
* We currently only check for compatibility (a full diff is
|
|
9
|
+
* harder :). The only thing we have to do is check for every API
|
|
10
|
+
* item whether it's still available and has the same shape (or
|
|
11
|
+
* bigger) in the new API.
|
|
12
|
+
*/
|
|
13
|
+
function compareAssemblies(original, updated, options = {}) {
|
|
14
|
+
const comparison = new type_comparison_1.AssemblyComparison(options);
|
|
15
|
+
comparison.load(original, updated);
|
|
16
|
+
comparison.compare();
|
|
17
|
+
return comparison.mismatches;
|
|
18
|
+
}
|
|
19
|
+
exports.compareAssemblies = compareAssemblies;
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSx1REFBdUQ7QUFHdkQ7Ozs7Ozs7R0FPRztBQUNILFNBQWdCLGlCQUFpQixDQUMvQixRQUEwQixFQUMxQixPQUF5QixFQUN6QixVQUE2QixFQUFFO0lBRS9CLE1BQU0sVUFBVSxHQUFHLElBQUksb0NBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbkQsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbkMsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBRXJCLE9BQU8sVUFBVSxDQUFDLFVBQVUsQ0FBQztBQUMvQixDQUFDO0FBVkQsOENBVUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyByZWZsZWN0IGZyb20gJ2pzaWktcmVmbGVjdCc7XG5cbmltcG9ydCB7IEFzc2VtYmx5Q29tcGFyaXNvbiB9IGZyb20gJy4vdHlwZS1jb21wYXJpc29uJztcbmltcG9ydCB7IENvbXBhcmlzb25PcHRpb25zLCBNaXNtYXRjaGVzIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogQ29tcGFyZSB0d28gYXNzZW1ibGllc1xuICpcbiAqIFdlIGN1cnJlbnRseSBvbmx5IGNoZWNrIGZvciBjb21wYXRpYmlsaXR5IChhIGZ1bGwgZGlmZiBpc1xuICogaGFyZGVyIDopLiBUaGUgb25seSB0aGluZyB3ZSBoYXZlIHRvIGRvIGlzIGNoZWNrIGZvciBldmVyeSBBUElcbiAqIGl0ZW0gd2hldGhlciBpdCdzIHN0aWxsIGF2YWlsYWJsZSBhbmQgaGFzIHRoZSBzYW1lIHNoYXBlIChvclxuICogYmlnZ2VyKSBpbiB0aGUgbmV3IEFQSS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBhcmVBc3NlbWJsaWVzKFxuICBvcmlnaW5hbDogcmVmbGVjdC5Bc3NlbWJseSxcbiAgdXBkYXRlZDogcmVmbGVjdC5Bc3NlbWJseSxcbiAgb3B0aW9uczogQ29tcGFyaXNvbk9wdGlvbnMgPSB7fSxcbik6IE1pc21hdGNoZXMge1xuICBjb25zdCBjb21wYXJpc29uID0gbmV3IEFzc2VtYmx5Q29tcGFyaXNvbihvcHRpb25zKTtcbiAgY29tcGFyaXNvbi5sb2FkKG9yaWdpbmFsLCB1cGRhdGVkKTtcbiAgY29tcGFyaXNvbi5jb21wYXJlKCk7XG5cbiAgcmV0dXJuIGNvbXBhcmlzb24ubWlzbWF0Y2hlcztcbn1cbiJdfQ==
|
package/lib/stability.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateStabilities = void 0;
|
|
4
|
+
const spec = require("@jsii/spec");
|
|
5
|
+
function validateStabilities(original, updated, mismatches) {
|
|
6
|
+
// Nothing to do in these cases
|
|
7
|
+
if (original.docs.stability === undefined ||
|
|
8
|
+
original.docs.stability === updated.docs.stability) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
// Not allowed to disavow stability
|
|
12
|
+
if (updated.docs.stability === undefined) {
|
|
13
|
+
mismatches.report({
|
|
14
|
+
ruleKey: 'removed-stability',
|
|
15
|
+
message: `stability was '${original.docs.stability}', has been removed`,
|
|
16
|
+
violator: original,
|
|
17
|
+
});
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const allowed = allowedTransitions(original.docs.stability);
|
|
21
|
+
if (!allowed.includes(updated.docs.stability)) {
|
|
22
|
+
mismatches.report({
|
|
23
|
+
ruleKey: 'changed-stability',
|
|
24
|
+
message: `stability not allowed to go from '${original.docs.stability}' to '${updated.docs.stability}'`,
|
|
25
|
+
violator: original,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.validateStabilities = validateStabilities;
|
|
30
|
+
function allowedTransitions(start) {
|
|
31
|
+
switch (start) {
|
|
32
|
+
// Experimental can go to stable, external, or be deprecated
|
|
33
|
+
case spec.Stability.Experimental:
|
|
34
|
+
return [
|
|
35
|
+
spec.Stability.Stable,
|
|
36
|
+
spec.Stability.Deprecated,
|
|
37
|
+
spec.Stability.External,
|
|
38
|
+
];
|
|
39
|
+
// Stable can be deprecated, or switched to external
|
|
40
|
+
case spec.Stability.Stable:
|
|
41
|
+
return [spec.Stability.Deprecated, spec.Stability.External];
|
|
42
|
+
// Deprecated can be reinstated
|
|
43
|
+
case spec.Stability.Deprecated:
|
|
44
|
+
return [spec.Stability.Stable, spec.Stability.External];
|
|
45
|
+
// external can be stableified, or deprecated
|
|
46
|
+
case spec.Stability.External:
|
|
47
|
+
return [spec.Stability.Stable, spec.Stability.Deprecated];
|
|
48
|
+
default:
|
|
49
|
+
throw new Error(`Unrecognized stability: ${start}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhYmlsaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3RhYmlsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFtQztBQUtuQyxTQUFnQixtQkFBbUIsQ0FDakMsUUFBMkMsRUFDM0MsT0FBNkIsRUFDN0IsVUFBbUI7SUFFbkIsK0JBQStCO0lBQy9CLElBQ0UsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLEtBQUssU0FBUztRQUNyQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFDbEQ7UUFDQSxPQUFPO0tBQ1I7SUFFRCxtQ0FBbUM7SUFDbkMsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUU7UUFDeEMsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUNoQixPQUFPLEVBQUUsbUJBQW1CO1lBQzVCLE9BQU8sRUFBRSxrQkFBa0IsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLHFCQUFxQjtZQUN2RSxRQUFRLEVBQUUsUUFBUTtTQUNuQixDQUFDLENBQUM7UUFDSCxPQUFPO0tBQ1I7SUFFRCxNQUFNLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzVELElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUU7UUFDN0MsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUNoQixPQUFPLEVBQUUsbUJBQW1CO1lBQzVCLE9BQU8sRUFBRSxxQ0FBcUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLFNBQVMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUc7WUFDdkcsUUFBUSxFQUFFLFFBQVE7U0FDbkIsQ0FBQyxDQUFDO0tBQ0o7QUFDSCxDQUFDO0FBL0JELGtEQStCQztBQUVELFNBQVMsa0JBQWtCLENBQUMsS0FBcUI7SUFDL0MsUUFBUSxLQUFLLEVBQUU7UUFDYiw0REFBNEQ7UUFDNUQsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVk7WUFDOUIsT0FBTztnQkFDTCxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU07Z0JBQ3JCLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVTtnQkFDekIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRO2FBQ3hCLENBQUM7UUFFSixvREFBb0Q7UUFDcEQsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU07WUFDeEIsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFOUQsK0JBQStCO1FBQy9CLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVO1lBQzVCLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRTFELDZDQUE2QztRQUM3QyxLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUTtZQUMxQixPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUU1RDtZQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLEtBQVksRUFBRSxDQUFDLENBQUM7S0FDOUQ7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgc3BlYyBmcm9tICdAanNpaS9zcGVjJztcbmltcG9ydCAqIGFzIHJlZmxlY3QgZnJvbSAnanNpaS1yZWZsZWN0JztcblxuaW1wb3J0IHsgQXBpRWxlbWVudCwgSVJlcG9ydCB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVTdGFiaWxpdGllcyhcbiAgb3JpZ2luYWw6IHJlZmxlY3QuRG9jdW1lbnRhYmxlICYgQXBpRWxlbWVudCxcbiAgdXBkYXRlZDogcmVmbGVjdC5Eb2N1bWVudGFibGUsXG4gIG1pc21hdGNoZXM6IElSZXBvcnQsXG4pIHtcbiAgLy8gTm90aGluZyB0byBkbyBpbiB0aGVzZSBjYXNlc1xuICBpZiAoXG4gICAgb3JpZ2luYWwuZG9jcy5zdGFiaWxpdHkgPT09IHVuZGVmaW5lZCB8fFxuICAgIG9yaWdpbmFsLmRvY3Muc3RhYmlsaXR5ID09PSB1cGRhdGVkLmRvY3Muc3RhYmlsaXR5XG4gICkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIE5vdCBhbGxvd2VkIHRvIGRpc2F2b3cgc3RhYmlsaXR5XG4gIGlmICh1cGRhdGVkLmRvY3Muc3RhYmlsaXR5ID09PSB1bmRlZmluZWQpIHtcbiAgICBtaXNtYXRjaGVzLnJlcG9ydCh7XG4gICAgICBydWxlS2V5OiAncmVtb3ZlZC1zdGFiaWxpdHknLFxuICAgICAgbWVzc2FnZTogYHN0YWJpbGl0eSB3YXMgJyR7b3JpZ2luYWwuZG9jcy5zdGFiaWxpdHl9JywgaGFzIGJlZW4gcmVtb3ZlZGAsXG4gICAgICB2aW9sYXRvcjogb3JpZ2luYWwsXG4gICAgfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgYWxsb3dlZCA9IGFsbG93ZWRUcmFuc2l0aW9ucyhvcmlnaW5hbC5kb2NzLnN0YWJpbGl0eSk7XG4gIGlmICghYWxsb3dlZC5pbmNsdWRlcyh1cGRhdGVkLmRvY3Muc3RhYmlsaXR5KSkge1xuICAgIG1pc21hdGNoZXMucmVwb3J0KHtcbiAgICAgIHJ1bGVLZXk6ICdjaGFuZ2VkLXN0YWJpbGl0eScsXG4gICAgICBtZXNzYWdlOiBgc3RhYmlsaXR5IG5vdCBhbGxvd2VkIHRvIGdvIGZyb20gJyR7b3JpZ2luYWwuZG9jcy5zdGFiaWxpdHl9JyB0byAnJHt1cGRhdGVkLmRvY3Muc3RhYmlsaXR5fSdgLFxuICAgICAgdmlvbGF0b3I6IG9yaWdpbmFsLFxuICAgIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG93ZWRUcmFuc2l0aW9ucyhzdGFydDogc3BlYy5TdGFiaWxpdHkpOiBzcGVjLlN0YWJpbGl0eVtdIHtcbiAgc3dpdGNoIChzdGFydCkge1xuICAgIC8vIEV4cGVyaW1lbnRhbCBjYW4gZ28gdG8gc3RhYmxlLCBleHRlcm5hbCwgb3IgYmUgZGVwcmVjYXRlZFxuICAgIGNhc2Ugc3BlYy5TdGFiaWxpdHkuRXhwZXJpbWVudGFsOlxuICAgICAgcmV0dXJuIFtcbiAgICAgICAgc3BlYy5TdGFiaWxpdHkuU3RhYmxlLFxuICAgICAgICBzcGVjLlN0YWJpbGl0eS5EZXByZWNhdGVkLFxuICAgICAgICBzcGVjLlN0YWJpbGl0eS5FeHRlcm5hbCxcbiAgICAgIF07XG5cbiAgICAvLyBTdGFibGUgY2FuIGJlIGRlcHJlY2F0ZWQsIG9yIHN3aXRjaGVkIHRvIGV4dGVybmFsXG4gICAgY2FzZSBzcGVjLlN0YWJpbGl0eS5TdGFibGU6XG4gICAgICByZXR1cm4gW3NwZWMuU3RhYmlsaXR5LkRlcHJlY2F0ZWQsIHNwZWMuU3RhYmlsaXR5LkV4dGVybmFsXTtcblxuICAgIC8vIERlcHJlY2F0ZWQgY2FuIGJlIHJlaW5zdGF0ZWRcbiAgICBjYXNlIHNwZWMuU3RhYmlsaXR5LkRlcHJlY2F0ZWQ6XG4gICAgICByZXR1cm4gW3NwZWMuU3RhYmlsaXR5LlN0YWJsZSwgc3BlYy5TdGFiaWxpdHkuRXh0ZXJuYWxdO1xuXG4gICAgLy8gZXh0ZXJuYWwgY2FuIGJlIHN0YWJsZWlmaWVkLCBvciBkZXByZWNhdGVkXG4gICAgY2FzZSBzcGVjLlN0YWJpbGl0eS5FeHRlcm5hbDpcbiAgICAgIHJldHVybiBbc3BlYy5TdGFiaWxpdHkuU3RhYmxlLCBzcGVjLlN0YWJpbGl0eS5EZXByZWNhdGVkXTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBzdGFiaWxpdHk6ICR7c3RhcnQgYXMgYW55fWApO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as reflect from 'jsii-reflect';
|
|
2
|
+
/**
|
|
3
|
+
* Check whether A is a supertype of B
|
|
4
|
+
*
|
|
5
|
+
* Put differently: whether any value of type B would be assignable to a
|
|
6
|
+
* variable of type A.
|
|
7
|
+
*
|
|
8
|
+
* We always check the relationship in the NEW (latest, updated) typesystem.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isSuperType(a: reflect.TypeReference, b: reflect.TypeReference, updatedSystem: reflect.TypeSystem): Analysis;
|
|
11
|
+
/**
|
|
12
|
+
* Find types A and B in the updated type system, and check whether they have a supertype relationship in the type system
|
|
13
|
+
*/
|
|
14
|
+
export declare function isNominalSuperType(a: reflect.TypeReference, b: reflect.TypeReference, updatedSystem: reflect.TypeSystem): Analysis;
|
|
15
|
+
/**
|
|
16
|
+
* Is struct A a structural supertype of struct B?
|
|
17
|
+
*
|
|
18
|
+
* Trying to answer the question, is this assignment legal for all values
|
|
19
|
+
* of `expr in B`.
|
|
20
|
+
*
|
|
21
|
+
* ```ts
|
|
22
|
+
* const var: A = expr as B;
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* A is a structural supertype of B if all required members of A are also
|
|
26
|
+
* required in B, and of a compatible type.
|
|
27
|
+
*
|
|
28
|
+
* Nullable members of A must either not exist in B, or be of a compatible
|
|
29
|
+
* type.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isStructuralSuperType(a: reflect.InterfaceType, b: reflect.InterfaceType, updatedSystem: reflect.TypeSystem): Analysis;
|
|
32
|
+
export declare type Analysis = {
|
|
33
|
+
success: true;
|
|
34
|
+
} | FailedAnalysis;
|
|
35
|
+
export declare type FailedAnalysis = {
|
|
36
|
+
success: false;
|
|
37
|
+
reasons: string[];
|
|
38
|
+
};
|
|
39
|
+
export declare function prependReason(analysis: Analysis, message: string): Analysis;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prependReason = exports.isStructuralSuperType = exports.isNominalSuperType = exports.isSuperType = void 0;
|
|
4
|
+
const util_1 = require("./util");
|
|
5
|
+
/**
|
|
6
|
+
* Check whether A is a supertype of B
|
|
7
|
+
*
|
|
8
|
+
* Put differently: whether any value of type B would be assignable to a
|
|
9
|
+
* variable of type A.
|
|
10
|
+
*
|
|
11
|
+
* We always check the relationship in the NEW (latest, updated) typesystem.
|
|
12
|
+
*/
|
|
13
|
+
function isSuperType(a, b, updatedSystem) {
|
|
14
|
+
if (a.void || b.void) {
|
|
15
|
+
throw new Error('isSuperType() does not handle voids');
|
|
16
|
+
}
|
|
17
|
+
if (a.isAny) {
|
|
18
|
+
return { success: true };
|
|
19
|
+
}
|
|
20
|
+
if (a.primitive !== undefined) {
|
|
21
|
+
if (a.primitive === b.primitive) {
|
|
22
|
+
return { success: true };
|
|
23
|
+
}
|
|
24
|
+
return failure(`${b.toString()} is not assignable to ${a.toString()}`);
|
|
25
|
+
}
|
|
26
|
+
if (a.arrayOfType !== undefined) {
|
|
27
|
+
// Arrays are covariant
|
|
28
|
+
if (b.arrayOfType === undefined) {
|
|
29
|
+
return failure(`${b.toString()} is not an array type`);
|
|
30
|
+
}
|
|
31
|
+
return prependReason(isSuperType(a.arrayOfType, b.arrayOfType, updatedSystem), `${b.toString()} is not assignable to ${a.toString()}`);
|
|
32
|
+
}
|
|
33
|
+
if (a.mapOfType !== undefined) {
|
|
34
|
+
// Maps are covariant (are they?)
|
|
35
|
+
if (b.mapOfType === undefined) {
|
|
36
|
+
return failure(`${b.toString()} is not a map type`);
|
|
37
|
+
}
|
|
38
|
+
return prependReason(isSuperType(a.mapOfType, b.mapOfType, updatedSystem), `${b.toString()} is not assignable to ${a.toString()}`);
|
|
39
|
+
}
|
|
40
|
+
// Every element of B can be assigned to A
|
|
41
|
+
if (b.unionOfTypes !== undefined) {
|
|
42
|
+
const analyses = b.unionOfTypes.map((bbb) => isSuperType(a, bbb, updatedSystem));
|
|
43
|
+
if (analyses.every((x) => x.success)) {
|
|
44
|
+
return { success: true };
|
|
45
|
+
}
|
|
46
|
+
return failure(`some of ${b.toString()} are not assignable to ${a.toString()}`, ...util_1.flatMap(analyses, (x) => (x.success ? [] : x.reasons)));
|
|
47
|
+
}
|
|
48
|
+
// There should be an element of A which can accept all of B
|
|
49
|
+
if (a.unionOfTypes !== undefined) {
|
|
50
|
+
const analyses = a.unionOfTypes.map((aaa) => isSuperType(aaa, b, updatedSystem));
|
|
51
|
+
if (analyses.some((x) => x.success)) {
|
|
52
|
+
return { success: true };
|
|
53
|
+
}
|
|
54
|
+
return failure(`none of ${b.toString()} are assignable to ${a.toString()}`, ...util_1.flatMap(analyses, (x) => (x.success ? [] : x.reasons)));
|
|
55
|
+
}
|
|
56
|
+
// We have two named types, recursion might happen so protect against it.
|
|
57
|
+
try {
|
|
58
|
+
// For named types, we'll always do a nominal typing relationship.
|
|
59
|
+
// That is, if in the updated typesystem someone were to use the type name
|
|
60
|
+
// from the old assembly, do they have a typing relationship that's accepted
|
|
61
|
+
// by a nominal type system. (That check also rules out enums)
|
|
62
|
+
const nominalCheck = isNominalSuperType(a, b, updatedSystem);
|
|
63
|
+
if (nominalCheck.success === false) {
|
|
64
|
+
return nominalCheck;
|
|
65
|
+
}
|
|
66
|
+
// At this point, the only thing left to do is recurse into the structs.
|
|
67
|
+
// We used to do that here, but we don't anymore; structs check themselves
|
|
68
|
+
// for structural weakening/strengthening.
|
|
69
|
+
return { success: true };
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
return failure(e.message);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.isSuperType = isSuperType;
|
|
76
|
+
/**
|
|
77
|
+
* Find types A and B in the updated type system, and check whether they have a supertype relationship in the type system
|
|
78
|
+
*/
|
|
79
|
+
function isNominalSuperType(a, b, updatedSystem) {
|
|
80
|
+
if (a.fqn === undefined) {
|
|
81
|
+
throw new Error(`I was expecting a named type, got '${a.toString()}'`);
|
|
82
|
+
}
|
|
83
|
+
// Named type vs a non-named type
|
|
84
|
+
if (b.fqn === undefined) {
|
|
85
|
+
return failure(`${b.toString()} is not assignable to ${a.toString()}`);
|
|
86
|
+
}
|
|
87
|
+
// Short-circuit of the types are the same name, saves us some lookup
|
|
88
|
+
if (a.fqn === b.fqn) {
|
|
89
|
+
return { success: true };
|
|
90
|
+
}
|
|
91
|
+
// We now need to do subtype analysis on the
|
|
92
|
+
// Find A in B's typesystem, and see if B is a subtype of A'
|
|
93
|
+
const B = updatedSystem.tryFindFqn(b.fqn);
|
|
94
|
+
const A = updatedSystem.tryFindFqn(a.fqn);
|
|
95
|
+
if (!B) {
|
|
96
|
+
return failure(`could not find type ${b.toString()}`);
|
|
97
|
+
}
|
|
98
|
+
if (!A) {
|
|
99
|
+
return failure(`could not find type ${a.toString()}`);
|
|
100
|
+
}
|
|
101
|
+
// If they're enums, they should have been exactly the same (tested above)
|
|
102
|
+
// enums are never subtypes of any other type.
|
|
103
|
+
if (A.isEnumType()) {
|
|
104
|
+
return failure(`${a.toString()} is an enum different from ${b.toString()}`);
|
|
105
|
+
}
|
|
106
|
+
if (B.isEnumType()) {
|
|
107
|
+
return failure(`${b.toString()} is an enum different from ${a.toString()}`);
|
|
108
|
+
}
|
|
109
|
+
if (B.extends(A)) {
|
|
110
|
+
return { success: true };
|
|
111
|
+
}
|
|
112
|
+
return failure(`${b.toString()} does not extend ${a.toString()}`);
|
|
113
|
+
}
|
|
114
|
+
exports.isNominalSuperType = isNominalSuperType;
|
|
115
|
+
/**
|
|
116
|
+
* Is struct A a structural supertype of struct B?
|
|
117
|
+
*
|
|
118
|
+
* Trying to answer the question, is this assignment legal for all values
|
|
119
|
+
* of `expr in B`.
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* const var: A = expr as B;
|
|
123
|
+
* ```
|
|
124
|
+
*
|
|
125
|
+
* A is a structural supertype of B if all required members of A are also
|
|
126
|
+
* required in B, and of a compatible type.
|
|
127
|
+
*
|
|
128
|
+
* Nullable members of A must either not exist in B, or be of a compatible
|
|
129
|
+
* type.
|
|
130
|
+
*/
|
|
131
|
+
function isStructuralSuperType(a, b, updatedSystem) {
|
|
132
|
+
// We know all members can only be properties, so that makes it easier.
|
|
133
|
+
const bProps = b.getProperties(true);
|
|
134
|
+
// Use timing words in error message to make it more understandable
|
|
135
|
+
const formerly = b.system === updatedSystem ? 'formerly' : 'newly';
|
|
136
|
+
const is = b.system === updatedSystem ? 'is' : 'used to be';
|
|
137
|
+
const removed = b.system === updatedSystem ? 'removed' : 'added';
|
|
138
|
+
for (const [name, aProp] of Object.entries(a.getProperties(true))) {
|
|
139
|
+
const bProp = bProps[name];
|
|
140
|
+
if (aProp.optional) {
|
|
141
|
+
// Optional field, only requirement is that IF it exists, the type must match.
|
|
142
|
+
if (!bProp) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
if (!bProp) {
|
|
148
|
+
return failure(`${formerly} required property '${name}' ${removed}`);
|
|
149
|
+
}
|
|
150
|
+
if (bProp.optional) {
|
|
151
|
+
return failure(`${formerly} required property '${name}' ${is} optional`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const ana = isSuperType(aProp.type, bProp.type, updatedSystem);
|
|
155
|
+
if (!ana.success) {
|
|
156
|
+
return failure(`property ${name}`, ...ana.reasons);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return { success: true };
|
|
160
|
+
}
|
|
161
|
+
exports.isStructuralSuperType = isStructuralSuperType;
|
|
162
|
+
function failure(...reasons) {
|
|
163
|
+
return { success: false, reasons };
|
|
164
|
+
}
|
|
165
|
+
function prependReason(analysis, message) {
|
|
166
|
+
if (analysis.success) {
|
|
167
|
+
return analysis;
|
|
168
|
+
}
|
|
169
|
+
return failure(message, ...analysis.reasons);
|
|
170
|
+
}
|
|
171
|
+
exports.prependReason = prependReason;
|
|
172
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1hbmFseXNpcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInR5cGUtYW5hbHlzaXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsaUNBQWlDO0FBRWpDOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixXQUFXLENBQ3pCLENBQXdCLEVBQ3hCLENBQXdCLEVBQ3hCLGFBQWlDO0lBRWpDLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFO1FBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztLQUN4RDtJQUNELElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtRQUNYLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7S0FDMUI7SUFFRCxJQUFJLENBQUMsQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFO1FBQzdCLElBQUksQ0FBQyxDQUFDLFNBQVMsS0FBSyxDQUFDLENBQUMsU0FBUyxFQUFFO1lBQy9CLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7U0FDMUI7UUFDRCxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUseUJBQXlCLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7S0FDeEU7SUFFRCxJQUFJLENBQUMsQ0FBQyxXQUFXLEtBQUssU0FBUyxFQUFFO1FBQy9CLHVCQUF1QjtRQUN2QixJQUFJLENBQUMsQ0FBQyxXQUFXLEtBQUssU0FBUyxFQUFFO1lBQy9CLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1NBQ3hEO1FBQ0QsT0FBTyxhQUFhLENBQ2xCLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLEVBQ3hELEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDLFFBQVEsRUFB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QUtDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuaW1wb3J0ICogYXMgcmVmbGVjdCBmcm9tICdqc2lpLXJlZmxlY3QnO1xuXG5pbXBvcnQgeyBmbGF0TWFwIH0gZnJvbSAnLi91dGlsJztcblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIEEgaXMgYSBzdXBlcnR5cGUgb2YgQlxuICpcbiAqIFB1dCBkaWZmZXJlbnRseTogd2hldGhlciBhbnkgdmFsdWUgb2YgdHlwZSBCIHdvdWxkIGJlIGFzc2lnbmFibGUgdG8gYVxuICogdmFyaWFibGUgb2YgdHlwZSBBLlxuICpcbiAqIFdlIGFsd2F5cyBjaGVjayB0aGUgcmVsYXRpb25zaGlwIGluIHRoZSBORVcgKGxhdGVzdCwgdXBkYXRlZCkgdHlwZXN5c3RlbS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3VwZXJUeXBlKFxuICBhOiByZWZsZWN0LlR5cGVSZWZlcmVuY2UsXG4gIGI6IHJlZmxlY3QuVHlwZVJlZmVyZW5jZSxcbiAgdXBkYXRlZFN5c3RlbTogcmVmbGVjdC5UeXBlU3lzdGVtLFxuKTogQW5hbHlzaXMge1xuICBpZiAoYS52b2lkIHx8IGIudm9pZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignaXNTdXBlclR5cGUoKSBkb2VzIG5vdCBoYW5kbGUgdm9pZHMnKTtcbiAgfVxuICBpZiAoYS5pc0FueSkge1xuICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgfVxuXG4gIGlmIChhLnByaW1pdGl2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGEucHJpbWl0aXZlID09PSBiLnByaW1pdGl2ZSkge1xuICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICAgIH1cbiAgICByZXR1cm4gZmFpbHVyZShgJHtiLnRvU3RyaW5nKCl9IGlzIG5vdCBhc3NpZ25hYmxlIHRvICR7YS50b1N0cmluZygpfWApO1xuICB9XG5cbiAgaWYgKGEuYXJyYXlPZlR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIEFycmF5cyBhcmUgY292YXJpYW50XG4gICAgaWYgKGIuYXJyYXlPZlR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhaWx1cmUoYCR7Yi50b1N0cmluZygpfSBpcyBub3QgYW4gYXJyYXkgdHlwZWApO1xuICAgIH1cbiAgICByZXR1cm4gcHJlcGVuZFJlYXNvbihcbiAgICAgIGlzU3VwZXJUeXBlKGEuYXJyYXlPZlR5cGUsIGIuYXJyYXlPZlR5cGUsIHVwZGF0ZWRTeXN0ZW0pLFxuICAgICAgYCR7Yi50b1N0cmluZygpfSBpcyBub3QgYXNzaWduYWJsZSB0byAke2EudG9TdHJpbmcoKX1gLFxuICAgICk7XG4gIH1cblxuICBpZiAoYS5tYXBPZlR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE1hcHMgYXJlIGNvdmFyaWFudCAoYXJlIHRoZXk/KVxuICAgIGlmIChiLm1hcE9mVHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFpbHVyZShgJHtiLnRvU3RyaW5nKCl9IGlzIG5vdCBhIG1hcCB0eXBlYCk7XG4gICAgfVxuICAgIHJldHVybiBwcmVwZW5kUmVhc29uKFxuICAgICAgaXNTdXBlclR5cGUoYS5tYXBPZlR5cGUsIGIubWFwT2ZUeXBlLCB1cGRhdGVkU3lzdGVtKSxcbiAgICAgIGAke2IudG9TdHJpbmcoKX0gaXMgbm90IGFzc2lnbmFibGUgdG8gJHthLnRvU3RyaW5nKCl9YCxcbiAgICApO1xuICB9XG5cbiAgLy8gRXZlcnkgZWxlbWVudCBvZiBCIGNhbiBiZSBhc3NpZ25lZCB0byBBXG4gIGlmIChiLnVuaW9uT2ZUeXBlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgYW5hbHlzZXMgPSBiLnVuaW9uT2ZUeXBlcy5tYXAoKGJiYikgPT5cbiAgICAgIGlzU3VwZXJUeXBlKGEsIGJiYiwgdXBkYXRlZFN5c3RlbSksXG4gICAgKTtcbiAgICBpZiAoYW5hbHlzZXMuZXZlcnkoKHgpID0+IHguc3VjY2VzcykpIHtcbiAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIGZhaWx1cmUoXG4gICAgICBgc29tZSBvZiAke2IudG9TdHJpbmcoKX0gYXJlIG5vdCBhc3NpZ25hYmxlIHRvICR7YS50b1N0cmluZygpfWAsXG4gICAgICAuLi5mbGF0TWFwKGFuYWx5c2VzLCAoeCkgPT4gKHguc3VjY2VzcyA/IFtdIDogeC5yZWFzb25zKSksXG4gICAgKTtcbiAgfVxuICAvLyBUaGVyZSBzaG91bGQgYmUgYW4gZWxlbWVudCBvZiBBIHdoaWNoIGNhbiBhY2NlcHQgYWxsIG9mIEJcbiAgaWYgKGEudW5pb25PZlR5cGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBhbmFseXNlcyA9IGEudW5pb25PZlR5cGVzLm1hcCgoYWFhKSA9PlxuICAgICAgaXNTdXBlclR5cGUoYWFhLCBiLCB1cGRhdGVkU3lzdGVtKSxcbiAgICApO1xuICAgIGlmIChhbmFseXNlcy5zb21lKCh4KSA9PiB4LnN1Y2Nlc3MpKSB7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgfVxuICAgIHJldHVybiBmYWlsdXJlKFxuICAgICAgYG5vbmUgb2YgJHtiLnRvU3RyaW5nKCl9IGFyZSBhc3NpZ25hYmxlIHRvICR7YS50b1N0cmluZygpfWAsXG4gICAgICAuLi5mbGF0TWFwKGFuYWx5c2VzLCAoeCkgPT4gKHguc3VjY2VzcyA/IFtdIDogeC5yZWFzb25zKSksXG4gICAgKTtcbiAgfVxuXG4gIC8vIFdlIGhhdmUgdHdvIG5hbWVkIHR5cGVzLCByZWN1cnNpb24gbWlnaHQgaGFwcGVuIHNvIHByb3RlY3QgYWdhaW5zdCBpdC5cbiAgdHJ5IHtcbiAgICAvLyBGb3IgbmFtZWQgdHlwZXMsIHdlJ2xsIGFsd2F5cyBkbyBhIG5vbWluYWwgdHlwaW5nIHJlbGF0aW9uc2hpcC5cbiAgICAvLyBUaGF0IGlzLCBpZiBpbiB0aGUgdXBkYXRlZCB0eXBlc3lzdGVtIHNvbWVvbmUgd2VyZSB0byB1c2UgdGhlIHR5cGUgbmFtZVxuICAgIC8vIGZyb20gdGhlIG9sZCBhc3NlbWJseSwgZG8gdGhleSBoYXZlIGEgdHlwaW5nIHJlbGF0aW9uc2hpcCB0aGF0J3MgYWNjZXB0ZWRcbiAgICAvLyBieSBhIG5vbWluYWwgdHlwZSBzeXN0ZW0uIChUaGF0IGNoZWNrIGFsc28gcnVsZXMgb3V0IGVudW1zKVxuICAgIGNvbnN0IG5vbWluYWxDaGVjayA9IGlzTm9taW5hbFN1cGVyVHlwZShhLCBiLCB1cGRhdGVkU3lzdGVtKTtcbiAgICBpZiAobm9taW5hbENoZWNrLnN1Y2Nlc3MgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gbm9taW5hbENoZWNrO1xuICAgIH1cblxuICAgIC8vIEF0IHRoaXMgcG9pbnQsIHRoZSBvbmx5IHRoaW5nIGxlZnQgdG8gZG8gaXMgcmVjdXJzZSBpbnRvIHRoZSBzdHJ1Y3RzLlxuICAgIC8vIFdlIHVzZWQgdG8gZG8gdGhhdCBoZXJlLCBidXQgd2UgZG9uJ3QgYW55bW9yZTsgc3RydWN0cyBjaGVjayB0aGVtc2VsdmVzXG4gICAgLy8gZm9yIHN0cnVjdHVyYWwgd2Vha2VuaW5nL3N0cmVuZ3RoZW5pbmcuXG4gICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhaWx1cmUoZS5tZXNzYWdlKTtcbiAgfVxufVxuXG4vKipcbiAqIEZpbmQgdHlwZXMgQSBhbmQgQiBpbiB0aGUgdXBkYXRlZCB0eXBlIHN5c3RlbSwgYW5kIGNoZWNrIHdoZXRoZXIgdGhleSBoYXZlIGEgc3VwZXJ0eXBlIHJlbGF0aW9uc2hpcCBpbiB0aGUgdHlwZSBzeXN0ZW1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTm9taW5hbFN1cGVyVHlwZShcbiAgYTogcmVmbGVjdC5UeXBlUmVmZXJlbmNlLFxuICBiOiByZWZsZWN0LlR5cGVSZWZlcmVuY2UsXG4gIHVwZGF0ZWRTeXN0ZW06IHJlZmxlY3QuVHlwZVN5c3RlbSxcbik6IEFuYWx5c2lzIHtcbiAgaWYgKGEuZnFuID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEkgd2FzIGV4cGVjdGluZyBhIG5hbWVkIHR5cGUsIGdvdCAnJHthLnRvU3RyaW5nKCl9J2ApO1xuICB9XG5cbiAgLy8gTmFtZWQgdHlwZSB2cyBhIG5vbi1uYW1lZCB0eXBlXG4gIGlmIChiLmZxbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZhaWx1cmUoYCR7Yi50b1N0cmluZygpfSBpcyBub3QgYXNzaWduYWJsZSB0byAke2EudG9TdHJpbmcoKX1gKTtcbiAgfVxuXG4gIC8vIFNob3J0LWNpcmN1aXQgb2YgdGhlIHR5cGVzIGFyZSB0aGUgc2FtZSBuYW1lLCBzYXZlcyB1cyBzb21lIGxvb2t1cFxuICBpZiAoYS5mcW4gPT09IGIuZnFuKSB7XG4gICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICB9XG5cbiAgLy8gV2Ugbm93IG5lZWQgdG8gZG8gc3VidHlwZSBhbmFseXNpcyBvbiB0aGVcbiAgLy8gRmluZCBBIGluIEIncyB0eXBlc3lzdGVtLCBhbmQgc2VlIGlmIEIgaXMgYSBzdWJ0eXBlIG9mIEEnXG4gIGNvbnN0IEIgPSB1cGRhdGVkU3lzdGVtLnRyeUZpbmRGcW4oYi5mcW4pO1xuICBjb25zdCBBID0gdXBkYXRlZFN5c3RlbS50cnlGaW5kRnFuKGEuZnFuKTtcblxuICBpZiAoIUIpIHtcbiAgICByZXR1cm4gZmFpbHVyZShgY291bGQgbm90IGZpbmQgdHlwZSAke2IudG9TdHJpbmcoKX1gKTtcbiAgfVxuICBpZiAoIUEpIHtcbiAgICByZXR1cm4gZmFpbHVyZShgY291bGQgbm90IGZpbmQgdHlwZSAke2EudG9TdHJpbmcoKX1gKTtcbiAgfVxuXG4gIC8vIElmIHRoZXkncmUgZW51bXMsIHRoZXkgc2hvdWxkIGhhdmUgYmVlbiBleGFjdGx5IHRoZSBzYW1lICh0ZXN0ZWQgYWJvdmUpXG4gIC8vIGVudW1zIGFyZSBuZXZlciBzdWJ0eXBlcyBvZiBhbnkgb3RoZXIgdHlwZS5cbiAgaWYgKEEuaXNFbnVtVHlwZSgpKSB7XG4gICAgcmV0dXJuIGZhaWx1cmUoYCR7YS50b1N0cmluZygpfSBpcyBhbiBlbnVtIGRpZmZlcmVudCBmcm9tICR7Yi50b1N0cmluZygpfWApO1xuICB9XG4gIGlmIChCLmlzRW51bVR5cGUoKSkge1xuICAgIHJldHVybiBmYWlsdXJlKGAke2IudG9TdHJpbmcoKX0gaXMgYW4gZW51bSBkaWZmZXJlbnQgZnJvbSAke2EudG9TdHJpbmcoKX1gKTtcbiAgfVxuXG4gIGlmIChCLmV4dGVuZHMoQSkpIHtcbiAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gIH1cbiAgcmV0dXJuIGZhaWx1cmUoYCR7Yi50b1N0cmluZygpfSBkb2VzIG5vdCBleHRlbmQgJHthLnRvU3RyaW5nKCl9YCk7XG59XG5cbi8qKlxuICogSXMgc3RydWN0IEEgYSBzdHJ1Y3R1cmFsIHN1cGVydHlwZSBvZiBzdHJ1Y3QgQj9cbiAqXG4gKiBUcnlpbmcgdG8gYW5zd2VyIHRoZSBxdWVzdGlvbiwgaXMgdGhpcyBhc3NpZ25tZW50IGxlZ2FsIGZvciBhbGwgdmFsdWVzXG4gKiBvZiBgZXhwciBpbiBCYC5cbiAqXG4gKiBgYGB0c1xuICogY29uc3QgdmFyOiBBID0gZXhwciBhcyBCO1xuICogYGBgXG4gKlxuICogQSBpcyBhIHN0cnVjdHVyYWwgc3VwZXJ0eXBlIG9mIEIgaWYgYWxsIHJlcXVpcmVkIG1lbWJlcnMgb2YgQSBhcmUgYWxzb1xuICogcmVxdWlyZWQgaW4gQiwgYW5kIG9mIGEgY29tcGF0aWJsZSB0eXBlLlxuICpcbiAqIE51bGxhYmxlIG1lbWJlcnMgb2YgQSBtdXN0IGVpdGhlciBub3QgZXhpc3QgaW4gQiwgb3IgYmUgb2YgYSBjb21wYXRpYmxlXG4gKiB0eXBlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTdHJ1Y3R1cmFsU3VwZXJUeXBlKFxuICBhOiByZWZsZWN0LkludGVyZmFjZVR5cGUsXG4gIGI6IHJlZmxlY3QuSW50ZXJmYWNlVHlwZSxcbiAgdXBkYXRlZFN5c3RlbTogcmVmbGVjdC5UeXBlU3lzdGVtLFxuKTogQW5hbHlzaXMge1xuICAvLyBXZSBrbm93IGFsbCBtZW1iZXJzIGNhbiBvbmx5IGJlIHByb3BlcnRpZXMsIHNvIHRoYXQgbWFrZXMgaXQgZWFzaWVyLlxuICBjb25zdCBiUHJvcHMgPSBiLmdldFByb3BlcnRpZXModHJ1ZSk7XG5cbiAgLy8gVXNlIHRpbWluZyB3b3JkcyBpbiBlcnJvciBtZXNzYWdlIHRvIG1ha2UgaXQgbW9yZSB1bmRlcnN0YW5kYWJsZVxuICBjb25zdCBmb3JtZXJseSA9IGIuc3lzdGVtID09PSB1cGRhdGVkU3lzdGVtID8gJ2Zvcm1lcmx5JyA6ICduZXdseSc7XG4gIGNvbnN0IGlzID0gYi5zeXN0ZW0gPT09IHVwZGF0ZWRTeXN0ZW0gPyAnaXMnIDogJ3VzZWQgdG8gYmUnO1xuICBjb25zdCByZW1vdmVkID0gYi5zeXN0ZW0gPT09IHVwZGF0ZWRTeXN0ZW0gPyAncmVtb3ZlZCcgOiAnYWRkZWQnO1xuXG4gIGZvciAoY29uc3QgW25hbWUsIGFQcm9wXSBvZiBPYmplY3QuZW50cmllcyhhLmdldFByb3BlcnRpZXModHJ1ZSkpKSB7XG4gICAgY29uc3QgYlByb3AgPSBiUHJvcHNbbmFtZV07XG5cbiAgICBpZiAoYVByb3Aub3B0aW9uYWwpIHtcbiAgICAgIC8vIE9wdGlvbmFsIGZpZWxkLCBvbmx5IHJlcXVpcmVtZW50IGlzIHRoYXQgSUYgaXQgZXhpc3RzLCB0aGUgdHlwZSBtdXN0IG1hdGNoLlxuICAgICAgaWYgKCFiUHJvcCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFiUHJvcCkge1xuICAgICAgICByZXR1cm4gZmFpbHVyZShgJHtmb3JtZXJseX0gcmVxdWlyZWQgcHJvcGVydHkgJyR7bmFtZX0nICR7cmVtb3ZlZH1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChiUHJvcC5vcHRpb25hbCkge1xuICAgICAgICByZXR1cm4gZmFpbHVyZShcbiAgICAgICAgICBgJHtmb3JtZXJseX0gcmVxdWlyZWQgcHJvcGVydHkgJyR7bmFtZX0nICR7aXN9IG9wdGlvbmFsYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBhbmEgPSBpc1N1cGVyVHlwZShhUHJvcC50eXBlLCBiUHJvcC50eXBlLCB1cGRhdGVkU3lzdGVtKTtcbiAgICBpZiAoIWFuYS5zdWNjZXNzKSB7XG4gICAgICByZXR1cm4gZmFpbHVyZShgcHJvcGVydHkgJHtuYW1lfWAsIC4uLmFuYS5yZWFzb25zKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG59XG5cbi8vIE9oIHRhZ2dlZCB1bmlvbiB0eXBlcyBJIGxvdmUgeW91IHNvIG11Y2ghXG5leHBvcnQgdHlwZSBBbmFseXNpcyA9IHsgc3VjY2VzczogdHJ1ZSB9IHwgRmFpbGVkQW5hbHlzaXM7XG5cbmV4cG9ydCB0eXBlIEZhaWxlZEFuYWx5c2lzID0geyBzdWNjZXNzOiBmYWxzZTsgcmVhc29uczogc3RyaW5nW10gfTtcblxuZnVuY3Rpb24gZmFpbHVyZSguLi5yZWFzb25zOiBzdHJpbmdbXSk6IEZhaWxlZEFuYWx5c2lzIHtcbiAgcmV0dXJuIHsgc3VjY2VzczogZmFsc2UsIHJlYXNvbnMgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByZXBlbmRSZWFzb24oYW5hbHlzaXM6IEFuYWx5c2lzLCBtZXNzYWdlOiBzdHJpbmcpOiBBbmFseXNpcyB7XG4gIGlmIChhbmFseXNpcy5zdWNjZXNzKSB7XG4gICAgcmV0dXJuIGFuYWx5c2lzO1xuICB9XG4gIHJldHVybiBmYWlsdXJlKG1lc3NhZ2UsIC4uLmFuYWx5c2lzLnJlYXNvbnMpO1xufVxuIl19
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import * as reflect from 'jsii-reflect';
|
|
2
|
+
import { ComparisonOptions, Mismatches } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Root object for comparing two assemblies
|
|
5
|
+
*
|
|
6
|
+
* Tracks mismatches and used as a lookup table to convert FQNs -> ComparableType objects
|
|
7
|
+
*/
|
|
8
|
+
export declare class AssemblyComparison {
|
|
9
|
+
readonly options: ComparisonOptions;
|
|
10
|
+
readonly mismatches: Mismatches;
|
|
11
|
+
private readonly types;
|
|
12
|
+
constructor(options: ComparisonOptions);
|
|
13
|
+
/**
|
|
14
|
+
* Load the types from two assemblies to compare
|
|
15
|
+
*
|
|
16
|
+
* Adds appropriate ComparableType<> instances.
|
|
17
|
+
*/
|
|
18
|
+
load(original: reflect.Assembly, updated: reflect.Assembly): void;
|
|
19
|
+
/**
|
|
20
|
+
* Perform the comparison for all loaded types
|
|
21
|
+
*/
|
|
22
|
+
compare(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Based on a JSII TypeReference, return all reachable ComparableType<> objects.
|
|
25
|
+
*/
|
|
26
|
+
typesIn(ref: reflect.TypeReference): Array<ComparableType<any>>;
|
|
27
|
+
/**
|
|
28
|
+
* All ComparableType<>s
|
|
29
|
+
*/
|
|
30
|
+
private get comparableTypes();
|
|
31
|
+
/**
|
|
32
|
+
* Find the matching type in the updated assembly based on all types in the original assembly
|
|
33
|
+
*/
|
|
34
|
+
private typePairs;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Base class for comparable types
|
|
38
|
+
*
|
|
39
|
+
* Manages notions of crawling types for other reference types, and whether
|
|
40
|
+
* they occur in an input/output role, and marking as such on the comparison
|
|
41
|
+
* object.
|
|
42
|
+
*/
|
|
43
|
+
export declare abstract class ComparableType<T> {
|
|
44
|
+
protected readonly assemblyComparison: AssemblyComparison;
|
|
45
|
+
protected readonly oldType: T;
|
|
46
|
+
protected readonly newType: T;
|
|
47
|
+
private static readonly recursionBreaker;
|
|
48
|
+
private readonly _inputTypeReasons;
|
|
49
|
+
private readonly _outputTypeReasons;
|
|
50
|
+
constructor(assemblyComparison: AssemblyComparison, oldType: T, newType: T);
|
|
51
|
+
/**
|
|
52
|
+
* Does this type occur in an input role?
|
|
53
|
+
*/
|
|
54
|
+
get inputType(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Does this type occur in an output role?
|
|
57
|
+
*/
|
|
58
|
+
get outputType(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Mark this type as occuring in an input rule.
|
|
61
|
+
*
|
|
62
|
+
* All types reachable from this type will be marked as input types as well.
|
|
63
|
+
*/
|
|
64
|
+
markAsInputType(...reasonFragments: string[]): void;
|
|
65
|
+
/**
|
|
66
|
+
* Mark this type as occuring in an input rule.
|
|
67
|
+
*
|
|
68
|
+
* All types reachable from this type will be marked as input types as well.
|
|
69
|
+
*/
|
|
70
|
+
markAsOutputType(...reasonFragments: string[]): void;
|
|
71
|
+
/**
|
|
72
|
+
* Describe why this type is an input type (if it is)
|
|
73
|
+
*/
|
|
74
|
+
get inputTypeReason(): string;
|
|
75
|
+
/**
|
|
76
|
+
* Describe why this type is an output type (if it is)
|
|
77
|
+
*/
|
|
78
|
+
get outputTypeReason(): string;
|
|
79
|
+
/**
|
|
80
|
+
* Should be overriden in subclasses to mark reachable types as input/output types
|
|
81
|
+
*
|
|
82
|
+
* Should only be implemented by subclasses that contain callables.
|
|
83
|
+
*/
|
|
84
|
+
markTypeRoles(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Should be overridden in subclasses to perform the comparison
|
|
87
|
+
*
|
|
88
|
+
* Input/output marking will already have been performed before this is called.
|
|
89
|
+
*/
|
|
90
|
+
abstract compare(): void;
|
|
91
|
+
/**
|
|
92
|
+
* Alias for the root object Mismaches object
|
|
93
|
+
*/
|
|
94
|
+
protected get mismatches(): Mismatches;
|
|
95
|
+
/**
|
|
96
|
+
* Should be overriden in subclasses to execute the callback on reachable types
|
|
97
|
+
*
|
|
98
|
+
* Should be overriden only for product types (structs).
|
|
99
|
+
*/
|
|
100
|
+
protected forEachRoleSharingType(cb: (t: ComparableType<any>, reason: string) => void): void;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Base class for reference types
|
|
104
|
+
*
|
|
105
|
+
* Contains shared code that applies to both class and interface types.
|
|
106
|
+
*/
|
|
107
|
+
export declare abstract class ComparableReferenceType<T extends reflect.ReferenceType> extends ComparableType<T> {
|
|
108
|
+
/**
|
|
109
|
+
* Compare members of the reference types
|
|
110
|
+
*/
|
|
111
|
+
compare(): void;
|
|
112
|
+
/**
|
|
113
|
+
* Mark type accesses (input/output) of methods and properties
|
|
114
|
+
*/
|
|
115
|
+
markTypeRoles(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Validate type signatures on all methods
|
|
118
|
+
*/
|
|
119
|
+
protected validateMethods(): void;
|
|
120
|
+
/**
|
|
121
|
+
* Validate type signature changes on the given method
|
|
122
|
+
*/
|
|
123
|
+
protected validateMethod(original: reflect.Method, updated: reflect.Method): void;
|
|
124
|
+
/**
|
|
125
|
+
* Validate type signature changes on the given callable (method or initializer)
|
|
126
|
+
*/
|
|
127
|
+
protected validateCallable<T extends reflect.Method | reflect.Initializer>(original: T, updated: T): void;
|
|
128
|
+
/**
|
|
129
|
+
* Validate type signature changes on all properties
|
|
130
|
+
*/
|
|
131
|
+
protected validateProperties(): void;
|
|
132
|
+
/**
|
|
133
|
+
* Validate type signature changes on the given property
|
|
134
|
+
*/
|
|
135
|
+
protected validateProperty(original: reflect.Property, updated: reflect.Property): void;
|
|
136
|
+
/**
|
|
137
|
+
* Whether the current reference type has been marked as subclassable
|
|
138
|
+
*/
|
|
139
|
+
private get subclassableType();
|
|
140
|
+
}
|
|
141
|
+
export declare class ComparableClassType extends ComparableReferenceType<reflect.ClassType> {
|
|
142
|
+
/**
|
|
143
|
+
* Perform the reference type comparison and include class-specific checks
|
|
144
|
+
*/
|
|
145
|
+
compare(): void;
|
|
146
|
+
/**
|
|
147
|
+
* Type role marking -- include the initializer
|
|
148
|
+
*/
|
|
149
|
+
markTypeRoles(): void;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Interface type comparison
|
|
153
|
+
*
|
|
154
|
+
* (Actually just plain reference type comparison)
|
|
155
|
+
*/
|
|
156
|
+
export declare class ComparableInterfaceType extends ComparableReferenceType<reflect.InterfaceType> {
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Struct type comparison
|
|
160
|
+
*
|
|
161
|
+
* Most notably: does no-strengthening/no-weakening checks based on whether
|
|
162
|
+
* structs appear in input/output positions.
|
|
163
|
+
*/
|
|
164
|
+
export declare class ComparableStructType extends ComparableType<reflect.InterfaceType> {
|
|
165
|
+
compare(): void;
|
|
166
|
+
/**
|
|
167
|
+
* Every type of every property should have the same in/out classification as the outer type
|
|
168
|
+
*/
|
|
169
|
+
protected forEachRoleSharingType(cb: (t: ComparableType<any>, reason: string) => void): void;
|
|
170
|
+
/**
|
|
171
|
+
* Check that all properties are still present
|
|
172
|
+
*
|
|
173
|
+
* This is because for all non-structurally typed languages it is not allowed
|
|
174
|
+
* to specify members which aren't actually present in the type.
|
|
175
|
+
*/
|
|
176
|
+
private validateNoPropertiesRemoved;
|
|
177
|
+
/**
|
|
178
|
+
* Check that the current type is not weakened
|
|
179
|
+
*/
|
|
180
|
+
private validateNotWeakened;
|
|
181
|
+
/**
|
|
182
|
+
* Check that the current type is not strengthened
|
|
183
|
+
*/
|
|
184
|
+
private validateNotStrengthened;
|
|
185
|
+
private isStructuralSuperType;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Comparison for enums
|
|
189
|
+
*/
|
|
190
|
+
export declare class ComparableEnumType extends ComparableType<reflect.EnumType> {
|
|
191
|
+
/**
|
|
192
|
+
* Perform comparisons on enum members
|
|
193
|
+
*/
|
|
194
|
+
compare(): void;
|
|
195
|
+
}
|