From 194c2bc2ca806f5f1014113329e33207f683037c Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 18 Jul 2017 10:38:21 -0700 Subject: [PATCH] Make NodeArray readonly (#17213) * Make NodeArray readonly * Fix bug: use emptyArray instead of undefined * Fix bug: Don't expose MutableNodeArray * Undo trailing whitespace changes --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 56 +-- src/compiler/declarationEmitter.ts | 12 +- src/compiler/emitter.ts | 2 +- src/compiler/factory.ts | 438 +++++++++++++++------ src/compiler/parser.ts | 14 +- src/compiler/transformers/destructuring.ts | 2 +- src/compiler/transformers/es2015.ts | 4 +- src/compiler/transformers/esnext.ts | 2 +- src/compiler/transformers/generators.ts | 2 +- src/compiler/transformers/jsx.ts | 2 +- src/compiler/transformers/ts.ts | 20 +- src/compiler/types.ts | 5 +- src/compiler/utilities.ts | 4 +- src/compiler/visitor.ts | 12 +- src/harness/unittests/textChanges.ts | 6 +- src/services/codefixes/helpers.ts | 10 +- src/services/completions.ts | 34 +- src/services/documentHighlights.ts | 11 +- src/services/formatting/formatting.ts | 2 +- src/services/formatting/smartIndenter.ts | 4 +- src/services/goToDefinition.ts | 2 +- src/services/jsDoc.ts | 4 +- 23 files changed, 446 insertions(+), 204 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b35f7c0196d..b07812d75ed 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1327,7 +1327,7 @@ namespace ts { function bindInitializedVariableFlow(node: VariableDeclaration | ArrayBindingElement) { const name = !isOmittedExpression(node) ? node.name : undefined; if (isBindingPattern(name)) { - for (const child of name.elements) { + for (const child of name.elements) { bindInitializedVariableFlow(child); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 689893d70b5..5d01000f23b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2670,7 +2670,7 @@ namespace ts { entityName = nameIdentifier; } - let typeArgumentNodes: TypeNode[] | undefined; + let typeArgumentNodes: ReadonlyArray | undefined; if (typeArguments.length > 0) { const typeParameterCount = (type.target.typeParameters || emptyArray).length; typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context); @@ -2907,7 +2907,7 @@ namespace ts { function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { Debug.assert(chain && 0 <= index && index < chain.length); const symbol = chain[index]; - let typeParameterNodes: TypeNode[] | undefined; + let typeParameterNodes: ReadonlyArray | undefined; if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index > 0) { const parentSymbol = chain[index - 1]; let typeParameters: TypeParameter[]; @@ -3667,7 +3667,7 @@ namespace ts { } } - function buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { + function buildDisplayForTypeParametersAndDelimiters(typeParameters: ReadonlyArray, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (typeParameters && typeParameters.length) { writePunctuation(writer, SyntaxKind.LessThanToken); buildDisplayForCommaSeparatedList(typeParameters, writer, p => buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack)); @@ -3675,7 +3675,7 @@ namespace ts { } } - function buildDisplayForCommaSeparatedList(list: T[], writer: SymbolWriter, action: (item: T) => void) { + function buildDisplayForCommaSeparatedList(list: ReadonlyArray, writer: SymbolWriter, action: (item: T) => void) { for (let i = 0; i < list.length; i++) { if (i > 0) { writePunctuation(writer, SyntaxKind.CommaToken); @@ -3685,7 +3685,7 @@ namespace ts { } } - function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) { + function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: ReadonlyArray, mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) { if (typeParameters && typeParameters.length) { writePunctuation(writer, SyntaxKind.LessThanToken); let flags = TypeFormatFlags.InFirstTypeArgument; @@ -4738,7 +4738,7 @@ namespace ts { // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set. // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set // in-place and returns the same array. - function appendTypeParameters(typeParameters: TypeParameter[], declarations: TypeParameterDeclaration[]): TypeParameter[] { + function appendTypeParameters(typeParameters: TypeParameter[], declarations: ReadonlyArray): TypeParameter[] { for (const declaration of declarations) { const tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); if (!typeParameters) { @@ -4825,14 +4825,14 @@ namespace ts { return getClassExtendsHeritageClauseElement(type.symbol.valueDeclaration); } - function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[], location: Node): Signature[] { + function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray, location: Node): Signature[] { const typeArgCount = length(typeArgumentNodes); const isJavaScript = isInJavaScriptFile(location); return filter(getSignaturesOfType(type, SignatureKind.Construct), sig => (isJavaScript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= length(sig.typeParameters)); } - function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[], location: Node): Signature[] { + function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray, location: Node): Signature[] { const signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location); const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); return sameMap(signatures, sig => some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments) : sig); @@ -14906,7 +14906,7 @@ namespace ts { } } - function getSpreadArgumentIndex(args: Expression[]): number { + function getSpreadArgumentIndex(args: ReadonlyArray): number { for (let i = 0; i < args.length; i++) { const arg = args[i]; if (arg && arg.kind === SyntaxKind.SpreadElement) { @@ -14916,7 +14916,7 @@ namespace ts { return -1; } - function hasCorrectArity(node: CallLikeExpression, args: Expression[], signature: Signature, signatureHelpTrailingComma = false) { + function hasCorrectArity(node: CallLikeExpression, args: ReadonlyArray, signature: Signature, signatureHelpTrailingComma = false) { let argCount: number; // Apparent number of arguments we will have in this call let typeArguments: NodeArray; // Type arguments (undefined if none) let callIsIncomplete: boolean; // In incomplete call we want to be lenient when we have too few arguments @@ -15027,7 +15027,7 @@ namespace ts { return getSignatureInstantiation(signature, getInferredTypes(context)); } - function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: Expression[], excludeArgument: boolean[], context: InferenceContext): Type[] { + function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray, excludeArgument: boolean[], context: InferenceContext): Type[] { // Clear out all the inference results from the last time inferTypeArguments was called on this context for (const inference of context.inferences) { // As an optimization, we don't have to clear (and later recompute) inferred types @@ -15115,7 +15115,7 @@ namespace ts { return getInferredTypes(context); } - function checkTypeArguments(signature: Signature, typeArgumentNodes: TypeNode[], typeArgumentTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean { + function checkTypeArguments(signature: Signature, typeArgumentNodes: ReadonlyArray, typeArgumentTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean { const typeParameters = signature.typeParameters; let typeArgumentsAreAssignable = true; let mapper: TypeMapper; @@ -15179,7 +15179,13 @@ namespace ts { return checkTypeRelatedTo(attributesType, paramType, relation, /*errorNode*/ undefined, headMessage); } - function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map, excludeArgument: boolean[], reportErrors: boolean) { + function checkApplicableSignature( + node: CallLikeExpression, + args: ReadonlyArray, + signature: Signature, + relation: Map, + excludeArgument: boolean[], + reportErrors: boolean) { if (isJsxOpeningLikeElement(node)) { return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation); } @@ -15247,16 +15253,16 @@ namespace ts { * If 'node' is a Decorator, the argument list will be `undefined`, and its arguments and types * will be supplied from calls to `getEffectiveArgumentCount` and `getEffectiveArgumentType`. */ - function getEffectiveCallArguments(node: CallLikeExpression): Expression[] { - let args: Expression[]; + function getEffectiveCallArguments(node: CallLikeExpression): ReadonlyArray { if (node.kind === SyntaxKind.TaggedTemplateExpression) { const template = (node).template; - args = [undefined]; + const args: Expression[] = [undefined]; if (template.kind === SyntaxKind.TemplateExpression) { forEach((template).templateSpans, span => { args.push(span.expression); }); } + return args; } else if (node.kind === SyntaxKind.Decorator) { // For a decorator, we return undefined as we will determine @@ -15265,13 +15271,11 @@ namespace ts { return undefined; } else if (isJsxOpeningLikeElement(node)) { - args = node.attributes.properties.length > 0 ? [node.attributes] : emptyArray; + return node.attributes.properties.length > 0 ? [node.attributes] : emptyArray; } else { - args = node.arguments || emptyArray; + return node.arguments || emptyArray; } - - return args; } @@ -15288,7 +15292,7 @@ namespace ts { * us to match a property decorator. * Otherwise, the argument count is the length of the 'args' array. */ - function getEffectiveArgumentCount(node: CallLikeExpression, args: Expression[], signature: Signature) { + function getEffectiveArgumentCount(node: CallLikeExpression, args: ReadonlyArray, signature: Signature) { if (node.kind === SyntaxKind.Decorator) { switch (node.parent.kind) { case SyntaxKind.ClassDeclaration: @@ -15520,7 +15524,7 @@ namespace ts { /** * Gets the effective argument expression for an argument in a call expression. */ - function getEffectiveArgument(node: CallLikeExpression, args: Expression[], argIndex: number) { + function getEffectiveArgument(node: CallLikeExpression, args: ReadonlyArray, argIndex: number) { // For a decorator or the first argument of a tagged template expression we return undefined. if (node.kind === SyntaxKind.Decorator || (argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression)) { @@ -15552,7 +15556,7 @@ namespace ts { const isDecorator = node.kind === SyntaxKind.Decorator; const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node); - let typeArguments: TypeNode[]; + let typeArguments: ReadonlyArray; if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) { typeArguments = (node).typeArguments; @@ -17065,7 +17069,7 @@ namespace ts { } /** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */ - function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ObjectLiteralElementLike[]) { + function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ReadonlyArray) { if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) { const name = (property).name; if (name.kind === SyntaxKind.ComputedPropertyName) { @@ -18509,7 +18513,7 @@ namespace ts { checkDecorators(node); } - function checkTypeArgumentConstraints(typeParameters: TypeParameter[], typeArgumentNodes: TypeNode[]): boolean { + function checkTypeArgumentConstraints(typeParameters: TypeParameter[], typeArgumentNodes: ReadonlyArray): boolean { const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); let typeArguments: Type[]; let mapper: TypeMapper; @@ -20955,7 +20959,7 @@ namespace ts { /** * Check each type parameter and check that type parameters have no duplicate type parameter declarations */ - function checkTypeParameters(typeParameterDeclarations: TypeParameterDeclaration[]) { + function checkTypeParameters(typeParameterDeclarations: ReadonlyArray) { if (typeParameterDeclarations) { let seenDefault = false; for (let i = 0; i < typeParameterDeclarations.length; i++) { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 753080cc6a0..5f4b3175ca9 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -211,7 +211,7 @@ namespace ts { decreaseIndent = newWriter.decreaseIndent; } - function writeAsynchronousModuleElements(nodes: Node[]) { + function writeAsynchronousModuleElements(nodes: ReadonlyArray) { const oldWriter = writer; forEach(nodes, declaration => { let nodeToCheck: Node; @@ -374,13 +374,13 @@ namespace ts { } } - function emitLines(nodes: Node[]) { + function emitLines(nodes: ReadonlyArray) { for (const node of nodes) { emit(node); } } - function emitSeparatedList(nodes: Node[], separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) { + function emitSeparatedList(nodes: ReadonlyArray, separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) { let currentWriterPos = writer.getTextPos(); for (const node of nodes) { if (!canEmitFn || canEmitFn(node)) { @@ -393,7 +393,7 @@ namespace ts { } } - function emitCommaList(nodes: Node[], eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) { + function emitCommaList(nodes: ReadonlyArray, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) { emitSeparatedList(nodes, ", ", eachNodeEmitFn, canEmitFn); } @@ -1007,7 +1007,7 @@ namespace ts { return node.parent.kind === SyntaxKind.MethodDeclaration && hasModifier(node.parent, ModifierFlags.Private); } - function emitTypeParameters(typeParameters: TypeParameterDeclaration[]) { + function emitTypeParameters(typeParameters: ReadonlyArray) { function emitTypeParameter(node: TypeParameterDeclaration) { increaseIndent(); emitJsDocComments(node); @@ -1109,7 +1109,7 @@ namespace ts { } } - function emitHeritageClause(typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) { + function emitHeritageClause(typeReferences: ReadonlyArray, isImplementsList: boolean) { if (typeReferences) { write(isImplementsList ? " implements " : " extends "); emitCommaList(typeReferences, emitTypeOfTypeReference); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f8c3c6a12af..759fe9f0abc 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2228,7 +2228,7 @@ namespace ts { * Emits any prologue directives at the start of a Statement list, returning the * number of prologue directives written to the output. */ - function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean, seenPrologueDirectives?: Map): number { + function emitPrologueDirectives(statements: ReadonlyArray, startWithNewLine?: boolean, seenPrologueDirectives?: Map): number { for (let i = 0; i < statements.length; i++) { const statement = statements[i]; if (isPrologueDirective(statement)) { diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index c51ebe9fd58..e58f30a215f 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -21,10 +21,12 @@ namespace ts { return updated; } + /* @internal */ export function createNodeArray(elements?: T[], hasTrailingComma?: boolean): MutableNodeArray; + export function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray; /** * Make `elements` into a `NodeArray`. If `elements` is `undefined`, returns an empty `NodeArray`. */ - export function createNodeArray(elements?: T[], hasTrailingComma?: boolean): NodeArray { + export function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray { if (elements) { if (isNodeArray(elements)) { return elements; @@ -109,8 +111,8 @@ namespace ts { export function createIdentifier(text: string): Identifier; /* @internal */ - export function createIdentifier(text: string, typeArguments: TypeNode[]): Identifier; - export function createIdentifier(text: string, typeArguments?: TypeNode[]): Identifier { + export function createIdentifier(text: string, typeArguments: ReadonlyArray): Identifier; + export function createIdentifier(text: string, typeArguments?: ReadonlyArray): Identifier { const node = createSynthesizedNode(SyntaxKind.Identifier); node.text = escapeLeadingUnderscores(text); node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown; @@ -244,7 +246,14 @@ namespace ts { : node; } - export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { + export function createParameter( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + dotDotDotToken: DotDotDotToken | undefined, + name: string | BindingName, + questionToken?: QuestionToken, + type?: TypeNode, + initializer?: Expression) { const node = createSynthesizedNode(SyntaxKind.Parameter); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -256,7 +265,15 @@ namespace ts { return node; } - export function updateParameter(node: ParameterDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { + export function updateParameter( + node: ParameterDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + dotDotDotToken: DotDotDotToken | undefined, + name: string | BindingName, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.dotDotDotToken !== dotDotDotToken @@ -283,7 +300,12 @@ namespace ts { // Type Elements - export function createPropertySignature(modifiers: Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature { + export function createPropertySignature( + modifiers: ReadonlyArray | undefined, + name: PropertyName | string, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined): PropertySignature { const node = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; node.modifiers = asNodeArray(modifiers); node.name = asName(name); @@ -293,7 +315,13 @@ namespace ts { return node; } - export function updatePropertySignature(node: PropertySignature, modifiers: Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { + export function updatePropertySignature( + node: PropertySignature, + modifiers: ReadonlyArray | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined) { return node.modifiers !== modifiers || node.name !== name || node.questionToken !== questionToken @@ -303,7 +331,13 @@ namespace ts { : node; } - export function createProperty(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { + export function createProperty( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: string | PropertyName, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined) { const node = createSynthesizedNode(SyntaxKind.PropertyDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -314,7 +348,14 @@ namespace ts { return node; } - export function updateProperty(node: PropertyDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { + export function updateProperty( + node: PropertyDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: string | PropertyName, + questionToken: QuestionToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -325,7 +366,12 @@ namespace ts { : node; } - export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined) { + export function createMethodSignature( + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + name: string | PropertyName, + questionToken: QuestionToken | undefined) { const node = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature; node.name = asName(name); node.questionToken = questionToken; @@ -342,7 +388,16 @@ namespace ts { : node; } - export function createMethod(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function createMethod( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + asteriskToken: AsteriskToken | undefined, + name: string | PropertyName, + questionToken: QuestionToken | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.MethodDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -356,7 +411,17 @@ namespace ts { return node; } - export function updateMethod(node: MethodDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function updateMethod( + node: MethodDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + asteriskToken: AsteriskToken | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken @@ -370,7 +435,7 @@ namespace ts { : node; } - export function createConstructor(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], body: Block | undefined) { + export function createConstructor(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.Constructor); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -381,7 +446,12 @@ namespace ts { return node; } - export function updateConstructor(node: ConstructorDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], body: Block | undefined) { + export function updateConstructor( + node: ConstructorDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + parameters: ReadonlyArray, + body: Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.parameters !== parameters @@ -390,7 +460,13 @@ namespace ts { : node; } - export function createGetAccessor(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function createGetAccessor( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: string | PropertyName, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.GetAccessor); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -402,7 +478,14 @@ namespace ts { return node; } - export function updateGetAccessor(node: GetAccessorDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function updateGetAccessor( + node: GetAccessorDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: PropertyName, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -413,7 +496,12 @@ namespace ts { : node; } - export function createSetAccessor(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, parameters: ParameterDeclaration[], body: Block | undefined) { + export function createSetAccessor( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: string | PropertyName, + parameters: ReadonlyArray, + body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.SetAccessor); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -424,7 +512,13 @@ namespace ts { return node; } - export function updateSetAccessor(node: SetAccessorDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, parameters: ParameterDeclaration[], body: Block | undefined) { + export function updateSetAccessor( + node: SetAccessorDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: PropertyName, + parameters: ReadonlyArray, + body: Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -450,7 +544,11 @@ namespace ts { return updateSignatureDeclaration(node, typeParameters, parameters, type); } - export function createIndexSignature(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration { + export function createIndexSignature( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode): IndexSignatureDeclaration { const node = createSynthesizedNode(SyntaxKind.IndexSignature) as IndexSignatureDeclaration; node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -459,7 +557,12 @@ namespace ts { return node; } - export function updateIndexSignature(node: IndexSignatureDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode) { + export function updateIndexSignature( + node: IndexSignatureDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode) { return node.parameters !== parameters || node.type !== type || node.decorators !== decorators @@ -469,7 +572,7 @@ namespace ts { } /* @internal */ - export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined) { const node = createSynthesizedNode(kind) as SignatureDeclaration; node.typeParameters = asNodeArray(typeParameters); node.parameters = asNodeArray(parameters); @@ -505,7 +608,7 @@ namespace ts { : node; } - export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: TypeNode[] | undefined) { + export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined) { const node = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; node.typeName = asName(typeName); node.typeArguments = typeArguments && parenthesizeTypeParameters(typeArguments); @@ -547,7 +650,7 @@ namespace ts { : node; } - export function createTypeLiteralNode(members: TypeElement[]) { + export function createTypeLiteralNode(members: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.TypeLiteral) as TypeLiteralNode; node.members = createNodeArray(members); return node; @@ -571,13 +674,13 @@ namespace ts { : node; } - export function createTupleTypeNode(elementTypes: TypeNode[]) { + export function createTupleTypeNode(elementTypes: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode; node.elementTypes = createNodeArray(elementTypes); return node; } - export function updateTypleTypeNode(node: TupleTypeNode, elementTypes: TypeNode[]) { + export function updateTypleTypeNode(node: TupleTypeNode, elementTypes: ReadonlyArray) { return node.elementTypes !== elementTypes ? updateNode(createTupleTypeNode(elementTypes), node) : node; @@ -599,7 +702,7 @@ namespace ts { return updateUnionOrIntersectionTypeNode(node, types); } - export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]) { + export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: ReadonlyArray) { const node = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode; node.types = parenthesizeElementTypeMembers(types); return node; @@ -684,25 +787,25 @@ namespace ts { // Binding Patterns - export function createObjectBindingPattern(elements: BindingElement[]) { + export function createObjectBindingPattern(elements: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.ObjectBindingPattern); node.elements = createNodeArray(elements); return node; } - export function updateObjectBindingPattern(node: ObjectBindingPattern, elements: BindingElement[]) { + export function updateObjectBindingPattern(node: ObjectBindingPattern, elements: ReadonlyArray) { return node.elements !== elements ? updateNode(createObjectBindingPattern(elements), node) : node; } - export function createArrayBindingPattern(elements: ArrayBindingElement[]) { + export function createArrayBindingPattern(elements: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.ArrayBindingPattern); node.elements = createNodeArray(elements); return node; } - export function updateArrayBindingPattern(node: ArrayBindingPattern, elements: ArrayBindingElement[]) { + export function updateArrayBindingPattern(node: ArrayBindingPattern, elements: ReadonlyArray) { return node.elements !== elements ? updateNode(createArrayBindingPattern(elements), node) : node; @@ -728,27 +831,27 @@ namespace ts { // Expression - export function createArrayLiteral(elements?: Expression[], multiLine?: boolean) { + export function createArrayLiteral(elements?: ReadonlyArray, multiLine?: boolean) { const node = createSynthesizedNode(SyntaxKind.ArrayLiteralExpression); node.elements = parenthesizeListElements(createNodeArray(elements)); if (multiLine) node.multiLine = true; return node; } - export function updateArrayLiteral(node: ArrayLiteralExpression, elements: Expression[]) { + export function updateArrayLiteral(node: ArrayLiteralExpression, elements: ReadonlyArray) { return node.elements !== elements ? updateNode(createArrayLiteral(elements, node.multiLine), node) : node; } - export function createObjectLiteral(properties?: ObjectLiteralElementLike[], multiLine?: boolean) { + export function createObjectLiteral(properties?: ReadonlyArray, multiLine?: boolean) { const node = createSynthesizedNode(SyntaxKind.ObjectLiteralExpression); node.properties = createNodeArray(properties); if (multiLine) node.multiLine = true; return node; } - export function updateObjectLiteral(node: ObjectLiteralExpression, properties: ObjectLiteralElementLike[]) { + export function updateObjectLiteral(node: ObjectLiteralExpression, properties: ReadonlyArray) { return node.properties !== properties ? updateNode(createObjectLiteral(properties, node.multiLine), node) : node; @@ -785,7 +888,7 @@ namespace ts { : node; } - export function createCall(expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[]) { + export function createCall(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.CallExpression); node.expression = parenthesizeForAccess(expression); node.typeArguments = asNodeArray(typeArguments); @@ -793,7 +896,7 @@ namespace ts { return node; } - export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[]) { + export function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray) { return node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray @@ -801,7 +904,7 @@ namespace ts { : node; } - export function createNew(expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[] | undefined) { + export function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined) { const node = createSynthesizedNode(SyntaxKind.NewExpression); node.expression = parenthesizeForNew(expression); node.typeArguments = asNodeArray(typeArguments); @@ -809,7 +912,7 @@ namespace ts { return node; } - export function updateNew(node: NewExpression, expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[] | undefined) { + export function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined) { return node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray @@ -857,7 +960,14 @@ namespace ts { : node; } - export function createFunctionExpression(modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block) { + export function createFunctionExpression( + modifiers: ReadonlyArray | undefined, + asteriskToken: AsteriskToken | undefined, + name: string | Identifier | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: Block) { const node = createSynthesizedNode(SyntaxKind.FunctionExpression); node.modifiers = asNodeArray(modifiers); node.asteriskToken = asteriskToken; @@ -869,7 +979,15 @@ namespace ts { return node; } - export function updateFunctionExpression(node: FunctionExpression, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block) { + export function updateFunctionExpression( + node: FunctionExpression, + modifiers: ReadonlyArray | undefined, + asteriskToken: AsteriskToken | undefined, + name: Identifier | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: Block) { return node.name !== name || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken @@ -881,7 +999,13 @@ namespace ts { : node; } - export function createArrowFunction(modifiers: Modifier[] | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody) { + export function createArrowFunction( + modifiers: ReadonlyArray | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + equalsGreaterThanToken: EqualsGreaterThanToken | undefined, + body: ConciseBody) { const node = createSynthesizedNode(SyntaxKind.ArrowFunction); node.modifiers = asNodeArray(modifiers); node.typeParameters = asNodeArray(typeParameters); @@ -892,7 +1016,13 @@ namespace ts { return node; } - export function updateArrowFunction(node: ArrowFunction, modifiers: Modifier[] | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: ConciseBody) { + export function updateArrowFunction( + node: ArrowFunction, + modifiers: ReadonlyArray | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: ConciseBody) { return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters @@ -1013,14 +1143,14 @@ namespace ts { : node; } - export function createTemplateExpression(head: TemplateHead, templateSpans: TemplateSpan[]) { + export function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.TemplateExpression); node.head = head; node.templateSpans = createNodeArray(templateSpans); return node; } - export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: TemplateSpan[]) { + export function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray) { return node.head !== head || node.templateSpans !== templateSpans ? updateNode(createTemplateExpression(head, templateSpans), node) @@ -1055,7 +1185,12 @@ namespace ts { : node; } - export function createClassExpression(modifiers: Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) { + export function createClassExpression( + modifiers: ReadonlyArray | undefined, + name: string | Identifier | undefined, + typeParameters: ReadonlyArray | undefined, + heritageClauses: ReadonlyArray, + members: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.ClassExpression); node.decorators = undefined; node.modifiers = asNodeArray(modifiers); @@ -1066,7 +1201,13 @@ namespace ts { return node; } - export function updateClassExpression(node: ClassExpression, modifiers: Modifier[] | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) { + export function updateClassExpression( + node: ClassExpression, + modifiers: ReadonlyArray | undefined, + name: Identifier | undefined, + typeParameters: ReadonlyArray | undefined, + heritageClauses: ReadonlyArray, + members: ReadonlyArray) { return node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters @@ -1080,14 +1221,14 @@ namespace ts { return createSynthesizedNode(SyntaxKind.OmittedExpression); } - export function createExpressionWithTypeArguments(typeArguments: TypeNode[], expression: Expression) { + export function createExpressionWithTypeArguments(typeArguments: ReadonlyArray, expression: Expression) { const node = createSynthesizedNode(SyntaxKind.ExpressionWithTypeArguments); node.expression = parenthesizeForAccess(expression); node.typeArguments = asNodeArray(typeArguments); return node; } - export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: TypeNode[], expression: Expression) { + export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: ReadonlyArray, expression: Expression) { return node.typeArguments !== typeArguments || node.expression !== expression ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node) @@ -1155,20 +1296,20 @@ namespace ts { // Element - export function createBlock(statements: Statement[], multiLine?: boolean): Block { + export function createBlock(statements: ReadonlyArray, multiLine?: boolean): Block { const block = createSynthesizedNode(SyntaxKind.Block); block.statements = createNodeArray(statements); if (multiLine) block.multiLine = multiLine; return block; } - export function updateBlock(node: Block, statements: Statement[]) { + export function updateBlock(node: Block, statements: ReadonlyArray) { return node.statements !== statements ? updateNode(createBlock(statements, node.multiLine), node) : node; } - export function createVariableStatement(modifiers: Modifier[] | undefined, declarationList: VariableDeclarationList | VariableDeclaration[]) { + export function createVariableStatement(modifiers: ReadonlyArray | undefined, declarationList: VariableDeclarationList | ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.VariableStatement); node.decorators = undefined; node.modifiers = asNodeArray(modifiers); @@ -1176,7 +1317,7 @@ namespace ts { return node; } - export function updateVariableStatement(node: VariableStatement, modifiers: Modifier[] | undefined, declarationList: VariableDeclarationList) { + export function updateVariableStatement(node: VariableStatement, modifiers: ReadonlyArray | undefined, declarationList: VariableDeclarationList) { return node.modifiers !== modifiers || node.declarationList !== declarationList ? updateNode(createVariableStatement(modifiers, declarationList), node) @@ -1421,20 +1562,28 @@ namespace ts { : node; } - export function createVariableDeclarationList(declarations: VariableDeclaration[], flags?: NodeFlags) { + export function createVariableDeclarationList(declarations: ReadonlyArray, flags?: NodeFlags) { const node = createSynthesizedNode(SyntaxKind.VariableDeclarationList); node.flags |= flags & NodeFlags.BlockScoped; node.declarations = createNodeArray(declarations); return node; } - export function updateVariableDeclarationList(node: VariableDeclarationList, declarations: VariableDeclaration[]) { + export function updateVariableDeclarationList(node: VariableDeclarationList, declarations: ReadonlyArray) { return node.declarations !== declarations ? updateNode(createVariableDeclarationList(declarations, node.flags), node) : node; } - export function createFunctionDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function createFunctionDeclaration( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + asteriskToken: AsteriskToken | undefined, + name: string | Identifier | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.FunctionDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -1447,7 +1596,16 @@ namespace ts { return node; } - export function updateFunctionDeclaration(node: FunctionDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function updateFunctionDeclaration( + node: FunctionDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + asteriskToken: AsteriskToken | undefined, + name: Identifier | undefined, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + type: TypeNode | undefined, + body: Block | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken @@ -1460,7 +1618,13 @@ namespace ts { : node; } - export function createClassDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) { + export function createClassDeclaration( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: string | Identifier | undefined, + typeParameters: ReadonlyArray | undefined, + heritageClauses: ReadonlyArray, + members: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.ClassDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -1471,7 +1635,14 @@ namespace ts { return node; } - export function updateClassDeclaration(node: ClassDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) { + export function updateClassDeclaration( + node: ClassDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: Identifier | undefined, + typeParameters: ReadonlyArray | undefined, + heritageClauses: ReadonlyArray, + members: ReadonlyArray) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -1482,7 +1653,13 @@ namespace ts { : node; } - export function createInterfaceDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[] | undefined, members: TypeElement[]) { + export function createInterfaceDeclaration( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: string | Identifier, + typeParameters: ReadonlyArray | undefined, + heritageClauses: ReadonlyArray | undefined, + members: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.InterfaceDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -1493,7 +1670,14 @@ namespace ts { return node; } - export function updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[] | undefined, members: TypeElement[]) { + export function updateInterfaceDeclaration( + node: InterfaceDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: Identifier, + typeParameters: ReadonlyArray | undefined, + heritageClauses: ReadonlyArray | undefined, + members: ReadonlyArray) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -1504,7 +1688,12 @@ namespace ts { : node; } - export function createTypeAliasDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier, typeParameters: TypeParameterDeclaration[] | undefined, type: TypeNode) { + export function createTypeAliasDeclaration( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: string | Identifier, + typeParameters: ReadonlyArray | undefined, + type: TypeNode) { const node = createSynthesizedNode(SyntaxKind.TypeAliasDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -1514,7 +1703,13 @@ namespace ts { return node; } - export function updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier, typeParameters: TypeParameterDeclaration[] | undefined, type: TypeNode) { + export function updateTypeAliasDeclaration( + node: TypeAliasDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: Identifier, + typeParameters: ReadonlyArray | undefined, + type: TypeNode) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -1524,7 +1719,11 @@ namespace ts { : node; } - export function createEnumDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier, members: EnumMember[]) { + export function createEnumDeclaration( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: string | Identifier, + members: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.EnumDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -1533,7 +1732,12 @@ namespace ts { return node; } - export function updateEnumDeclaration(node: EnumDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier, members: EnumMember[]) { + export function updateEnumDeclaration( + node: EnumDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: Identifier, + members: ReadonlyArray) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -1542,7 +1746,7 @@ namespace ts { : node; } - export function createModuleDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags) { + export function createModuleDeclaration(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags) { const node = createSynthesizedNode(SyntaxKind.ModuleDeclaration); node.flags |= flags & (NodeFlags.Namespace | NodeFlags.NestedNamespace | NodeFlags.GlobalAugmentation); node.decorators = asNodeArray(decorators); @@ -1552,7 +1756,7 @@ namespace ts { return node; } - export function updateModuleDeclaration(node: ModuleDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined) { + export function updateModuleDeclaration(node: ModuleDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: ModuleName, body: ModuleBody | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -1561,25 +1765,25 @@ namespace ts { : node; } - export function createModuleBlock(statements: Statement[]) { + export function createModuleBlock(statements: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.ModuleBlock); node.statements = createNodeArray(statements); return node; } - export function updateModuleBlock(node: ModuleBlock, statements: Statement[]) { + export function updateModuleBlock(node: ModuleBlock, statements: ReadonlyArray) { return node.statements !== statements ? updateNode(createModuleBlock(statements), node) : node; } - export function createCaseBlock(clauses: CaseOrDefaultClause[]): CaseBlock { + export function createCaseBlock(clauses: ReadonlyArray): CaseBlock { const node = createSynthesizedNode(SyntaxKind.CaseBlock); node.clauses = createNodeArray(clauses); return node; } - export function updateCaseBlock(node: CaseBlock, clauses: CaseOrDefaultClause[]) { + export function updateCaseBlock(node: CaseBlock, clauses: ReadonlyArray) { return node.clauses !== clauses ? updateNode(createCaseBlock(clauses), node) : node; @@ -1597,7 +1801,7 @@ namespace ts { : node; } - export function createImportEqualsDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference) { + export function createImportEqualsDeclaration(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: string | Identifier, moduleReference: ModuleReference) { const node = createSynthesizedNode(SyntaxKind.ImportEqualsDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -1606,7 +1810,7 @@ namespace ts { return node; } - export function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference) { + export function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, name: Identifier, moduleReference: ModuleReference) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name @@ -1615,7 +1819,11 @@ namespace ts { : node; } - export function createImportDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier?: Expression): ImportDeclaration { + export function createImportDeclaration( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + importClause: ImportClause | undefined, + moduleSpecifier?: Expression): ImportDeclaration { const node = createSynthesizedNode(SyntaxKind.ImportDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -1624,7 +1832,12 @@ namespace ts { return node; } - export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression | undefined) { + export function updateImportDeclaration( + node: ImportDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + importClause: ImportClause | undefined, + moduleSpecifier: Expression | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.importClause !== importClause @@ -1659,13 +1872,13 @@ namespace ts { : node; } - export function createNamedImports(elements: ImportSpecifier[]): NamedImports { + export function createNamedImports(elements: ReadonlyArray): NamedImports { const node = createSynthesizedNode(SyntaxKind.NamedImports); node.elements = createNodeArray(elements); return node; } - export function updateNamedImports(node: NamedImports, elements: ImportSpecifier[]) { + export function updateNamedImports(node: NamedImports, elements: ReadonlyArray) { return node.elements !== elements ? updateNode(createNamedImports(elements), node) : node; @@ -1685,7 +1898,7 @@ namespace ts { : node; } - export function createExportAssignment(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, isExportEquals: boolean, expression: Expression) { + export function createExportAssignment(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, isExportEquals: boolean, expression: Expression) { const node = createSynthesizedNode(SyntaxKind.ExportAssignment); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -1694,7 +1907,7 @@ namespace ts { return node; } - export function updateExportAssignment(node: ExportAssignment, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, expression: Expression) { + export function updateExportAssignment(node: ExportAssignment, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, expression: Expression) { return node.decorators !== decorators || node.modifiers !== modifiers || node.expression !== expression @@ -1702,7 +1915,7 @@ namespace ts { : node; } - export function createExportDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, exportClause: NamedExports | undefined, moduleSpecifier?: Expression) { + export function createExportDeclaration(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, exportClause: NamedExports | undefined, moduleSpecifier?: Expression) { const node = createSynthesizedNode(SyntaxKind.ExportDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -1711,7 +1924,12 @@ namespace ts { return node; } - export function updateExportDeclaration(node: ExportDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, exportClause: NamedExports | undefined, moduleSpecifier: Expression | undefined) { + export function updateExportDeclaration( + node: ExportDeclaration, + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + exportClause: NamedExports | undefined, + moduleSpecifier: Expression | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers || node.exportClause !== exportClause @@ -1720,13 +1938,13 @@ namespace ts { : node; } - export function createNamedExports(elements: ExportSpecifier[]) { + export function createNamedExports(elements: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.NamedExports); node.elements = createNodeArray(elements); return node; } - export function updateNamedExports(node: NamedExports, elements: ExportSpecifier[]) { + export function updateNamedExports(node: NamedExports, elements: ReadonlyArray) { return node.elements !== elements ? updateNode(createNamedExports(elements), node) : node; @@ -1762,7 +1980,7 @@ namespace ts { // JSX - export function createJsxElement(openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement) { + export function createJsxElement(openingElement: JsxOpeningElement, children: ReadonlyArray, closingElement: JsxClosingElement) { const node = createSynthesizedNode(SyntaxKind.JsxElement); node.openingElement = openingElement; node.children = createNodeArray(children); @@ -1770,7 +1988,7 @@ namespace ts { return node; } - export function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement) { + export function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: ReadonlyArray, closingElement: JsxClosingElement) { return node.openingElement !== openingElement || node.children !== children || node.closingElement !== closingElement @@ -1832,13 +2050,13 @@ namespace ts { : node; } - export function createJsxAttributes(properties: JsxAttributeLike[]) { + export function createJsxAttributes(properties: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.JsxAttributes); node.properties = createNodeArray(properties); return node; } - export function updateJsxAttributes(node: JsxAttributes, properties: JsxAttributeLike[]) { + export function updateJsxAttributes(node: JsxAttributes, properties: ReadonlyArray) { return node.properties !== properties ? updateNode(createJsxAttributes(properties), node) : node; @@ -1871,40 +2089,40 @@ namespace ts { // Clauses - export function createCaseClause(expression: Expression, statements: Statement[]) { + export function createCaseClause(expression: Expression, statements: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.CaseClause); node.expression = parenthesizeExpressionForList(expression); node.statements = createNodeArray(statements); return node; } - export function updateCaseClause(node: CaseClause, expression: Expression, statements: Statement[]) { + export function updateCaseClause(node: CaseClause, expression: Expression, statements: ReadonlyArray) { return node.expression !== expression || node.statements !== statements ? updateNode(createCaseClause(expression, statements), node) : node; } - export function createDefaultClause(statements: Statement[]) { + export function createDefaultClause(statements: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.DefaultClause); node.statements = createNodeArray(statements); return node; } - export function updateDefaultClause(node: DefaultClause, statements: Statement[]) { + export function updateDefaultClause(node: DefaultClause, statements: ReadonlyArray) { return node.statements !== statements ? updateNode(createDefaultClause(statements), node) : node; } - export function createHeritageClause(token: HeritageClause["token"], types: ExpressionWithTypeArguments[]) { + export function createHeritageClause(token: HeritageClause["token"], types: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.HeritageClause); node.token = token; node.types = createNodeArray(types); return node; } - export function updateHeritageClause(node: HeritageClause, types: ExpressionWithTypeArguments[]) { + export function updateHeritageClause(node: HeritageClause, types: ReadonlyArray) { return node.types !== types ? updateNode(createHeritageClause(node.token, types), node) : node; @@ -1985,7 +2203,7 @@ namespace ts { // Top-level nodes - export function updateSourceFileNode(node: SourceFile, statements: Statement[]) { + export function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray) { if (node.statements !== statements) { const updated = createSynthesizedNode(SyntaxKind.SourceFile); updated.flags |= node.flags; @@ -2097,7 +2315,7 @@ namespace ts { return node; } - function flattenCommaElements(node: Expression): Expression | Expression[] { + function flattenCommaElements(node: Expression): Expression | ReadonlyArray { if (nodeIsSynthesized(node) && !isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) { if (node.kind === SyntaxKind.CommaListExpression) { return (node).elements; @@ -2109,13 +2327,13 @@ namespace ts { return node; } - export function createCommaList(elements: Expression[]) { + export function createCommaList(elements: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.CommaListExpression); node.elements = createNodeArray(sameFlatMap(elements, flattenCommaElements)); return node; } - export function updateCommaList(node: CommaListExpression, elements: Expression[]) { + export function updateCommaList(node: CommaListExpression, elements: ReadonlyArray) { return node.elements !== elements ? updateNode(createCommaList(elements), node) : node; @@ -2227,7 +2445,7 @@ namespace ts { return typeof value === "string" || typeof value === "number" ? createLiteral(value) : value; } - function asNodeArray(array: T[] | undefined): NodeArray | undefined { + function asNodeArray(array: ReadonlyArray | undefined): NodeArray | undefined { return array ? createNodeArray(array) : undefined; } @@ -2575,7 +2793,7 @@ namespace ts { } } - export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: Expression[], location?: TextRange) { + export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: ReadonlyArray, location?: TextRange) { return setTextRange( createCall( createPropertyAccess(func, "call"), @@ -3273,7 +3491,7 @@ namespace ts { * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives * @param visitor: Optional callback used to visit any custom prologue directives. */ - export function addPrologue(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number { + export function addPrologue(target: Statement[], source: ReadonlyArray, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number { const offset = addStandardPrologue(target, source, ensureUseStrict); return addCustomPrologue(target, source, offset, visitor); } @@ -3284,7 +3502,7 @@ namespace ts { * This function needs to be called whenever we transform the statement * list of a source file, namespace, or function-like body. */ - export function addStandardPrologue(target: Statement[], source: Statement[], ensureUseStrict?: boolean): number { + export function addStandardPrologue(target: Statement[], source: ReadonlyArray, ensureUseStrict?: boolean): number { Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array"); let foundUseStrict = false; let statementOffset = 0; @@ -3314,7 +3532,7 @@ namespace ts { * This function needs to be called whenever we transform the statement * list of a source file, namespace, or function-like body. */ - export function addCustomPrologue(target: Statement[], source: Statement[], statementOffset: number, visitor?: (node: Node) => VisitResult): number { + export function addCustomPrologue(target: Statement[], source: ReadonlyArray, statementOffset: number, visitor?: (node: Node) => VisitResult): number { const numStatements = source.length; while (statementOffset < numStatements) { const statement = source[statementOffset]; @@ -3329,7 +3547,7 @@ namespace ts { return statementOffset; } - export function startsWithUseStrict(statements: Statement[]) { + export function startsWithUseStrict(statements: ReadonlyArray) { const firstStatement = firstOrUndefined(statements); return firstStatement !== undefined && isPrologueDirective(firstStatement) @@ -3680,21 +3898,21 @@ namespace ts { return member; } - export function parenthesizeElementTypeMembers(members: TypeNode[]) { + export function parenthesizeElementTypeMembers(members: ReadonlyArray) { return createNodeArray(sameMap(members, parenthesizeElementTypeMember)); } - export function parenthesizeTypeParameters(typeParameters: TypeNode[]) { + export function parenthesizeTypeParameters(typeParameters: ReadonlyArray) { if (some(typeParameters)) { - const nodeArray = createNodeArray() as NodeArray; + const params: TypeNode[] = []; for (let i = 0; i < typeParameters.length; ++i) { const entry = typeParameters[i]; - nodeArray.push(i === 0 && isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ? + params.push(i === 0 && isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ? createParenthesizedType(entry) : entry); } - return nodeArray; + return createNodeArray(params); } } @@ -4122,18 +4340,18 @@ namespace ts { /** * Gets the elements of a BindingOrAssignmentPattern */ - export function getElementsOfBindingOrAssignmentPattern(name: BindingOrAssignmentPattern): BindingOrAssignmentElement[] { + export function getElementsOfBindingOrAssignmentPattern(name: BindingOrAssignmentPattern): ReadonlyArray { switch (name.kind) { case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ArrayLiteralExpression: // `a` in `{a}` // `a` in `[a]` - return name.elements; + return >name.elements; case SyntaxKind.ObjectLiteralExpression: // `a` in `{a}` - return name.properties; + return >name.properties; } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4613f49a749..0be7734968f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1121,8 +1121,8 @@ namespace ts { new TokenConstructor(kind, pos, pos); } - function createNodeArray(elements?: T[], pos?: number): NodeArray { - const array = >(elements || []); + function createNodeArray(elements?: T[], pos?: number): MutableNodeArray { + const array = >(elements || []); if (!(pos >= 0)) { pos = getNodePos(); } @@ -5395,7 +5395,7 @@ namespace ts { } function parseDecorators(): NodeArray { - let decorators: NodeArray; + let decorators: NodeArray & Decorator[]; while (true) { const decoratorStart = getNodePos(); if (!parseOptional(SyntaxKind.AtToken)) { @@ -5426,7 +5426,7 @@ namespace ts { * In such situations, 'permitInvalidConstAsModifier' should be set to true. */ function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray | undefined { - let modifiers: NodeArray | undefined; + let modifiers: MutableNodeArray | undefined; while (true) { const modifierStart = scanner.getStartPos(); const modifierKind = token(); @@ -6165,7 +6165,7 @@ namespace ts { Debug.assert(start <= end); Debug.assert(end <= content.length); - let tags: NodeArray; + let tags: MutableNodeArray; const comments: string[] = []; let result: JSDoc; @@ -6673,9 +6673,9 @@ namespace ts { const propertyTag = parseParameterOrPropertyTag(atToken, tagName, /*shouldParseParamTag*/ false) as JSDocPropertyTag; if (propertyTag) { if (!parentTag.jsDocPropertyTags) { - parentTag.jsDocPropertyTags = >[]; + parentTag.jsDocPropertyTags = >[]; } - parentTag.jsDocPropertyTags.push(propertyTag); + (parentTag.jsDocPropertyTags as MutableNodeArray).push(propertyTag); return true; } // Error parsing property tag diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index eca28ee814b..1f9b179dabb 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -492,7 +492,7 @@ namespace ts { /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);` */ - function createRestCall(context: TransformationContext, value: Expression, elements: BindingOrAssignmentElement[], computedTempVariables: Expression[], location: TextRange): Expression { + function createRestCall(context: TransformationContext, value: Expression, elements: ReadonlyArray, computedTempVariables: ReadonlyArray, location: TextRange): Expression { context.requestEmitHelper(restHelper); const propertyNames: Expression[] = []; let computedTempVariableOffset = 0; diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 19f9d00c656..823b133a4cc 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1963,7 +1963,7 @@ namespace ts { updated, setTextRange( createNodeArray( - prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true) + prependCaptureNewTargetIfNeeded(updated.statements as MutableNodeArray, node, /*copyOnWrite*/ true) ), /*location*/ updated.statements ) @@ -3199,7 +3199,7 @@ namespace ts { function addStatementToStartOfBlock(block: Block, statement: Statement): Block { const transformedStatements = visitNodes(block.statements, visitor, isStatement); - return updateBlock(block, [statement].concat(transformedStatements)); + return updateBlock(block, [statement, ...transformedStatements]); } /** diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 0b332c237f7..732a613f1b4 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -156,7 +156,7 @@ namespace ts { return visitEachChild(node, visitor, context); } - function chunkObjectLiteralElements(elements: ObjectLiteralElement[]): Expression[] { + function chunkObjectLiteralElements(elements: ReadonlyArray): Expression[] { let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[]; const objects: Expression[] = []; for (const e of elements) { diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index a12a34c9537..b120f5c8227 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -1176,7 +1176,7 @@ namespace ts { return visitEachChild(node, visitor, context); } - function transformAndEmitStatements(statements: Statement[], start = 0) { + function transformAndEmitStatements(statements: ReadonlyArray, start = 0) { const numStatements = statements.length; for (let i = start; i < numStatements; i++) { transformAndEmitStatement(statements[i]); diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index ca22cb701d0..efdf38009e0 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -77,7 +77,7 @@ namespace ts { return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node); } - function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[], isChild: boolean, location: TextRange) { + function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: ReadonlyArray, isChild: boolean, location: TextRange) { const tagName = getTagName(node); let objectProperties: Expression; const attrs = node.attributes.properties; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 5fd1b7b62da..4c20807fa86 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -522,7 +522,7 @@ namespace ts { return parameter.decorators !== undefined && parameter.decorators.length > 0; } - function getClassFacts(node: ClassDeclaration, staticProperties: PropertyDeclaration[]) { + function getClassFacts(node: ClassDeclaration, staticProperties: ReadonlyArray) { let facts = ClassFacts.None; if (some(staticProperties)) facts |= ClassFacts.HasStaticInitializedProperties; if (getClassExtendsHeritageClauseElement(node)) facts |= ClassFacts.HasExtendsClause; @@ -1051,7 +1051,7 @@ namespace ts { * * @param node The constructor node. */ - function getParametersWithPropertyAssignments(node: ConstructorDeclaration): ParameterDeclaration[] { + function getParametersWithPropertyAssignments(node: ConstructorDeclaration): ReadonlyArray { return filter(node.parameters, isParameterWithPropertyAssignment); } @@ -1104,7 +1104,7 @@ namespace ts { * @param node The class node. * @param isStatic A value indicating whether to get properties from the static or instance side of the class. */ - function getInitializedProperties(node: ClassExpression | ClassDeclaration, isStatic: boolean): PropertyDeclaration[] { + function getInitializedProperties(node: ClassExpression | ClassDeclaration, isStatic: boolean): ReadonlyArray { return filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty); } @@ -1144,7 +1144,7 @@ namespace ts { * @param properties An array of property declarations to transform. * @param receiver The receiver on which each property should be assigned. */ - function addInitializedPropertyStatements(statements: Statement[], properties: PropertyDeclaration[], receiver: LeftHandSideExpression) { + function addInitializedPropertyStatements(statements: Statement[], properties: ReadonlyArray, receiver: LeftHandSideExpression) { for (const property of properties) { const statement = createStatement(transformInitializedProperty(property, receiver)); setSourceMapRange(statement, moveRangePastModifiers(property)); @@ -1159,7 +1159,7 @@ namespace ts { * @param properties An array of property declarations to transform. * @param receiver The receiver on which each property should be assigned. */ - function generateInitializedPropertyExpressions(properties: PropertyDeclaration[], receiver: LeftHandSideExpression) { + function generateInitializedPropertyExpressions(properties: ReadonlyArray, receiver: LeftHandSideExpression) { const expressions: Expression[] = []; for (const property of properties) { const expression = transformInitializedProperty(property, receiver); @@ -1194,7 +1194,7 @@ namespace ts { * @param isStatic A value indicating whether to retrieve static or instance members of * the class. */ - function getDecoratedClassElements(node: ClassExpression | ClassDeclaration, isStatic: boolean): ClassElement[] { + function getDecoratedClassElements(node: ClassExpression | ClassDeclaration, isStatic: boolean): ReadonlyArray { return filter(node.members, isStatic ? isStaticDecoratedClassElement : isInstanceDecoratedClassElement); } @@ -1233,8 +1233,8 @@ namespace ts { * A structure describing the decorators for a class element. */ interface AllDecorators { - decorators: Decorator[]; - parameters?: Decorator[][]; + decorators: ReadonlyArray; + parameters?: ReadonlyArray>; } /** @@ -1244,7 +1244,7 @@ namespace ts { * @param node The function-like node. */ function getDecoratorsOfParameters(node: FunctionLikeDeclaration) { - let decorators: Decorator[][]; + let decorators: ReadonlyArray[]; if (node) { const parameters = node.parameters; for (let i = 0; i < parameters.length; i++) { @@ -1377,7 +1377,7 @@ namespace ts { const decoratorExpressions: Expression[] = []; addRange(decoratorExpressions, map(allDecorators.decorators, transformDecorator)); - addRange(decoratorExpressions, flatMap(allDecorators.parameters, transformDecoratorsOfParameter)); + addRange(decoratorExpressions, flatMap(allDecorators.parameters, transformDecoratorsOfParameter)); addTypeMetadata(node, container, decoratorExpressions); return decoratorExpressions; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9aa6c07816e..f1f79e57d94 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -523,7 +523,10 @@ namespace ts { /* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type } - export interface NodeArray extends Array, TextRange { + /* @internal */ + export type MutableNodeArray = NodeArray & T[]; + + export interface NodeArray extends ReadonlyArray, TextRange { hasTrailingComma?: boolean; /* @internal */ transformFlags?: TransformFlags; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a84e8eb8538..e001ec43f62 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2731,7 +2731,7 @@ namespace ts { * Gets the effective type parameters. If the node was parsed in a * JavaScript file, gets the type parameters from the `@template` tag from JSDoc. */ - export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): TypeParameterDeclaration[] { + export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray { if (node.typeParameters) { return node.typeParameters; } @@ -4739,7 +4739,7 @@ namespace ts { // Node Arrays /* @internal */ - export function isNodeArray(array: T[]): array is NodeArray { + export function isNodeArray(array: ReadonlyArray): array is NodeArray { return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 4dbfbf72e9f..1ce42199372 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -86,7 +86,7 @@ namespace ts { return nodes; } - let updated: NodeArray; + let updated: MutableNodeArray; // Ensure start and count have valid values const length = nodes.length; @@ -901,7 +901,7 @@ namespace ts { * * @param nodes The NodeArray. */ - function extractSingleNode(nodes: Node[]): Node { + function extractSingleNode(nodes: ReadonlyArray): Node { Debug.assert(nodes.length <= 1, "Too many nodes written to output."); return singleOrUndefined(nodes); } @@ -1421,13 +1421,13 @@ namespace ts { /** * Merges generated lexical declarations into a new statement list. */ - export function mergeLexicalEnvironment(statements: NodeArray, declarations: Statement[]): NodeArray; + export function mergeLexicalEnvironment(statements: NodeArray, declarations: ReadonlyArray): NodeArray; /** * Appends generated lexical declarations to an array of statements. */ - export function mergeLexicalEnvironment(statements: Statement[], declarations: Statement[]): Statement[]; - export function mergeLexicalEnvironment(statements: Statement[], declarations: Statement[]) { + export function mergeLexicalEnvironment(statements: Statement[], declarations: ReadonlyArray): Statement[]; + export function mergeLexicalEnvironment(statements: Statement[] | NodeArray, declarations: ReadonlyArray) { if (!some(declarations)) { return statements; } @@ -1442,7 +1442,7 @@ namespace ts { * * @param nodes The NodeArray. */ - export function liftToBlock(nodes: Node[]): Statement { + export function liftToBlock(nodes: ReadonlyArray): Statement { Debug.assert(every(nodes, isStatement), "Cannot lift nodes to a Block."); return singleOrUndefined(nodes) || createBlock(>nodes); } diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts index 8ac74668023..3c9ebff68f9 100644 --- a/src/harness/unittests/textChanges.ts +++ b/src/harness/unittests/textChanges.ts @@ -67,12 +67,12 @@ namespace ts { } function flattenNodes(n: Node) { - const data: (Node | NodeArray)[] = []; + const data: (Node | NodeArray)[] = []; walk(n); return data; - function walk(n: Node | Node[]): void { - data.push(n); + function walk(n: Node | NodeArray): void { + data.push(n); return isArray(n) ? forEach(n, walk) : forEachChild(n, walk, walk); } } diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index b45d2448a0a..d1599dc4cac 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -186,7 +186,7 @@ namespace ts.codefix { return parameters; } - function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, optional: boolean, modifiers: Modifier[] | undefined): MethodDeclaration { + function createMethodImplementingSignatures(signatures: ReadonlyArray, name: PropertyName, optional: boolean, modifiers: ReadonlyArray | undefined): MethodDeclaration { /** This is *a* signature with the maximal number of arguments, * such that if there is a "maximal" signature without rest arguments, * this is one of them. @@ -231,7 +231,13 @@ namespace ts.codefix { /*returnType*/ undefined); } - export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, optional: boolean, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { + export function createStubbedMethod( + modifiers: ReadonlyArray, + name: PropertyName, + optional: boolean, + typeParameters: ReadonlyArray | undefined, + parameters: ReadonlyArray, + returnType: TypeNode | undefined) { return createMethod( /*decorators*/ undefined, modifiers, diff --git a/src/services/completions.ts b/src/services/completions.ts index 12796a9b791..d7f0701caf2 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -963,7 +963,7 @@ namespace ts.Completions { isMemberCompletion = true; let typeMembers: Symbol[]; - let existingMembers: Declaration[]; + let existingMembers: ReadonlyArray; if (objectLikeContainer.kind === SyntaxKind.ObjectLiteralExpression) { // We are completing on contextual types, but may also include properties @@ -1093,14 +1093,14 @@ namespace ts.Completions { } } const implementedInterfaceTypePropertySymbols = (classElementModifierFlags & ModifierFlags.Static) ? - undefined : - flatMap(implementsTypeNodes, typeNode => typeChecker.getPropertiesOfType(typeChecker.getTypeAtLocation(typeNode))); + emptyArray : + flatMap(implementsTypeNodes || emptyArray, typeNode => typeChecker.getPropertiesOfType(typeChecker.getTypeAtLocation(typeNode))); // List of property symbols of base type that are not private and already implemented symbols = filterClassMembersList( baseClassTypeToGetPropertiesFrom ? typeChecker.getPropertiesOfType(baseClassTypeToGetPropertiesFrom) : - undefined, + emptyArray, implementedInterfaceTypePropertySymbols, classLikeDeclaration.members, classElementModifierFlags); @@ -1443,7 +1443,7 @@ namespace ts.Completions { * @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports * do not occur at the current position and have not otherwise been typed. */ - function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] { + function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ReadonlyArray): Symbol[] { const existingImportsOrExports = createUnderscoreEscapedMap(); for (const element of namedImportsOrExports) { @@ -1469,7 +1469,7 @@ namespace ts.Completions { * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations * do not occur at the current position and have not otherwise been typed. */ - function filterObjectMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] { + function filterObjectMembersList(contextualMemberSymbols: Symbol[], existingMembers: ReadonlyArray): Symbol[] { if (!existingMembers || existingMembers.length === 0) { return contextualMemberSymbols; } @@ -1518,7 +1518,11 @@ namespace ts.Completions { * * @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags */ - function filterClassMembersList(baseSymbols: Symbol[], implementingTypeSymbols: Symbol[], existingMembers: ClassElement[], currentClassElementModifierFlags: ModifierFlags): Symbol[] { + function filterClassMembersList( + baseSymbols: ReadonlyArray, + implementingTypeSymbols: ReadonlyArray, + existingMembers: ReadonlyArray, + currentClassElementModifierFlags: ModifierFlags): Symbol[] { const existingMemberNames = createUnderscoreEscapedMap(); for (const m of existingMembers) { // Ignore omitted expressions for missing members @@ -1553,10 +1557,18 @@ namespace ts.Completions { } } - return concatenate( - filter(baseSymbols, baseProperty => isValidProperty(baseProperty, ModifierFlags.Private)), - filter(implementingTypeSymbols, implementingProperty => isValidProperty(implementingProperty, ModifierFlags.NonPublicAccessibilityModifier)) - ); + const result: Symbol[] = []; + addPropertySymbols(baseSymbols, ModifierFlags.Private); + addPropertySymbols(implementingTypeSymbols, ModifierFlags.NonPublicAccessibilityModifier); + return result; + + function addPropertySymbols(properties: ReadonlyArray, inValidModifierFlags: ModifierFlags) { + for (const property of properties) { + if (isValidProperty(property, inValidModifierFlags)) { + result.push(property); + } + } + } function isValidProperty(propertySymbol: Symbol, inValidModifierFlags: ModifierFlags) { return !existingMemberNames.get(propertySymbol.name) && diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 0a2c8e726fc..eb1e2531143 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -298,21 +298,20 @@ namespace ts.DocumentHighlights { const keywords: Node[] = []; const modifierFlag: ModifierFlags = getFlagFromModifier(modifier); - let nodes: Node[]; + let nodes: ReadonlyArray; switch (container.kind) { case SyntaxKind.ModuleBlock: case SyntaxKind.SourceFile: // Container is either a class declaration or the declaration is a classDeclaration if (modifierFlag & ModifierFlags.Abstract) { - nodes = ((declaration).members).concat(declaration); + nodes = [...(declaration).members, declaration]; } else { nodes = (container).statements; } break; case SyntaxKind.Constructor: - nodes = ((container).parameters).concat( - (container.parent).members); + nodes = [...(container).parameters, ...(container.parent).members]; break; case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: @@ -326,11 +325,11 @@ namespace ts.DocumentHighlights { }); if (constructor) { - nodes = nodes.concat(constructor.parameters); + nodes = [...nodes, ...constructor.parameters]; } } else if (modifierFlag & ModifierFlags.Abstract) { - nodes = nodes.concat(container); + nodes = [...nodes, container]; } break; default: diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index b5ba809ec7d..ad9b2f179aa 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -1152,7 +1152,7 @@ namespace ts.formatting { } } - function getOpenTokenForList(node: Node, list: Node[]) { + function getOpenTokenForList(node: Node, list: ReadonlyArray) { switch (node.kind) { case SyntaxKind.Constructor: case SyntaxKind.FunctionDeclaration: diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 18b0479c85a..a98986472f3 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -328,7 +328,7 @@ namespace ts.formatting { const containingList = getContainingList(node, sourceFile); return containingList ? getActualIndentationFromList(containingList) : Value.Unknown; - function getActualIndentationFromList(list: Node[]): number { + function getActualIndentationFromList(list: ReadonlyArray): number { const index = indexOf(list, node); return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : Value.Unknown; } @@ -378,7 +378,7 @@ namespace ts.formatting { } } - function deriveActualIndentationFromList(list: Node[], index: number, sourceFile: SourceFile, options: EditorSettings): number { + function deriveActualIndentationFromList(list: ReadonlyArray, index: number, sourceFile: SourceFile, options: EditorSettings): number { Debug.assert(index >= 0 && index < list.length); const node = list[index]; diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 0bed84a393b..b388a8551d2 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -191,7 +191,7 @@ namespace ts.GoToDefinition { return false; } - function tryAddSignature(signatureDeclarations: Declaration[] | undefined, selectConstructors: boolean, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) { + function tryAddSignature(signatureDeclarations: ReadonlyArray | undefined, selectConstructors: boolean, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) { if (!signatureDeclarations) { return false; } diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index c5e437f20fc..070b96101e2 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -241,7 +241,7 @@ namespace ts.JsDoc { return { newText: result, caretOffset: preamble.length }; } - function getParametersForJsDocOwningNode(commentOwner: Node): ParameterDeclaration[] { + function getParametersForJsDocOwningNode(commentOwner: Node): ReadonlyArray { if (isFunctionLike(commentOwner)) { return commentOwner.parameters; } @@ -266,7 +266,7 @@ namespace ts.JsDoc { * @param rightHandSide the expression which may contain an appropriate set of parameters * @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'. */ - function getParametersFromRightHandSideOfAssignment(rightHandSide: Expression): ParameterDeclaration[] { + function getParametersFromRightHandSideOfAssignment(rightHandSide: Expression): ReadonlyArray { while (rightHandSide.kind === SyntaxKind.ParenthesizedExpression) { rightHandSide = (rightHandSide).expression; }