From 150b6f210925684d7261f6ddade07741fad8ea17 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Wed, 4 Jan 2023 09:38:19 +0100 Subject: [PATCH] Protobuf postprocessing: Use NodeFactory to create nodes Most `ts.create*` and `ts.update*` functions are deprecated as of TypeScript 4.0. See this pull request for more details: https://github.com/microsoft/TypeScript/pull/35282 Additionally, some API calls (especially `createImportClause`) needed to be updated because apparently the API changed. --- tools/generate-protobuf-postprocess.cjs | 58 ++++++++++++++----------- tools/generator-utils.cjs | 39 +++++++++-------- 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/tools/generate-protobuf-postprocess.cjs b/tools/generate-protobuf-postprocess.cjs index ecefbb1a..57463ee7 100755 --- a/tools/generate-protobuf-postprocess.cjs +++ b/tools/generate-protobuf-postprocess.cjs @@ -11,14 +11,14 @@ const { /** * Convert interface name `IFoo` or `Foo` to `FooEncodable`. * - * @param interface Interface name (`IFoo` or `Foo`). + * @param iface Interface name (`IFoo` or `Foo`). * @returns Converted interface name (`FooEncodable`). */ -function getEncodableInterfaceName(interface) { +function getEncodableInterfaceName(iface) { const base = - interface.escapedText.match(/^I[A-Z]/u) !== null - ? interface.escapedText.slice(1) - : interface.escapedText; + iface.escapedText.match(/^I[A-Z]/u) !== null + ? iface.escapedText.slice(1) + : iface.escapedText; return `${base}Encodable`; } @@ -28,9 +28,9 @@ function getEncodableInterfaceName(interface) { * - Make all array properties `readonly` * - Tag the interface with `tag.ProtobufMessage` */ -function updateMessageInterface(interface) { +function updateMessageInterface(iface) { // Make all array properties `readonly` - for (const member of interface.members) { + for (const member of iface.members) { if ( member.type.kind !== ts.SyntaxKind.ParenthesizedType || member.type.type.kind !== ts.SyntaxKind.UnionType @@ -43,16 +43,16 @@ function updateMessageInterface(interface) { if (type.kind !== ts.SyntaxKind.ArrayType) { continue; } - union.types[i] = ts.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, type); + union.types[i] = ts.factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, type); } } // Tag the interface with `tag.ProtobufMessage` - return createNewtypeNode(getEncodableInterfaceName(interface.name), interface, [ - ts.createTypeReferenceNode( - ts.createQualifiedName( - ts.createIdentifier('tag'), - ts.createIdentifier('ProtobufMessage'), + return createNewtypeNode(getEncodableInterfaceName(iface.name), iface, [ + ts.factory.createTypeReferenceNode( + ts.factory.createQualifiedName( + ts.factory.createIdentifier('tag'), + ts.factory.createIdentifier('ProtobufMessage'), ), undefined, ), @@ -74,7 +74,10 @@ function updateMessageClass(class_) { member.kind === ts.SyntaxKind.PropertyDeclaration && member.type.kind === ts.SyntaxKind.ArrayType ) { - member.type = ts.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, member.type); + member.type = ts.factory.createTypeOperatorNode( + ts.SyntaxKind.ReadonlyKeyword, + member.type, + ); } // Update `encode` method interface reference @@ -86,7 +89,7 @@ function updateMessageClass(class_) { if (parameter.name.escapedText !== 'message') { continue; } - parameter.type.typeName.right = ts.createIdentifier( + parameter.type.typeName.right = ts.factory.createIdentifier( getEncodableInterfaceName(parameter.type.typeName.right), ); } @@ -96,17 +99,20 @@ function updateMessageClass(class_) { /** * Create tag import (for `ProtobufMessage`). + * + * Output: + * + * import type * as tag from "../tag"; */ function createTagImportNode() { - return ts.createImportDeclaration( - undefined, + return ts.factory.createImportDeclaration( undefined, - ts.createImportClause( - undefined, - ts.createNamespaceImport(ts.createIdentifier('tag')), + ts.factory.createImportClause( true, + ts.factory.createNamespaceImport(ts.factory.createIdentifier('tag')), + undefined, ), - ts.createStringLiteral('../tag'), + ts.factory.createStringLiteral('../tag'), ); } @@ -153,7 +159,8 @@ function updateMessageNamespaces(root, matchers) { function main() { // Parse source from stdin - const source = createSource('index.d.ts', fs.readFileSync(0, 'utf8')); + const sourceFromStdin = fs.readFileSync(0, 'utf8'); + const source = createSource('index.d.ts', sourceFromStdin); // Insert tag import source.statements.unshift(createTagImportNode()); @@ -164,11 +171,10 @@ function main() { // Insert 'Long' import // TODO(WEBMD-48): To be removed once we make use of BigInt source.statements.unshift( - ts.createImportDeclaration( - undefined, + ts.factory.createImportDeclaration( undefined, - ts.createImportClause(ts.createIdentifier('Long'), undefined, true), - ts.createStringLiteral('long'), + ts.factory.createImportClause(true, ts.factory.createIdentifier('Long'), undefined), + ts.factory.createStringLiteral('long'), ), ); diff --git a/tools/generator-utils.cjs b/tools/generator-utils.cjs index e0a00560..0fe64ada 100644 --- a/tools/generator-utils.cjs +++ b/tools/generator-utils.cjs @@ -33,17 +33,20 @@ function traverse(root, matchers, transform) { /** * Create types import (for `WeakOpaque`). + * + * Output: + * + * import type * as types from "~/common/types"; */ function createTypesImportNode() { - return ts.createImportDeclaration( - undefined, + return ts.factory.createImportDeclaration( undefined, - ts.createImportClause( - undefined, - ts.createNamespaceImport(ts.createIdentifier('types')), + ts.factory.createImportClause( true, + ts.factory.createNamespaceImport(ts.factory.createIdentifier('types')), + undefined, ), - ts.createStringLiteral('~/common/types'), + ts.factory.createStringLiteral('~/common/types'), ); } @@ -56,24 +59,26 @@ function createTypesImportNode() { * @returns a new-type node. */ function createNewtypeNode(name, target, tags) { - return ts.createTypeAliasDeclaration( - undefined, + return ts.factory.createTypeAliasDeclaration( undefined, name, undefined, - ts.createTypeReferenceNode( - ts.createQualifiedName(ts.createIdentifier('types'), ts.createIdentifier('WeakOpaque')), + ts.factory.createTypeReferenceNode( + ts.factory.createQualifiedName( + ts.factory.createIdentifier('types'), + ts.factory.createIdentifier('WeakOpaque'), + ), [ - ts.createTypeReferenceNode(target.name, undefined), - ts.createIntersectionTypeNode([ - ts.createTypeLiteralNode([ - ts.createPropertySignature( - [ts.createModifier(ts.SyntaxKind.ReadonlyKeyword)], + ts.factory.createTypeReferenceNode(target.name, undefined), + ts.factory.createIntersectionTypeNode([ + ts.factory.createTypeLiteralNode([ + ts.factory.createPropertySignature( + [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)], name, undefined, - ts.createTypeOperatorNode( + ts.factory.createTypeOperatorNode( ts.SyntaxKind.UniqueKeyword, - ts.createKeywordTypeNode(ts.SyntaxKind.SymbolKeyword), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.SymbolKeyword), ), undefined, ),