UNPKG

jsii-rosetta

Version:

[![Join the chat at https://cdk.Dev](https://img.shields.io/static/v1?label=Slack&message=cdk.dev&color=brightgreen&logo=slack)](https://cdk.dev) [![All Contributors](https://img.shields.io/github/all-contributors/aws/jsii/main?label=%E2%9C%A8%20All%20Con

304 lines • 11.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DefaultVisitor = void 0; const ts = require("typescript"); const jsii_types_1 = require("../jsii/jsii-types"); const jsii_utils_1 = require("../jsii/jsii-utils"); const o_tree_1 = require("../o-tree"); const renderer_1 = require("../renderer"); const ast_utils_1 = require("../typescript/ast-utils"); const types_1 = require("../typescript/types"); /** * A basic visitor that applies for most curly-braces-based languages */ class DefaultVisitor { constructor() { this.statementTerminator = ';'; } commentRange(comment, _context) { return new o_tree_1.OTree([comment.isTrailing ? ' ' : '', comment.text, comment.hasTrailingNewLine ? '\n' : '']); } sourceFile(node, context) { return new o_tree_1.OTree(context.convertAll(node.statements)); } jsDoc(_node, _context) { // Already handled by other doc handlers return new o_tree_1.OTree([]); } importStatement(node, context) { return this.notImplemented(node.node, context); } functionDeclaration(node, children) { return this.notImplemented(node, children); } stringLiteral(node, _renderer) { return new o_tree_1.OTree([JSON.stringify(node.text)]); } numericLiteral(node, _children) { return new o_tree_1.OTree([node.text]); } identifier(node, _children) { return new o_tree_1.OTree([node.text]); } block(node, children) { return new o_tree_1.OTree(['{'], ['\n', ...children.convertAll(node.statements)], { indent: 4, suffix: '}', }); } parameterDeclaration(node, children) { return this.notImplemented(node, children); } returnStatement(node, children) { return new o_tree_1.OTree(['return ', children.convert(node.expression), this.statementTerminator], [], { canBreakLine: true, }); } binaryExpression(node, context) { const operator = context.textOf(node.operatorToken); if (operator === '??') { context.reportUnsupported(node.operatorToken, undefined); } const operatorToken = this.translateBinaryOperator(operator); return new o_tree_1.OTree([context.convert(node.left), ' ', operatorToken, ' ', context.convert(node.right)]); } prefixUnaryExpression(node, context) { return new o_tree_1.OTree([this.translateUnaryOperator(node.operator), context.convert(node.operand)]); } translateUnaryOperator(operator) { return UNARY_OPS[operator]; } translateBinaryOperator(operator) { if (operator === '===') { return '=='; } return operator; } ifStatement(node, context) { return this.notImplemented(node, context); } propertyAccessExpression(node, context, _submoduleReference) { return new o_tree_1.OTree([context.convert(node.expression), '.', context.convert(node.name)]); } /** * Do some work on property accesses to translate common JavaScript-isms to language-specific idioms */ callExpression(node, context) { const functionText = context.textOf(node.expression); if (functionText === 'console.log' || functionText === 'console.error') { return this.printStatement(node.arguments, context); } if (functionText === 'super') { return this.superCallExpression(node, context); } return this.regularCallExpression(node, context); } awaitExpression(node, context) { return context.convert(node.expression); } regularCallExpression(node, context) { return new o_tree_1.OTree([context.convert(node.expression), '(', this.argumentList(node.arguments, context), ')']); } superCallExpression(node, context) { return this.regularCallExpression(node, context); } printStatement(args, context) { return new o_tree_1.OTree(['<PRINT>', '(', this.argumentList(args, context), ')']); } expressionStatement(node, context) { return new o_tree_1.OTree([context.convert(node.expression)], [], { canBreakLine: true, }); } token(node, context) { return new o_tree_1.OTree([context.textOf(node)]); } /** * An object literal can render as one of three things: * * - Don't know the type (render as an unknown struct) * - Know the type: * - It's a struct (render as known struct) * - It's not a struct (render as key-value map) */ objectLiteralExpression(node, context) { // If any of the elements of the objectLiteralExpression are not a literal property // assignment, report them. We can't support those. const unsupported = node.properties.filter((p) => !ts.isPropertyAssignment(p) && !ts.isShorthandPropertyAssignment(p)); for (const unsup of unsupported) { context.report(unsup, `Use of ${ts.SyntaxKind[unsup.kind]} in an object literal is not supported.`); } const anyMembersFunctions = node.properties.some((p) => ts.isPropertyAssignment(p) ? isExpressionOfFunctionType(context.typeChecker, p.initializer) : ts.isShorthandPropertyAssignment(p) ? isExpressionOfFunctionType(context.typeChecker, p.name) : false); const inferredType = (0, types_1.inferredTypeOfExpression)(context.typeChecker, node); if ((inferredType && (0, jsii_utils_1.isJsiiProtocolType)(context.typeChecker, inferredType)) || anyMembersFunctions) { context.report(node, `You cannot use an object literal to make an instance of an interface. Define a class instead.`); } const lit = (0, jsii_types_1.analyzeObjectLiteral)(context.typeChecker, node); switch (lit.kind) { case 'unknown': return this.unknownTypeObjectLiteralExpression(node, context); case 'struct': case 'local-struct': return this.knownStructObjectLiteralExpression(node, lit, context); case 'map': return this.keyValueObjectLiteralExpression(node, context); } } unknownTypeObjectLiteralExpression(node, context) { return this.notImplemented(node, context); } knownStructObjectLiteralExpression(node, _structType, context) { return this.notImplemented(node, context); } keyValueObjectLiteralExpression(node, context) { return this.notImplemented(node, context); } newExpression(node, context) { return new o_tree_1.OTree(['new ', context.convert(node.expression), '(', this.argumentList(node.arguments, context), ')'], [], { canBreakLine: true }); } propertyAssignment(node, context) { return this.notImplemented(node, context); } variableStatement(node, context) { return new o_tree_1.OTree([context.convert(node.declarationList)], [], { canBreakLine: true, }); } variableDeclarationList(node, context) { return new o_tree_1.OTree([], context.convertAll(node.declarations)); } variableDeclaration(node, context) { return this.notImplemented(node, context); } arrayLiteralExpression(node, context) { return new o_tree_1.OTree(['['], context.convertAll(node.elements), { separator: ', ', suffix: ']', }); } shorthandPropertyAssignment(node, context) { return this.notImplemented(node, context); } forOfStatement(node, context) { return this.notImplemented(node, context); } classDeclaration(node, context) { return this.notImplemented(node, context); } constructorDeclaration(node, context) { return this.notImplemented(node, context); } propertyDeclaration(node, context) { return this.notImplemented(node, context); } computedPropertyName(node, context) { return context.convert(node); } methodDeclaration(node, context) { return this.notImplemented(node, context); } interfaceDeclaration(node, context) { if ((0, jsii_utils_1.isNamedLikeStruct)(context.textOf(node.name))) { return this.structInterfaceDeclaration(node, context); } return this.regularInterfaceDeclaration(node, context); } structInterfaceDeclaration(node, context) { return this.notImplemented(node, context); } regularInterfaceDeclaration(node, context) { return this.notImplemented(node, context); } propertySignature(node, context) { return this.notImplemented(node, context); } methodSignature(node, context) { return this.notImplemented(node, context); } asExpression(node, context) { return this.notImplemented(node, context); } spreadElement(node, context) { return this.notImplemented(node, context); } spreadAssignment(node, context) { return this.notImplemented(node, context); } ellipsis(_node, _context) { return new o_tree_1.OTree(['...']); } templateExpression(node, context) { return this.notImplemented(node, context); } elementAccessExpression(node, context) { const expression = context.convert(node.expression); const index = context.convert(node.argumentExpression); return new o_tree_1.OTree([expression, '[', index, ']']); } nonNullExpression(node, context) { // We default we drop the non-null assertion return context.convert(node.expression); } parenthesizedExpression(node, context) { return new o_tree_1.OTree(['(', context.convert(node.expression), ')']); } maskingVoidExpression(node, context) { // Don't render anything by default when nodes are masked const arg = (0, ast_utils_1.voidExpressionString)(node); if (arg === 'block') { return this.commentRange({ pos: context.getPosition(node).start, text: '\n// ...', kind: ts.SyntaxKind.SingleLineCommentTrivia, hasTrailingNewLine: false, }, context); } if (arg === '...') { return new o_tree_1.OTree(['...']); } return o_tree_1.NO_SYNTAX; } argumentList(args, context) { return new o_tree_1.OTree([], args ? context.convertAll(args) : [], { separator: ', ', }); } notImplemented(node, context) { context.reportUnsupported(node, this.language); return (0, renderer_1.nimpl)(node, context); } } exports.DefaultVisitor = DefaultVisitor; const UNARY_OPS = { [ts.SyntaxKind.PlusPlusToken]: '++', [ts.SyntaxKind.MinusMinusToken]: '--', [ts.SyntaxKind.PlusToken]: '+', [ts.SyntaxKind.MinusToken]: '-', [ts.SyntaxKind.TildeToken]: '~', [ts.SyntaxKind.ExclamationToken]: '!', }; /** * Whether the given expression evaluates to a value that is of type "function" * * Examples of function types: * * ```ts * // GIVEN * function someFunction() { } * * // THEN * const x = someFunction; // <- function type * const y = () => 42; // <- function type * const z = x; // <- function type * Array.isArray; // <- function type * ``` */ function isExpressionOfFunctionType(typeChecker, expr) { const type = typeChecker.getTypeAtLocation(expr).getNonNullableType(); return type.getCallSignatures().length > 0; } //# sourceMappingURL=default.js.map