chore(deps): upgrade jsii & typescript (#3624)
Upgrades project dependencies. See details in workflow run.
Automatically created by projen via the “upgrade-jsii-main” workflow
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802032778号
Overview
jsii-rosettatranslates code samples contained in jsii libraries from TypeScript to supported jsii target languages. This is what enables the AWS Cloud Development Kit to deliver polyglot documentation from a single codebase!jsii-rosettaleverages knowledge about jsii language translation conventions in order to produce translations. It only supports a limited set of TypeScript language features (which can be reliably represented in other languages).Head over to our documentation website!
The jsii toolchain spreads out on multiple repositories:
jsiicompiler is maintained (except releases in the1.xline)jsii-rosettasample code transliteration tool is maintained (except releases in the1.xline)@jsii/spec, the package that defines the.jsiiassembly specificationjsii-config, an interactive tool to help configure your jsii packagejsii-pacmak, the bindings generator for jsii packagesjsii-reflect, a higher-level way to process.jsiiassemblies1.xrelease lines ofjsiiandjsii-rosetta:gear: Maintenance & Support
The applicable Maintenance & Support policy can be reviewed in SUPPORT.md.
The current status of
jsii-rosettareleases is:5.9.x5.8.x5.7.x:gear: Contributing
See CONTRIBUTING.
Rosetta for example authors
This section describes what to pay attention to when writing examples that will be converted by Rosetta.
Making examples compile
The translator can translate both code that completely compiles and typechecks, as well as code that doesn’t.
In case of non-compiling samples the translations will be based off of grammatical parsing only. This has the downside that we do not have the type information available to the exact thing in all instances. Specifically struct types will not be able to be inferred from object literals. Have a look at the following piece of code:
In non-TypeScript languages, it is important to know the type of the second argument to the method here. However, without access to the definition of
someMethod(), it’s impossible for Rosetta to know the type, and hence it cannot translate the example. It is therefore important to include necessary imports, variable declarations, etc, to give Rosetta enough information to figure out what’s going on in this code, and the example should read like this:Enforcing correct examples
By default, Rosetta will accept non-compiling examples. If you set
jsiiRosetta.stricttotruein yourpackage.json, the Rosetta command will fail if any example contains an error:Fixtures
To avoid having to repeat common setup every time, code samples can use “fixtures”: a source template where the example is inserted. A fixture must contain the text
/// hereand typically looks like this:The example will be inserted at the location marked as
/// hereand will have access tomodule,objandthis. Anyimportstatements found in the example will automatically be hoisted at the top of the fixture, where they are guaranteed to be syntactically valid.The default file loaded as a fixture is called
rosetta/default.ts-fixturein the package directory (if it exists).Examples can request an alternative fixture by specifying a
fixtureparameter as part of the code block fence:Or opt out of using the default fixture by specifying
nofixture:To specify fixtures in an
@exampleblock, use an accompanying@exampleMetadatatag:Dependencies
When compiling examples, Rosetta will make sure your package itself and all of its
dependenciesandpeerDependenciesare available in the dependency closure that your examples will be compiled in.If there are packages you want to use in an example that should not be part of your package’s dependencies, declare them in
jsiiRosetta.exampleDependenciesin yourpackage.json:You can also set up a directory with correct dependencies yourself, and pass
--directorywhen runningjsii-rosetta extract. We recommend using the automatic closure building mechanism and specifyingexampleDependenciesthough.Rosetta for package publishers
This section describes how Rosetta integrates into your build process.
Extract
Rosetta has a number of subcommands. The most important one is
jsii-rosetta extract.The
jsii-rosetta extractcommand will take one or more jsii assemblies, extract the snippets from them, will try to compile them with respect to a given home directory, and finally store all translations in something called a “tablet”.A couple of things to note here:
jsiito regenerate the assembly, before re-runningjsii-rosetta extract.imports. Currently, you are responsible for building a directory with the correctnode_modulesdirectories in there so that a TypeScript compilation step will find all libraries referenced in the examples. This is especially revelant if your examples include libraries that depend on the current library: it is not uncommon to write examples in libraryAshowing how to use it in combination with libraryB, whereBdepends onA. However, since by definitionBcannot be in the set of dependencies ofA, you must build a directory with bothBandAin it somewhere in your filesystem and run Rosetta in that directory.The extract command will write a file named
.jsii.tabl.jsonnext to every assembly, containing translations for all samples found in the assembly. You should include this file in your NPM package when you publish, so that downstream consumers of the package have access to the translations.An example invocation of
jsii-rosetta extractlooks like this:Running in parallel
Since TypeScript compilation takes a lot of time, much time can be gained by using the CPUs in your system effectively.
jsii-rosetta extractwill run the compilations in parallel.jsii-rosettawill use a number of workers equal to half the number of CPU cores, up to a maximum of 16 workers. This default maximum can be overridden by setting theJSII_ROSETTA_MAX_WORKER_COUNTenvironment variable.If you get out of memory errors running too many workers, run a command like this to raise the memory allowed for your workers:
Caching
Rosetta extract will translate all examples found in
.jsiiand write the translations to.jsii.tabl.json. From compilation to compilation, many of these examples won’t have changed. Since TypeScript compilation is a fairly expensive process, we would like to avoid doing unnecessary work as much as possible.To that end, rosetta can reuse translations from a cache, and write new translations into the same cache:
The
--trim-cacheflag will remove any old translations from the cache that don’t exist anymore in any of the given assemblies. This prevents the cache from growing endlessly over time (an equivalentjsii-rosetta trim-cachecommand is available if your workflow involves runningextractin multiple distinct invocations and want to retain the cache between them).Dirty Translations
When reusing translations from cache, Rosetta checks if cached translations are still valid. A translation becomes “dirty” (and is dropped from cache) when:
--compilemode is enabled.Dirty translations are dropped and re-translated.
Infuse
The
jsii-rosetta infusecommand increases the coverage of examples for classes in the assembly.It finds classes in the assembly that don’t have an example associated with them yet (as specified via the
@exampletag in the doc comments), but that are used in another example found elsewhere—in either aREADMEor an example of another class—it will copy the example to all classes involved. This will make sure your handwritten examples go as far as possible.Note that in order to do this,
infusewill modify the assemblies it is given.rosetta infusedepends on the analysis perfomed byrosetta extract, and must therefore be run afterextract. It can also be run as part ofextract, by passing the--infuseflag:Debugging
Type Fingerprints
To debug type fingerprinting issues, set the
DEBUG_TYPE_FINGERPRINTSenvironment variable to a file path. This writes all computed type fingerprints to the specified file in alphabetically sorted format:The output file contains one line per type in the format
<fqn>: <hash>, making it easy to compare fingerprints across different runs using standard diff tools.Translation Timing
To display timing information for snippet translations, set the
TIMING=1environment variable:This outputs a table showing compilation time for each snippet, helping identify performance bottlenecks. Note that timing is not supported when using batch compilation mode.
Translations and pacmak
jsii-pacmakwill read translation from tablets to substitute translated examples into the generated source bindings.pacmakwill automatically read individual.jsii.tabl.jsonfiles if present, and can additionally also read from a global tablet file.When a translation for a code sample cannot be found,
pacmakcan be configured to do one of the following:extractcommand)Example:
Data flow
The diagram below shows how data flows through the jsii tools when used together:
Advanced topics
Hiding code from samples
In order to make examples compile, boilerplate code may need to be added that detracts from the example at hand (such as variable declarations and imports).
This package supports hiding parts of the original source after translation.
To mark special locations in the source tree, we can use one of three mechanisms:
voidexpression statement to mark statement locations in the AST.commaoperator combined with avoidexpression to mark expression locations in the AST./// !hide,/// !show) to mark locations that span AST nodes. This is less reliable (because the source location of translated syntax sometimes will have to be estimated) but the only option if you want to mark non-contiguous nodes (such as hide part of a class declaration but show statements inside the constructor).The
voidexpression keyword and or thecommaoperator feature are little-used JavaScript features that are reliably parsed by TypeScript and do not affect the semantics of the application in which they appear (so the program executes the same with or without them).A handy mnemonic for this feature is that you can use it to “send your code into the void”.
Hiding statements
Statement hiding looks like this:
Hiding expressions
For hiding expressions, we use
commaexpressions to attach avoidstatement to an expression value without changing the meaning of the code.Example:
Will render as
Also supports a visible ellipsis:
Renders to:
Hiding across AST nodes
Use special comment directives:
:balance_scale: License
jsii is distributed under the Apache License, Version 2.0.
See LICENSE and NOTICE for more information.