jsii 5.9.9-dev.2 → 5.9.9-dev.4
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.js +11 -1
- package/lib/assembler.js.map +1 -1
- package/lib/helpers.js +1 -1
- package/lib/helpers.js.map +1 -1
- package/lib/validator.d.ts +6 -2
- package/lib/validator.js +146 -14
- 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 +2 -2
package/lib/helpers.js
CHANGED
@@ -22,7 +22,7 @@ const utils_1 = require("./utils");
|
|
22
22
|
/**
|
23
23
|
* Assembly features supported by this compiler
|
24
24
|
*/
|
25
|
-
exports.ASSEMBLY_FEATURES_SUPPORTED = ['intersection-types'];
|
25
|
+
exports.ASSEMBLY_FEATURES_SUPPORTED = ['intersection-types', 'class-covariant-overrides'];
|
26
26
|
/**
|
27
27
|
* Compile a piece of source and return the JSII assembly for it
|
28
28
|
*
|
package/lib/helpers.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAoCH,wDASC;AA4DD,gDAsFC;AA2MD,kDAKC;AA7YD,8BAA8B;AAC9B,8BAA8B;AAC9B,kCAAkC;AAClC,qCAA8E;AAE9E,2CAA4D;AAE5D,yCAAuD;AACvD,iDAA8D;AAC9D,mCAAsD;AAUtD;;GAEG;AACU,QAAA,2BAA2B,GAAuB,CAAC,oBAAoB,CAAC,CAAC;AAEtF;;;;;;;;;GASG;AACH,SAAgB,sBAAsB,CACpC,MAAoC,EACpC,OAA+D;IAE/D,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC;AAkDD;;;;;;;;;GASG;AACH,SAAgB,kBAAkB,CAChC,MAA+D,EAC/D,OAA0C,EAC1C,eAAgE;IAEhE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,cAAc,GAClB,eAAe,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAElH,oFAAoF;IACpF,+EAA+E;IAC/E,OAAO,cAAc,CAAC,GAAG,EAAE;QACzB,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,eAAe,CAClD,UAAU,EACV,OAAO,OAAO,KAAK,UAAU;YAC3B,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE;gBACL,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;YACxE,CAAC,CACN,CAAC;QACF,MAAM,QAAQ,GAAG,IAAI,mBAAQ,CAAC;YAC5B,WAAW;YACX,GAAG,eAAe;SACnB,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,+BAAkB,CAAC,KAAK,CAAC,CAAC;QAE7F,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,EAAE,kBAAkB,EAAE,CAAC;YAChE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,OAAO,CAAC,KAAK,CAAC,IAAA,wBAAgB,EAAC,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;gBAChE,yEAAyE;YAC3E,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;YAChD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,EAAE,kBAAkB,EAAE,CAAC;gBAC/D,OAAO;oBACL,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,UAAU,CAAC,WAAW;iBACD,CAAC;YACvC,CAAC;YACD,MAAM,IAAI,iBAAS,CAAC,4BAA4B,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,QAAQ,GAAG,IAAA,2BAAoB,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,mCAA2B,CAAC,CAAC;QACzF,MAAM,KAAK,GAA2B,EAAE,CAAC;QAEzC,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC9C,IAAI,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACjD,IAAI,WAAW,CAAC,GAAG,EAAE,MAAM,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACxD,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBACnD,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACvD,CAAC;YAED,4CAA4C;YAC5C,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAC/D,4CAA4C;YAC5C,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAEjE,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;YAC7C,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACpC,4CAA4C;gBAC5C,KAAK,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE;oBAC1D,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO;YACL,IAAI,EAAE,SAAS;YACf,QAAQ;YACR,KAAK;YACL,WAAW;YACX,gBAAgB,EAAE,eAAe,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;YACrF,WAAW,EAAE,UAAU,CAAC,WAAW;SACF,CAAC;IACtC,CAAC,CAAuB,CAAC;AAC3B,CAAC;AAMD,SAAS,SAAS,CAAI,KAAc;IAClC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;IACpB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvB,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,6EAA6E;IAC7E,OAAO,CAAoB,KAAc,EAAK,EAAE;QAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC;YACH,OAAO,KAAK,EAAE,CAAC;QACjB,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,eAAe,CACtB,KAAa,EACb,EAA+B;IAE/B,MAAM,WAAW,GAAgB;QAC/B,KAAK;QACL,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,OAAO,CAAC;QAChD,IAAI,EAAE,SAAS,EAAE,uDAAuD;QACxE,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,YAAY;QACrB,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;QAC5B,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,iCAAiC,EAAE;QACnE,IAAI,EAAE,EAAE;KACT,CAAC;IAEF,IAAI,EAAE,EAAE,CAAC;QACP,EAAE,CAAC,WAAW,CAAC,CAAC;IAClB,CAAC;IAED,EAAE,CAAC,aAAa,CACd,cAAc,EACd,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAS,EAAE,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EACxD,OAAO,CACR,CAAC;IAEF,MAAM,EAAE,WAAW,EAAE,GAAG,IAAA,8BAAe,EAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AACtC,CAAC;AAqCD,SAAS,eAAe,CACtB,CAAoE;IAEpE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAa,aAAa;IACxB;;;;OAIG;IACI,MAAM,CAAC,MAAM;QAClB,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;QAC5E,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,aAAa,CAAI,KAA+B;QAC5D,MAAM,EAAE,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,OAAO,KAAK,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,OAAO,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAID,YAAoC,aAAqB;QAArB,kBAAa,GAAb,aAAa,CAAQ;QAFxC,cAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEa,CAAC;IAE7D;;OAEG;IACI,aAAa,CAAC,kBAAwC;QAC3D,IAAI,kBAAkB,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC1C,MAAM,IAAI,iBAAS,CAAC,oDAAoD,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,iBAAS,CACjB,2BAA2B,kBAAkB,CAAC,QAAQ,CAAC,IAAI,qDAAqD,CACjH,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAErD,+EAA+E;QAC/E,0EAA0E;QAC1E,kEAAkE;QAClE,EAAE;QACF,qEAAqE;QACrE,6BAA6B;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,EAAE,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/F,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1C,IAAA,oBAAa,EAAC,MAAM,EAAE,kBAAkB,CAAC,QAAQ,EAAE;YACjD,QAAQ,EAAE,kBAAkB,CAAC,gBAAgB;SAC9C,CAAC,CAAC;QACH,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EACjC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EACvD,OAAO,CACR,CAAC;QAEF,KAAK,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YAChF,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE;gBACtD,SAAS,EAAE,IAAI;aAChB,CAAC,CAAC;YACH,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAEM,aAAa,CAAC,IAAY;QAC/B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,iBAAS,CAAC,4BAA4B,IAAI,sBAAsB,CAAC,CAAC;QAC9E,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;IAC7D,CAAC;IAEM,OAAO;QACZ,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;CACF;AA/ED,sCA+EC;AAKD;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CAAC,IAAY,EAAE,eAAwB;IACxE,IAAI,eAAe,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACjE,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;AAC9C,CAAC","sourcesContent":["/**\n * Helper routines for use with the jsii compiler\n *\n * These are mostly used for testing, but all projects that need to exercise\n * the JSII compiler to test something need to share this code, so might as\n * well put it in one reusable place.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { PackageJson, loadAssemblyFromPath, writeAssembly } from '@jsii/spec';\nimport * as spec from '@jsii/spec';\nimport { Diagnostic, DiagnosticCategory } from 'typescript';\n\nimport { Compiler, CompilerOptions } from './compiler';\nimport { loadProjectInfo, ProjectInfo } from './project-info';\nimport { formatDiagnostic, JsiiError } from './utils';\n\n/**\n * A set of source files for `sourceToAssemblyHelper`, at least containing 'index.ts'\n */\nexport type MultipleSourceFiles = {\n 'index.ts': string;\n [name: string]: string;\n};\n\n/**\n * Assembly features supported by this compiler\n */\nexport const ASSEMBLY_FEATURES_SUPPORTED: spec.JsiiFeature[] = ['intersection-types'];\n\n/**\n * Compile a piece of source and return the JSII assembly for it\n *\n * Only usable for trivial cases and tests.\n *\n * @param source can either be a single `string` (the content of `index.ts`), or\n * a map of fileName to content, which *must* include `index.ts`.\n * @param options accepts a callback for historical reasons but really expects to\n * take an options object.\n */\nexport function sourceToAssemblyHelper(\n source: string | MultipleSourceFiles,\n options?: TestCompilationOptions | ((obj: PackageJson) => void),\n): spec.Assembly {\n const result = compileJsiiForTest(source, options);\n if (result.type !== 'success') {\n throw new Error('Compilation failed');\n }\n return result.assembly;\n}\n\nexport type HelperCompilationOut = HelperCompilationResult | HelperCompilationFailure;\n\n/**\n * Successful output of a compilation command (for testing)\n *\n * A better name would have been `HelperCompilationSuccess`, but the name is part of\n * the public API surface, so we keep it like this.\n */\nexport interface HelperCompilationResult {\n readonly type: 'success';\n\n /**\n * The generated assembly\n */\n readonly assembly: spec.Assembly;\n\n /**\n * Generated .js/.d.ts file(s)\n */\n readonly files: Record<string, string>;\n\n /**\n * The packageInfo used\n */\n readonly packageJson: PackageJson;\n\n /**\n * Whether to compress the assembly file\n */\n readonly compressAssembly: boolean;\n\n /**\n * Diagnostics that occurred during compilation\n */\n readonly diagnostics: readonly Diagnostic[];\n}\n\nexport interface HelperCompilationFailure {\n readonly type: 'failure';\n\n /**\n * Diagnostics that occurred during compilation\n *\n * Contains at least one error.\n */\n readonly diagnostics: readonly Diagnostic[];\n}\n\n/**\n * Compile a piece of source and return the assembly and compiled sources for it\n *\n * Only usable for trivial cases and tests.\n *\n * @param source can either be a single `string` (the content of `index.ts`), or\n * a map of fileName to content, which *must* include `index.ts`.\n * @param options accepts a callback for historical reasons but really expects to\n * take an options object.\n */\nexport function compileJsiiForTest<O extends TestCompilationOptions>(\n source: string | { 'index.ts': string; [name: string]: string },\n options?: O | ((obj: PackageJson) => void),\n compilerOptions?: Omit<CompilerOptions, 'projectInfo' | 'watch'>,\n): ResultOrSuccess<O> {\n if (typeof source === 'string') {\n source = { 'index.ts': source };\n }\n\n const inSomeLocation =\n isOptionsObject(options) && options.compilationDirectory ? inOtherDir(options.compilationDirectory) : inTempDir;\n\n // Easiest way to get the source into the compiler is to write it to disk somewhere.\n // I guess we could make an in-memory compiler host but that seems like work...\n return inSomeLocation(() => {\n for (const [fileName, content] of Object.entries(source)) {\n fs.mkdirSync(path.dirname(fileName), { recursive: true });\n fs.writeFileSync(fileName, content, { encoding: 'utf-8' });\n }\n const { projectInfo, packageJson } = makeProjectInfo(\n 'index.ts',\n typeof options === 'function'\n ? options\n : (pi) => {\n Object.assign(pi, options?.packageJson ?? options?.projectInfo ?? {});\n },\n );\n const compiler = new Compiler({\n projectInfo,\n ...compilerOptions,\n });\n const emitResult = compiler.emit();\n\n const errors = emitResult.diagnostics.filter((d) => d.category === DiagnosticCategory.Error);\n\n if (typeof options !== 'object' || !options?.captureDiagnostics) {\n for (const error of errors) {\n console.error(formatDiagnostic(error, projectInfo.projectRoot));\n // logDiagnostic() doesn't work out of the box, so console.error() it is.\n }\n }\n\n if (errors.length > 0 || emitResult.emitSkipped) {\n if (typeof options === 'object' && options?.captureDiagnostics) {\n return {\n type: 'failure',\n diagnostics: emitResult.diagnostics,\n } satisfies HelperCompilationFailure;\n }\n throw new JsiiError('There were compiler errors');\n }\n\n const assembly = loadAssemblyFromPath(process.cwd(), false, ASSEMBLY_FEATURES_SUPPORTED);\n const files: Record<string, string> = {};\n\n for (const filename of Object.keys(source)) {\n let jsFile = filename.replace(/\\.ts$/, '.js');\n let dtsFile = filename.replace(/\\.ts$/, '.d.ts');\n if (projectInfo.tsc?.outDir && filename !== 'README.md') {\n jsFile = path.join(projectInfo.tsc.outDir, jsFile);\n dtsFile = path.join(projectInfo.tsc.outDir, dtsFile);\n }\n\n // eslint-disable-next-line no-await-in-loop\n files[jsFile] = fs.readFileSync(jsFile, { encoding: 'utf-8' });\n // eslint-disable-next-line no-await-in-loop\n files[dtsFile] = fs.readFileSync(dtsFile, { encoding: 'utf-8' });\n\n const warningsFileName = '.warnings.jsii.js';\n if (fs.existsSync(warningsFileName)) {\n // eslint-disable-next-line no-await-in-loop\n files[warningsFileName] = fs.readFileSync(warningsFileName, {\n encoding: 'utf-8',\n });\n }\n }\n\n return {\n type: 'success',\n assembly,\n files,\n packageJson,\n compressAssembly: isOptionsObject(options) && options.compressAssembly ? true : false,\n diagnostics: emitResult.diagnostics,\n } satisfies HelperCompilationResult;\n }) as ResultOrSuccess<O>;\n}\n\ntype ResultOrSuccess<O extends TestCompilationOptions> = O['captureDiagnostics'] extends true\n ? HelperCompilationOut\n : HelperCompilationResult;\n\nfunction inTempDir<T>(block: () => T): T {\n const origDir = process.cwd();\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jsii'));\n process.chdir(tmpDir);\n const ret = block();\n process.chdir(origDir);\n fs.rmSync(tmpDir, { force: true, recursive: true });\n return ret;\n}\n\nfunction inOtherDir(dir: string) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint\n return <T extends unknown>(block: () => T): T => {\n const origDir = process.cwd();\n process.chdir(dir);\n try {\n return block();\n } finally {\n process.chdir(origDir);\n }\n };\n}\n\n/**\n * Obtain project info so we can call the compiler\n *\n * Creating this directly in-memory leads to slightly different behavior from calling\n * jsii from the command-line, and I don't want to figure out right now.\n *\n * Most consistent behavior seems to be to write a package.json to disk and\n * then calling the same functions as the CLI would.\n */\nfunction makeProjectInfo(\n types: string,\n cb?: (obj: PackageJson) => void,\n): { projectInfo: ProjectInfo; packageJson: PackageJson } {\n const packageJson: PackageJson = {\n types,\n main: types.replace(/(?:\\.d)?\\.ts(x?)/, '.js$1'),\n name: 'testpkg', // That's what package.json would tell if we look up...\n version: '0.0.1',\n license: 'Apache-2.0',\n author: { name: 'John Doe' },\n repository: { type: 'git', url: 'https://github.com/aws/jsii.git' },\n jsii: {},\n };\n\n if (cb) {\n cb(packageJson);\n }\n\n fs.writeFileSync(\n 'package.json',\n JSON.stringify(packageJson, (_: string, v: any) => v, 2),\n 'utf-8',\n );\n\n const { projectInfo } = loadProjectInfo(path.resolve(process.cwd(), '.'));\n return { projectInfo, packageJson };\n}\n\nexport interface TestCompilationOptions {\n /**\n * The directory in which we write and compile the files\n */\n readonly compilationDirectory?: string;\n\n /**\n * Parts of projectInfo to override (package name etc)\n *\n * @deprecated Prefer using `packageJson` instead.\n */\n readonly projectInfo?: Partial<PackageJson>;\n\n /**\n * Parts of projectInfo to override (package name etc)\n *\n * @default - Use some default values\n */\n readonly packageJson?: Partial<PackageJson>;\n\n /**\n * Whether to compress the assembly file.\n *\n * @default false\n */\n readonly compressAssembly?: boolean;\n\n /**\n * Whether or not to print the diagnostics\n *\n * @default false\n */\n readonly captureDiagnostics?: boolean;\n}\n\nfunction isOptionsObject(\n x: TestCompilationOptions | ((obj: PackageJson) => void) | undefined,\n): x is TestCompilationOptions {\n return x ? typeof x === 'object' : false;\n}\n\n/**\n * An NPM-ready workspace where we can install test-compile dependencies and compile new assemblies\n */\nexport class TestWorkspace {\n /**\n * Create a new workspace.\n *\n * Creates a temporary directory, don't forget to call cleanUp\n */\n public static create(): TestWorkspace {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jsii-testworkspace'));\n fs.mkdirSync(tmpDir, { recursive: true });\n return new TestWorkspace(tmpDir);\n }\n\n /**\n * Execute a block with a temporary workspace\n */\n public static withWorkspace<A>(block: (ws: TestWorkspace) => A): A {\n const ws = TestWorkspace.create();\n try {\n return block(ws);\n } finally {\n ws.cleanup();\n }\n }\n\n private readonly installed = new Set<string>();\n\n private constructor(public readonly rootDirectory: string) {}\n\n /**\n * Add a test-compiled jsii assembly as a dependency\n */\n public addDependency(dependencyAssembly: HelperCompilationOut) {\n if (dependencyAssembly.type !== 'success') {\n throw new JsiiError('Cannot add dependency: assembly compilation failed');\n }\n\n if (this.installed.has(dependencyAssembly.assembly.name)) {\n throw new JsiiError(\n `A dependency with name '${dependencyAssembly.assembly.name}' was already installed. Give one a different name.`,\n );\n }\n this.installed.add(dependencyAssembly.assembly.name);\n\n // The following is silly, however: the helper has compiled the given source to\n // an assembly, and output files, and then removed their traces from disk.\n // We need those files back on disk, so write them back out again.\n //\n // We will drop them in 'node_modules/<name>' so they can be imported\n // as if they were installed.\n const modDir = path.join(this.rootDirectory, 'node_modules', dependencyAssembly.assembly.name);\n fs.mkdirSync(modDir, { recursive: true });\n\n writeAssembly(modDir, dependencyAssembly.assembly, {\n compress: dependencyAssembly.compressAssembly,\n });\n fs.writeFileSync(\n path.join(modDir, 'package.json'),\n JSON.stringify(dependencyAssembly.packageJson, null, 2),\n 'utf-8',\n );\n\n for (const [fileName, fileContents] of Object.entries(dependencyAssembly.files)) {\n fs.mkdirSync(path.dirname(path.join(modDir, fileName)), {\n recursive: true,\n });\n fs.writeFileSync(path.join(modDir, fileName), fileContents);\n }\n }\n\n public dependencyDir(name: string) {\n if (!this.installed.has(name)) {\n throw new JsiiError(`No dependency with name '${name}' has been installed`);\n }\n return path.join(this.rootDirectory, 'node_modules', name);\n }\n\n public cleanup() {\n fs.rmSync(this.rootDirectory, { force: true, recursive: true });\n }\n}\n\n// Alias for backwards compatibility\nexport type PackageInfo = PackageJson;\n\n/**\n * TSConfig paths can either be relative to the project or absolute.\n * This function normalizes paths to be relative to the provided root.\n * After normalization, code using these paths can be much simpler.\n *\n * @param root the project root\n * @param pathToNormalize the path to normalize, might be empty\n */\nexport function normalizeConfigPath(root: string, pathToNormalize?: string): string | undefined {\n if (pathToNormalize == null || !path.isAbsolute(pathToNormalize)) {\n return pathToNormalize;\n }\n return path.relative(root, pathToNormalize);\n}\n"]}
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Helper routines for use with the jsii compiler\n *\n * These are mostly used for testing, but all projects that need to exercise\n * the JSII compiler to test something need to share this code, so might as\n * well put it in one reusable place.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { PackageJson, loadAssemblyFromPath, writeAssembly } from '@jsii/spec';\nimport * as spec from '@jsii/spec';\nimport { Diagnostic, DiagnosticCategory } from 'typescript';\n\nimport { Compiler, CompilerOptions } from './compiler';\nimport { loadProjectInfo, ProjectInfo } from './project-info';\nimport { formatDiagnostic, JsiiError } from './utils';\n\n/**\n * A set of source files for `sourceToAssemblyHelper`, at least containing 'index.ts'\n */\nexport type MultipleSourceFiles = {\n 'index.ts': string;\n [name: string]: string;\n};\n\n/**\n * Assembly features supported by this compiler\n */\nexport const ASSEMBLY_FEATURES_SUPPORTED: spec.JsiiFeature[] = ['intersection-types', 'class-covariant-overrides'];\n\n/**\n * Compile a piece of source and return the JSII assembly for it\n *\n * Only usable for trivial cases and tests.\n *\n * @param source can either be a single `string` (the content of `index.ts`), or\n * a map of fileName to content, which *must* include `index.ts`.\n * @param options accepts a callback for historical reasons but really expects to\n * take an options object.\n */\nexport function sourceToAssemblyHelper(\n source: string | MultipleSourceFiles,\n options?: TestCompilationOptions | ((obj: PackageJson) => void),\n): spec.Assembly {\n const result = compileJsiiForTest(source, options);\n if (result.type !== 'success') {\n throw new Error('Compilation failed');\n }\n return result.assembly;\n}\n\nexport type HelperCompilationOut = HelperCompilationResult | HelperCompilationFailure;\n\n/**\n * Successful output of a compilation command (for testing)\n *\n * A better name would have been `HelperCompilationSuccess`, but the name is part of\n * the public API surface, so we keep it like this.\n */\nexport interface HelperCompilationResult {\n readonly type: 'success';\n\n /**\n * The generated assembly\n */\n readonly assembly: spec.Assembly;\n\n /**\n * Generated .js/.d.ts file(s)\n */\n readonly files: Record<string, string>;\n\n /**\n * The packageInfo used\n */\n readonly packageJson: PackageJson;\n\n /**\n * Whether to compress the assembly file\n */\n readonly compressAssembly: boolean;\n\n /**\n * Diagnostics that occurred during compilation\n */\n readonly diagnostics: readonly Diagnostic[];\n}\n\nexport interface HelperCompilationFailure {\n readonly type: 'failure';\n\n /**\n * Diagnostics that occurred during compilation\n *\n * Contains at least one error.\n */\n readonly diagnostics: readonly Diagnostic[];\n}\n\n/**\n * Compile a piece of source and return the assembly and compiled sources for it\n *\n * Only usable for trivial cases and tests.\n *\n * @param source can either be a single `string` (the content of `index.ts`), or\n * a map of fileName to content, which *must* include `index.ts`.\n * @param options accepts a callback for historical reasons but really expects to\n * take an options object.\n */\nexport function compileJsiiForTest<O extends TestCompilationOptions>(\n source: string | { 'index.ts': string; [name: string]: string },\n options?: O | ((obj: PackageJson) => void),\n compilerOptions?: Omit<CompilerOptions, 'projectInfo' | 'watch'>,\n): ResultOrSuccess<O> {\n if (typeof source === 'string') {\n source = { 'index.ts': source };\n }\n\n const inSomeLocation =\n isOptionsObject(options) && options.compilationDirectory ? inOtherDir(options.compilationDirectory) : inTempDir;\n\n // Easiest way to get the source into the compiler is to write it to disk somewhere.\n // I guess we could make an in-memory compiler host but that seems like work...\n return inSomeLocation(() => {\n for (const [fileName, content] of Object.entries(source)) {\n fs.mkdirSync(path.dirname(fileName), { recursive: true });\n fs.writeFileSync(fileName, content, { encoding: 'utf-8' });\n }\n const { projectInfo, packageJson } = makeProjectInfo(\n 'index.ts',\n typeof options === 'function'\n ? options\n : (pi) => {\n Object.assign(pi, options?.packageJson ?? options?.projectInfo ?? {});\n },\n );\n const compiler = new Compiler({\n projectInfo,\n ...compilerOptions,\n });\n const emitResult = compiler.emit();\n\n const errors = emitResult.diagnostics.filter((d) => d.category === DiagnosticCategory.Error);\n\n if (typeof options !== 'object' || !options?.captureDiagnostics) {\n for (const error of errors) {\n console.error(formatDiagnostic(error, projectInfo.projectRoot));\n // logDiagnostic() doesn't work out of the box, so console.error() it is.\n }\n }\n\n if (errors.length > 0 || emitResult.emitSkipped) {\n if (typeof options === 'object' && options?.captureDiagnostics) {\n return {\n type: 'failure',\n diagnostics: emitResult.diagnostics,\n } satisfies HelperCompilationFailure;\n }\n throw new JsiiError('There were compiler errors');\n }\n\n const assembly = loadAssemblyFromPath(process.cwd(), false, ASSEMBLY_FEATURES_SUPPORTED);\n const files: Record<string, string> = {};\n\n for (const filename of Object.keys(source)) {\n let jsFile = filename.replace(/\\.ts$/, '.js');\n let dtsFile = filename.replace(/\\.ts$/, '.d.ts');\n if (projectInfo.tsc?.outDir && filename !== 'README.md') {\n jsFile = path.join(projectInfo.tsc.outDir, jsFile);\n dtsFile = path.join(projectInfo.tsc.outDir, dtsFile);\n }\n\n // eslint-disable-next-line no-await-in-loop\n files[jsFile] = fs.readFileSync(jsFile, { encoding: 'utf-8' });\n // eslint-disable-next-line no-await-in-loop\n files[dtsFile] = fs.readFileSync(dtsFile, { encoding: 'utf-8' });\n\n const warningsFileName = '.warnings.jsii.js';\n if (fs.existsSync(warningsFileName)) {\n // eslint-disable-next-line no-await-in-loop\n files[warningsFileName] = fs.readFileSync(warningsFileName, {\n encoding: 'utf-8',\n });\n }\n }\n\n return {\n type: 'success',\n assembly,\n files,\n packageJson,\n compressAssembly: isOptionsObject(options) && options.compressAssembly ? true : false,\n diagnostics: emitResult.diagnostics,\n } satisfies HelperCompilationResult;\n }) as ResultOrSuccess<O>;\n}\n\ntype ResultOrSuccess<O extends TestCompilationOptions> = O['captureDiagnostics'] extends true\n ? HelperCompilationOut\n : HelperCompilationResult;\n\nfunction inTempDir<T>(block: () => T): T {\n const origDir = process.cwd();\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jsii'));\n process.chdir(tmpDir);\n const ret = block();\n process.chdir(origDir);\n fs.rmSync(tmpDir, { force: true, recursive: true });\n return ret;\n}\n\nfunction inOtherDir(dir: string) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint\n return <T extends unknown>(block: () => T): T => {\n const origDir = process.cwd();\n process.chdir(dir);\n try {\n return block();\n } finally {\n process.chdir(origDir);\n }\n };\n}\n\n/**\n * Obtain project info so we can call the compiler\n *\n * Creating this directly in-memory leads to slightly different behavior from calling\n * jsii from the command-line, and I don't want to figure out right now.\n *\n * Most consistent behavior seems to be to write a package.json to disk and\n * then calling the same functions as the CLI would.\n */\nfunction makeProjectInfo(\n types: string,\n cb?: (obj: PackageJson) => void,\n): { projectInfo: ProjectInfo; packageJson: PackageJson } {\n const packageJson: PackageJson = {\n types,\n main: types.replace(/(?:\\.d)?\\.ts(x?)/, '.js$1'),\n name: 'testpkg', // That's what package.json would tell if we look up...\n version: '0.0.1',\n license: 'Apache-2.0',\n author: { name: 'John Doe' },\n repository: { type: 'git', url: 'https://github.com/aws/jsii.git' },\n jsii: {},\n };\n\n if (cb) {\n cb(packageJson);\n }\n\n fs.writeFileSync(\n 'package.json',\n JSON.stringify(packageJson, (_: string, v: any) => v, 2),\n 'utf-8',\n );\n\n const { projectInfo } = loadProjectInfo(path.resolve(process.cwd(), '.'));\n return { projectInfo, packageJson };\n}\n\nexport interface TestCompilationOptions {\n /**\n * The directory in which we write and compile the files\n */\n readonly compilationDirectory?: string;\n\n /**\n * Parts of projectInfo to override (package name etc)\n *\n * @deprecated Prefer using `packageJson` instead.\n */\n readonly projectInfo?: Partial<PackageJson>;\n\n /**\n * Parts of projectInfo to override (package name etc)\n *\n * @default - Use some default values\n */\n readonly packageJson?: Partial<PackageJson>;\n\n /**\n * Whether to compress the assembly file.\n *\n * @default false\n */\n readonly compressAssembly?: boolean;\n\n /**\n * Whether or not to print the diagnostics\n *\n * @default false\n */\n readonly captureDiagnostics?: boolean;\n}\n\nfunction isOptionsObject(\n x: TestCompilationOptions | ((obj: PackageJson) => void) | undefined,\n): x is TestCompilationOptions {\n return x ? typeof x === 'object' : false;\n}\n\n/**\n * An NPM-ready workspace where we can install test-compile dependencies and compile new assemblies\n */\nexport class TestWorkspace {\n /**\n * Create a new workspace.\n *\n * Creates a temporary directory, don't forget to call cleanUp\n */\n public static create(): TestWorkspace {\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jsii-testworkspace'));\n fs.mkdirSync(tmpDir, { recursive: true });\n return new TestWorkspace(tmpDir);\n }\n\n /**\n * Execute a block with a temporary workspace\n */\n public static withWorkspace<A>(block: (ws: TestWorkspace) => A): A {\n const ws = TestWorkspace.create();\n try {\n return block(ws);\n } finally {\n ws.cleanup();\n }\n }\n\n private readonly installed = new Set<string>();\n\n private constructor(public readonly rootDirectory: string) {}\n\n /**\n * Add a test-compiled jsii assembly as a dependency\n */\n public addDependency(dependencyAssembly: HelperCompilationOut) {\n if (dependencyAssembly.type !== 'success') {\n throw new JsiiError('Cannot add dependency: assembly compilation failed');\n }\n\n if (this.installed.has(dependencyAssembly.assembly.name)) {\n throw new JsiiError(\n `A dependency with name '${dependencyAssembly.assembly.name}' was already installed. Give one a different name.`,\n );\n }\n this.installed.add(dependencyAssembly.assembly.name);\n\n // The following is silly, however: the helper has compiled the given source to\n // an assembly, and output files, and then removed their traces from disk.\n // We need those files back on disk, so write them back out again.\n //\n // We will drop them in 'node_modules/<name>' so they can be imported\n // as if they were installed.\n const modDir = path.join(this.rootDirectory, 'node_modules', dependencyAssembly.assembly.name);\n fs.mkdirSync(modDir, { recursive: true });\n\n writeAssembly(modDir, dependencyAssembly.assembly, {\n compress: dependencyAssembly.compressAssembly,\n });\n fs.writeFileSync(\n path.join(modDir, 'package.json'),\n JSON.stringify(dependencyAssembly.packageJson, null, 2),\n 'utf-8',\n );\n\n for (const [fileName, fileContents] of Object.entries(dependencyAssembly.files)) {\n fs.mkdirSync(path.dirname(path.join(modDir, fileName)), {\n recursive: true,\n });\n fs.writeFileSync(path.join(modDir, fileName), fileContents);\n }\n }\n\n public dependencyDir(name: string) {\n if (!this.installed.has(name)) {\n throw new JsiiError(`No dependency with name '${name}' has been installed`);\n }\n return path.join(this.rootDirectory, 'node_modules', name);\n }\n\n public cleanup() {\n fs.rmSync(this.rootDirectory, { force: true, recursive: true });\n }\n}\n\n// Alias for backwards compatibility\nexport type PackageInfo = PackageJson;\n\n/**\n * TSConfig paths can either be relative to the project or absolute.\n * This function normalizes paths to be relative to the provided root.\n * After normalization, code using these paths can be much simpler.\n *\n * @param root the project root\n * @param pathToNormalize the path to normalize, might be empty\n */\nexport function normalizeConfigPath(root: string, pathToNormalize?: string): string | undefined {\n if (pathToNormalize == null || !path.isAbsolute(pathToNormalize)) {\n return pathToNormalize;\n }\n return path.relative(root, pathToNormalize);\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
@@ -16,12 +16,14 @@ class Validator {
|
|
16
16
|
}
|
17
17
|
emit() {
|
18
18
|
const diagnostics = new Array();
|
19
|
+
const usedFeatures = new Array();
|
19
20
|
for (const validation of Validator.VALIDATIONS) {
|
20
|
-
validation(this, this.assembly, diagnostics.push.bind(diagnostics));
|
21
|
+
validation(this, this.assembly, diagnostics.push.bind(diagnostics), usedFeatures.push.bind(usedFeatures));
|
21
22
|
}
|
22
23
|
return {
|
23
24
|
diagnostics: diagnostics,
|
24
25
|
emitSkipped: diagnostics.some((diag) => diag.category === ts.DiagnosticCategory.Error),
|
26
|
+
usedFeatures,
|
25
27
|
};
|
26
28
|
}
|
27
29
|
}
|
@@ -34,7 +36,7 @@ function _defaultValidations() {
|
|
34
36
|
_staticConstantNamesMustUseUpperSnakeCase,
|
35
37
|
_memberNamesMustNotLookLikeJavaGettersOrSetters,
|
36
38
|
_allTypeReferencesAreValid,
|
37
|
-
|
39
|
+
_inheritanceDoesNotChangeContracts,
|
38
40
|
_staticMembersAndNestedTypesMustNotSharePascalCaseName,
|
39
41
|
_abstractClassesMustImplementAllProperties,
|
40
42
|
];
|
@@ -107,7 +109,7 @@ function _defaultValidations() {
|
|
107
109
|
}
|
108
110
|
}
|
109
111
|
}
|
110
|
-
function
|
112
|
+
function _inheritanceDoesNotChangeContracts(validator, assembly, diagnostic, useFeature) {
|
111
113
|
for (const type of _allTypes(assembly)) {
|
112
114
|
if (spec.isClassType(type)) {
|
113
115
|
for (const method of type.methods ?? []) {
|
@@ -183,7 +185,9 @@ function _defaultValidations() {
|
|
183
185
|
if (!overridden) {
|
184
186
|
return _validateMethodOverride(method, baseType);
|
185
187
|
}
|
186
|
-
_assertSignaturesMatch(overridden, method, `${type.fqn}#${method.name}`, `overriding ${baseType.fqn}
|
188
|
+
_assertSignaturesMatch(overridden, method, `${type.fqn}#${method.name}`, `overriding ${baseType.fqn}`, {
|
189
|
+
returnTypeCovariance: true,
|
190
|
+
});
|
187
191
|
method.overrides = baseType.fqn;
|
188
192
|
return true;
|
189
193
|
}
|
@@ -199,7 +203,9 @@ function _defaultValidations() {
|
|
199
203
|
if (!overridden) {
|
200
204
|
return _validatePropertyOverride(property, baseType);
|
201
205
|
}
|
202
|
-
_assertPropertiesMatch(overridden, property, `${type.fqn}#${property.name}`, `overriding ${baseType.fqn}
|
206
|
+
_assertPropertiesMatch(overridden, property, `${type.fqn}#${property.name}`, `overriding ${baseType.fqn}`, {
|
207
|
+
covariance: true,
|
208
|
+
});
|
203
209
|
property.overrides = baseType.fqn;
|
204
210
|
return true;
|
205
211
|
}
|
@@ -215,7 +221,9 @@ function _defaultValidations() {
|
|
215
221
|
const ifaceType = _dereference(iface, assembly, validator);
|
216
222
|
const implemented = (ifaceType.methods ?? []).find((m) => m.name === method.name);
|
217
223
|
if (implemented) {
|
218
|
-
_assertSignaturesMatch(implemented, method, `${type.fqn}#${method.name}`, `implementing ${ifaceType.fqn}
|
224
|
+
_assertSignaturesMatch(implemented, method, `${type.fqn}#${method.name}`, `implementing ${ifaceType.fqn}`, {
|
225
|
+
returnTypeCovariance: false,
|
226
|
+
});
|
219
227
|
// We won't replace a previous overrides declaration from a method override, as those have
|
220
228
|
// higher precedence than an initial implementation.
|
221
229
|
method.overrides = method.overrides ?? iface;
|
@@ -239,7 +247,7 @@ function _defaultValidations() {
|
|
239
247
|
const ifaceType = _dereference(iface, assembly, validator);
|
240
248
|
const implemented = (ifaceType.properties ?? []).find((p) => p.name === property.name);
|
241
249
|
if (implemented) {
|
242
|
-
_assertPropertiesMatch(implemented, property, `${type.fqn}#${property.name}`, `implementing ${ifaceType.fqn}
|
250
|
+
_assertPropertiesMatch(implemented, property, `${type.fqn}#${property.name}`, `implementing ${ifaceType.fqn}`, { covariance: false });
|
243
251
|
// We won't replace a previous overrides declaration from a property override, as those
|
244
252
|
// have higher precedence than an initial implementation.
|
245
253
|
property.overrides = property.overrides ?? ifaceType.fqn;
|
@@ -251,16 +259,30 @@ function _defaultValidations() {
|
|
251
259
|
}
|
252
260
|
return false;
|
253
261
|
}
|
254
|
-
function _assertSignaturesMatch(expected, actual, label, action) {
|
262
|
+
function _assertSignaturesMatch(expected, actual, label, action, opts) {
|
255
263
|
if (!!expected.protected !== !!actual.protected) {
|
256
264
|
const expVisibility = expected.protected ? 'protected' : 'public';
|
257
265
|
const actVisibility = actual.protected ? 'protected' : 'public';
|
258
266
|
diagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_5002_OVERRIDE_CHANGES_VISIBILITY.createDetached(label, action, actVisibility, expVisibility));
|
259
267
|
}
|
268
|
+
// Types must generally be the same, but can be covariant sometimes
|
260
269
|
if (!deepEqual(actual.returns, expected.returns)) {
|
261
|
-
const
|
262
|
-
const
|
263
|
-
|
270
|
+
const actualReturnType = actual.returns?.type;
|
271
|
+
const expectedReturnType = expected.returns?.type;
|
272
|
+
if (
|
273
|
+
// return type covariance is allowed
|
274
|
+
opts.returnTypeCovariance &&
|
275
|
+
// static members can never change
|
276
|
+
!actual.static &&
|
277
|
+
// this is a valid covariant return type (actual is more specific than expected)
|
278
|
+
_isCovariantOf(actualReturnType, expectedReturnType)) {
|
279
|
+
useFeature('class-covariant-overrides');
|
280
|
+
}
|
281
|
+
else {
|
282
|
+
const expType = spec.describeTypeReference(expectedReturnType);
|
283
|
+
const actType = spec.describeTypeReference(actualReturnType);
|
284
|
+
diagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_5003_OVERRIDE_CHANGES_RETURN_TYPE.createDetached(label, action, actType, expType));
|
285
|
+
}
|
264
286
|
}
|
265
287
|
const expectedParams = expected.parameters ?? [];
|
266
288
|
const actualParams = actual.parameters ?? [];
|
@@ -283,7 +305,104 @@ function _defaultValidations() {
|
|
283
305
|
}
|
284
306
|
}
|
285
307
|
}
|
286
|
-
|
308
|
+
/**
|
309
|
+
* Check if subType is indeed covariant to superType
|
310
|
+
*/
|
311
|
+
function _isCovariantOf(subType, superType) {
|
312
|
+
// one void, while other isn't => not covariant
|
313
|
+
if ((subType === undefined) !== (superType === undefined)) {
|
314
|
+
return false;
|
315
|
+
}
|
316
|
+
// Same type is always covariant
|
317
|
+
if (deepEqual(subType, superType)) {
|
318
|
+
return true;
|
319
|
+
}
|
320
|
+
// Handle array collections (covariant)
|
321
|
+
if (spec.isCollectionTypeReference(subType) && spec.isCollectionTypeReference(superType)) {
|
322
|
+
if (subType.collection.kind === 'array' && superType.collection.kind === 'array') {
|
323
|
+
return _isCovariantOf(subType.collection.elementtype, superType.collection.elementtype);
|
324
|
+
}
|
325
|
+
// Maps/Records are not allowed to be covariant in C#, so we exclude them here
|
326
|
+
return false;
|
327
|
+
}
|
328
|
+
// We only support classes for named types
|
329
|
+
if (!spec.isNamedTypeReference(subType) || !spec.isNamedTypeReference(superType)) {
|
330
|
+
return false;
|
331
|
+
}
|
332
|
+
const subTypeSpec = _dereference(subType.fqn, assembly, validator);
|
333
|
+
const superTypeSpec = _dereference(superType.fqn, assembly, validator);
|
334
|
+
if (!subTypeSpec || !superTypeSpec) {
|
335
|
+
return false;
|
336
|
+
}
|
337
|
+
// Handle class-to-class inheritance
|
338
|
+
if (spec.isClassType(subTypeSpec) && spec.isClassType(superTypeSpec)) {
|
339
|
+
return _classExtendsClass(subTypeSpec, superType.fqn);
|
340
|
+
}
|
341
|
+
// Handle interface-to-interface inheritance
|
342
|
+
if (spec.isInterfaceType(subTypeSpec) && spec.isInterfaceType(superTypeSpec)) {
|
343
|
+
return _interfaceExtendsInterface(subTypeSpec, superType.fqn);
|
344
|
+
}
|
345
|
+
// Handle class implementing interface
|
346
|
+
if (spec.isClassType(subTypeSpec) && spec.isInterfaceType(superTypeSpec)) {
|
347
|
+
return _classImplementsInterface(subTypeSpec, superType.fqn);
|
348
|
+
}
|
349
|
+
return false;
|
350
|
+
}
|
351
|
+
function _classExtendsClass(classType, targetFqn) {
|
352
|
+
let current = classType;
|
353
|
+
while (current.base) {
|
354
|
+
if (current.base === targetFqn) {
|
355
|
+
return true;
|
356
|
+
}
|
357
|
+
const baseType = _dereference(current.base, assembly, validator);
|
358
|
+
if (!spec.isClassType(baseType)) {
|
359
|
+
break;
|
360
|
+
}
|
361
|
+
current = baseType;
|
362
|
+
}
|
363
|
+
return false;
|
364
|
+
}
|
365
|
+
function _classImplementsInterface(classType, interfaceFqn) {
|
366
|
+
// Check direct interfaces
|
367
|
+
if (classType.interfaces?.includes(interfaceFqn)) {
|
368
|
+
return true;
|
369
|
+
}
|
370
|
+
// Check inherited interfaces
|
371
|
+
if (classType.interfaces) {
|
372
|
+
for (const iface of classType.interfaces) {
|
373
|
+
const ifaceType = _dereference(iface, assembly, validator);
|
374
|
+
if (spec.isInterfaceType(ifaceType) && _interfaceExtendsInterface(ifaceType, interfaceFqn)) {
|
375
|
+
return true;
|
376
|
+
}
|
377
|
+
}
|
378
|
+
}
|
379
|
+
// Check base class interfaces
|
380
|
+
if (classType.base) {
|
381
|
+
const baseType = _dereference(classType.base, assembly, validator);
|
382
|
+
if (spec.isClassType(baseType)) {
|
383
|
+
return _classImplementsInterface(baseType, interfaceFqn);
|
384
|
+
}
|
385
|
+
}
|
386
|
+
return false;
|
387
|
+
}
|
388
|
+
function _interfaceExtendsInterface(interfaceType, targetFqn) {
|
389
|
+
if (interfaceType.fqn === targetFqn) {
|
390
|
+
return true;
|
391
|
+
}
|
392
|
+
if (interfaceType.interfaces) {
|
393
|
+
for (const iface of interfaceType.interfaces) {
|
394
|
+
if (iface === targetFqn) {
|
395
|
+
return true;
|
396
|
+
}
|
397
|
+
const ifaceType = _dereference(iface, assembly, validator);
|
398
|
+
if (spec.isInterfaceType(ifaceType) && _interfaceExtendsInterface(ifaceType, targetFqn)) {
|
399
|
+
return true;
|
400
|
+
}
|
401
|
+
}
|
402
|
+
}
|
403
|
+
return false;
|
404
|
+
}
|
405
|
+
function _assertPropertiesMatch(expected, actual, label, action, opts) {
|
287
406
|
const actualNode = bindings.getPropertyRelatedNode(actual);
|
288
407
|
const expectedNode = bindings.getPropertyRelatedNode(expected);
|
289
408
|
if (!!expected.protected !== !!actual.protected) {
|
@@ -291,8 +410,21 @@ function _defaultValidations() {
|
|
291
410
|
const actVisibility = actual.protected ? 'protected' : 'public';
|
292
411
|
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
412
|
}
|
294
|
-
|
295
|
-
|
413
|
+
// Types must generally be the same, but can be covariant sometimes
|
414
|
+
if (!deepEqual(actual.type, expected.type)) {
|
415
|
+
if (
|
416
|
+
// return type covariance is allowed
|
417
|
+
opts.covariance &&
|
418
|
+
// static members can never change
|
419
|
+
!actual.static &&
|
420
|
+
// immutable properties may change in some case, as long as they are covariant
|
421
|
+
actual.immutable &&
|
422
|
+
_isCovariantOf(actual.type, expected.type)) {
|
423
|
+
useFeature('class-covariant-overrides');
|
424
|
+
}
|
425
|
+
else {
|
426
|
+
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.'));
|
427
|
+
}
|
296
428
|
}
|
297
429
|
if (expected.immutable !== actual.immutable) {
|
298
430
|
diagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_5010_OVERRIDE_CHANGES_MUTABILITY.create(actualNode?.modifiers?.find((mod) => mod.kind === ts.SyntaxKind.ReadonlyKeyword) ??
|