Skip to content

Commit 194c2bc

Browse files
author
Andy
authored
Make NodeArray readonly (#17213)
* Make NodeArray readonly * Fix bug: use emptyArray instead of undefined * Fix bug: Don't expose MutableNodeArray * Undo trailing whitespace changes
1 parent 80b19a0 commit 194c2bc

23 files changed

+446
-204
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1327,7 +1327,7 @@ namespace ts {
13271327
function bindInitializedVariableFlow(node: VariableDeclaration | ArrayBindingElement) {
13281328
const name = !isOmittedExpression(node) ? node.name : undefined;
13291329
if (isBindingPattern(name)) {
1330-
for (const child of <ArrayBindingElement[]>name.elements) {
1330+
for (const child of name.elements) {
13311331
bindInitializedVariableFlow(child);
13321332
}
13331333
}

src/compiler/checker.ts

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2670,7 +2670,7 @@ namespace ts {
26702670
entityName = nameIdentifier;
26712671
}
26722672

2673-
let typeArgumentNodes: TypeNode[] | undefined;
2673+
let typeArgumentNodes: ReadonlyArray<TypeNode> | undefined;
26742674
if (typeArguments.length > 0) {
26752675
const typeParameterCount = (type.target.typeParameters || emptyArray).length;
26762676
typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context);
@@ -2907,7 +2907,7 @@ namespace ts {
29072907
function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName {
29082908
Debug.assert(chain && 0 <= index && index < chain.length);
29092909
const symbol = chain[index];
2910-
let typeParameterNodes: TypeNode[] | undefined;
2910+
let typeParameterNodes: ReadonlyArray<TypeNode> | undefined;
29112911
if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index > 0) {
29122912
const parentSymbol = chain[index - 1];
29132913
let typeParameters: TypeParameter[];
@@ -3667,15 +3667,15 @@ namespace ts {
36673667
}
36683668
}
36693669

3670-
function buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
3670+
function buildDisplayForTypeParametersAndDelimiters(typeParameters: ReadonlyArray<TypeParameter>, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
36713671
if (typeParameters && typeParameters.length) {
36723672
writePunctuation(writer, SyntaxKind.LessThanToken);
36733673
buildDisplayForCommaSeparatedList(typeParameters, writer, p => buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack));
36743674
writePunctuation(writer, SyntaxKind.GreaterThanToken);
36753675
}
36763676
}
36773677

3678-
function buildDisplayForCommaSeparatedList<T>(list: T[], writer: SymbolWriter, action: (item: T) => void) {
3678+
function buildDisplayForCommaSeparatedList<T>(list: ReadonlyArray<T>, writer: SymbolWriter, action: (item: T) => void) {
36793679
for (let i = 0; i < list.length; i++) {
36803680
if (i > 0) {
36813681
writePunctuation(writer, SyntaxKind.CommaToken);
@@ -3685,7 +3685,7 @@ namespace ts {
36853685
}
36863686
}
36873687

3688-
function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) {
3688+
function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: ReadonlyArray<TypeParameter>, mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) {
36893689
if (typeParameters && typeParameters.length) {
36903690
writePunctuation(writer, SyntaxKind.LessThanToken);
36913691
let flags = TypeFormatFlags.InFirstTypeArgument;
@@ -4738,7 +4738,7 @@ namespace ts {
47384738
// Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set.
47394739
// The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set
47404740
// in-place and returns the same array.
4741-
function appendTypeParameters(typeParameters: TypeParameter[], declarations: TypeParameterDeclaration[]): TypeParameter[] {
4741+
function appendTypeParameters(typeParameters: TypeParameter[], declarations: ReadonlyArray<TypeParameterDeclaration>): TypeParameter[] {
47424742
for (const declaration of declarations) {
47434743
const tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration));
47444744
if (!typeParameters) {
@@ -4825,14 +4825,14 @@ namespace ts {
48254825
return getClassExtendsHeritageClauseElement(<ClassLikeDeclaration>type.symbol.valueDeclaration);
48264826
}
48274827

4828-
function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[], location: Node): Signature[] {
4828+
function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray<TypeNode>, location: Node): Signature[] {
48294829
const typeArgCount = length(typeArgumentNodes);
48304830
const isJavaScript = isInJavaScriptFile(location);
48314831
return filter(getSignaturesOfType(type, SignatureKind.Construct),
48324832
sig => (isJavaScript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= length(sig.typeParameters));
48334833
}
48344834

4835-
function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[], location: Node): Signature[] {
4835+
function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray<TypeNode>, location: Node): Signature[] {
48364836
const signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location);
48374837
const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode);
48384838
return sameMap(signatures, sig => some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments) : sig);
@@ -14906,7 +14906,7 @@ namespace ts {
1490614906
}
1490714907
}
1490814908

14909-
function getSpreadArgumentIndex(args: Expression[]): number {
14909+
function getSpreadArgumentIndex(args: ReadonlyArray<Expression>): number {
1491014910
for (let i = 0; i < args.length; i++) {
1491114911
const arg = args[i];
1491214912
if (arg && arg.kind === SyntaxKind.SpreadElement) {
@@ -14916,7 +14916,7 @@ namespace ts {
1491614916
return -1;
1491714917
}
1491814918

14919-
function hasCorrectArity(node: CallLikeExpression, args: Expression[], signature: Signature, signatureHelpTrailingComma = false) {
14919+
function hasCorrectArity(node: CallLikeExpression, args: ReadonlyArray<Expression>, signature: Signature, signatureHelpTrailingComma = false) {
1492014920
let argCount: number; // Apparent number of arguments we will have in this call
1492114921
let typeArguments: NodeArray<TypeNode>; // Type arguments (undefined if none)
1492214922
let callIsIncomplete: boolean; // In incomplete call we want to be lenient when we have too few arguments
@@ -15027,7 +15027,7 @@ namespace ts {
1502715027
return getSignatureInstantiation(signature, getInferredTypes(context));
1502815028
}
1502915029

15030-
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: Expression[], excludeArgument: boolean[], context: InferenceContext): Type[] {
15030+
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray<Expression>, excludeArgument: boolean[], context: InferenceContext): Type[] {
1503115031
// Clear out all the inference results from the last time inferTypeArguments was called on this context
1503215032
for (const inference of context.inferences) {
1503315033
// As an optimization, we don't have to clear (and later recompute) inferred types
@@ -15115,7 +15115,7 @@ namespace ts {
1511515115
return getInferredTypes(context);
1511615116
}
1511715117

15118-
function checkTypeArguments(signature: Signature, typeArgumentNodes: TypeNode[], typeArgumentTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean {
15118+
function checkTypeArguments(signature: Signature, typeArgumentNodes: ReadonlyArray<TypeNode>, typeArgumentTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean {
1511915119
const typeParameters = signature.typeParameters;
1512015120
let typeArgumentsAreAssignable = true;
1512115121
let mapper: TypeMapper;
@@ -15179,7 +15179,13 @@ namespace ts {
1517915179
return checkTypeRelatedTo(attributesType, paramType, relation, /*errorNode*/ undefined, headMessage);
1518015180
}
1518115181

15182-
function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[], reportErrors: boolean) {
15182+
function checkApplicableSignature(
15183+
node: CallLikeExpression,
15184+
args: ReadonlyArray<Expression>,
15185+
signature: Signature,
15186+
relation: Map<RelationComparisonResult>,
15187+
excludeArgument: boolean[],
15188+
reportErrors: boolean) {
1518315189
if (isJsxOpeningLikeElement(node)) {
1518415190
return checkApplicableSignatureForJsxOpeningLikeElement(<JsxOpeningLikeElement>node, signature, relation);
1518515191
}
@@ -15247,16 +15253,16 @@ namespace ts {
1524715253
* If 'node' is a Decorator, the argument list will be `undefined`, and its arguments and types
1524815254
* will be supplied from calls to `getEffectiveArgumentCount` and `getEffectiveArgumentType`.
1524915255
*/
15250-
function getEffectiveCallArguments(node: CallLikeExpression): Expression[] {
15251-
let args: Expression[];
15256+
function getEffectiveCallArguments(node: CallLikeExpression): ReadonlyArray<Expression> {
1525215257
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
1525315258
const template = (<TaggedTemplateExpression>node).template;
15254-
args = [undefined];
15259+
const args: Expression[] = [undefined];
1525515260
if (template.kind === SyntaxKind.TemplateExpression) {
1525615261
forEach((<TemplateExpression>template).templateSpans, span => {
1525715262
args.push(span.expression);
1525815263
});
1525915264
}
15265+
return args;
1526015266
}
1526115267
else if (node.kind === SyntaxKind.Decorator) {
1526215268
// For a decorator, we return undefined as we will determine
@@ -15265,13 +15271,11 @@ namespace ts {
1526515271
return undefined;
1526615272
}
1526715273
else if (isJsxOpeningLikeElement(node)) {
15268-
args = node.attributes.properties.length > 0 ? [node.attributes] : emptyArray;
15274+
return node.attributes.properties.length > 0 ? [node.attributes] : emptyArray;
1526915275
}
1527015276
else {
15271-
args = node.arguments || emptyArray;
15277+
return node.arguments || emptyArray;
1527215278
}
15273-
15274-
return args;
1527515279
}
1527615280

1527715281

@@ -15288,7 +15292,7 @@ namespace ts {
1528815292
* us to match a property decorator.
1528915293
* Otherwise, the argument count is the length of the 'args' array.
1529015294
*/
15291-
function getEffectiveArgumentCount(node: CallLikeExpression, args: Expression[], signature: Signature) {
15295+
function getEffectiveArgumentCount(node: CallLikeExpression, args: ReadonlyArray<Expression>, signature: Signature) {
1529215296
if (node.kind === SyntaxKind.Decorator) {
1529315297
switch (node.parent.kind) {
1529415298
case SyntaxKind.ClassDeclaration:
@@ -15520,7 +15524,7 @@ namespace ts {
1552015524
/**
1552115525
* Gets the effective argument expression for an argument in a call expression.
1552215526
*/
15523-
function getEffectiveArgument(node: CallLikeExpression, args: Expression[], argIndex: number) {
15527+
function getEffectiveArgument(node: CallLikeExpression, args: ReadonlyArray<Expression>, argIndex: number) {
1552415528
// For a decorator or the first argument of a tagged template expression we return undefined.
1552515529
if (node.kind === SyntaxKind.Decorator ||
1552615530
(argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression)) {
@@ -15552,7 +15556,7 @@ namespace ts {
1555215556
const isDecorator = node.kind === SyntaxKind.Decorator;
1555315557
const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
1555415558

15555-
let typeArguments: TypeNode[];
15559+
let typeArguments: ReadonlyArray<TypeNode>;
1555615560

1555715561
if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) {
1555815562
typeArguments = (<CallExpression>node).typeArguments;
@@ -17065,7 +17069,7 @@ namespace ts {
1706517069
}
1706617070

1706717071
/** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
17068-
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ObjectLiteralElementLike[]) {
17072+
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ReadonlyArray<ObjectLiteralElementLike>) {
1706917073
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
1707017074
const name = <PropertyName>(<PropertyAssignment>property).name;
1707117075
if (name.kind === SyntaxKind.ComputedPropertyName) {
@@ -18509,7 +18513,7 @@ namespace ts {
1850918513
checkDecorators(node);
1851018514
}
1851118515

18512-
function checkTypeArgumentConstraints(typeParameters: TypeParameter[], typeArgumentNodes: TypeNode[]): boolean {
18516+
function checkTypeArgumentConstraints(typeParameters: TypeParameter[], typeArgumentNodes: ReadonlyArray<TypeNode>): boolean {
1851318517
const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
1851418518
let typeArguments: Type[];
1851518519
let mapper: TypeMapper;
@@ -20955,7 +20959,7 @@ namespace ts {
2095520959
/**
2095620960
* Check each type parameter and check that type parameters have no duplicate type parameter declarations
2095720961
*/
20958-
function checkTypeParameters(typeParameterDeclarations: TypeParameterDeclaration[]) {
20962+
function checkTypeParameters(typeParameterDeclarations: ReadonlyArray<TypeParameterDeclaration>) {
2095920963
if (typeParameterDeclarations) {
2096020964
let seenDefault = false;
2096120965
for (let i = 0; i < typeParameterDeclarations.length; i++) {

src/compiler/declarationEmitter.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ namespace ts {
211211
decreaseIndent = newWriter.decreaseIndent;
212212
}
213213

214-
function writeAsynchronousModuleElements(nodes: Node[]) {
214+
function writeAsynchronousModuleElements(nodes: ReadonlyArray<Node>) {
215215
const oldWriter = writer;
216216
forEach(nodes, declaration => {
217217
let nodeToCheck: Node;
@@ -374,13 +374,13 @@ namespace ts {
374374
}
375375
}
376376

377-
function emitLines(nodes: Node[]) {
377+
function emitLines(nodes: ReadonlyArray<Node>) {
378378
for (const node of nodes) {
379379
emit(node);
380380
}
381381
}
382382

383-
function emitSeparatedList(nodes: Node[], separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
383+
function emitSeparatedList(nodes: ReadonlyArray<Node>, separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
384384
let currentWriterPos = writer.getTextPos();
385385
for (const node of nodes) {
386386
if (!canEmitFn || canEmitFn(node)) {
@@ -393,7 +393,7 @@ namespace ts {
393393
}
394394
}
395395

396-
function emitCommaList(nodes: Node[], eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
396+
function emitCommaList(nodes: ReadonlyArray<Node>, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
397397
emitSeparatedList(nodes, ", ", eachNodeEmitFn, canEmitFn);
398398
}
399399

@@ -1007,7 +1007,7 @@ namespace ts {
10071007
return node.parent.kind === SyntaxKind.MethodDeclaration && hasModifier(node.parent, ModifierFlags.Private);
10081008
}
10091009

1010-
function emitTypeParameters(typeParameters: TypeParameterDeclaration[]) {
1010+
function emitTypeParameters(typeParameters: ReadonlyArray<TypeParameterDeclaration>) {
10111011
function emitTypeParameter(node: TypeParameterDeclaration) {
10121012
increaseIndent();
10131013
emitJsDocComments(node);
@@ -1109,7 +1109,7 @@ namespace ts {
11091109
}
11101110
}
11111111

1112-
function emitHeritageClause(typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) {
1112+
function emitHeritageClause(typeReferences: ReadonlyArray<ExpressionWithTypeArguments>, isImplementsList: boolean) {
11131113
if (typeReferences) {
11141114
write(isImplementsList ? " implements " : " extends ");
11151115
emitCommaList(typeReferences, emitTypeOfTypeReference);

src/compiler/emitter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2228,7 +2228,7 @@ namespace ts {
22282228
* Emits any prologue directives at the start of a Statement list, returning the
22292229
* number of prologue directives written to the output.
22302230
*/
2231-
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean, seenPrologueDirectives?: Map<true>): number {
2231+
function emitPrologueDirectives(statements: ReadonlyArray<Node>, startWithNewLine?: boolean, seenPrologueDirectives?: Map<true>): number {
22322232
for (let i = 0; i < statements.length; i++) {
22332233
const statement = statements[i];
22342234
if (isPrologueDirective(statement)) {

0 commit comments

Comments
 (0)