diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 469ecf80c84..04766f22c4e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3182,7 +3182,7 @@ module ts { function getRestTypeOfSignature(signature: Signature): Type { if (signature.hasRestParameter) { - let type = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); + let type = getTypeOfSymbol(lastOrUndefined(signature.parameters)); if (type.flags & TypeFlags.Reference && (type).target === globalArrayType) { return (type).typeArguments[0]; } @@ -5666,7 +5666,7 @@ module ts { // If last parameter is contextually rest parameter get its type if (indexOfParameter === (func.parameters.length - 1) && funcHasRestParameters && contextualSignature.hasRestParameter && func.parameters.length >= contextualSignature.parameters.length) { - return getTypeOfSymbol(contextualSignature.parameters[contextualSignature.parameters.length - 1]); + return getTypeOfSymbol(lastOrUndefined(contextualSignature.parameters)); } } } @@ -7215,9 +7215,9 @@ module ts { links.type = instantiateType(getTypeAtPosition(context, i), mapper); } if (signature.hasRestParameter && context.hasRestParameter && signature.parameters.length >= context.parameters.length) { - let parameter = signature.parameters[signature.parameters.length - 1]; + let parameter = lastOrUndefined(signature.parameters); let links = getSymbolLinks(parameter); - links.type = instantiateType(getTypeOfSymbol(context.parameters[context.parameters.length - 1]), mapper); + links.type = instantiateType(getTypeOfSymbol(lastOrUndefined(context.parameters)), mapper); } } @@ -12829,7 +12829,7 @@ module ts { function checkGrammarBindingElement(node: BindingElement) { if (node.dotDotDotToken) { let elements = (node.parent).elements; - if (node !== elements[elements.length - 1]) { + if (node !== lastOrUndefined(elements)) { return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_an_array_destructuring_pattern); } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 6383108b0d6..9b987ba77c6 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -470,7 +470,7 @@ module ts { let normalized: string[] = []; for (let part of parts) { if (part !== ".") { - if (part === ".." && normalized.length > 0 && normalized[normalized.length - 1] !== "..") { + if (part === ".." && normalized.length > 0 && lastOrUndefined(normalized) !== "..") { normalized.pop(); } else { @@ -586,7 +586,7 @@ module ts { export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, getCanonicalFileName: (fileName: string) => string, isAbsolutePathAnUrl: boolean) { let pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory); let directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory); - if (directoryComponents.length > 1 && directoryComponents[directoryComponents.length - 1] === "") { + if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") { // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name // that is ["test", "cases", ""] needs to be actually ["test", "cases"] directoryComponents.length--; diff --git a/src/compiler/emitter.js b/src/compiler/emitter.js index 9a6b96640c9..a00f3a4dde3 100644 --- a/src/compiler/emitter.js +++ b/src/compiler/emitter.js @@ -267,7 +267,7 @@ var ts; var sourceMapNameIndexMap = {}; var sourceMapNameIndices = []; function getSourceMapNameIndex() { - return sourceMapNameIndices.length ? sourceMapNameIndices[sourceMapNameIndices.length - 1] : -1; + return sourceMapNameIndices.length ? lastOrUndefined(sourceMapNameIndices) : -1; } // Last recorded and encoded spans var lastRecordedSourceMapSpan; @@ -5084,11 +5084,11 @@ var ts; } } function hasDetachedComments(pos) { - return detachedCommentsInfo !== undefined && detachedCommentsInfo[detachedCommentsInfo.length - 1].nodePos === pos; + return detachedCommentsInfo !== undefined && lastOrUndefined(detachedCommentsInfo).nodePos === pos; } function getLeadingCommentsWithoutDetachedComments() { // get the leading comments from detachedPos - var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, detachedCommentsInfo[detachedCommentsInfo.length - 1].detachedCommentEndPos); + var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos); if (detachedCommentsInfo.length - 1) { detachedCommentsInfo.pop(); } @@ -5189,13 +5189,13 @@ var ts; // All comments look like they could have been part of the copyright header. Make // sure there is at least one blank line between it and the node. If not, it's not // a copyright header. - var lastCommentLine = ts.getLineOfLocalPosition(currentSourceFile, detachedComments[detachedComments.length - 1].end); + var lastCommentLine = ts.getLineOfLocalPosition(currentSourceFile, lastOrUndefined(detachedComments).end); var nodeLine = ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node.pos)); if (nodeLine >= lastCommentLine + 2) { // Valid detachedComments ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments); ts.emitComments(currentSourceFile, writer, detachedComments, true, newLine, writeComment); - var currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: detachedComments[detachedComments.length - 1].end }; + var currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: lastOrUndefined(detachedComments).end }; if (detachedCommentsInfo) { detachedCommentsInfo.push(currentDetachedCommentInfo); } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 83a4ccf3c1a..5a9a654ce60 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -336,7 +336,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { let sourceMapNameIndexMap: Map = {}; let sourceMapNameIndices: number[] = []; function getSourceMapNameIndex() { - return sourceMapNameIndices.length ? sourceMapNameIndices[sourceMapNameIndices.length - 1] : -1; + return sourceMapNameIndices.length ? lastOrUndefined(sourceMapNameIndices) : -1; } // Last recorded and encoded spans @@ -5890,13 +5890,13 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } function hasDetachedComments(pos: number) { - return detachedCommentsInfo !== undefined && detachedCommentsInfo[detachedCommentsInfo.length - 1].nodePos === pos; + return detachedCommentsInfo !== undefined && lastOrUndefined(detachedCommentsInfo).nodePos === pos; } function getLeadingCommentsWithoutDetachedComments() { // get the leading comments from detachedPos let leadingComments = getLeadingCommentRanges(currentSourceFile.text, - detachedCommentsInfo[detachedCommentsInfo.length - 1].detachedCommentEndPos); + lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos); if (detachedCommentsInfo.length - 1) { detachedCommentsInfo.pop(); } @@ -6017,13 +6017,13 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { // All comments look like they could have been part of the copyright header. Make // sure there is at least one blank line between it and the node. If not, it's not // a copyright header. - let lastCommentLine = getLineOfLocalPosition(currentSourceFile, detachedComments[detachedComments.length - 1].end); + let lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastOrUndefined(detachedComments).end); let nodeLine = getLineOfLocalPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.pos)); if (nodeLine >= lastCommentLine + 2) { // Valid detachedComments emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments); emitComments(currentSourceFile, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment); - let currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: detachedComments[detachedComments.length - 1].end }; + let currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: lastOrUndefined(detachedComments).end }; if (detachedCommentsInfo) { detachedCommentsInfo.push(currentDetachedCommentInfo); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7d984a3dfa4..055fc1b6f74 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1691,7 +1691,7 @@ module ts { do { templateSpans.push(parseTemplateSpan()); } - while (templateSpans[templateSpans.length - 1].literal.kind === SyntaxKind.TemplateMiddle) + while (lastOrUndefined(templateSpans).literal.kind === SyntaxKind.TemplateMiddle) templateSpans.end = getNodeEnd(); template.templateSpans = templateSpans; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index f7224e619bb..4ed5d1cdb5b 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -522,7 +522,7 @@ module ts { } collecting = true; if (result && result.length) { - result[result.length - 1].hasTrailingNewLine = true; + lastOrUndefined(result).hasTrailingNewLine = true; } continue; case CharacterCodes.tab: @@ -569,7 +569,7 @@ module ts { default: if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch) || isLineBreak(ch))) { if (result && result.length && isLineBreak(ch)) { - result[result.length - 1].hasTrailingNewLine = true; + lastOrUndefined(result).hasTrailingNewLine = true; } pos++; continue; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5296f063a94..3e825c6802c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -856,7 +856,7 @@ module ts { } export function hasRestParameters(s: SignatureDeclaration): boolean { - return s.parameters.length > 0 && s.parameters[s.parameters.length - 1].dotDotDotToken !== undefined; + return s.parameters.length > 0 && lastOrUndefined(s.parameters).dotDotDotToken !== undefined; } export function isLiteralKind(kind: SyntaxKind): boolean { @@ -1362,7 +1362,7 @@ module ts { let lineStartsOfS = computeLineStarts(s); if (lineStartsOfS.length > 1) { lineCount = lineCount + lineStartsOfS.length - 1; - linePos = output.length - s.length + lineStartsOfS[lineStartsOfS.length - 1]; + linePos = output.length - s.length + lastOrUndefined(lineStartsOfS); } } } @@ -1727,8 +1727,8 @@ module ts { output.push(((charCode >> 6) & 0B00111111) | 0B10000000); output.push((charCode & 0B00111111) | 0B10000000); } - else { - Debug.assert(false, "Unexpected code point"); + else { + Debug.assert(false, "Unexpected code point"); } } diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 19235269f22..41079c08201 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -446,14 +446,14 @@ module ts.BreakpointResolver { // fall through. case SyntaxKind.CatchClause: - return spanInNode((node.parent).statements[(node.parent).statements.length - 1]);; + return spanInNode(lastOrUndefined((node.parent).statements));; case SyntaxKind.CaseBlock: // breakpoint in last statement of the last clause let caseBlock = node.parent; - let lastClause = caseBlock.clauses[caseBlock.clauses.length - 1]; + let lastClause = lastOrUndefined(caseBlock.clauses); if (lastClause) { - return spanInNode(lastClause.statements[lastClause.statements.length - 1]); + return spanInNode(lastOrUndefined(lastClause.statements)); } return undefined; diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 388d9428ffc..e09b5dfba92 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -51,7 +51,7 @@ module ts.formatting { if (isStarted) { if (trailingTrivia) { Debug.assert(trailingTrivia.length !== 0); - wasNewLine = trailingTrivia[trailingTrivia.length - 1].kind === SyntaxKind.NewLineTrivia; + wasNewLine = lastOrUndefined(trailingTrivia).kind === SyntaxKind.NewLineTrivia; } else { wasNewLine = false; diff --git a/src/services/services.ts b/src/services/services.ts index 6496363fb72..d51a9233d45 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4058,7 +4058,7 @@ module ts { return true; } else if (declarations.length) { - result.push(createDefinitionInfo(declarations[declarations.length - 1], symbolKind, symbolName, containerName)); + result.push(createDefinitionInfo(lastOrUndefined(declarations), symbolKind, symbolName, containerName)); return true; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 5e1460bbdcd..f2074d43ec9 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -200,7 +200,7 @@ module ts { function nodeEndsWith(n: Node, expectedLastToken: SyntaxKind, sourceFile: SourceFile): boolean { let children = n.getChildren(sourceFile); if (children.length) { - let last = children[children.length - 1]; + let last = lastOrUndefined(children); if (last.kind === expectedLastToken) { return true; }