Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(jsii): added warnings for usage of deprecated elements #3051

Merged
merged 19 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/jsii/bin/jsii.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ const warningTypes = Object.keys(enabledWarnings);
type: 'boolean',
default: false,
desc: '[EXPERIMENTAL] Hides all @deprecated members from the API (implementations remain)',
})
.option('add-deprecation-warnings', {
type: 'boolean',
default: false,
desc: '[EXPERIMENTAL] Injects warning statements for all deprecated elements, to be printed at runtime',
}),
)
.option('verbose', {
Expand Down Expand Up @@ -102,6 +107,7 @@ const warningTypes = Object.keys(enabledWarnings);
projectReferences: argv['project-references'],
failOnWarnings: argv['fail-on-warnings'],
stripDeprecated: argv['strip-deprecated'],
addDeprecationWarnings: argv['add-deprecation-warnings'],
});

const emitResult = await (argv.watch ? compiler.watch() : compiler.emit());
Expand Down
30 changes: 30 additions & 0 deletions packages/jsii/lib/assembler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as bindings from './node-bindings';
import { ProjectInfo } from './project-info';
import { isReservedName } from './reserved-words';
import { DeprecatedRemover } from './transforms/deprecated-remover';
import { DeprecationWarningsInjector } from './transforms/deprecation-warnings';
import { RuntimeTypeInfoInjector } from './transforms/runtime-info';
import { TsCommentReplacer } from './transforms/ts-comment-replacer';
import { combinedTransformers } from './transforms/utils';
Expand All @@ -42,6 +43,7 @@ export class Assembler implements Emitter {
private readonly commentReplacer = new TsCommentReplacer();
private readonly runtimeTypeInfoInjector: RuntimeTypeInfoInjector;
private readonly deprecatedRemover?: DeprecatedRemover;
private readonly warningsInjector?: DeprecationWarningsInjector;

private readonly mainFile: string;

Expand Down Expand Up @@ -77,6 +79,12 @@ export class Assembler implements Emitter {
this.deprecatedRemover = new DeprecatedRemover(this._typeChecker);
}

if (options.addDeprecationWarnings) {
this.warningsInjector = new DeprecationWarningsInjector(
this._typeChecker,
);
}

const dts = projectInfo.types;
let mainFile = dts.replace(/\.d\.ts(x?)$/, '.ts$1');

Expand Down Expand Up @@ -106,6 +114,7 @@ export class Assembler implements Emitter {
this.deprecatedRemover?.customTransformers ?? {},
this.runtimeTypeInfoInjector.makeTransformers(),
this.commentReplacer.makeTransformers(),
this.warningsInjector?.customTransformers ?? {},
);
}

Expand Down Expand Up @@ -239,6 +248,20 @@ export class Assembler implements Emitter {
this._diagnostics.push(...this.deprecatedRemover.removeFrom(assembly));
}

if (this.warningsInjector) {
const jsiiMetadata = {
...(assembly.metadata?.jsii ?? {}),
...{ compiledWithDeprecationWarnings: true },
};

if (assembly.metadata) {
assembly.metadata.jsii = jsiiMetadata;
} else {
assembly.metadata = { jsii: jsiiMetadata };
}
this.warningsInjector.process(assembly, this.projectInfo);
}

const validator = new Validator(this.projectInfo, assembly);
const validationResult = await validator.emit();
if (!validationResult.emitSkipped) {
Expand Down Expand Up @@ -2732,6 +2755,13 @@ export interface AssemblerOptions {
* @default false
*/
readonly stripDeprecated?: boolean;

/**
* Whether to inject code that warns when a deprecated element is used.
*
* @default false
*/
readonly addDeprecationWarnings?: boolean;
}

interface SubmoduleSpec {
Expand Down
3 changes: 3 additions & 0 deletions packages/jsii/lib/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export interface CompilerOptions {
failOnWarnings?: boolean;
/** Whether to strip deprecated members from emitted artifacts */
stripDeprecated?: boolean;
/** Whether to add warnings for deprecated elements */
addDeprecationWarnings?: boolean;
}

export interface TypescriptConfig {
Expand Down Expand Up @@ -235,6 +237,7 @@ export class Compiler implements Emitter {
// to post-process the AST
const assembler = new Assembler(this.options.projectInfo, program, stdlib, {
stripDeprecated: this.options.stripDeprecated,
addDeprecationWarnings: this.options.addDeprecationWarnings,
});

try {
Expand Down
8 changes: 8 additions & 0 deletions packages/jsii/lib/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ export async function compileJsiiForTest(
files[jsFile] = await fs.readFile(jsFile, { encoding: 'utf-8' });
// eslint-disable-next-line no-await-in-loop
files[dtsFile] = await fs.readFile(dtsFile, { encoding: 'utf-8' });

const warningsFileName = '.warnings.jsii.js';
if (fs.existsSync(warningsFileName)) {
// eslint-disable-next-line no-await-in-loop
files[warningsFileName] = await fs.readFile(warningsFileName, {
encoding: 'utf-8',
});
}
}

return { assembly, files };
Expand Down
Loading