diff --git a/src/compiler/factory/nodeChildren.ts b/src/compiler/factory/nodeChildren.ts index 89fa8383b281d..aa41f5955fb69 100644 --- a/src/compiler/factory/nodeChildren.ts +++ b/src/compiler/factory/nodeChildren.ts @@ -1,14 +1,20 @@ -import { Node } from "../_namespaces/ts"; +import { + emptyArray, + isNodeKind, + Node, +} from "../_namespaces/ts"; -const nodeChildren = new WeakMap(); +const nodeChildren = new WeakMap(); /** @internal */ -export function getNodeChildren(node: Node): Node[] | undefined { +export function getNodeChildren(node: Node): readonly Node[] | undefined { + if (!isNodeKind(node.kind)) return emptyArray; + return nodeChildren.get(node); } /** @internal */ -export function setNodeChildren(node: Node, children: Node[]): Node[] { +export function setNodeChildren(node: Node, children: readonly Node[]): readonly Node[] { nodeChildren.set(node, children); return children; } diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index c2b9f0d615005..78e3e3e5fd5ef 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -6209,7 +6209,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function createSyntaxList(children: Node[]) { + function createSyntaxList(children: readonly Node[]) { const node = createBaseNode(SyntaxKind.SyntaxList); setNodeChildren(node, children); return node; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d97dc608adcbf..45d4a41825d88 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -9006,7 +9006,7 @@ export interface NodeFactory { // Synthetic Nodes // /** @internal */ createSyntheticExpression(type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember): SyntheticExpression; - /** @internal */ createSyntaxList(children: Node[]): SyntaxList; + /** @internal */ createSyntaxList(children: readonly Node[]): SyntaxList; // // Transformation nodes diff --git a/src/services/services.ts b/src/services/services.ts index 18f0b4d151439..7096705f0c3e3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -438,7 +438,7 @@ class NodeObject implements Node { return this.getChildren(sourceFile)[index]; } - public getChildren(sourceFile?: SourceFileLike): Node[] { + public getChildren(sourceFile?: SourceFileLike): readonly Node[] { this.assertHasRealPosition("Node without a real position cannot be scanned and thus has no token nodes - use forEachChild and collect the result if that's fine"); return getNodeChildren(this) ?? setNodeChildren(this, createChildren(this, sourceFile)); } @@ -473,11 +473,7 @@ class NodeObject implements Node { } } -function createChildren(node: Node, sourceFile: SourceFileLike | undefined): Node[] { - if (!isNodeKind(node.kind)) { - return emptyArray; - } - +function createChildren(node: Node, sourceFile: SourceFileLike | undefined): readonly Node[] { const children: Node[] = []; if (isJSDocCommentContainingNode(node)) { diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts index d1cc5ca92472b..d726d177e682a 100644 --- a/src/services/smartSelection.ts +++ b/src/services/smartSelection.ts @@ -279,7 +279,7 @@ function getSelectionChildren(node: Node): readonly Node[] { * Groups sibling nodes together into their own SyntaxList if they * a) are adjacent, AND b) match a predicate function. */ -function groupChildren(children: Node[], groupOn: (child: Node) => boolean): Node[] { +function groupChildren(children: readonly Node[], groupOn: (child: Node) => boolean): Node[] { const result: Node[] = []; let group: Node[] | undefined; for (const child of children) { @@ -315,7 +315,7 @@ function groupChildren(children: Node[], groupOn: (child: Node) => boolean): Nod * @param separateTrailingSemicolon If the last token is a semicolon, it will be returned as a separate * child rather than be included in the right-hand group. */ -function splitChildren(children: Node[], pivotOn: (child: Node) => boolean, separateTrailingSemicolon = true): Node[] { +function splitChildren(children: readonly Node[], pivotOn: (child: Node) => boolean, separateTrailingSemicolon = true): readonly Node[] { if (children.length < 2) { return children; } @@ -336,7 +336,7 @@ function splitChildren(children: Node[], pivotOn: (child: Node) => boolean, sepa return separateLastToken ? result.concat(lastToken) : result; } -function createSyntaxList(children: Node[]): SyntaxList { +function createSyntaxList(children: readonly Node[]): SyntaxList { Debug.assertGreaterThanOrEqual(children.length, 1); return setTextRangePosEnd(parseNodeFactory.createSyntaxList(children), children[0].pos, last(children).end); } diff --git a/src/services/types.ts b/src/services/types.ts index f98d317d61dd5..3adcf0c39e65f 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -49,9 +49,9 @@ declare module "../compiler/types" { getSourceFile(): SourceFile; getChildCount(sourceFile?: SourceFile): number; getChildAt(index: number, sourceFile?: SourceFile): Node; - getChildren(sourceFile?: SourceFile): Node[]; + getChildren(sourceFile?: SourceFile): readonly Node[]; /** @internal */ - getChildren(sourceFile?: SourceFileLike): Node[]; // eslint-disable-line @typescript-eslint/unified-signatures + getChildren(sourceFile?: SourceFileLike): readonly Node[]; // eslint-disable-line @typescript-eslint/unified-signatures getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number; /** @internal */ getStart(sourceFile?: SourceFileLike, includeJsDocComment?: boolean): number; // eslint-disable-line @typescript-eslint/unified-signatures diff --git a/src/services/utilities.ts b/src/services/utilities.ts index dade1fe37bdd3..3fb95f79cb90f 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1830,7 +1830,7 @@ function findRightmostToken(n: Node, sourceFile: SourceFileLike): Node | undefin /** * Finds the rightmost child to the left of `children[exclusiveStartPosition]` which is a non-all-whitespace token or has constituent tokens. */ -function findRightmostChildNodeWithTokens(children: Node[], exclusiveStartPosition: number, sourceFile: SourceFileLike, parentKind: SyntaxKind): Node | undefined { +function findRightmostChildNodeWithTokens(children: readonly Node[], exclusiveStartPosition: number, sourceFile: SourceFileLike, parentKind: SyntaxKind): Node | undefined { for (let i = exclusiveStartPosition - 1; i >= 0; i--) { const child = children[i]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index ad1b05ed05eb7..be8af15e26d6a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4215,7 +4215,7 @@ declare namespace ts { getSourceFile(): SourceFile; getChildCount(sourceFile?: SourceFile): number; getChildAt(index: number, sourceFile?: SourceFile): Node; - getChildren(sourceFile?: SourceFile): Node[]; + getChildren(sourceFile?: SourceFile): readonly Node[]; getStart(sourceFile?: SourceFile, includeJsDocComment?: boolean): number; getFullStart(): number; getEnd(): number;