From 7d6020d33aad58630d0a866545948ef293133371 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Oct 2023 17:33:57 -0400 Subject: [PATCH 1/2] Expose 'updateModifiers' in public NodeFactory API --- src/compiler/factory/nodeFactory.ts | 6 +++--- src/compiler/types.ts | 10 ++++++++-- src/services/completions.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 8 ++++++++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index c01dee21917dd..ebd101f5f97db 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1179,7 +1179,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode liftToBlock, mergeLexicalEnvironment, updateModifiers, - updateModifierLike, + updateDecoratorsAndModifiers, }; forEach(nodeFactoryPatchers, fn => fn(factory)); @@ -7137,8 +7137,8 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode Debug.assertNever(node); } - function updateModifierLike(node: T, modifiers: readonly ModifierLike[]): T; - function updateModifierLike(node: HasModifiers & HasDecorators, modifierArray: readonly ModifierLike[]) { + function updateDecoratorsAndModifiers(node: T, modifiers: readonly ModifierLike[]): T; + function updateDecoratorsAndModifiers(node: HasModifiers & HasDecorators, modifierArray: readonly ModifierLike[]) { return isParameter(node) ? updateParameterDeclaration(node, modifierArray, node.dotDotDotToken, node.name, node.questionToken, node.type, node.initializer) : isPropertyDeclaration(node) ? updatePropertyDeclaration(node, modifierArray, node.name, node.questionToken ?? node.exclamationToken, node.type, node.initializer) : isMethodDeclaration(node) ? updateMethodDeclaration(node, modifierArray, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, node.body) : diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a64c4c86b596d..16d16c70b3668 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -9072,8 +9072,14 @@ export interface NodeFactory { * @internal */ cloneNode(node: T): T; - /** @internal */ updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags | undefined): T; - /** @internal */ updateModifierLike(node: T, modifierLike: readonly ModifierLike[] | undefined): T; + /** + * Updates a node that may contain modifiers, replacing only the modifiers of the node. + */ + updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags | undefined): T; + /** + * Updates a node that may contain decorators or modifiers, replacing only the decorators and modifiers of the node. + */ + updateDecoratorsAndModifiers(node: T, modifiers: readonly ModifierLike[] | undefined): T; } /** @internal */ diff --git a/src/services/completions.ts b/src/services/completions.ts index d1f8bd04d4094..7531f010c7915 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -2023,7 +2023,7 @@ function getEntryForMemberCompletion( if (presentDecorators?.length) { const lastNode = completionNodes[completionNodes.length - 1]; if (canHaveDecorators(lastNode)) { - completionNodes[completionNodes.length - 1] = factory.updateModifierLike(lastNode, (presentDecorators as ModifierLike[]).concat(getModifiers(lastNode) || [])); + completionNodes[completionNodes.length - 1] = factory.updateDecoratorsAndModifiers(lastNode, (presentDecorators as ModifierLike[]).concat(getModifiers(lastNode) || [])); } } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 51b0ea6c9f003..7f88119d35713 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -8387,6 +8387,14 @@ declare namespace ts { createExportDefault(expression: Expression): ExportAssignment; createExternalModuleExport(exportName: Identifier): ExportDeclaration; restoreOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds?: OuterExpressionKinds): Expression; + /** + * Updates a node that may contain modifiers, replacing only the modifiers of the node. + */ + updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags | undefined): T; + /** + * Updates a node that may contain decorators or modifiers, replacing only the decorators and modifiers of the node. + */ + updateDecoratorsAndModifiers(node: T, modifiers: readonly ModifierLike[] | undefined): T; } interface CoreTransformationContext { readonly factory: NodeFactory; From 24cf4fe7c4102062346d14c06d299d2c5612b779 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 23 Oct 2023 17:51:25 -0400 Subject: [PATCH 2/2] Rename 'updateModifiers' to 'replaceModifiers' to differentiate from other 'updateX' methods --- src/compiler/checker.ts | 6 +++--- src/compiler/factory/nodeFactory.ts | 12 ++++++------ src/compiler/transformers/declarations.ts | 4 ++-- src/compiler/types.ts | 4 ++-- src/services/codefixes/addMissingAsync.ts | 2 +- src/services/completions.ts | 6 +++--- tests/baselines/reference/api/typescript.d.ts | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9ed6f52c38c71..219f922b49c3f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8816,12 +8816,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function addExportModifier(node: Extract) { const flags = (getEffectiveModifierFlags(node) | ModifierFlags.Export) & ~ModifierFlags.Ambient; - return factory.updateModifiers(node, flags); + return factory.replaceModifiers(node, flags); } function removeExportModifier(node: Extract) { const flags = getEffectiveModifierFlags(node) & ~ModifierFlags.Export; - return factory.updateModifiers(node, flags); + return factory.replaceModifiers(node, flags); } function visitSymbolTable(symbolTable: SymbolTable, suppressNewPrivateContext?: boolean, propertyAsAlias?: boolean) { @@ -9120,7 +9120,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { newModifierFlags |= ModifierFlags.Default; } if (newModifierFlags) { - node = factory.updateModifiers(node, newModifierFlags | getEffectiveModifierFlags(node)); + node = factory.replaceModifiers(node, newModifierFlags | getEffectiveModifierFlags(node)); } } results.push(node); diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index ebd101f5f97db..b5adef0c6dd33 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1178,8 +1178,8 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode ensureUseStrict, liftToBlock, mergeLexicalEnvironment, - updateModifiers, - updateDecoratorsAndModifiers, + replaceModifiers, + replaceDecoratorsAndModifiers, }; forEach(nodeFactoryPatchers, fn => fn(factory)); @@ -7100,8 +7100,8 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode return statements; } - function updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags): T; - function updateModifiers(node: HasModifiers, modifiers: readonly Modifier[] | ModifierFlags) { + function replaceModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags): T; + function replaceModifiers(node: HasModifiers, modifiers: readonly Modifier[] | ModifierFlags) { let modifierArray; if (typeof modifiers === "number") { modifierArray = createModifiersFromModifierFlags(modifiers); @@ -7137,8 +7137,8 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode Debug.assertNever(node); } - function updateDecoratorsAndModifiers(node: T, modifiers: readonly ModifierLike[]): T; - function updateDecoratorsAndModifiers(node: HasModifiers & HasDecorators, modifierArray: readonly ModifierLike[]) { + function replaceDecoratorsAndModifiers(node: T, modifiers: readonly ModifierLike[]): T; + function replaceDecoratorsAndModifiers(node: HasModifiers & HasDecorators, modifierArray: readonly ModifierLike[]) { return isParameter(node) ? updateParameterDeclaration(node, modifierArray, node.dotDotDotToken, node.name, node.questionToken, node.type, node.initializer) : isPropertyDeclaration(node) ? updatePropertyDeclaration(node, modifierArray, node.name, node.questionToken ?? node.exclamationToken, node.type, node.initializer) : isMethodDeclaration(node) ? updateMethodDeclaration(node, modifierArray, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, node.body) : diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 512c2eb4704f8..e649e1b2b4330 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1436,7 +1436,7 @@ export function transformDeclarations(context: TransformationContext) { } const modifiers = factory.createModifiersFromModifierFlags(getEffectiveModifierFlags(statement) & (ModifierFlags.All ^ ModifierFlags.Export)); - return factory.updateModifiers(statement, modifiers); + return factory.replaceModifiers(statement, modifiers); } function updateModuleDeclarationAndKeyword( @@ -1566,7 +1566,7 @@ export function transformDeclarations(context: TransformationContext) { return factory.createVariableStatement(isNonContextualKeywordName ? undefined : [factory.createToken(SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([varDecl])); }); if (!exportMappings.length) { - declarations = mapDefined(declarations, declaration => factory.updateModifiers(declaration, ModifierFlags.None)); + declarations = mapDefined(declarations, declaration => factory.replaceModifiers(declaration, ModifierFlags.None)); } else { declarations.push(factory.createExportDeclaration( diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 16d16c70b3668..6baa124617bbf 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -9075,11 +9075,11 @@ export interface NodeFactory { /** * Updates a node that may contain modifiers, replacing only the modifiers of the node. */ - updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags | undefined): T; + replaceModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags | undefined): T; /** * Updates a node that may contain decorators or modifiers, replacing only the decorators and modifiers of the node. */ - updateDecoratorsAndModifiers(node: T, modifiers: readonly ModifierLike[] | undefined): T; + replaceDecoratorsAndModifiers(node: T, modifiers: readonly ModifierLike[] | undefined): T; } /** @internal */ diff --git a/src/services/codefixes/addMissingAsync.ts b/src/services/codefixes/addMissingAsync.ts index ef1087ad0ba11..39a6f97c8bacd 100644 --- a/src/services/codefixes/addMissingAsync.ts +++ b/src/services/codefixes/addMissingAsync.ts @@ -87,7 +87,7 @@ function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: Source } } fixedDeclarations?.add(getNodeId(insertionSite)); - const cloneWithModifier = factory.updateModifiers( + const cloneWithModifier = factory.replaceModifiers( getSynthesizedDeepClone(insertionSite, /*includeTrivia*/ true), factory.createNodeArray(factory.createModifiersFromModifierFlags(getSyntacticModifierFlags(insertionSite) | ModifierFlags.Async)), ); diff --git a/src/services/completions.ts b/src/services/completions.ts index 7531f010c7915..11fbce92c6b41 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1988,7 +1988,7 @@ function getEntryForMemberCompletion( // and we need to make sure the modifiers are uniform for all nodes/signatures. modifiers = node.modifierFlagsCache | requiredModifiers; } - node = factory.updateModifiers(node, modifiers); + node = factory.replaceModifiers(node, modifiers); completionNodes.push(node); }, body, @@ -2018,12 +2018,12 @@ function getEntryForMemberCompletion( modifiers &= ~ModifierFlags.Public; } modifiers |= allowedAndPresent; - completionNodes = completionNodes.map(node => factory.updateModifiers(node, modifiers)); + completionNodes = completionNodes.map(node => factory.replaceModifiers(node, modifiers)); // Add back the decorators that were already present. if (presentDecorators?.length) { const lastNode = completionNodes[completionNodes.length - 1]; if (canHaveDecorators(lastNode)) { - completionNodes[completionNodes.length - 1] = factory.updateDecoratorsAndModifiers(lastNode, (presentDecorators as ModifierLike[]).concat(getModifiers(lastNode) || [])); + completionNodes[completionNodes.length - 1] = factory.replaceDecoratorsAndModifiers(lastNode, (presentDecorators as ModifierLike[]).concat(getModifiers(lastNode) || [])); } } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 7f88119d35713..bf4779d975924 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -8390,11 +8390,11 @@ declare namespace ts { /** * Updates a node that may contain modifiers, replacing only the modifiers of the node. */ - updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags | undefined): T; + replaceModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags | undefined): T; /** * Updates a node that may contain decorators or modifiers, replacing only the decorators and modifiers of the node. */ - updateDecoratorsAndModifiers(node: T, modifiers: readonly ModifierLike[] | undefined): T; + replaceDecoratorsAndModifiers(node: T, modifiers: readonly ModifierLike[] | undefined): T; } interface CoreTransformationContext { readonly factory: NodeFactory;