Skip to content

Commit d9d9c7f

Browse files
author
Andy Hanson
committed
createNodeArray mutates its input if not already a NodeArray
1 parent 8f23bf8 commit d9d9c7f

File tree

14 files changed

+428
-421
lines changed

14 files changed

+428
-421
lines changed

src/compiler/checker.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2811,7 +2811,7 @@ namespace ts {
28112811
entityName = nameIdentifier;
28122812
}
28132813

2814-
let typeArgumentNodes: ReadonlyArray<TypeNode> | undefined;
2814+
let typeArgumentNodes: TypeNode[] | undefined;
28152815
if (typeArguments.length > 0) {
28162816
const typeParameterCount = (type.target.typeParameters || emptyArray).length;
28172817
typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context);
@@ -3039,7 +3039,7 @@ namespace ts {
30393039
function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName {
30403040
Debug.assert(chain && 0 <= index && index < chain.length);
30413041
const symbol = chain[index];
3042-
let typeParameterNodes: ReadonlyArray<TypeNode> | undefined;
3042+
let typeParameterNodes: TypeNode[] | undefined;
30433043
if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index > 0) {
30443044
const parentSymbol = chain[index - 1];
30453045
let typeParameters: TypeParameter[];

src/compiler/factory.ts

+192-194
Large diffs are not rendered by default.

src/compiler/transformers/es2017.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ namespace ts {
259259
const declarations = endLexicalEnvironment();
260260
if (some(declarations)) {
261261
const block = convertToFunctionBody(expression);
262-
return updateBlock(block, setTextRange(createNodeArray(concatenate(block.statements, declarations)), block.statements));
262+
return updateBlock(block, concatToNodeArray(block.statements, declarations));
263263
}
264264

265265
return expression;
@@ -274,7 +274,7 @@ namespace ts {
274274
startLexicalEnvironment();
275275
const visited = convertToFunctionBody(visitNode(body, visitor, isConciseBody));
276276
const declarations = endLexicalEnvironment();
277-
return updateBlock(visited, setTextRange(createNodeArray(concatenate(visited.statements, declarations)), visited.statements));
277+
return updateBlock(visited, concatToNodeArray(visited.statements, declarations));
278278
}
279279
}
280280

src/compiler/utilities.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
/* @internal */
44
namespace ts {
5-
export const emptyArray: never[] = [] as never[];
5+
// TODO: GH#16312 Should be a ReadonlyArray<never>
6+
export const emptyArray: never[] = Object.freeze([]) as never[];
67
export const emptyMap: ReadonlyMap<never> = createMap<never>();
78

89
export const externalHelpersModuleNameText = "tslib";
@@ -2841,7 +2842,7 @@ namespace ts {
28412842
* Gets the effective type parameters. If the node was parsed in a
28422843
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
28432844
*/
2844-
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters, checkJSDoc?: boolean): ReadonlyArray<TypeParameterDeclaration> {
2845+
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters, checkJSDoc?: boolean): NodeArray<TypeParameterDeclaration> {
28452846
if (node.typeParameters) {
28462847
return node.typeParameters;
28472848
}

src/compiler/visitor.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,14 @@ namespace ts {
144144
context.startLexicalEnvironment();
145145
statements = visitNodes(statements, visitor, isStatement, start);
146146
if (ensureUseStrict && !startsWithUseStrict(statements)) {
147-
statements = setTextRange(createNodeArray([createStatement(createLiteral("use strict")), ...statements]), statements);
147+
statements = setTextRange(createNodeArray([createStatement(createLiteral("use strict")), ...statements]), statements); //don't think this call to setTextRange is necessary
148148
}
149-
const declarations = context.endLexicalEnvironment();
150-
return setTextRange(createNodeArray(concatenate(statements, declarations)), statements);
149+
return concatToNodeArray(statements, context.endLexicalEnvironment());
150+
}
151+
152+
/* @internal */
153+
export function concatToNodeArray<T extends Node>(a: NodeArray<T>, b: ReadonlyArray<T> | undefined): NodeArray<T> {
154+
return b === undefined ? a : setTextRange(createNodeArray(a.concat(b)), a);
151155
}
152156

153157
/**
@@ -1448,7 +1452,7 @@ namespace ts {
14481452
}
14491453

14501454
return isNodeArray(statements)
1451-
? setTextRange(createNodeArray(concatenate(statements, declarations)), statements)
1455+
? setTextRange(createNodeArray(statements.concat(declarations)), statements)
14521456
: addRange(statements, declarations);
14531457
}
14541458

src/harness/unittests/printer.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ namespace ts {
143143
/*decorators*/ undefined,
144144
/*modifiers*/ [createToken(SyntaxKind.DeclareKeyword)],
145145
createIdentifier("global"),
146-
createModuleBlock(emptyArray),
146+
createModuleBlock([]),
147147
NodeFlags.GlobalAugmentation),
148148
createSourceFile("source.ts", "", ScriptTarget.ES2015)
149149
));
@@ -154,7 +154,7 @@ namespace ts {
154154
/*decorators*/ undefined,
155155
/*modifiers*/ undefined,
156156
createIdentifier("global"),
157-
createModuleBlock(emptyArray),
157+
createModuleBlock([]),
158158
NodeFlags.GlobalAugmentation),
159159
createSourceFile("source.ts", "", ScriptTarget.ES2015)
160160
));

src/harness/unittests/textChanges.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ namespace M
9898
/*asteriskToken*/ undefined,
9999
/*name*/ "bar",
100100
/*typeParameters*/ undefined,
101-
/*parameters*/ emptyArray,
101+
/*parameters*/ [],
102102
/*type*/ createKeywordTypeNode(SyntaxKind.AnyKeyword),
103103
/*body */ createBlock(statements)
104104
);
@@ -110,7 +110,7 @@ namespace M
110110
createCall(
111111
/*expression*/ newFunction.name,
112112
/*typeArguments*/ undefined,
113-
/*argumentsArray*/ emptyArray
113+
/*argumentsArray*/ [],
114114
));
115115
changeTracker.replaceNodeRange(sourceFile, statements[0], lastOrUndefined(statements), newStatement, { suffix: newLineCharacter });
116116
});
@@ -346,8 +346,8 @@ namespace M {
346346
function createTestSuperCall() {
347347
const superCall = createCall(
348348
createSuper(),
349-
/*typeArguments*/ undefined,
350-
/*argumentsArray*/ emptyArray
349+
/*typeArguments*/ undefined,
350+
/*argumentsArray*/ [],
351351
);
352352
return createStatement(superCall);
353353
}

src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace ts.codefix {
1111
}
1212

1313
const changeTracker = textChanges.ChangeTracker.fromContext(context);
14-
const superCall = createStatement(createCall(createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray));
14+
const superCall = createStatement(createCall(createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ []));
1515
changeTracker.insertNodeAtConstructorStart(sourceFile, <ConstructorDeclaration>token.parent, superCall, context.newLineCharacter);
1616

1717
return [{

src/services/codefixes/helpers.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ namespace ts.codefix {
185185
return parameters;
186186
}
187187

188-
function createMethodImplementingSignatures(signatures: ReadonlyArray<Signature>, name: PropertyName, optional: boolean, modifiers: ReadonlyArray<Modifier> | undefined): MethodDeclaration {
188+
function createMethodImplementingSignatures(signatures: ReadonlyArray<Signature>, name: PropertyName, optional: boolean, modifiers: Nodes<Modifier> | undefined): MethodDeclaration {
189189
/** This is *a* signature with the maximal number of arguments,
190190
* such that if there is a "maximal" signature without rest arguments,
191191
* this is one of them.
@@ -230,11 +230,11 @@ namespace ts.codefix {
230230
}
231231

232232
export function createStubbedMethod(
233-
modifiers: ReadonlyArray<Modifier>,
233+
modifiers: Nodes<Modifier>,
234234
name: PropertyName,
235235
optional: boolean,
236-
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
237-
parameters: ReadonlyArray<ParameterDeclaration>,
236+
typeParameters: Nodes<TypeParameterDeclaration> | undefined,
237+
parameters: Nodes<ParameterDeclaration>,
238238
returnType: TypeNode | undefined) {
239239
return createMethod(
240240
/*decorators*/ undefined,

src/services/refactors/annotateWithTypeFromJSDoc.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
157157
switch (node.kind) {
158158
case SyntaxKind.JSDocAllType:
159159
case SyntaxKind.JSDocUnknownType:
160-
return createTypeReferenceNode("any", emptyArray);
160+
return createTypeReferenceNode("any", []);
161161
case SyntaxKind.JSDocOptionalType:
162162
return transformJSDocOptionalType(node as JSDocOptionalType);
163163
case SyntaxKind.JSDocNonNullableType:
@@ -180,11 +180,11 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
180180
}
181181

182182
function transformJSDocOptionalType(node: JSDocOptionalType) {
183-
return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("undefined", emptyArray)]);
183+
return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("undefined", [])]);
184184
}
185185

186186
function transformJSDocNullableType(node: JSDocNullableType) {
187-
return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("null", emptyArray)]);
187+
return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("null", [])]);
188188
}
189189

190190
function transformJSDocVariadicType(node: JSDocVariadicType) {
@@ -193,7 +193,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
193193

194194
function transformJSDocFunctionType(node: JSDocFunctionType) {
195195
const parameters = node.parameters && node.parameters.map(transformJSDocType);
196-
return createFunctionTypeNode(emptyArray, parameters as ParameterDeclaration[], node.type);
196+
return createFunctionTypeNode([], parameters as ParameterDeclaration[], node.type);
197197
}
198198

199199
function transformJSDocParameter(node: ParameterDeclaration) {
@@ -227,7 +227,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
227227
}
228228
name = createIdentifier(text);
229229
if ((text === "Array" || text === "Promise") && !node.typeArguments) {
230-
args = createNodeArray([createTypeReferenceNode("any", emptyArray)]);
230+
args = createNodeArray([createTypeReferenceNode("any", [])]);
231231
}
232232
else {
233233
args = visitNodes(node.typeArguments, transformJSDocType);

src/services/refactors/convertFunctionToEs6Class.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ namespace ts.refactor.convertFunctionToES6Class {
263263
}
264264

265265
function getModifierKindFromSource(source: Node, kind: SyntaxKind) {
266-
return filter(source.modifiers, modifier => modifier.kind === kind);
266+
return source.modifiers && source.modifiers.filter(modifier => modifier.kind === kind);
267267
}
268268
}
269269

src/services/refactors/extractSymbol.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -751,13 +751,13 @@ namespace ts.refactor.extractSymbol {
751751
const typeParametersAndDeclarations = arrayFrom(typeParameterUsages.values()).map(type => ({ type, declaration: getFirstDeclaration(type) }));
752752
const sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder);
753753

754-
const typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined = sortedTypeParametersAndDeclarations.length === 0
754+
const typeParameters = sortedTypeParametersAndDeclarations.length === 0
755755
? undefined
756756
: sortedTypeParametersAndDeclarations.map(t => t.declaration as TypeParameterDeclaration);
757757

758758
// Strictly speaking, we should check whether each name actually binds to the appropriate type
759759
// parameter. In cases of shadowing, they may not.
760-
const callTypeArguments: ReadonlyArray<TypeNode> | undefined = typeParameters !== undefined
760+
const callTypeArguments = typeParameters !== undefined
761761
? typeParameters.map(decl => createTypeReferenceNode(decl.name, /*typeArguments*/ undefined))
762762
: undefined;
763763

0 commit comments

Comments
 (0)