Skip to content

Commit

Permalink
chore(release): 1.40.0 (#3082)
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Oct 20, 2021
2 parents 8af72c2 + 514e66d commit 9713b9d
Show file tree
Hide file tree
Showing 52 changed files with 1,852 additions and 255 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/docker-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ jobs:
fi
fi
# We only authenticate to Docker for 'push' events, as 'pull_request' from forks will not have the secret
# We only authenticate to Docker on the 'aws/jsii' repo, as forks will not have the secret
- name: Login to Docker
if: steps.should-run.outputs.result == 'true' && github.event_name == 'push'
if: steps.should-run.outputs.result == 'true' && github.repository == 'aws/jsii'
# The DOCKER_CREDENTIALS secret is expected to contain a username:token pair
run: |-
docker login \
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [1.40.0](https://github.com/aws/jsii/compare/v1.39.0...v1.40.0) (2021-10-19)


### Features

* **jsii:** added warnings for usage of deprecated elements ([#3051](https://github.com/aws/jsii/issues/3051)) ([8c0dd3b](https://github.com/aws/jsii/commit/8c0dd3b88f6ecb47e858ad5fc3c14f074c2c4a45))
* **jsii:** allow customizing tsconfig.json file name ([#3076](https://github.com/aws/jsii/issues/3076)) ([c611f26](https://github.com/aws/jsii/commit/c611f262c0ecba286e0fa84e03196614e1e3c722))


### Bug Fixes

* **rosetta:** allow only property assignments in object literals ([#3065](https://github.com/aws/jsii/issues/3065)) ([c783ab7](https://github.com/aws/jsii/commit/c783ab7037773dfcfa586ccd8d90c8450a5602bc)), closes [#3061](https://github.com/aws/jsii/issues/3061)
* **rosetta:** breaks when given a lot of snippets ([#3075](https://github.com/aws/jsii/issues/3075)) ([eca552e](https://github.com/aws/jsii/commit/eca552ebbfb39222f62033a2c7503c193f3f9acf))
* **rosetta:** class declaration uses wrong constructor name in C# ([#3064](https://github.com/aws/jsii/issues/3064)) ([13f75a1](https://github.com/aws/jsii/commit/13f75a15c6b5b3c5aa8ac56122a593393fed8c3e)), closes [#3056](https://github.com/aws/jsii/issues/3056)
* **rosetta:** disallow nullish coalescing operator in examples ([#3060](https://github.com/aws/jsii/issues/3060)) ([a35bbfa](https://github.com/aws/jsii/commit/a35bbfa7a104213b670ffafeac064dd629ad64a4)), closes [#3053](https://github.com/aws/jsii/issues/3053)
* **rosetta:** fix usage of Builders in Java ([#3058](https://github.com/aws/jsii/issues/3058)) ([a0ce42d](https://github.com/aws/jsii/commit/a0ce42db08238e30739fe9cdb28e4ca0e9b52192)), closes [#2984](https://github.com/aws/jsii/issues/2984)
* **rosetta:** newlines after return statements missing ([#3063](https://github.com/aws/jsii/issues/3063)) ([26c95f5](https://github.com/aws/jsii/commit/26c95f5cbcf23fe026faf3190488be2534313dd3)), closes [#3054](https://github.com/aws/jsii/issues/3054)

## [1.39.0](https://github.com/aws/jsii/compare/v1.38.0...v1.39.0) (2021-10-12)


Expand Down
9 changes: 6 additions & 3 deletions eslint-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,6 @@ rules:
'complexity':
- off

'consistent-return':
- error

'dot-notation':
- error

Expand Down Expand Up @@ -240,3 +237,9 @@ rules:
'@typescript-eslint/unbound-method': off
'no-case-declarations': off
'require-atomic-updates': off

# 'consistent-return' actually decreases safety. Its use will enforce useless `throws`
# statements, forcing a runtime error that occlude cases where the TypeScript type
# checker would actually have caught something like a non-exhaustive `switch` statement
# at compile time.
'consistent-return': off
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
"rejectCycles": true
}
},
"version": "1.39.0"
"version": "1.40.0"
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 56 additions & 19 deletions packages/jsii-rosetta/bin/jsii-rosetta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as fs from 'fs-extra';
import * as path from 'path';
import * as yargs from 'yargs';

import { TranslateResult, DEFAULT_TABLET_NAME, translateTypeScript } from '../lib';
import { TranslateResult, DEFAULT_TABLET_NAME, translateTypeScript, RosettaDiagnostic } from '../lib';
import { translateMarkdown } from '../lib/commands/convert';
import { extractSnippets } from '../lib/commands/extract';
import { readTablet } from '../lib/commands/read';
Expand All @@ -13,7 +13,7 @@ import { TargetLanguage } from '../lib/languages';
import { PythonVisitor } from '../lib/languages/python';
import { VisualizeAstVisitor } from '../lib/languages/visualize';
import * as logging from '../lib/logging';
import { File, printDiagnostics, isErrorDiagnostic } from '../lib/util';
import { File, printDiagnostics } from '../lib/util';

function main() {
const argv = yargs
Expand Down Expand Up @@ -41,7 +41,7 @@ function main() {
}),
wrapHandler(async (args) => {
const result = translateTypeScript(await makeFileSource(args.FILE ?? '-', 'stdin.ts'), makeVisitor(args));
renderResult(result);
handleSingleResult(result);
}),
)
.command(
Expand All @@ -60,7 +60,7 @@ function main() {
}),
wrapHandler(async (args) => {
const result = translateMarkdown(await makeFileSource(args.FILE ?? '-', 'stdin.md'), makeVisitor(args));
renderResult(result);
handleSingleResult(result);
}),
)
.command(
Expand Down Expand Up @@ -140,15 +140,7 @@ function main() {
only: args.include,
});

printDiagnostics(result.diagnostics, process.stderr);

if (result.diagnostics.length > 0) {
logging.warn(`${result.diagnostics.length} diagnostics encountered in ${result.tablet.count} snippets`);
}

if (result.diagnostics.some((diag) => isErrorDiagnostic(diag, { onlyStrict: !args.fail }))) {
process.exitCode = 1;
}
handleDiagnostics(result.diagnostics, args.fail, result.tablet.count);
}),
)
.command(
Expand Down Expand Up @@ -285,7 +277,9 @@ function wrapHandler<A extends { verbose?: number }, R>(handler: (x: A) => Promi
return (argv: A) => {
logging.configure({ level: argv.verbose !== undefined ? argv.verbose : 0 });
handler(argv).catch((e) => {
throw e;
logging.error(e.message);
logging.error(e.stack);
process.exitCode = 1;
});
};
}
Expand Down Expand Up @@ -329,15 +323,58 @@ async function readStdin(): Promise<string> {
});
}

function renderResult(result: TranslateResult) {
function handleSingleResult(result: TranslateResult) {
process.stdout.write(`${result.translation}\n`);

if (result.diagnostics.length > 0) {
printDiagnostics(result.diagnostics, process.stderr);
// For a single result, we always request implicit failure.
handleDiagnostics(result.diagnostics, 'implicit');
}

if (result.diagnostics.some((diag) => isErrorDiagnostic(diag, { onlyStrict: false }))) {
process.exit(1);
/**
* Print diagnostics and set exit code
*
* 'fail' is whether or not the user passed '--fail' for commands that accept
* it, or 'implicit' for commands that should always fail. 'implicit' will be
* treated as 'fail=true, but will not print to the user that the '--fail' is
* set (because for this particular command that switch does not exist and so it
* would be confusing).
*/
function handleDiagnostics(diagnostics: readonly RosettaDiagnostic[], fail: boolean | 'implicit', snippetCount = 1) {
if (fail !== false) {
// Fail on any diagnostic
if (diagnostics.length > 0) {
printDiagnostics(diagnostics, process.stderr);
logging.error(
[
`${diagnostics.length} diagnostics encountered in ${snippetCount} snippets`,
...(fail === true ? ["(running with '--fail')"] : []),
].join(' '),
);
process.exitCode = 1;
}

return;
}

// Otherwise fail only on strict diagnostics. If we have strict diagnostics, print only those
// (so it's very clear what is failing the build), otherwise print everything.
const strictDiagnostics = diagnostics.filter((diag) => diag.isFromStrictAssembly);
if (strictDiagnostics.length > 0) {
printDiagnostics(strictDiagnostics, process.stderr);
const remaining = diagnostics.length - strictDiagnostics.length;
logging.warn(
[
`${strictDiagnostics.length} diagnostics from assemblies with 'strict' mode on`,
...(remaining > 0 ? [`(and ${remaining} more non-strict diagnostics)`] : []),
].join(' '),
);
process.exitCode = 1;
return;
}

if (diagnostics.length > 0) {
printDiagnostics(diagnostics, process.stderr);
logging.warn(`${diagnostics.length} diagnostics encountered in ${snippetCount} snippets`);
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/jsii-rosetta/lib/commands/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { transformMarkdown } from '../markdown/markdown';
import { MarkdownRenderer } from '../markdown/markdown-renderer';
import { ReplaceTypeScriptTransform } from '../markdown/replace-typescript-transform';
import { AstHandler, AstRendererOptions } from '../renderer';
import { TranslateResult, Translator } from '../translate';
import { TranslateResult, Translator, rosettaDiagFromTypescript } from '../translate';
import { File } from '../util';

export interface TranslateMarkdownOptions extends AstRendererOptions {
Expand Down Expand Up @@ -38,6 +38,6 @@ export function translateMarkdown(

return {
translation: translatedMarkdown,
diagnostics: translator.diagnostics,
diagnostics: translator.diagnostics.map(rosettaDiagFromTypescript),
};
}
8 changes: 4 additions & 4 deletions packages/jsii-rosetta/lib/commands/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import * as logging from '../logging';
import { TypeScriptSnippet } from '../snippet';
import { snippetKey } from '../tablets/key';
import { LanguageTablet, TranslatedSnippet } from '../tablets/tablets';
import { Translator } from '../translate';
import { RosettaDiagnostic, Translator, rosettaDiagFromTypescript } from '../translate';
import { divideEvenly } from '../util';

export interface ExtractResult {
diagnostics: ts.Diagnostic[];
diagnostics: RosettaDiagnostic[];
tablet: LanguageTablet;
}

Expand Down Expand Up @@ -64,7 +64,7 @@ export async function extractSnippets(

interface TranslateAllResult {
translatedSnippets: TranslatedSnippet[];
diagnostics: ts.Diagnostic[];
diagnostics: RosettaDiagnostic[];
}

/**
Expand Down Expand Up @@ -133,7 +133,7 @@ export function singleThreadedTranslateAll(

return {
translatedSnippets,
diagnostics: [...translator.diagnostics, ...failures],
diagnostics: [...translator.diagnostics, ...failures].map(rosettaDiagFromTypescript),
};
}

Expand Down
11 changes: 8 additions & 3 deletions packages/jsii-rosetta/lib/commands/extract_worker.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/**
* Pool worker for extract.ts
*/
import * as ts from 'typescript';
import * as worker from 'worker_threads';

import * as logging from '../logging';
import { TypeScriptSnippet } from '../snippet';
import { TranslatedSnippetSchema } from '../tablets/schema';
import { RosettaDiagnostic } from '../translate';
import { singleThreadedTranslateAll } from './extract';

export interface TranslateRequest {
Expand All @@ -14,7 +15,7 @@ export interface TranslateRequest {
}

export interface TranslateResponse {
diagnostics: ts.Diagnostic[];
diagnostics: RosettaDiagnostic[];
// Cannot be 'TranslatedSnippet' because needs to be serializable
translatedSnippetSchemas: TranslatedSnippetSchema[];
}
Expand All @@ -36,6 +37,10 @@ if (worker.isMainThread) {
throw new Error('This script should be run as a worker, not included directly.');
}

const request = worker.workerData;
const request: TranslateRequest = worker.workerData;
const startTime = Date.now();
const response = translateSnippet(request);
const delta = (Date.now() - startTime) / 1000;
// eslint-disable-next-line prettier/prettier
logging.info(`Finished translation of ${request.snippets.length} in ${delta.toFixed(0)}s (${response.translatedSnippetSchemas.length} responses)`);
worker.parentPort!.postMessage(response);
60 changes: 53 additions & 7 deletions packages/jsii-rosetta/lib/jsii/jsii-types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as ts from 'typescript';

import { BuiltInType, builtInTypeName, mapElementType } from '../typescript/types';
import { inferredTypeOfExpression, BuiltInType, builtInTypeName, mapElementType } from '../typescript/types';
import { hasAnyFlag, analyzeStructType } from './jsii-utils';

// eslint-disable-next-line prettier/prettier
export type JsiiType =
Expand All @@ -20,10 +21,6 @@ export function determineJsiiType(typeChecker: ts.TypeChecker, type: ts.Type): J

type = type.getNonNullableType();

if (type.isUnion() || type.isIntersection()) {
return { kind: 'error', message: 'Type unions or intersections are not supported in examples' };
}

const mapValuesType = mapElementType(type, typeChecker);
if (mapValuesType.result === 'map') {
return {
Expand All @@ -43,9 +40,58 @@ export function determineJsiiType(typeChecker: ts.TypeChecker, type: ts.Type): J
}

const typeScriptBuiltInType = builtInTypeName(type);
if (!typeScriptBuiltInType) {
if (typeScriptBuiltInType) {
return { kind: 'builtIn', builtIn: typeScriptBuiltInType };
}

if (type.isUnion() || type.isIntersection()) {
return { kind: 'error', message: 'Type unions or intersections are not supported in examples' };
}
return { kind: 'unknown' };
}

export type ObjectLiteralAnalysis =
| { readonly kind: 'struct'; readonly type: ts.Type }
| { readonly kind: 'local-struct'; readonly type: ts.Type }
| { readonly kind: 'map' }
| { readonly kind: 'unknown' };

export function analyzeObjectLiteral(
typeChecker: ts.TypeChecker,
node: ts.ObjectLiteralExpression,
): ObjectLiteralAnalysis {
const type = inferredTypeOfExpression(typeChecker, node);
if (!type) {
return { kind: 'unknown' };
}

return { kind: 'builtIn', builtIn: typeScriptBuiltInType };
const call = findEnclosingCallExpression(node);
const isDeclaredCall = !!(call && typeChecker.getResolvedSignature(call)?.declaration);

if (hasAnyFlag(type.flags, ts.TypeFlags.Any)) {
// The type checker by itself won't tell us the difference between an `any` that
// was literally declared as a type in the code, vs an `any` it assumes because it
// can't find a function's type declaration.
//
// Search for the function's declaration and only if we can't find it,
// the type is actually unknown (otherwise it's a literal 'any').
return isDeclaredCall ? { kind: 'map' } : { kind: 'unknown' };
}

const structType = analyzeStructType(type);
if (structType) {
return { kind: structType, type };
}
return { kind: 'map' };
}

function findEnclosingCallExpression(node?: ts.Node): ts.CallLikeExpression | undefined {
while (node) {
if (ts.isCallLikeExpression(node)) {
return node;
}
node = node.parent;
}

return undefined;
}
Loading

0 comments on commit 9713b9d

Please sign in to comment.