jsii 5.8.22-dev.8 → 5.8.22
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/lib/assembler.d.ts +24 -1
- package/lib/assembler.js +268 -38
- package/lib/assembler.js.map +1 -1
- package/lib/helpers.d.ts +37 -3
- package/lib/helpers.js +27 -6
- package/lib/helpers.js.map +1 -1
- package/lib/jsii-diagnostic.d.ts +5 -0
- package/lib/jsii-diagnostic.js +25 -0
- package/lib/jsii-diagnostic.js.map +1 -1
- package/lib/project-info.js +2 -1
- package/lib/project-info.js.map +1 -1
- package/lib/sets.d.ts +16 -0
- package/lib/sets.js +41 -0
- package/lib/sets.js.map +1 -0
- package/lib/type-analysis.d.ts +11 -0
- package/lib/type-analysis.js +123 -0
- package/lib/type-analysis.js.map +1 -0
- package/lib/type-reference.d.ts +20 -0
- package/lib/type-reference.js +75 -0
- package/lib/type-reference.js.map +1 -0
- package/lib/type-visitor.d.ts +19 -0
- package/lib/type-visitor.js +51 -0
- package/lib/type-visitor.js.map +1 -0
- package/lib/validator.d.ts +6 -2
- package/lib/validator.js +62 -34
- package/lib/validator.js.map +1 -1
- package/lib/version.d.ts +2 -2
- package/lib/version.js +2 -2
- package/lib/version.js.map +1 -1
- package/package.json +4 -4
- package/testspee/.eslintrc.js +3 -0
- package/testspee/LICENSE +201 -0
- package/testspee/NOTICE +406 -0
- package/testspee/README.md +1305 -0
- package/testspee/scripts/minify-sources.sh +26 -0
- package/testspee/scripts/verify-imports-resolve-same.ts +142 -0
- package/testspee/scripts/verify-imports-shielded.ts +57 -0
- package/testspee/scripts/verify-stripped-exp.ts +158 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isAllowedCovariantSubtype = isAllowedCovariantSubtype;
|
|
4
|
+
const spec = require("@jsii/spec");
|
|
5
|
+
const deepEqual = require("fast-deep-equal");
|
|
6
|
+
/**
|
|
7
|
+
* Check if subType is an allowed covariant subtype to superType
|
|
8
|
+
*
|
|
9
|
+
* This is not a generic check for subtypes or covariance, but a specific implementation
|
|
10
|
+
* that checks the currently allowed conditions for class covariance.
|
|
11
|
+
* In practice, this is driven by C# limitations.
|
|
12
|
+
*/
|
|
13
|
+
function isAllowedCovariantSubtype(subType, superType, dereference) {
|
|
14
|
+
// one void, while other isn't => not covariant
|
|
15
|
+
if ((subType === undefined) !== (superType === undefined)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
// Same type is always covariant
|
|
19
|
+
if (deepEqual(subType, superType)) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
// Handle array collections (covariant)
|
|
23
|
+
if (spec.isCollectionTypeReference(subType) && spec.isCollectionTypeReference(superType)) {
|
|
24
|
+
if (subType.collection.kind === 'array' && superType.collection.kind === 'array') {
|
|
25
|
+
return isAllowedCovariantSubtype(subType.collection.elementtype, superType.collection.elementtype, dereference);
|
|
26
|
+
}
|
|
27
|
+
// Maps are not allowed to be covariant in C#, so we exclude them here.
|
|
28
|
+
// This seems to be because we use C# Dictionary to implements Maps, which are using generics and generics are not allowed to be covariant
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
// Union types are currently not allowed, because we have not seen the need for it.
|
|
32
|
+
// Technically narrowing (removing `| Type` or subtyping) could be allowed and this works in C#.
|
|
33
|
+
if (spec.isUnionTypeReference(subType) || spec.isUnionTypeReference(superType)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
// Intersection types are invalid, because intersections are only allowed as inputs
|
|
37
|
+
// and covariance is only allowed in outputs.
|
|
38
|
+
if (spec.isIntersectionTypeReference(subType) || spec.isIntersectionTypeReference(superType)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
// Primitives can never be covariant to each other in C#
|
|
42
|
+
if (spec.isPrimitiveTypeReference(subType) || spec.isPrimitiveTypeReference(superType)) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
// We really only support covariance for named types (and lists of named types).
|
|
46
|
+
// To be safe, let's guard against any unknown cases.
|
|
47
|
+
if (!spec.isNamedTypeReference(subType) || !spec.isNamedTypeReference(superType)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const subTypeSpec = dereference(subType.fqn);
|
|
51
|
+
const superTypeSpec = dereference(superType.fqn);
|
|
52
|
+
if (!subTypeSpec || !superTypeSpec) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
// Handle class-to-class inheritance
|
|
56
|
+
if (spec.isClassType(subTypeSpec) && spec.isClassType(superTypeSpec)) {
|
|
57
|
+
return _classExtendsClass(subTypeSpec, superType.fqn);
|
|
58
|
+
}
|
|
59
|
+
// Handle interface-to-interface inheritance
|
|
60
|
+
if (spec.isInterfaceType(subTypeSpec) && spec.isInterfaceType(superTypeSpec)) {
|
|
61
|
+
return _interfaceExtendsInterface(subTypeSpec, superType.fqn);
|
|
62
|
+
}
|
|
63
|
+
// Handle class implementing interface
|
|
64
|
+
if (spec.isClassType(subTypeSpec) && spec.isInterfaceType(superTypeSpec)) {
|
|
65
|
+
return _classImplementsInterface(subTypeSpec, superType.fqn);
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
function _classExtendsClass(classType, targetFqn) {
|
|
69
|
+
let current = classType;
|
|
70
|
+
while (current.base) {
|
|
71
|
+
if (current.base === targetFqn) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
const baseType = dereference(current.base);
|
|
75
|
+
if (!spec.isClassType(baseType)) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
current = baseType;
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
function _classImplementsInterface(classType, interfaceFqn) {
|
|
83
|
+
// Check direct interfaces
|
|
84
|
+
if (classType.interfaces?.includes(interfaceFqn)) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
// Check inherited interfaces
|
|
88
|
+
if (classType.interfaces) {
|
|
89
|
+
for (const iface of classType.interfaces) {
|
|
90
|
+
const ifaceType = dereference(iface);
|
|
91
|
+
if (spec.isInterfaceType(ifaceType) && _interfaceExtendsInterface(ifaceType, interfaceFqn)) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Check base class interfaces
|
|
97
|
+
if (classType.base) {
|
|
98
|
+
const baseType = dereference(classType.base);
|
|
99
|
+
if (spec.isClassType(baseType)) {
|
|
100
|
+
return _classImplementsInterface(baseType, interfaceFqn);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
function _interfaceExtendsInterface(interfaceType, targetFqn) {
|
|
106
|
+
if (interfaceType.fqn === targetFqn) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
if (interfaceType.interfaces) {
|
|
110
|
+
for (const iface of interfaceType.interfaces) {
|
|
111
|
+
if (iface === targetFqn) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
const ifaceType = dereference(iface);
|
|
115
|
+
if (spec.isInterfaceType(ifaceType) && _interfaceExtendsInterface(ifaceType, targetFqn)) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=type-analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-analysis.js","sourceRoot":"","sources":["../src/type-analysis.ts"],"names":[],"mappings":"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","sourcesContent":["import * as spec from '@jsii/spec';\nimport * as deepEqual from 'fast-deep-equal';\nimport { TypeResolver } from './type-reference';\n\n/**\n * Check if subType is an allowed covariant subtype to superType\n *\n * This is not a generic check for subtypes or covariance, but a specific implementation\n * that checks the currently allowed conditions for class covariance.\n * In practice, this is driven by C# limitations.\n */\nexport function isAllowedCovariantSubtype(\n subType: spec.TypeReference | undefined,\n superType: spec.TypeReference | undefined,\n dereference: TypeResolver,\n): boolean {\n // one void, while other isn't => not covariant\n if ((subType === undefined) !== (superType === undefined)) {\n return false;\n }\n\n // Same type is always covariant\n if (deepEqual(subType, superType)) {\n return true;\n }\n\n // Handle array collections (covariant)\n if (spec.isCollectionTypeReference(subType) && spec.isCollectionTypeReference(superType)) {\n if (subType.collection.kind === 'array' && superType.collection.kind === 'array') {\n return isAllowedCovariantSubtype(subType.collection.elementtype, superType.collection.elementtype, dereference);\n }\n // Maps are not allowed to be covariant in C#, so we exclude them here.\n // This seems to be because we use C# Dictionary to implements Maps, which are using generics and generics are not allowed to be covariant\n return false;\n }\n\n // Union types are currently not allowed, because we have not seen the need for it.\n // Technically narrowing (removing `| Type` or subtyping) could be allowed and this works in C#.\n if (spec.isUnionTypeReference(subType) || spec.isUnionTypeReference(superType)) {\n return false;\n }\n\n // Intersection types are invalid, because intersections are only allowed as inputs\n // and covariance is only allowed in outputs.\n if (spec.isIntersectionTypeReference(subType) || spec.isIntersectionTypeReference(superType)) {\n return false;\n }\n\n // Primitives can never be covariant to each other in C#\n if (spec.isPrimitiveTypeReference(subType) || spec.isPrimitiveTypeReference(superType)) {\n return false;\n }\n\n // We really only support covariance for named types (and lists of named types).\n // To be safe, let's guard against any unknown cases.\n if (!spec.isNamedTypeReference(subType) || !spec.isNamedTypeReference(superType)) {\n return false;\n }\n\n const subTypeSpec = dereference(subType.fqn);\n const superTypeSpec = dereference(superType.fqn);\n\n if (!subTypeSpec || !superTypeSpec) {\n return false;\n }\n\n // Handle class-to-class inheritance\n if (spec.isClassType(subTypeSpec) && spec.isClassType(superTypeSpec)) {\n return _classExtendsClass(subTypeSpec, superType.fqn);\n }\n\n // Handle interface-to-interface inheritance\n if (spec.isInterfaceType(subTypeSpec) && spec.isInterfaceType(superTypeSpec)) {\n return _interfaceExtendsInterface(subTypeSpec, superType.fqn);\n }\n\n // Handle class implementing interface\n if (spec.isClassType(subTypeSpec) && spec.isInterfaceType(superTypeSpec)) {\n return _classImplementsInterface(subTypeSpec, superType.fqn);\n }\n\n return false;\n\n function _classExtendsClass(classType: spec.ClassType, targetFqn: string): boolean {\n let current = classType;\n while (current.base) {\n if (current.base === targetFqn) {\n return true;\n }\n const baseType = dereference(current.base);\n if (!spec.isClassType(baseType)) {\n break;\n }\n current = baseType;\n }\n return false;\n }\n\n function _classImplementsInterface(classType: spec.ClassType, interfaceFqn: string): boolean {\n // Check direct interfaces\n if (classType.interfaces?.includes(interfaceFqn)) {\n return true;\n }\n\n // Check inherited interfaces\n if (classType.interfaces) {\n for (const iface of classType.interfaces) {\n const ifaceType = dereference(iface);\n if (spec.isInterfaceType(ifaceType) && _interfaceExtendsInterface(ifaceType, interfaceFqn)) {\n return true;\n }\n }\n }\n\n // Check base class interfaces\n if (classType.base) {\n const baseType = dereference(classType.base);\n if (spec.isClassType(baseType)) {\n return _classImplementsInterface(baseType, interfaceFqn);\n }\n }\n\n return false;\n }\n\n function _interfaceExtendsInterface(interfaceType: spec.InterfaceType, targetFqn: string): boolean {\n if (interfaceType.fqn === targetFqn) {\n return true;\n }\n\n if (interfaceType.interfaces) {\n for (const iface of interfaceType.interfaces) {\n if (iface === targetFqn) {\n return true;\n }\n const ifaceType = dereference(iface);\n if (spec.isInterfaceType(ifaceType) && _interfaceExtendsInterface(ifaceType, targetFqn)) {\n return true;\n }\n }\n }\n\n return false;\n }\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as spec from '@jsii/spec';
|
|
2
|
+
/**
|
|
3
|
+
* Convert a type reference to a string
|
|
4
|
+
*/
|
|
5
|
+
export declare function typeReferenceToString(x: spec.TypeReference): string;
|
|
6
|
+
/**
|
|
7
|
+
* Return whether the given type references are equal
|
|
8
|
+
*/
|
|
9
|
+
export declare function typeReferenceEqual(a: spec.TypeReference, b: spec.TypeReference): boolean;
|
|
10
|
+
export type TypeResolver = (typeRef: string | spec.NamedTypeReference) => spec.Type | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a type resolver function for a given context (assembly + dependency closure).
|
|
13
|
+
*/
|
|
14
|
+
export declare function createTypeResolver(assembly: spec.Assembly, dependencyClosure: readonly spec.Assembly[]): TypeResolver;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a type from a name to the actual type.
|
|
17
|
+
* Uses a given assembly and dependency closure for lookup.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveType(typeRef: string | spec.NamedTypeReference, assembly: spec.Assembly, dependencyClosure: readonly spec.Assembly[]): spec.Type | undefined;
|
|
20
|
+
//# sourceMappingURL=type-reference.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.typeReferenceToString = typeReferenceToString;
|
|
4
|
+
exports.typeReferenceEqual = typeReferenceEqual;
|
|
5
|
+
exports.createTypeResolver = createTypeResolver;
|
|
6
|
+
exports.resolveType = resolveType;
|
|
7
|
+
const spec = require("@jsii/spec");
|
|
8
|
+
const type_visitor_1 = require("./type-visitor");
|
|
9
|
+
/**
|
|
10
|
+
* Convert a type reference to a string
|
|
11
|
+
*/
|
|
12
|
+
function typeReferenceToString(x) {
|
|
13
|
+
return (0, type_visitor_1.visitTypeReference)(x, {
|
|
14
|
+
named: function (ref) {
|
|
15
|
+
return ref.fqn;
|
|
16
|
+
},
|
|
17
|
+
primitive: function (ref) {
|
|
18
|
+
return ref.primitive;
|
|
19
|
+
},
|
|
20
|
+
collection: function (ref) {
|
|
21
|
+
return `${ref.collection.kind}<${typeReferenceToString(ref.collection.elementtype)}>`;
|
|
22
|
+
},
|
|
23
|
+
union: function (ref) {
|
|
24
|
+
return ref.union.types.map(typeReferenceToString).join(' | ');
|
|
25
|
+
},
|
|
26
|
+
intersection: function (ref) {
|
|
27
|
+
return ref.intersection.types.map(typeReferenceToString).join(' & ');
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Return whether the given type references are equal
|
|
33
|
+
*/
|
|
34
|
+
function typeReferenceEqual(a, b) {
|
|
35
|
+
if (spec.isNamedTypeReference(a) && spec.isNamedTypeReference(b)) {
|
|
36
|
+
return a.fqn === b.fqn;
|
|
37
|
+
}
|
|
38
|
+
if (spec.isPrimitiveTypeReference(a) && spec.isPrimitiveTypeReference(b)) {
|
|
39
|
+
return a.primitive === b.primitive;
|
|
40
|
+
}
|
|
41
|
+
if (spec.isCollectionTypeReference(a) && spec.isCollectionTypeReference(b)) {
|
|
42
|
+
return (a.collection.kind === b.collection.kind && typeReferenceEqual(a.collection.elementtype, b.collection.elementtype));
|
|
43
|
+
}
|
|
44
|
+
if (spec.isUnionTypeReference(a) && spec.isUnionTypeReference(b)) {
|
|
45
|
+
return (a.union.types.length === b.union.types.length &&
|
|
46
|
+
a.union.types.every((aType, i) => typeReferenceEqual(aType, b.union.types[i])));
|
|
47
|
+
}
|
|
48
|
+
if (spec.isIntersectionTypeReference(a) && spec.isIntersectionTypeReference(b)) {
|
|
49
|
+
return (a.intersection.types.length === b.intersection.types.length &&
|
|
50
|
+
a.intersection.types.every((aType, i) => typeReferenceEqual(aType, b.intersection.types[i])));
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Creates a type resolver function for a given context (assembly + dependency closure).
|
|
56
|
+
*/
|
|
57
|
+
function createTypeResolver(assembly, dependencyClosure) {
|
|
58
|
+
return (typeRef) => resolveType(typeRef, assembly, dependencyClosure);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Resolve a type from a name to the actual type.
|
|
62
|
+
* Uses a given assembly and dependency closure for lookup.
|
|
63
|
+
*/
|
|
64
|
+
function resolveType(typeRef, assembly, dependencyClosure) {
|
|
65
|
+
if (typeof typeRef !== 'string') {
|
|
66
|
+
typeRef = typeRef.fqn;
|
|
67
|
+
}
|
|
68
|
+
const [assm] = typeRef.split('.');
|
|
69
|
+
if (assembly.name === assm) {
|
|
70
|
+
return assembly.types?.[typeRef];
|
|
71
|
+
}
|
|
72
|
+
const foreignAssm = dependencyClosure.find((dep) => dep.name === assm);
|
|
73
|
+
return foreignAssm?.types?.[typeRef];
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=type-reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-reference.js","sourceRoot":"","sources":["../src/type-reference.ts"],"names":[],"mappings":"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","sourcesContent":["import * as spec from '@jsii/spec';\nimport { visitTypeReference } from './type-visitor';\n\n/**\n * Convert a type reference to a string\n */\nexport function typeReferenceToString(x: spec.TypeReference): string {\n return visitTypeReference<string>(x, {\n named: function (ref: spec.NamedTypeReference) {\n return ref.fqn;\n },\n primitive: function (ref: spec.PrimitiveTypeReference) {\n return ref.primitive;\n },\n collection: function (ref: spec.CollectionTypeReference) {\n return `${ref.collection.kind}<${typeReferenceToString(ref.collection.elementtype)}>`;\n },\n union: function (ref: spec.UnionTypeReference) {\n return ref.union.types.map(typeReferenceToString).join(' | ');\n },\n intersection: function (ref: spec.IntersectionTypeReference) {\n return ref.intersection.types.map(typeReferenceToString).join(' & ');\n },\n });\n}\n\n/**\n * Return whether the given type references are equal\n */\nexport function typeReferenceEqual(a: spec.TypeReference, b: spec.TypeReference): boolean {\n if (spec.isNamedTypeReference(a) && spec.isNamedTypeReference(b)) {\n return a.fqn === b.fqn;\n }\n if (spec.isPrimitiveTypeReference(a) && spec.isPrimitiveTypeReference(b)) {\n return a.primitive === b.primitive;\n }\n if (spec.isCollectionTypeReference(a) && spec.isCollectionTypeReference(b)) {\n return (\n a.collection.kind === b.collection.kind && typeReferenceEqual(a.collection.elementtype, b.collection.elementtype)\n );\n }\n if (spec.isUnionTypeReference(a) && spec.isUnionTypeReference(b)) {\n return (\n a.union.types.length === b.union.types.length &&\n a.union.types.every((aType, i) => typeReferenceEqual(aType, b.union.types[i]))\n );\n }\n if (spec.isIntersectionTypeReference(a) && spec.isIntersectionTypeReference(b)) {\n return (\n a.intersection.types.length === b.intersection.types.length &&\n a.intersection.types.every((aType, i) => typeReferenceEqual(aType, b.intersection.types[i]))\n );\n }\n return false;\n}\n\nexport type TypeResolver = (typeRef: string | spec.NamedTypeReference) => spec.Type | undefined;\n\n/**\n * Creates a type resolver function for a given context (assembly + dependency closure).\n */\nexport function createTypeResolver(assembly: spec.Assembly, dependencyClosure: readonly spec.Assembly[]): TypeResolver {\n return (typeRef) => resolveType(typeRef, assembly, dependencyClosure);\n}\n\n/**\n * Resolve a type from a name to the actual type.\n * Uses a given assembly and dependency closure for lookup.\n */\nexport function resolveType(\n typeRef: string | spec.NamedTypeReference,\n assembly: spec.Assembly,\n dependencyClosure: readonly spec.Assembly[],\n): spec.Type | undefined {\n if (typeof typeRef !== 'string') {\n typeRef = typeRef.fqn;\n }\n const [assm] = typeRef.split('.');\n if (assembly.name === assm) {\n return assembly.types?.[typeRef];\n }\n const foreignAssm = dependencyClosure.find((dep) => dep.name === assm);\n return foreignAssm?.types?.[typeRef];\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as spec from '@jsii/spec';
|
|
2
|
+
export interface TypeReferenceVisitor<A = void> {
|
|
3
|
+
named(ref: spec.NamedTypeReference): A;
|
|
4
|
+
primitive(ref: spec.PrimitiveTypeReference): A;
|
|
5
|
+
collection(ref: spec.CollectionTypeReference): A;
|
|
6
|
+
union(ref: spec.UnionTypeReference): A;
|
|
7
|
+
intersection(ref: spec.IntersectionTypeReference): A;
|
|
8
|
+
}
|
|
9
|
+
export declare function visitTypeReference<A>(typeRef: spec.TypeReference, visitor: TypeReferenceVisitor<A>): A;
|
|
10
|
+
export interface TypeVisitor<A = void> {
|
|
11
|
+
classType(t: spec.ClassType): A;
|
|
12
|
+
interfaceType(t: spec.InterfaceType): A;
|
|
13
|
+
dataType(t: spec.InterfaceType): A;
|
|
14
|
+
enumType(t: spec.EnumType): A;
|
|
15
|
+
}
|
|
16
|
+
export declare function visitType<A>(t: spec.Type, visitor: TypeVisitor<A>): A;
|
|
17
|
+
export declare function isDataType(t: spec.Type): t is spec.InterfaceType;
|
|
18
|
+
export declare function isBehavioralInterfaceType(t: spec.Type): t is spec.InterfaceType;
|
|
19
|
+
//# sourceMappingURL=type-visitor.d.ts.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.visitTypeReference = visitTypeReference;
|
|
4
|
+
exports.visitType = visitType;
|
|
5
|
+
exports.isDataType = isDataType;
|
|
6
|
+
exports.isBehavioralInterfaceType = isBehavioralInterfaceType;
|
|
7
|
+
const spec = require("@jsii/spec");
|
|
8
|
+
function visitTypeReference(typeRef, visitor) {
|
|
9
|
+
if (spec.isNamedTypeReference(typeRef)) {
|
|
10
|
+
return visitor.named(typeRef);
|
|
11
|
+
}
|
|
12
|
+
else if (spec.isPrimitiveTypeReference(typeRef)) {
|
|
13
|
+
return visitor.primitive(typeRef);
|
|
14
|
+
}
|
|
15
|
+
else if (spec.isCollectionTypeReference(typeRef)) {
|
|
16
|
+
return visitor.collection(typeRef);
|
|
17
|
+
}
|
|
18
|
+
else if (spec.isUnionTypeReference(typeRef)) {
|
|
19
|
+
return visitor.union(typeRef);
|
|
20
|
+
}
|
|
21
|
+
else if (spec.isIntersectionTypeReference(typeRef)) {
|
|
22
|
+
return visitor.intersection(typeRef);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
throw new Error(`Unknown type reference: ${JSON.stringify(typeRef)}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function visitType(t, visitor) {
|
|
29
|
+
if (spec.isClassType(t)) {
|
|
30
|
+
return visitor.classType(t);
|
|
31
|
+
}
|
|
32
|
+
else if (spec.isInterfaceType(t) && t.datatype) {
|
|
33
|
+
return visitor.dataType(t);
|
|
34
|
+
}
|
|
35
|
+
else if (spec.isInterfaceType(t)) {
|
|
36
|
+
return visitor.interfaceType(t);
|
|
37
|
+
}
|
|
38
|
+
else if (spec.isEnumType(t)) {
|
|
39
|
+
return visitor.enumType(t);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
throw new Error(`Unknown type: ${JSON.stringify(t)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function isDataType(t) {
|
|
46
|
+
return spec.isInterfaceType(t) && !!t.datatype;
|
|
47
|
+
}
|
|
48
|
+
function isBehavioralInterfaceType(t) {
|
|
49
|
+
return spec.isInterfaceType(t) && !t.datatype;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=type-visitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-visitor.js","sourceRoot":"","sources":["../src/type-visitor.ts"],"names":[],"mappings":";;AAUA,gDAcC;AASD,8BAYC;AAED,gCAEC;AAED,8DAEC;AArDD,mCAAmC;AAUnC,SAAgB,kBAAkB,CAAI,OAA2B,EAAE,OAAgC;IACjG,IAAI,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;SAAM,IAAI,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;SAAM,IAAI,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,OAAO,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;SAAM,IAAI,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;SAAM,IAAI,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,OAAO,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AASD,SAAgB,SAAS,CAAI,CAAY,EAAE,OAAuB;IAChE,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;SAAM,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QACjD,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;SAAM,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;SAAM,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED,SAAgB,UAAU,CAAC,CAAY;IACrC,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AACjD,CAAC;AAED,SAAgB,yBAAyB,CAAC,CAAY;IACpD,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAChD,CAAC","sourcesContent":["import * as spec from '@jsii/spec';\n\nexport interface TypeReferenceVisitor<A = void> {\n named(ref: spec.NamedTypeReference): A;\n primitive(ref: spec.PrimitiveTypeReference): A;\n collection(ref: spec.CollectionTypeReference): A;\n union(ref: spec.UnionTypeReference): A;\n intersection(ref: spec.IntersectionTypeReference): A;\n}\n\nexport function visitTypeReference<A>(typeRef: spec.TypeReference, visitor: TypeReferenceVisitor<A>) {\n if (spec.isNamedTypeReference(typeRef)) {\n return visitor.named(typeRef);\n } else if (spec.isPrimitiveTypeReference(typeRef)) {\n return visitor.primitive(typeRef);\n } else if (spec.isCollectionTypeReference(typeRef)) {\n return visitor.collection(typeRef);\n } else if (spec.isUnionTypeReference(typeRef)) {\n return visitor.union(typeRef);\n } else if (spec.isIntersectionTypeReference(typeRef)) {\n return visitor.intersection(typeRef);\n } else {\n throw new Error(`Unknown type reference: ${JSON.stringify(typeRef)}`);\n }\n}\n\nexport interface TypeVisitor<A = void> {\n classType(t: spec.ClassType): A;\n interfaceType(t: spec.InterfaceType): A;\n dataType(t: spec.InterfaceType): A;\n enumType(t: spec.EnumType): A;\n}\n\nexport function visitType<A>(t: spec.Type, visitor: TypeVisitor<A>) {\n if (spec.isClassType(t)) {\n return visitor.classType(t);\n } else if (spec.isInterfaceType(t) && t.datatype) {\n return visitor.dataType(t);\n } else if (spec.isInterfaceType(t)) {\n return visitor.interfaceType(t);\n } else if (spec.isEnumType(t)) {\n return visitor.enumType(t);\n } else {\n throw new Error(`Unknown type: ${JSON.stringify(t)}`);\n }\n}\n\nexport function isDataType(t: spec.Type): t is spec.InterfaceType {\n return spec.isInterfaceType(t) && !!t.datatype;\n}\n\nexport function isBehavioralInterfaceType(t: spec.Type): t is spec.InterfaceType {\n return spec.isInterfaceType(t) && !t.datatype;\n}\n"]}
|
package/lib/validator.d.ts
CHANGED
|
@@ -3,13 +3,17 @@ import * as ts from 'typescript';
|
|
|
3
3
|
import { Emitter } from './emitter';
|
|
4
4
|
import { JsiiDiagnostic } from './jsii-diagnostic';
|
|
5
5
|
import { ProjectInfo } from './project-info';
|
|
6
|
+
export interface ValidationResult extends ts.EmitResult {
|
|
7
|
+
readonly usedFeatures?: spec.JsiiFeature[];
|
|
8
|
+
}
|
|
6
9
|
export declare class Validator implements Emitter {
|
|
7
10
|
readonly projectInfo: ProjectInfo;
|
|
8
11
|
readonly assembly: spec.Assembly;
|
|
9
12
|
static VALIDATIONS: ValidationFunction[];
|
|
10
13
|
constructor(projectInfo: ProjectInfo, assembly: spec.Assembly);
|
|
11
|
-
emit():
|
|
14
|
+
emit(): ValidationResult;
|
|
12
15
|
}
|
|
13
16
|
export type DiagnosticEmitter = (diag: JsiiDiagnostic) => void;
|
|
14
|
-
export type
|
|
17
|
+
export type FeatureTracker = (feat: spec.JsiiFeature) => void;
|
|
18
|
+
export type ValidationFunction = (validator: Validator, assembly: spec.Assembly, diagnostic: DiagnosticEmitter, useFeatures: FeatureTracker) => void;
|
|
15
19
|
//# sourceMappingURL=validator.d.ts.map
|
package/lib/validator.js
CHANGED
|
@@ -9,6 +9,8 @@ const Case = require("./case");
|
|
|
9
9
|
const jsii_diagnostic_1 = require("./jsii-diagnostic");
|
|
10
10
|
const node_bindings_1 = require("./node-bindings");
|
|
11
11
|
const bindings = require("./node-bindings");
|
|
12
|
+
const type_analysis_1 = require("./type-analysis");
|
|
13
|
+
const type_reference_1 = require("./type-reference");
|
|
12
14
|
class Validator {
|
|
13
15
|
constructor(projectInfo, assembly) {
|
|
14
16
|
this.projectInfo = projectInfo;
|
|
@@ -16,12 +18,14 @@ class Validator {
|
|
|
16
18
|
}
|
|
17
19
|
emit() {
|
|
18
20
|
const diagnostics = new Array();
|
|
21
|
+
const usedFeatures = new Array();
|
|
19
22
|
for (const validation of Validator.VALIDATIONS) {
|
|
20
|
-
validation(this, this.assembly, diagnostics.push.bind(diagnostics));
|
|
23
|
+
validation(this, this.assembly, diagnostics.push.bind(diagnostics), usedFeatures.push.bind(usedFeatures));
|
|
21
24
|
}
|
|
22
25
|
return {
|
|
23
26
|
diagnostics: diagnostics,
|
|
24
27
|
emitSkipped: diagnostics.some((diag) => diag.category === ts.DiagnosticCategory.Error),
|
|
28
|
+
usedFeatures,
|
|
25
29
|
};
|
|
26
30
|
}
|
|
27
31
|
}
|
|
@@ -34,7 +38,7 @@ function _defaultValidations() {
|
|
|
34
38
|
_staticConstantNamesMustUseUpperSnakeCase,
|
|
35
39
|
_memberNamesMustNotLookLikeJavaGettersOrSetters,
|
|
36
40
|
_allTypeReferencesAreValid,
|
|
37
|
-
|
|
41
|
+
_inheritanceDoesNotChangeContracts,
|
|
38
42
|
_staticMembersAndNestedTypesMustNotSharePascalCaseName,
|
|
39
43
|
_abstractClassesMustImplementAllProperties,
|
|
40
44
|
];
|
|
@@ -107,7 +111,8 @@ function _defaultValidations() {
|
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
113
|
}
|
|
110
|
-
function
|
|
114
|
+
function _inheritanceDoesNotChangeContracts(validator, assembly, diagnostic, useFeature) {
|
|
115
|
+
const _dereference = (0, type_reference_1.createTypeResolver)(assembly, validator.projectInfo.dependencyClosure);
|
|
111
116
|
for (const type of _allTypes(assembly)) {
|
|
112
117
|
if (spec.isClassType(type)) {
|
|
113
118
|
for (const method of type.methods ?? []) {
|
|
@@ -147,7 +152,7 @@ function _defaultValidations() {
|
|
|
147
152
|
}
|
|
148
153
|
if (spec.isClassType(type) && type.base) {
|
|
149
154
|
// We have a parent class, collect their concrete members, too (recursively)...
|
|
150
|
-
const base = _dereference(type.base
|
|
155
|
+
const base = _dereference(type.base);
|
|
151
156
|
assert(base != null && spec.isClassType(base));
|
|
152
157
|
for (const member of _allImplementations(base, getter)) {
|
|
153
158
|
if (known.has(member.name)) {
|
|
@@ -175,7 +180,7 @@ function _defaultValidations() {
|
|
|
175
180
|
if (!type.base) {
|
|
176
181
|
return false;
|
|
177
182
|
}
|
|
178
|
-
const baseType = _dereference(type.base
|
|
183
|
+
const baseType = _dereference(type.base);
|
|
179
184
|
if (!baseType) {
|
|
180
185
|
return false;
|
|
181
186
|
}
|
|
@@ -183,7 +188,9 @@ function _defaultValidations() {
|
|
|
183
188
|
if (!overridden) {
|
|
184
189
|
return _validateMethodOverride(method, baseType);
|
|
185
190
|
}
|
|
186
|
-
_assertSignaturesMatch(overridden, method, `${type.fqn}#${method.name}`, `overriding ${baseType.fqn}
|
|
191
|
+
_assertSignaturesMatch(overridden, method, `${type.fqn}#${method.name}`, `overriding ${baseType.fqn}`, {
|
|
192
|
+
allowReturnTypeCovariance: true,
|
|
193
|
+
});
|
|
187
194
|
method.overrides = baseType.fqn;
|
|
188
195
|
return true;
|
|
189
196
|
}
|
|
@@ -191,7 +198,7 @@ function _defaultValidations() {
|
|
|
191
198
|
if (!type.base) {
|
|
192
199
|
return false;
|
|
193
200
|
}
|
|
194
|
-
const baseType = _dereference(type.base
|
|
201
|
+
const baseType = _dereference(type.base);
|
|
195
202
|
if (!baseType) {
|
|
196
203
|
return false;
|
|
197
204
|
}
|
|
@@ -199,7 +206,9 @@ function _defaultValidations() {
|
|
|
199
206
|
if (!overridden) {
|
|
200
207
|
return _validatePropertyOverride(property, baseType);
|
|
201
208
|
}
|
|
202
|
-
_assertPropertiesMatch(overridden, property, `${type.fqn}#${property.name}`, `overriding ${baseType.fqn}
|
|
209
|
+
_assertPropertiesMatch(overridden, property, `${type.fqn}#${property.name}`, `overriding ${baseType.fqn}`, {
|
|
210
|
+
allowCovariance: true,
|
|
211
|
+
});
|
|
203
212
|
property.overrides = baseType.fqn;
|
|
204
213
|
return true;
|
|
205
214
|
}
|
|
@@ -207,15 +216,17 @@ function _defaultValidations() {
|
|
|
207
216
|
if (!type.interfaces) {
|
|
208
217
|
// Abstract classes may not directly implement all members, need to check their supertypes...
|
|
209
218
|
if (spec.isClassType(type) && type.base && type.abstract) {
|
|
210
|
-
return _validateMethodImplementation(method, _dereference(type.base
|
|
219
|
+
return _validateMethodImplementation(method, _dereference(type.base));
|
|
211
220
|
}
|
|
212
221
|
return false;
|
|
213
222
|
}
|
|
214
223
|
for (const iface of type.interfaces) {
|
|
215
|
-
const ifaceType = _dereference(iface
|
|
224
|
+
const ifaceType = _dereference(iface);
|
|
216
225
|
const implemented = (ifaceType.methods ?? []).find((m) => m.name === method.name);
|
|
217
226
|
if (implemented) {
|
|
218
|
-
_assertSignaturesMatch(implemented, method, `${type.fqn}#${method.name}`, `implementing ${ifaceType.fqn}
|
|
227
|
+
_assertSignaturesMatch(implemented, method, `${type.fqn}#${method.name}`, `implementing ${ifaceType.fqn}`, {
|
|
228
|
+
allowReturnTypeCovariance: false,
|
|
229
|
+
});
|
|
219
230
|
// We won't replace a previous overrides declaration from a method override, as those have
|
|
220
231
|
// higher precedence than an initial implementation.
|
|
221
232
|
method.overrides = method.overrides ?? iface;
|
|
@@ -231,15 +242,15 @@ function _defaultValidations() {
|
|
|
231
242
|
if (!type.interfaces) {
|
|
232
243
|
// Abstract classes may not directly implement all members, need to check their supertypes...
|
|
233
244
|
if (spec.isClassType(type) && type.base && type.abstract) {
|
|
234
|
-
return _validatePropertyImplementation(property, _dereference(type.base
|
|
245
|
+
return _validatePropertyImplementation(property, _dereference(type.base));
|
|
235
246
|
}
|
|
236
247
|
return false;
|
|
237
248
|
}
|
|
238
249
|
for (const iface of type.interfaces) {
|
|
239
|
-
const ifaceType = _dereference(iface
|
|
250
|
+
const ifaceType = _dereference(iface);
|
|
240
251
|
const implemented = (ifaceType.properties ?? []).find((p) => p.name === property.name);
|
|
241
252
|
if (implemented) {
|
|
242
|
-
_assertPropertiesMatch(implemented, property, `${type.fqn}#${property.name}`, `implementing ${ifaceType.fqn}
|
|
253
|
+
_assertPropertiesMatch(implemented, property, `${type.fqn}#${property.name}`, `implementing ${ifaceType.fqn}`, { allowCovariance: false });
|
|
243
254
|
// We won't replace a previous overrides declaration from a property override, as those
|
|
244
255
|
// have higher precedence than an initial implementation.
|
|
245
256
|
property.overrides = property.overrides ?? ifaceType.fqn;
|
|
@@ -251,16 +262,30 @@ function _defaultValidations() {
|
|
|
251
262
|
}
|
|
252
263
|
return false;
|
|
253
264
|
}
|
|
254
|
-
function _assertSignaturesMatch(expected, actual, label, action) {
|
|
265
|
+
function _assertSignaturesMatch(expected, actual, label, action, opts) {
|
|
255
266
|
if (!!expected.protected !== !!actual.protected) {
|
|
256
267
|
const expVisibility = expected.protected ? 'protected' : 'public';
|
|
257
268
|
const actVisibility = actual.protected ? 'protected' : 'public';
|
|
258
269
|
diagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_5002_OVERRIDE_CHANGES_VISIBILITY.createDetached(label, action, actVisibility, expVisibility));
|
|
259
270
|
}
|
|
271
|
+
// Types must generally be the same, but can be covariant sometimes
|
|
260
272
|
if (!deepEqual(actual.returns, expected.returns)) {
|
|
261
|
-
const
|
|
262
|
-
const
|
|
263
|
-
|
|
273
|
+
const actualReturnType = actual.returns?.type;
|
|
274
|
+
const expectedReturnType = expected.returns?.type;
|
|
275
|
+
if (
|
|
276
|
+
// return type covariance is allowed
|
|
277
|
+
opts.allowReturnTypeCovariance &&
|
|
278
|
+
// static members can never change
|
|
279
|
+
!actual.static &&
|
|
280
|
+
// this is a valid covariant return type (actual is more specific than expected)
|
|
281
|
+
(0, type_analysis_1.isAllowedCovariantSubtype)(actualReturnType, expectedReturnType, _dereference)) {
|
|
282
|
+
useFeature('class-covariant-overrides');
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
const expType = spec.describeTypeReference(expectedReturnType);
|
|
286
|
+
const actType = spec.describeTypeReference(actualReturnType);
|
|
287
|
+
diagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_5003_OVERRIDE_CHANGES_RETURN_TYPE.createDetached(label, action, actType, expType));
|
|
288
|
+
}
|
|
264
289
|
}
|
|
265
290
|
const expectedParams = expected.parameters ?? [];
|
|
266
291
|
const actualParams = actual.parameters ?? [];
|
|
@@ -283,7 +308,7 @@ function _defaultValidations() {
|
|
|
283
308
|
}
|
|
284
309
|
}
|
|
285
310
|
}
|
|
286
|
-
function _assertPropertiesMatch(expected, actual, label, action) {
|
|
311
|
+
function _assertPropertiesMatch(expected, actual, label, action, opts) {
|
|
287
312
|
const actualNode = bindings.getPropertyRelatedNode(actual);
|
|
288
313
|
const expectedNode = bindings.getPropertyRelatedNode(expected);
|
|
289
314
|
if (!!expected.protected !== !!actual.protected) {
|
|
@@ -291,8 +316,21 @@ function _defaultValidations() {
|
|
|
291
316
|
const actVisibility = actual.protected ? 'protected' : 'public';
|
|
292
317
|
diagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_5002_OVERRIDE_CHANGES_VISIBILITY.create(actualNode?.modifiers?.find((mod) => mod.kind === ts.SyntaxKind.PublicKeyword || mod.kind === ts.SyntaxKind.ProtectedKeyword) ?? declarationName(actualNode), label, action, actVisibility, expVisibility).maybeAddRelatedInformation(expectedNode?.modifiers?.find((mod) => mod.kind === ts.SyntaxKind.PublicKeyword || mod.kind === ts.SyntaxKind.ProtectedKeyword) ?? declarationName(expectedNode), 'The implemented declaration is here.'));
|
|
293
318
|
}
|
|
294
|
-
|
|
295
|
-
|
|
319
|
+
// Types must generally be the same, but can be covariant sometimes
|
|
320
|
+
if (!deepEqual(actual.type, expected.type)) {
|
|
321
|
+
if (
|
|
322
|
+
// return type covariance is allowed
|
|
323
|
+
opts.allowCovariance &&
|
|
324
|
+
// static members can never change
|
|
325
|
+
!actual.static &&
|
|
326
|
+
// immutable properties may change in some case, as long as they are covariant
|
|
327
|
+
actual.immutable &&
|
|
328
|
+
(0, type_analysis_1.isAllowedCovariantSubtype)(actual.type, expected.type, _dereference)) {
|
|
329
|
+
useFeature('class-covariant-overrides');
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
diagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_5004_OVERRIDE_CHANGES_PROP_TYPE.create(actualNode?.type ?? declarationName(actualNode), label, action, actual.type, expected.type).maybeAddRelatedInformation(expectedNode?.type ?? declarationName(expectedNode), 'The implemented declaration is here.'));
|
|
333
|
+
}
|
|
296
334
|
}
|
|
297
335
|
if (expected.immutable !== actual.immutable) {
|
|
298
336
|
diagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_5010_OVERRIDE_CHANGES_MUTABILITY.create(actualNode?.modifiers?.find((mod) => mod.kind === ts.SyntaxKind.ReadonlyKeyword) ??
|
|
@@ -316,6 +354,7 @@ function _defaultValidations() {
|
|
|
316
354
|
* don't want to give an implementation yet.
|
|
317
355
|
*/
|
|
318
356
|
function _abstractClassesMustImplementAllProperties(validator, assembly, diagnostic) {
|
|
357
|
+
const _dereference = (0, type_reference_1.createTypeResolver)(assembly, validator.projectInfo.dependencyClosure);
|
|
319
358
|
for (const type of _allTypes(assembly)) {
|
|
320
359
|
if (!spec.isClassType(type) || !type.abstract) {
|
|
321
360
|
continue;
|
|
@@ -333,7 +372,7 @@ function _defaultValidations() {
|
|
|
333
372
|
into.add(prop.name);
|
|
334
373
|
}
|
|
335
374
|
if (type.base) {
|
|
336
|
-
const base = _dereference(type.base
|
|
375
|
+
const base = _dereference(type.base);
|
|
337
376
|
if (spec.isClassType(base)) {
|
|
338
377
|
collectClassProps(base, into);
|
|
339
378
|
}
|
|
@@ -341,7 +380,7 @@ function _defaultValidations() {
|
|
|
341
380
|
return into;
|
|
342
381
|
}
|
|
343
382
|
function checkInterfacePropsImplemented(interfaceFqn, cls, propNames) {
|
|
344
|
-
const intf = _dereference(interfaceFqn
|
|
383
|
+
const intf = _dereference(interfaceFqn);
|
|
345
384
|
if (!spec.isInterfaceType(intf)) {
|
|
346
385
|
return;
|
|
347
386
|
}
|
|
@@ -482,17 +521,6 @@ function _allTypeReferences(assm) {
|
|
|
482
521
|
}
|
|
483
522
|
}
|
|
484
523
|
}
|
|
485
|
-
function _dereference(typeRef, assembly, validator) {
|
|
486
|
-
if (typeof typeRef !== 'string') {
|
|
487
|
-
typeRef = typeRef.fqn;
|
|
488
|
-
}
|
|
489
|
-
const [assm] = typeRef.split('.');
|
|
490
|
-
if (assembly.name === assm) {
|
|
491
|
-
return assembly.types?.[typeRef];
|
|
492
|
-
}
|
|
493
|
-
const foreignAssm = validator.projectInfo.dependencyClosure.find((dep) => dep.name === assm);
|
|
494
|
-
return foreignAssm?.types?.[typeRef];
|
|
495
|
-
}
|
|
496
524
|
function _isEmpty(array) {
|
|
497
525
|
return array == null || array.length === 0;
|
|
498
526
|
}
|