diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 1f87ae40745..c56ea72cd66 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -13,13 +13,13 @@ module ts.BreakpointResolver { return undefined; } - var tokenAtLocation = getTokenAtPosition(sourceFile, position); - var lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line; + let tokenAtLocation = getTokenAtPosition(sourceFile, position); + let lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line; if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart()).line > lineOfPosition) { // Get previous token if the token is returned starts on new line - // eg: var x =10; |--- cursor is here - // var y = 10; - // token at position will return var keyword on second line as the token but we would like to use + // eg: let x =10; |--- cursor is here + // let y = 10; + // token at position will return let keyword on second line as the token but we would like to use // token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line tokenAtLocation = findPrecedingToken(tokenAtLocation.pos, sourceFile); @@ -275,9 +275,9 @@ module ts.BreakpointResolver { return spanInNode(variableDeclaration.parent.parent); } - var isParentVariableStatement = variableDeclaration.parent.parent.kind === SyntaxKind.VariableStatement; - var isDeclarationOfForStatement = variableDeclaration.parent.parent.kind === SyntaxKind.ForStatement && contains(((variableDeclaration.parent.parent).initializer).declarations, variableDeclaration); - var declarations = isParentVariableStatement + let isParentVariableStatement = variableDeclaration.parent.parent.kind === SyntaxKind.VariableStatement; + let isDeclarationOfForStatement = variableDeclaration.parent.parent.kind === SyntaxKind.ForStatement && contains(((variableDeclaration.parent.parent).initializer).declarations, variableDeclaration); + let declarations = isParentVariableStatement ? (variableDeclaration.parent.parent).declarationList.declarations : isDeclarationOfForStatement ? ((variableDeclaration.parent.parent).initializer).declarations @@ -287,12 +287,12 @@ module ts.BreakpointResolver { if (variableDeclaration.initializer || (variableDeclaration.flags & NodeFlags.Export)) { if (declarations && declarations[0] === variableDeclaration) { if (isParentVariableStatement) { - // First declaration - include var keyword + // First declaration - include let keyword return textSpan(variableDeclaration.parent, variableDeclaration); } else { Debug.assert(isDeclarationOfForStatement); - // Include var keyword from for statement declarations in the span + // Include let keyword from for statement declarations in the span return textSpan(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration); } } @@ -303,7 +303,7 @@ module ts.BreakpointResolver { } else if (declarations && declarations[0] !== variableDeclaration) { // If we cant set breakpoint on this declaration, set it on previous one - var indexOfCurrentDeclaration = indexOf(declarations, variableDeclaration); + let indexOfCurrentDeclaration = indexOf(declarations, variableDeclaration); return spanInVariableDeclaration(declarations[indexOfCurrentDeclaration - 1]); } } @@ -319,8 +319,8 @@ module ts.BreakpointResolver { return textSpan(parameter); } else { - var functionDeclaration = parameter.parent; - var indexOfParameter = indexOf(functionDeclaration.parameters, parameter); + let functionDeclaration = parameter.parent; + let indexOfParameter = indexOf(functionDeclaration.parameters, parameter); if (indexOfParameter) { // Not a first parameter, go to previous parameter return spanInParameterDeclaration(functionDeclaration.parameters[indexOfParameter - 1]); @@ -353,7 +353,7 @@ module ts.BreakpointResolver { } function spanInFunctionBlock(block: Block): TextSpan { - var nodeForSpanInBlock = block.statements.length ? block.statements[0] : block.getLastToken(); + let nodeForSpanInBlock = block.statements.length ? block.statements[0] : block.getLastToken(); if (canFunctionHaveSpanInWholeDeclaration(block.parent)) { return spanInNodeIfStartsOnSameLine(block.parent, nodeForSpanInBlock); } @@ -387,7 +387,7 @@ module ts.BreakpointResolver { function spanInForStatement(forStatement: ForStatement): TextSpan { if (forStatement.initializer) { if (forStatement.initializer.kind === SyntaxKind.VariableDeclarationList) { - var variableDeclarationList = forStatement.initializer; + let variableDeclarationList = forStatement.initializer; if (variableDeclarationList.declarations.length > 0) { return spanInNode(variableDeclarationList.declarations[0]); } @@ -409,11 +409,11 @@ module ts.BreakpointResolver { function spanInOpenBraceToken(node: Node): TextSpan { switch (node.parent.kind) { case SyntaxKind.EnumDeclaration: - var enumDeclaration = node.parent; + let enumDeclaration = node.parent; return spanInNodeIfStartsOnSameLine(findPrecedingToken(node.pos, sourceFile, node.parent), enumDeclaration.members.length ? enumDeclaration.members[0] : enumDeclaration.getLastToken(sourceFile)); case SyntaxKind.ClassDeclaration: - var classDeclaration = node.parent; + let classDeclaration = node.parent; return spanInNodeIfStartsOnSameLine(findPrecedingToken(node.pos, sourceFile, node.parent), classDeclaration.members.length ? classDeclaration.members[0] : classDeclaration.getLastToken(sourceFile)); case SyntaxKind.CaseBlock: @@ -449,8 +449,8 @@ module ts.BreakpointResolver { case SyntaxKind.CaseBlock: // breakpoint in last statement of the last clause - var caseBlock = node.parent; - var lastClause = caseBlock.clauses[caseBlock.clauses.length - 1]; + let caseBlock = node.parent; + let lastClause = caseBlock.clauses[caseBlock.clauses.length - 1]; if (lastClause) { return spanInNode(lastClause.statements[lastClause.statements.length - 1]); } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 7757a7acf3a..9871a447c05 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -2,21 +2,21 @@ module ts.NavigateTo { type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration }; export function getNavigateToItems(program: Program, cancellationToken: CancellationTokenObject, searchValue: string, maxResultCount: number): NavigateToItem[] { - var patternMatcher = createPatternMatcher(searchValue); - var rawItems: RawNavigateToItem[] = []; + let patternMatcher = createPatternMatcher(searchValue); + let rawItems: RawNavigateToItem[] = []; // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[] forEach(program.getSourceFiles(), sourceFile => { cancellationToken.throwIfCancellationRequested(); - var declarations = sourceFile.getNamedDeclarations(); + let declarations = sourceFile.getNamedDeclarations(); for (let declaration of declarations) { var name = getDeclarationName(declaration); if (name !== undefined) { // First do a quick check to see if the name of the declaration matches the // last portion of the (possibly) dotted name they're searching for. - var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name); + let matches = patternMatcher.getMatchesForLastSegmentOfPattern(name); if (!matches) { continue; @@ -25,7 +25,7 @@ module ts.NavigateTo { // It was a match! If the pattern has dots in it, then also see if hte // declaration container matches as well. if (patternMatcher.patternContainsDots) { - var containers = getContainers(declaration); + let containers = getContainers(declaration); if (!containers) { return undefined; } @@ -37,8 +37,8 @@ module ts.NavigateTo { } } - var fileName = sourceFile.fileName; - var matchKind = bestMatchKind(matches); + let fileName = sourceFile.fileName; + let matchKind = bestMatchKind(matches); rawItems.push({ name, fileName, matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration }); } } @@ -49,7 +49,7 @@ module ts.NavigateTo { rawItems = rawItems.slice(0, maxResultCount); } - var items = map(rawItems, createNavigateToItem); + let items = map(rawItems, createNavigateToItem); return items; @@ -67,13 +67,13 @@ module ts.NavigateTo { } function getDeclarationName(declaration: Declaration): string { - var result = getTextOfIdentifierOrLiteral(declaration.name); + let result = getTextOfIdentifierOrLiteral(declaration.name); if (result !== undefined) { return result; } if (declaration.name.kind === SyntaxKind.ComputedPropertyName) { - var expr = (declaration.name).expression; + let expr = (declaration.name).expression; if (expr.kind === SyntaxKind.PropertyAccessExpression) { return (expr).name.text; } @@ -97,7 +97,7 @@ module ts.NavigateTo { function tryAddSingleDeclarationName(declaration: Declaration, containers: string[]) { if (declaration && declaration.name) { - var text = getTextOfIdentifierOrLiteral(declaration.name); + let text = getTextOfIdentifierOrLiteral(declaration.name); if (text !== undefined) { containers.unshift(text); } @@ -117,7 +117,7 @@ module ts.NavigateTo { // // [X.Y.Z]() { } function tryAddComputedPropertyName(expression: Expression, containers: string[], includeLastPortion: boolean): boolean { - var text = getTextOfIdentifierOrLiteral(expression); + let text = getTextOfIdentifierOrLiteral(expression); if (text !== undefined) { if (includeLastPortion) { containers.unshift(text); @@ -126,7 +126,7 @@ module ts.NavigateTo { } if (expression.kind === SyntaxKind.PropertyAccessExpression) { - var propertyAccess = expression; + let propertyAccess = expression; if (includeLastPortion) { containers.unshift(propertyAccess.name.text); } @@ -138,7 +138,7 @@ module ts.NavigateTo { } function getContainers(declaration: Declaration) { - var containers: string[] = []; + let containers: string[] = []; // First, if we started with a computed property name, then add all but the last // portion into the container array. @@ -164,10 +164,10 @@ module ts.NavigateTo { function bestMatchKind(matches: PatternMatch[]) { Debug.assert(matches.length > 0); - var bestMatchKind = PatternMatchKind.camelCase; + let bestMatchKind = PatternMatchKind.camelCase; for (let match of matches) { - var kind = match.kind; + let kind = match.kind; if (kind < bestMatchKind) { bestMatchKind = kind; } @@ -177,7 +177,7 @@ module ts.NavigateTo { } // This means "compare in a case insensitive manner." - var baseSensitivity: Intl.CollatorOptions = { sensitivity: "base" }; + let baseSensitivity: Intl.CollatorOptions = { sensitivity: "base" }; function compareNavigateToItems(i1: RawNavigateToItem, i2: RawNavigateToItem) { // TODO(cyrusn): get the gamut of comparisons that VS already uses here. // Right now we just sort by kind first, and then by name of the item. @@ -189,8 +189,8 @@ module ts.NavigateTo { } function createNavigateToItem(rawItem: RawNavigateToItem): NavigateToItem { - var declaration = rawItem.declaration; - var container = getContainerNode(declaration); + let declaration = rawItem.declaration; + let container = getContainerNode(declaration); return { name: rawItem.name, kind: getNodeKind(declaration), diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 1f67fef5e71..06eaa481dfb 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -4,16 +4,16 @@ module ts.NavigationBar { export function getNavigationBarItems(sourceFile: SourceFile): ts.NavigationBarItem[] { // If the source file has any child items, then it included in the tree // and takes lexical ownership of all other top-level items. - var hasGlobalNode = false; + let hasGlobalNode = false; return getItemsWorker(getTopLevelNodes(sourceFile), createTopLevelItem); function getIndent(node: Node): number { // If we have a global node in the tree, // then it adds an extra layer of depth to all subnodes. - var indent = hasGlobalNode ? 1 : 0; + let indent = hasGlobalNode ? 1 : 0; - var current = node.parent; + let current = node.parent; while (current) { switch (current.kind) { case SyntaxKind.ModuleDeclaration: @@ -39,7 +39,7 @@ module ts.NavigationBar { } function getChildNodes(nodes: Node[]): Node[] { - var childNodes: Node[] = []; + let childNodes: Node[] = []; function visit(node: Node) { switch (node.kind) { @@ -60,7 +60,7 @@ module ts.NavigationBar { break; case SyntaxKind.ImportDeclaration: - var importClause = (node).importClause; + let importClause = (node).importClause; if (importClause) { // Handle default import case e.g.: // import d from "mod"; @@ -102,8 +102,8 @@ module ts.NavigationBar { } } - //for (var i = 0, n = nodes.length; i < n; i++) { - // var node = nodes[i]; + //for (let i = 0, n = nodes.length; i < n; i++) { + // let node = nodes[i]; // if (node.kind === SyntaxKind.ClassDeclaration || // node.kind === SyntaxKind.EnumDeclaration || @@ -122,7 +122,7 @@ module ts.NavigationBar { } function getTopLevelNodes(node: SourceFile): Node[] { - var topLevelNodes: Node[] = []; + let topLevelNodes: Node[] = []; topLevelNodes.push(node); addTopLevelNodes(node.statements, topLevelNodes); @@ -159,13 +159,13 @@ module ts.NavigationBar { break; case SyntaxKind.ModuleDeclaration: - var moduleDeclaration = node; + let moduleDeclaration = node; topLevelNodes.push(node); addTopLevelNodes((getInnermostModule(moduleDeclaration).body).statements, topLevelNodes); break; case SyntaxKind.FunctionDeclaration: - var functionDeclaration = node; + let functionDeclaration = node; if (isTopLevelFunctionDeclaration(functionDeclaration)) { topLevelNodes.push(node); addTopLevelNodes((functionDeclaration.body).statements, topLevelNodes); @@ -199,17 +199,17 @@ module ts.NavigationBar { } function getItemsWorker(nodes: Node[], createItem: (n: Node) => ts.NavigationBarItem): ts.NavigationBarItem[] { - var items: ts.NavigationBarItem[] = []; + let items: ts.NavigationBarItem[] = []; - var keyToItem: Map = {}; + let keyToItem: Map = {}; for (let child of nodes) { - var item = createItem(child); + let item = createItem(child); if (item !== undefined) { if (item.text.length > 0) { - var key = item.text + "-" + item.kind + "-" + item.indent; + let key = item.text + "-" + item.kind + "-" + item.indent; - var itemWithSameName = keyToItem[key]; + let itemWithSameName = keyToItem[key]; if (itemWithSameName) { // We had an item with the same name. Merge these items together. merge(itemWithSameName, item); @@ -293,8 +293,8 @@ module ts.NavigationBar { case SyntaxKind.VariableDeclaration: case SyntaxKind.BindingElement: - var variableDeclarationNode: Node; - var name: Node; + let variableDeclarationNode: Node; + let name: Node; if (node.kind === SyntaxKind.BindingElement) { name = (node).name; @@ -391,7 +391,7 @@ module ts.NavigationBar { } // Otherwise, we need to aggregate each identifier to build up the qualified name. - var result: string[] = []; + let result: string[] = []; result.push(moduleDeclaration.name.text); @@ -405,9 +405,9 @@ module ts.NavigationBar { } function createModuleItem(node: ModuleDeclaration): NavigationBarItem { - var moduleName = getModuleName(node); + let moduleName = getModuleName(node); - var childItems = getItemsWorker(getChildNodes((getInnermostModule(node).body).statements), createChildItem); + let childItems = getItemsWorker(getChildNodes((getInnermostModule(node).body).statements), createChildItem); return getNavigationBarItem(moduleName, ts.ScriptElementKind.moduleElement, @@ -419,7 +419,7 @@ module ts.NavigationBar { function createFunctionItem(node: FunctionDeclaration) { if (node.name && node.body && node.body.kind === SyntaxKind.Block) { - var childItems = getItemsWorker(sortNodes((node.body).statements), createChildItem); + let childItems = getItemsWorker(sortNodes((node.body).statements), createChildItem); return getNavigationBarItem(node.name.text, ts.ScriptElementKind.functionElement, @@ -433,14 +433,14 @@ module ts.NavigationBar { } function createSourceFileItem(node: SourceFile): ts.NavigationBarItem { - var childItems = getItemsWorker(getChildNodes(node.statements), createChildItem); + let childItems = getItemsWorker(getChildNodes(node.statements), createChildItem); if (childItems === undefined || childItems.length === 0) { return undefined; } hasGlobalNode = true; - var rootName = isExternalModule(node) + let rootName = isExternalModule(node) ? "\"" + escapeString(getBaseFileName(removeFileExtension(normalizePath(node.fileName)))) + "\"" : "" @@ -457,22 +457,22 @@ module ts.NavigationBar { return undefined; } - var childItems: NavigationBarItem[]; + let childItems: NavigationBarItem[]; if (node.members) { - var constructor = forEach(node.members, member => { + let constructor = forEach(node.members, member => { return member.kind === SyntaxKind.Constructor && member; }); // Add the constructor parameters in as children of the class (for property parameters). // Note that *all non-binding pattern named* parameters will be added to the nodes array, but parameters that // are not properties will be filtered out later by createChildItem. - var nodes: Node[] = removeDynamicallyNamedProperties(node); + let nodes: Node[] = removeDynamicallyNamedProperties(node); if (constructor) { nodes.push.apply(nodes, filter(constructor.parameters, p => !isBindingPattern(p.name))); } - var childItems = getItemsWorker(sortNodes(nodes), createChildItem); + childItems = getItemsWorker(sortNodes(nodes), createChildItem); } return getNavigationBarItem( @@ -485,7 +485,7 @@ module ts.NavigationBar { } function createEnumItem(node: EnumDeclaration): ts.NavigationBarItem { - var childItems = getItemsWorker(sortNodes(removeComputedProperties(node)), createChildItem); + let childItems = getItemsWorker(sortNodes(removeComputedProperties(node)), createChildItem); return getNavigationBarItem( node.name.text, ts.ScriptElementKind.enumElement, @@ -496,7 +496,7 @@ module ts.NavigationBar { } function createIterfaceItem(node: InterfaceDeclaration): ts.NavigationBarItem { - var childItems = getItemsWorker(sortNodes(removeDynamicallyNamedProperties(node)), createChildItem); + let childItems = getItemsWorker(sortNodes(removeDynamicallyNamedProperties(node)), createChildItem); return getNavigationBarItem( node.name.text, ts.ScriptElementKind.interfaceElement, diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index eee537bbebb..4c9dcedc7a4 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -16,12 +16,12 @@ module ts { export module OutliningElementsCollector { export function collectElements(sourceFile: SourceFile): OutliningSpan[] { - var elements: OutliningSpan[] = []; - var collapseText = "..."; + let elements: OutliningSpan[] = []; + let collapseText = "..."; function addOutliningSpan(hintSpanNode: Node, startElement: Node, endElement: Node, autoCollapse: boolean) { if (hintSpanNode && startElement && endElement) { - var span: OutliningSpan = { + let span: OutliningSpan = { textSpan: createTextSpanFromBounds(startElement.pos, endElement.end), hintSpan: createTextSpanFromBounds(hintSpanNode.getStart(), hintSpanNode.end), bannerText: collapseText, @@ -35,8 +35,8 @@ module ts { return isFunctionBlock(node) && node.parent.kind !== SyntaxKind.ArrowFunction; } - var depth = 0; - var maxDepth = 20; + let depth = 0; + let maxDepth = 20; function walk(n: Node): void { if (depth > maxDepth) { return; @@ -44,9 +44,9 @@ module ts { switch (n.kind) { case SyntaxKind.Block: if (!isFunctionBlock(n)) { - var parent = n.parent; - var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); - var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); + let parent = n.parent; + let openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); + let closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); // Check if the block is standalone, or 'attached' to some parent statement. // If the latter, we want to collaps the block, but consider its hint span @@ -66,13 +66,13 @@ module ts { if (parent.kind === SyntaxKind.TryStatement) { // Could be the try-block, or the finally-block. - var tryStatement = parent; + let tryStatement = parent; if (tryStatement.tryBlock === n) { addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n)); break; } else if (tryStatement.finallyBlock === n) { - var finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); + let finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); if (finallyKeyword) { addOutliningSpan(finallyKeyword, openBrace, closeBrace, autoCollapse(n)); break; @@ -84,7 +84,7 @@ module ts { // Block was a standalone block. In this case we want to only collapse // the span of the block, independent of any parent span. - var span = createTextSpanFromBounds(n.getStart(), n.end); + let span = createTextSpanFromBounds(n.getStart(), n.end); elements.push({ textSpan: span, hintSpan: span, @@ -95,23 +95,25 @@ module ts { } // Fallthrough. - case SyntaxKind.ModuleBlock: - var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); - var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); + case SyntaxKind.ModuleBlock: { + let openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); + let closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); addOutliningSpan(n.parent, openBrace, closeBrace, autoCollapse(n)); break; + } case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.CaseBlock: - var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); - var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); + case SyntaxKind.CaseBlock: { + let openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); + let closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); addOutliningSpan(n, openBrace, closeBrace, autoCollapse(n)); break; + } case SyntaxKind.ArrayLiteralExpression: - var openBracket = findChildOfKind(n, SyntaxKind.OpenBracketToken, sourceFile); - var closeBracket = findChildOfKind(n, SyntaxKind.CloseBracketToken, sourceFile); + let openBracket = findChildOfKind(n, SyntaxKind.OpenBracketToken, sourceFile); + let closeBracket = findChildOfKind(n, SyntaxKind.CloseBracketToken, sourceFile); addOutliningSpan(n, openBracket, closeBracket, autoCollapse(n)); break; } diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index f7874519334..61642552cab 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -112,13 +112,13 @@ module ts { // we see the name of a module that is used everywhere, or the name of an overload). As // such, we cache the information we compute about the candidate for the life of this // pattern matcher so we don't have to compute it multiple times. - var stringToWordSpans: Map = {}; + let stringToWordSpans: Map = {}; pattern = pattern.trim(); - var fullPatternSegment = createSegment(pattern); - var dotSeparatedSegments = pattern.split(".").map(p => createSegment(p.trim())); - var invalidPattern = dotSeparatedSegments.length === 0 || forEach(dotSeparatedSegments, segmentIsInvalid); + let fullPatternSegment = createSegment(pattern); + let dotSeparatedSegments = pattern.split(".").map(p => createSegment(p.trim())); + let invalidPattern = dotSeparatedSegments.length === 0 || forEach(dotSeparatedSegments, segmentIsInvalid); return { getMatches, @@ -147,7 +147,7 @@ module ts { // First, check that the last part of the dot separated pattern matches the name of the // candidate. If not, then there's no point in proceeding and doing the more // expensive work. - var candidateMatch = matchSegment(candidate, lastOrUndefined(dotSeparatedSegments)); + let candidateMatch = matchSegment(candidate, lastOrUndefined(dotSeparatedSegments)); if (!candidateMatch) { return undefined; } @@ -164,16 +164,16 @@ module ts { // So far so good. Now break up the container for the candidate and check if all // the dotted parts match up correctly. - var totalMatch = candidateMatch; + let totalMatch = candidateMatch; - for (var i = dotSeparatedSegments.length - 2, j = candidateContainers.length - 1; + for (let i = dotSeparatedSegments.length - 2, j = candidateContainers.length - 1; i >= 0; i--, j--) { - var segment = dotSeparatedSegments[i]; - var containerName = candidateContainers[j]; + let segment = dotSeparatedSegments[i]; + let containerName = candidateContainers[j]; - var containerMatch = matchSegment(containerName, segment); + let containerMatch = matchSegment(containerName, segment); if (!containerMatch) { // This container didn't match the pattern piece. So there's no match at all. return undefined; @@ -196,7 +196,7 @@ module ts { } function matchTextChunk(candidate: string, chunk: TextChunk, punctuationStripped: boolean): PatternMatch { - var index = indexOfIgnoringCase(candidate, chunk.textLowerCase); + let index = indexOfIgnoringCase(candidate, chunk.textLowerCase); if (index === 0) { if (chunk.text.length === candidate.length) { // a) Check if the part matches the candidate entirely, in an case insensitive or @@ -210,7 +210,7 @@ module ts { } } - var isLowercase = chunk.isLowerCase; + let isLowercase = chunk.isLowerCase; if (isLowercase) { if (index > 0) { // c) If the part is entirely lowercase, then check if it is contained anywhere in the @@ -220,7 +220,7 @@ module ts { // Note: We only have a substring match if the lowercase part is prefix match of some // word part. That way we don't match something like 'Class' when the user types 'a'. // But we would match 'FooAttribute' (since 'Attribute' starts with 'a'). - var wordSpans = getWordSpans(candidate); + let wordSpans = getWordSpans(candidate); for (let span of wordSpans) { if (partStartsWith(candidate, span, chunk.text, /*ignoreCase:*/ true)) { return createPatternMatch(PatternMatchKind.substring, punctuationStripped, @@ -241,8 +241,8 @@ module ts { if (!isLowercase) { // e) If the part was not entirely lowercase, then attempt a camel cased match as well. if (chunk.characterSpans.length > 0) { - var candidateParts = getWordSpans(candidate); - var camelCaseWeight = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ false); + let candidateParts = getWordSpans(candidate); + let camelCaseWeight = tryCamelCaseMatch(candidate, candidateParts, chunk, /*ignoreCase:*/ false); if (camelCaseWeight !== undefined) { return createPatternMatch(PatternMatchKind.camelCase, punctuationStripped, /*isCaseSensitive:*/ true, /*camelCaseWeight:*/ camelCaseWeight); } @@ -273,8 +273,8 @@ module ts { } function containsSpaceOrAsterisk(text: string): boolean { - for (var i = 0; i < text.length; i++) { - var ch = text.charCodeAt(i); + for (let i = 0; i < text.length; i++) { + let ch = text.charCodeAt(i); if (ch === CharacterCodes.space || ch === CharacterCodes.asterisk) { return true; } @@ -292,7 +292,7 @@ module ts { // Note: if the segment contains a space or an asterisk then we must assume that it's a // multi-word segment. if (!containsSpaceOrAsterisk(segment.totalTextChunk.text)) { - var match = matchTextChunk(candidate, segment.totalTextChunk, /*punctuationStripped:*/ false); + let match = matchTextChunk(candidate, segment.totalTextChunk, /*punctuationStripped:*/ false); if (match) { return [match]; } @@ -335,12 +335,12 @@ module ts { // // Only if all words have some sort of match is the pattern considered matched. - var subWordTextChunks = segment.subWordTextChunks; - var matches: PatternMatch[] = undefined; + let subWordTextChunks = segment.subWordTextChunks; + let matches: PatternMatch[] = undefined; for (let subWordTextChunk of subWordTextChunks) { // Try to match the candidate with this word - var result = matchTextChunk(candidate, subWordTextChunk, /*punctuationStripped:*/ true); + let result = matchTextChunk(candidate, subWordTextChunk, /*punctuationStripped:*/ true); if (!result) { return undefined; } @@ -353,8 +353,8 @@ module ts { } function partStartsWith(candidate: string, candidateSpan: TextSpan, pattern: string, ignoreCase: boolean, patternSpan?: TextSpan): boolean { - var patternPartStart = patternSpan ? patternSpan.start : 0; - var patternPartLength = patternSpan ? patternSpan.length : pattern.length; + let patternPartStart = patternSpan ? patternSpan.start : 0; + let patternPartLength = patternSpan ? patternSpan.length : pattern.length; if (patternPartLength > candidateSpan.length) { // Pattern part is longer than the candidate part. There can never be a match. @@ -362,18 +362,18 @@ module ts { } if (ignoreCase) { - for (var i = 0; i < patternPartLength; i++) { - var ch1 = pattern.charCodeAt(patternPartStart + i); - var ch2 = candidate.charCodeAt(candidateSpan.start + i); + for (let i = 0; i < patternPartLength; i++) { + let ch1 = pattern.charCodeAt(patternPartStart + i); + let ch2 = candidate.charCodeAt(candidateSpan.start + i); if (toLowerCase(ch1) !== toLowerCase(ch2)) { return false; } } } else { - for (var i = 0; i < patternPartLength; i++) { - var ch1 = pattern.charCodeAt(patternPartStart + i); - var ch2 = candidate.charCodeAt(candidateSpan.start + i); + for (let i = 0; i < patternPartLength; i++) { + let ch1 = pattern.charCodeAt(patternPartStart + i); + let ch2 = candidate.charCodeAt(candidateSpan.start + i); if (ch1 !== ch2) { return false; } @@ -384,23 +384,23 @@ module ts { } function tryCamelCaseMatch(candidate: string, candidateParts: TextSpan[], chunk: TextChunk, ignoreCase: boolean): number { - var chunkCharacterSpans = chunk.characterSpans; + let chunkCharacterSpans = chunk.characterSpans; // Note: we may have more pattern parts than candidate parts. This is because multiple // pattern parts may match a candidate part. For example "SiUI" against "SimpleUI". // We'll have 3 pattern parts Si/U/I against two candidate parts Simple/UI. However, U // and I will both match in UI. - var currentCandidate = 0; - var currentChunkSpan = 0; - var firstMatch: number = undefined; - var contiguous: boolean = undefined; + let currentCandidate = 0; + let currentChunkSpan = 0; + let firstMatch: number = undefined; + let contiguous: boolean = undefined; while (true) { // Let's consider our termination cases if (currentChunkSpan === chunkCharacterSpans.length) { // We did match! We shall assign a weight to this - var weight = 0; + let weight = 0; // Was this contiguous? if (contiguous) { @@ -419,15 +419,15 @@ module ts { return undefined; } - var candidatePart = candidateParts[currentCandidate]; - var gotOneMatchThisCandidate = false; + let candidatePart = candidateParts[currentCandidate]; + let gotOneMatchThisCandidate = false; // Consider the case of matching SiUI against SimpleUIElement. The candidate parts // will be Simple/UI/Element, and the pattern parts will be Si/U/I. We'll match 'Si' // against 'Simple' first. Then we'll match 'U' against 'UI'. However, we want to // still keep matching pattern parts against that candidate part. for (; currentChunkSpan < chunkCharacterSpans.length; currentChunkSpan++) { - var chunkCharacterSpan = chunkCharacterSpans[currentChunkSpan]; + let chunkCharacterSpan = chunkCharacterSpans[currentChunkSpan]; if (gotOneMatchThisCandidate) { // We've already gotten one pattern part match in this candidate. We will @@ -537,7 +537,7 @@ module ts { // TODO: find a way to determine this for any unicode characters in a // non-allocating manner. - var str = String.fromCharCode(ch); + let str = String.fromCharCode(ch); return str === str.toUpperCase(); } @@ -554,12 +554,12 @@ module ts { // TODO: find a way to determine this for any unicode characters in a // non-allocating manner. - var str = String.fromCharCode(ch); + let str = String.fromCharCode(ch); return str === str.toLowerCase(); } function containsUpperCaseLetter(string: string): boolean { - for (var i = 0, n = string.length; i < n; i++) { + for (let i = 0, n = string.length; i < n; i++) { if (isUpperCaseLetter(string.charCodeAt(i))) { return true; } @@ -569,7 +569,7 @@ module ts { } function startsWith(string: string, search: string) { - for (var i = 0, n = search.length; i < n; i++) { + for (let i = 0, n = search.length; i < n; i++) { if (string.charCodeAt(i) !== search.charCodeAt(i)) { return false; } @@ -580,7 +580,7 @@ module ts { // Assumes 'value' is already lowercase. function indexOfIgnoringCase(string: string, value: string): number { - for (var i = 0, n = string.length - value.length; i <= n; i++) { + for (let i = 0, n = string.length - value.length; i <= n; i++) { if (startsWithIgnoringCase(string, value, i)) { return i; } @@ -591,9 +591,9 @@ module ts { // Assumes 'value' is already lowercase. function startsWithIgnoringCase(string: string, value: string, start: number): boolean { - for (var i = 0, n = value.length; i < n; i++) { - var ch1 = toLowerCase(string.charCodeAt(i + start)); - var ch2 = value.charCodeAt(i); + for (let i = 0, n = value.length; i < n; i++) { + let ch1 = toLowerCase(string.charCodeAt(i + start)); + let ch2 = value.charCodeAt(i); if (ch1 !== ch2) { return false; @@ -628,12 +628,12 @@ module ts { } function breakPatternIntoTextChunks(pattern: string): TextChunk[] { - var result: TextChunk[] = []; - var wordStart = 0; - var wordLength = 0; + let result: TextChunk[] = []; + let wordStart = 0; + let wordLength = 0; - for (var i = 0; i < pattern.length; i++) { - var ch = pattern.charCodeAt(i); + for (let i = 0; i < pattern.length; i++) { + let ch = pattern.charCodeAt(i); if (isWordChar(ch)) { if (wordLength++ === 0) { wordStart = i; @@ -655,7 +655,7 @@ module ts { } function createTextChunk(text: string): TextChunk { - var textLowerCase = text.toLowerCase(); + let textLowerCase = text.toLowerCase(); return { text, textLowerCase, @@ -673,15 +673,15 @@ module ts { } function breakIntoSpans(identifier: string, word: boolean): TextSpan[] { - var result: TextSpan[] = []; + let result: TextSpan[] = []; - var wordStart = 0; - for (var i = 1, n = identifier.length; i < n; i++) { - var lastIsDigit = isDigit(identifier.charCodeAt(i - 1)); - var currentIsDigit = isDigit(identifier.charCodeAt(i)); + let wordStart = 0; + for (let i = 1, n = identifier.length; i < n; i++) { + let lastIsDigit = isDigit(identifier.charCodeAt(i - 1)); + let currentIsDigit = isDigit(identifier.charCodeAt(i)); - var hasTransitionFromLowerToUpper = transitionFromLowerToUpper(identifier, word, i); - var hasTransitionFromUpperToLower = transitionFromUpperToLower(identifier, word, i, wordStart); + let hasTransitionFromLowerToUpper = transitionFromLowerToUpper(identifier, word, i); + let hasTransitionFromUpperToLower = transitionFromUpperToLower(identifier, word, i, wordStart); if (charIsPunctuation(identifier.charCodeAt(i - 1)) || charIsPunctuation(identifier.charCodeAt(i)) || @@ -736,8 +736,8 @@ module ts { } function isAllPunctuation(identifier: string, start: number, end: number): boolean { - for (var i = start; i < end; i++) { - var ch = identifier.charCodeAt(i); + for (let i = start; i < end; i++) { + let ch = identifier.charCodeAt(i); // We don't consider _ or $ as punctuation as there may be things with that name. if (!charIsPunctuation(ch) || ch === CharacterCodes._ || ch === CharacterCodes.$) { @@ -758,8 +758,8 @@ module ts { // etc. if (index != wordStart && index + 1 < identifier.length) { - var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index)); - var nextIsLower = isLowerCaseLetter(identifier.charCodeAt(index + 1)); + let currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index)); + let nextIsLower = isLowerCaseLetter(identifier.charCodeAt(index + 1)); if (currentIsUpper && nextIsLower) { // We have a transition from an upper to a lower letter here. But we only @@ -770,7 +770,7 @@ module ts { // that follows. Note: this will make the following not split properly: // "HELLOthere". However, these sorts of names do not show up in .Net // programs. - for (var i = wordStart; i < index; i++) { + for (let i = wordStart; i < index; i++) { if (!isUpperCaseLetter(identifier.charCodeAt(i))) { return false; } @@ -785,8 +785,8 @@ module ts { } function transitionFromLowerToUpper(identifier: string, word: boolean, index: number): boolean { - var lastIsUpper = isUpperCaseLetter(identifier.charCodeAt(index - 1)); - var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index)); + let lastIsUpper = isUpperCaseLetter(identifier.charCodeAt(index - 1)); + let currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index)); // See if the casing indicates we're starting a new word. Note: if we're breaking on // words, then just seeing an upper case character isn't enough. Instead, it has to @@ -801,7 +801,7 @@ module ts { // on characters would be: A M // // We break the search string on characters. But we break the symbol name on words. - var transition = word + let transition = word ? (currentIsUpper && !lastIsUpper) : currentIsUpper; return transition; diff --git a/src/services/services.ts b/src/services/services.ts index b4c0ef2bbd8..1bf5f6336d4 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -12,7 +12,7 @@ module ts { /** The version of the language service API */ - export var servicesVersion = "0.4" + export let servicesVersion = "0.4" export interface Node { getSourceFile(): SourceFile; @@ -124,12 +124,12 @@ module ts { isLibFile: boolean } - var scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); + let scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); - var emptyArray: any[] = []; + let emptyArray: any[] = []; function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject { - var node = new (getNodeConstructor(kind))(); + let node = new (getNodeConstructor(kind))(); node.pos = pos; node.end = end; node.flags = flags; @@ -184,8 +184,8 @@ module ts { private addSyntheticNodes(nodes: Node[], pos: number, end: number): number { scanner.setTextPos(pos); while (pos < end) { - var token = scanner.scan(); - var textPos = scanner.getTextPos(); + let token = scanner.scan(); + let textPos = scanner.getTextPos(); nodes.push(createNode(token, pos, textPos, NodeFlags.Synthetic, this)); pos = textPos; } @@ -193,9 +193,9 @@ module ts { } private createSyntaxList(nodes: NodeArray): Node { - var list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); + let list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this); list._children = []; - var pos = nodes.pos; + let pos = nodes.pos; for (let node of nodes) { if (pos < node.pos) { pos = this.addSyntheticNodes(list._children, pos, node.pos); @@ -210,18 +210,19 @@ module ts { } private createChildren(sourceFile?: SourceFile) { + let children: Node[]; if (this.kind >= SyntaxKind.FirstNode) { scanner.setText((sourceFile || this.getSourceFile()).text); - var children: Node[] = []; - var pos = this.pos; - var processNode = (node: Node) => { + children = []; + let pos = this.pos; + let processNode = (node: Node) => { if (pos < node.pos) { pos = this.addSyntheticNodes(children, pos, node.pos); } children.push(node); pos = node.end; }; - var processNodes = (nodes: NodeArray) => { + let processNodes = (nodes: NodeArray) => { if (pos < nodes.pos) { pos = this.addSyntheticNodes(children, pos, nodes.pos); } @@ -253,7 +254,7 @@ module ts { } public getFirstToken(sourceFile?: SourceFile): Node { - var children = this.getChildren(); + let children = this.getChildren(); for (let child of children) { if (child.kind < SyntaxKind.FirstNode) { return child; @@ -264,9 +265,9 @@ module ts { } public getLastToken(sourceFile?: SourceFile): Node { - var children = this.getChildren(sourceFile); - for (var i = children.length - 1; i >= 0; i--) { - var child = children[i]; + let children = this.getChildren(sourceFile); + for (let i = children.length - 1; i >= 0; i--) { + let child = children[i]; if (child.kind < SyntaxKind.FirstNode) { return child; } @@ -312,8 +313,8 @@ module ts { } function getJsDocCommentsFromDeclarations(declarations: Declaration[], name: string, canUseParsedParamTagComments: boolean) { - var documentationComment = []; - var docComments = getJsDocCommentsSeparatedByNewLines(); + let documentationComment = []; + let docComments = getJsDocCommentsSeparatedByNewLines(); ts.forEach(docComments, docComment => { if (documentationComment.length) { documentationComment.push(lineBreakPart()); @@ -324,22 +325,22 @@ module ts { return documentationComment; function getJsDocCommentsSeparatedByNewLines() { - var paramTag = "@param"; - var jsDocCommentParts: SymbolDisplayPart[] = []; + let paramTag = "@param"; + let jsDocCommentParts: SymbolDisplayPart[] = []; ts.forEach(declarations, (declaration, indexOfDeclaration) => { // Make sure we are collecting doc comment from declaration once, // In case of union property there might be same declaration multiple times // which only varies in type parameter - // Eg. var a: Array | Array; a.length + // Eg. let a: Array | Array; a.length // The property length will have two declarations of property length coming // from Array - Array and Array if (indexOf(declarations, declaration) === indexOfDeclaration) { - var sourceFileOfDeclaration = getSourceFileOfNode(declaration); + let sourceFileOfDeclaration = getSourceFileOfNode(declaration); // If it is parameter - try and get the jsDoc comment with @param tag from function declaration's jsDoc comments if (canUseParsedParamTagComments && declaration.kind === SyntaxKind.Parameter) { ts.forEach(getJsDocCommentTextRange(declaration.parent, sourceFileOfDeclaration), jsDocCommentTextRange => { - var cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + let cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedParamJsDocComment) { jsDocCommentParts.push.apply(jsDocCommentParts, cleanedParamJsDocComment); } @@ -359,7 +360,7 @@ module ts { // Get the cleaned js doc comment text from the declaration ts.forEach(getJsDocCommentTextRange( declaration.kind === SyntaxKind.VariableDeclaration ? declaration.parent.parent : declaration, sourceFileOfDeclaration), jsDocCommentTextRange => { - var cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); + let cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration); if (cleanedJsDocComment) { jsDocCommentParts.push.apply(jsDocCommentParts, cleanedJsDocComment); } @@ -385,7 +386,7 @@ module ts { } for (; pos < end; pos++) { - var ch = sourceFile.text.charCodeAt(pos); + let ch = sourceFile.text.charCodeAt(pos); if (!isWhiteSpace(ch) || isLineBreak(ch)) { // Either found lineBreak or non whiteSpace return pos; @@ -422,19 +423,19 @@ module ts { } function getCleanedJsDocComment(pos: number, end: number, sourceFile: SourceFile) { - var spacesToRemoveAfterAsterisk: number; - var docComments: SymbolDisplayPart[] = []; - var blankLineCount = 0; - var isInParamTag = false; + let spacesToRemoveAfterAsterisk: number; + let docComments: SymbolDisplayPart[] = []; + let blankLineCount = 0; + let isInParamTag = false; while (pos < end) { - var docCommentTextOfLine = ""; + let docCommentTextOfLine = ""; // First consume leading white space pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile); // If the comment starts with '*' consume the spaces on this line if (pos < end && sourceFile.text.charCodeAt(pos) === CharacterCodes.asterisk) { - var lineStartPos = pos + 1; + let lineStartPos = pos + 1; pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, spacesToRemoveAfterAsterisk); // Set the spaces to remove after asterisk as margin if not already set @@ -448,7 +449,7 @@ module ts { // Analyse text on this line while (pos < end && !isLineBreak(sourceFile.text.charCodeAt(pos))) { - var ch = sourceFile.text.charAt(pos); + let ch = sourceFile.text.charAt(pos); if (ch === "@") { // If it is @param tag if (isParamTag(pos, end, sourceFile)) { @@ -486,12 +487,12 @@ module ts { } function getCleanedParamJsDocComment(pos: number, end: number, sourceFile: SourceFile) { - var paramHelpStringMargin: number; - var paramDocComments: SymbolDisplayPart[] = []; + let paramHelpStringMargin: number; + let paramDocComments: SymbolDisplayPart[] = []; while (pos < end) { if (isParamTag(pos, end, sourceFile)) { - var blankLineCount = 0; - var recordedParamTag = false; + let blankLineCount = 0; + let recordedParamTag = false; // Consume leading spaces pos = consumeWhiteSpaces(pos + paramTag.length); if (pos >= end) { @@ -501,8 +502,8 @@ module ts { // Ignore type expression if (sourceFile.text.charCodeAt(pos) === CharacterCodes.openBrace) { pos++; - for (var curlies = 1; pos < end; pos++) { - var charCode = sourceFile.text.charCodeAt(pos); + for (let curlies = 1; pos < end; pos++) { + let charCode = sourceFile.text.charCodeAt(pos); // { character means we need to find another } to match the found one if (charCode === CharacterCodes.openBrace) { @@ -545,10 +546,10 @@ module ts { break; } - var paramHelpString = ""; - var firstLineParamHelpStringPos = pos; + let paramHelpString = ""; + let firstLineParamHelpStringPos = pos; while (pos < end) { - var ch = sourceFile.text.charCodeAt(pos); + let ch = sourceFile.text.charCodeAt(pos); // at line break, set this comment line text and go to next line if (isLineBreak(ch)) { @@ -617,15 +618,15 @@ module ts { } // Now consume white spaces max - var startOfLinePos = pos; + let startOfLinePos = pos; pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile, paramHelpStringMargin); if (pos >= end) { return; } - var consumedSpaces = pos - startOfLinePos; + let consumedSpaces = pos - startOfLinePos; if (consumedSpaces < paramHelpStringMargin) { - var ch = sourceFile.text.charCodeAt(pos); + let ch = sourceFile.text.charCodeAt(pos); if (ch === CharacterCodes.asterisk) { // Consume more spaces after asterisk pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, paramHelpStringMargin - consumedSpaces - 1); @@ -765,18 +766,18 @@ module ts { public getNamedDeclarations() { if (!this.namedDeclarations) { - var sourceFile = this; - var namedDeclarations: Declaration[] = []; + let sourceFile = this; + let namedDeclarations: Declaration[] = []; forEachChild(sourceFile, function visit(node: Node): void { switch (node.kind) { case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - var functionDeclaration = node; + let functionDeclaration = node; if (functionDeclaration.name && functionDeclaration.name.getFullWidth() > 0) { - var lastDeclaration = namedDeclarations.length > 0 ? + let lastDeclaration = namedDeclarations.length > 0 ? namedDeclarations[namedDeclarations.length - 1] : undefined; @@ -856,7 +857,7 @@ module ts { break; case SyntaxKind.ImportDeclaration: - var importClause = (node).importClause; + let importClause = (node).importClause; if (importClause) { // Handle default import case e.g.: // import d from "mod"; @@ -1324,7 +1325,7 @@ module ts { static enumElement = "enum"; // Inside module and script only - // var v = .. + // let v = .. static variableElement = "var"; // Inside function @@ -1468,7 +1469,7 @@ module ts { } // If the parent is not sourceFile or module block it is local variable - for (var parent = declaration.parent; !isFunctionBlock(parent); parent = parent.parent) { + for (let parent = declaration.parent; !isFunctionBlock(parent); parent = parent.parent) { // Reached source file or module block if (parent.kind === SyntaxKind.SourceFile || parent.kind === SyntaxKind.ModuleBlock) { return false; @@ -1520,7 +1521,7 @@ module ts { this.fileNameToEntry = {}; // Initialize the list with the root file names - var rootFileNames = host.getScriptFileNames(); + let rootFileNames = host.getScriptFileNames(); for (let fileName of rootFileNames) { this.createEntry(fileName); } @@ -1534,8 +1535,8 @@ module ts { } private createEntry(fileName: string) { - var entry: HostFileInformation; - var scriptSnapshot = this.host.getScriptSnapshot(fileName); + let entry: HostFileInformation; + let scriptSnapshot = this.host.getScriptSnapshot(fileName); if (scriptSnapshot) { entry = { hostFileName: fileName, @@ -1564,7 +1565,7 @@ module ts { } public getRootFileNames(): string[] { - var fileNames: string[] = []; + let fileNames: string[] = []; forEachKey(this.fileNameToEntry, key => { if (hasProperty(this.fileNameToEntry, key) && this.fileNameToEntry[key]) @@ -1575,12 +1576,12 @@ module ts { } public getVersion(fileName: string): string { - var file = this.getEntry(fileName); + let file = this.getEntry(fileName); return file && file.version; } public getScriptSnapshot(fileName: string): IScriptSnapshot { - var file = this.getEntry(fileName); + let file = this.getEntry(fileName); return file && file.scriptSnapshot; } } @@ -1597,14 +1598,14 @@ module ts { } public getCurrentSourceFile(fileName: string): SourceFile { - var scriptSnapshot = this.host.getScriptSnapshot(fileName); + let scriptSnapshot = this.host.getScriptSnapshot(fileName); if (!scriptSnapshot) { // The host does not know about this file. throw new Error("Could not find file: '" + fileName + "'."); } - var version = this.host.getScriptVersion(fileName); - var sourceFile: SourceFile; + let version = this.host.getScriptVersion(fileName); + let sourceFile: SourceFile; if (this.currentFileName !== fileName) { // This is a new file, just parse it @@ -1612,7 +1613,7 @@ module ts { } else if (this.currentFileVersion !== version) { // This is the same file, just a newer version. Incrementally parse the file. - var editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); + let editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange); } @@ -1634,14 +1635,14 @@ module ts { } export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile { - var sourceFile = createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), scriptTarget, setNodeParents); + let sourceFile = createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), scriptTarget, setNodeParents); setSourceFileFields(sourceFile, scriptSnapshot, version); // after full parsing we can use table with interned strings as name table sourceFile.nameTable = sourceFile.identifiers; return sourceFile; } - export var disableIncrementalParsing = false; + export let disableIncrementalParsing = false; export function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile { // If we were given a text change range, and our version or open-ness changed, then @@ -1650,7 +1651,7 @@ module ts { if (version !== sourceFile.version) { // Once incremental parsing is ready, then just call into this function. if (!disableIncrementalParsing) { - var newSourceFile = updateSourceFile(sourceFile, scriptSnapshot.getText(0, scriptSnapshot.getLength()), textChangeRange, aggressiveChecks); + let newSourceFile = updateSourceFile(sourceFile, scriptSnapshot.getText(0, scriptSnapshot.getLength()), textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later @@ -1667,15 +1668,15 @@ module ts { export function createDocumentRegistry(): DocumentRegistry { // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. - var buckets: Map> = {}; + let buckets: Map> = {}; function getKeyFromCompilationSettings(settings: CompilerOptions): string { return "_" + settings.target; // + "|" + settings.propagateEnumConstantoString() } function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): Map { - var key = getKeyFromCompilationSettings(settings); - var bucket = lookUp(buckets, key); + let key = getKeyFromCompilationSettings(settings); + let bucket = lookUp(buckets, key); if (!bucket && createIfMissing) { buckets[key] = bucket = {}; } @@ -1683,11 +1684,11 @@ module ts { } function reportStats() { - var bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === '_').map(name => { - var entries = lookUp(buckets, name); - var sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; - for (var i in entries) { - var entry = entries[i]; + let bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === '_').map(name => { + let entries = lookUp(buckets, name); + let sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; + for (let i in entries) { + let entry = entries[i]; sourceFiles.push({ name: i, refCount: entry.languageServiceRefCount, @@ -1718,13 +1719,13 @@ module ts { version: string, acquiring: boolean): SourceFile { - var bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); - var entry = lookUp(bucket, fileName); + let bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); + let entry = lookUp(bucket, fileName); if (!entry) { Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); // Have never seen this file with these settings. Create a new source file for it. - var sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false); + let sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false); bucket[fileName] = entry = { sourceFile: sourceFile, @@ -1755,10 +1756,10 @@ module ts { } function releaseDocument(fileName: string, compilationSettings: CompilerOptions): void { - var bucket = getBucketForCompilationSettings(compilationSettings, false); + let bucket = getBucketForCompilationSettings(compilationSettings, false); Debug.assert(bucket !== undefined); - var entry = lookUp(bucket, fileName); + let entry = lookUp(bucket, fileName); entry.languageServiceRefCount--; Debug.assert(entry.languageServiceRefCount >= 0); @@ -1776,18 +1777,18 @@ module ts { } export function preProcessFile(sourceText: string, readImportFiles = true): PreProcessedFileInfo { - var referencedFiles: FileReference[] = []; - var importedFiles: FileReference[] = []; - var isNoDefaultLib = false; + let referencedFiles: FileReference[] = []; + let importedFiles: FileReference[] = []; + let isNoDefaultLib = false; function processTripleSlashDirectives(): void { - var commentRanges = getLeadingCommentRanges(sourceText, 0); + let commentRanges = getLeadingCommentRanges(sourceText, 0); forEach(commentRanges, commentRange => { - var comment = sourceText.substring(commentRange.pos, commentRange.end); - var referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); + let comment = sourceText.substring(commentRange.pos, commentRange.end); + let referencePathMatchResult = getFileReferenceFromReferencePath(comment, commentRange); if (referencePathMatchResult) { isNoDefaultLib = referencePathMatchResult.isNoDefaultLib; - var fileReference = referencePathMatchResult.fileReference; + let fileReference = referencePathMatchResult.fileReference; if (fileReference) { referencedFiles.push(fileReference); } @@ -1796,8 +1797,8 @@ module ts { } function recordModuleName() { - var importPath = scanner.getTokenValue(); - var pos = scanner.getTokenPos(); + let importPath = scanner.getTokenValue(); + let pos = scanner.getTokenPos(); importedFiles.push({ fileName: importPath, pos: pos, @@ -1807,7 +1808,7 @@ module ts { function processImport(): void { scanner.setText(sourceText); - var token = scanner.scan(); + let token = scanner.scan(); // Look for: // import "mod"; // import d from "mod" @@ -1972,7 +1973,7 @@ module ts { * Note: 'node' cannot be a SourceFile. */ function isLabeledBy(node: Node, labelName: string) { - for (var owner = node.parent; owner.kind === SyntaxKind.LabeledStatement; owner = owner.parent) { + for (let owner = node.parent; owner.kind === SyntaxKind.LabeledStatement; owner = owner.parent) { if ((owner).label.text === labelName) { return true; } @@ -2066,8 +2067,8 @@ module ts { return true; } else if (position === comment.end) { - var text = sourceFile.text; - var width = comment.end - comment.pos; + let text = sourceFile.text; + let width = comment.end - comment.pos; // is single line comment or just /* if (width <= 2 || text.charCodeAt(comment.pos + 1) === CharacterCodes.slash) { return true; @@ -2099,8 +2100,8 @@ module ts { } // A cache of completion entries for keywords, these do not change between sessions - var keywordCompletions: CompletionEntry[] = []; - for (var i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) { + let keywordCompletions: CompletionEntry[] = []; + for (let i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) { keywordCompletions.push({ name: tokenToString(i), kind: ScriptElementKind.keyword, @@ -2171,15 +2172,15 @@ module ts { } export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = createDocumentRegistry()): LanguageService { - var syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); - var ruleProvider: formatting.RulesProvider; - var program: Program; + let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); + let ruleProvider: formatting.RulesProvider; + let program: Program; // this checker is used to answer all LS questions except errors - var typeInfoResolver: TypeChecker; - var useCaseSensitivefileNames = false; - var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); - var activeCompletionSession: CompletionSession; // The current active completion session, used to get the completion entry details + let typeInfoResolver: TypeChecker; + let useCaseSensitivefileNames = false; + let cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); + let activeCompletionSession: CompletionSession; // The current active completion session, used to get the completion entry details // Check if the localized messages json is set, otherwise query the host for it if (!localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) { @@ -2198,7 +2199,7 @@ module ts { function getValidSourceFile(fileName: string): SourceFile { fileName = normalizeSlashes(fileName); - var sourceFile = program.getSourceFile(getCanonicalFileName(fileName)); + let sourceFile = program.getSourceFile(getCanonicalFileName(fileName)); if (!sourceFile) { throw new Error("Could not find file: '" + fileName + "'."); } @@ -2217,7 +2218,7 @@ module ts { function synchronizeHostData(): void { // Get a fresh cache of the host information - var hostCache = new HostCache(host); + let hostCache = new HostCache(host); // If the program is already up-to-date, we can reuse it if (programUpToDate()) { @@ -2230,12 +2231,12 @@ module ts { // the program points to old source files that have been invalidated because of // incremental parsing. - var oldSettings = program && program.getCompilerOptions(); - var newSettings = hostCache.compilationSettings(); - var changesInCompilationSettingsAffectSyntax = oldSettings && oldSettings.target !== newSettings.target; + let oldSettings = program && program.getCompilerOptions(); + let newSettings = hostCache.compilationSettings(); + let changesInCompilationSettingsAffectSyntax = oldSettings && oldSettings.target !== newSettings.target; // Now create a new compiler - var newProgram = createProgram(hostCache.getRootFileNames(), newSettings, { + let newProgram = createProgram(hostCache.getRootFileNames(), newSettings, { getSourceFile: getOrCreateSourceFile, getCancellationToken: () => cancellationToken, getCanonicalFileName: (fileName) => useCaseSensitivefileNames ? fileName : fileName.toLowerCase(), @@ -2249,9 +2250,9 @@ module ts { // Release any files we have acquired in the old program but are // not part of the new program. if (program) { - var oldSourceFiles = program.getSourceFiles(); + let oldSourceFiles = program.getSourceFiles(); for (let oldSourceFile of oldSourceFiles) { - var fileName = oldSourceFile.fileName; + let fileName = oldSourceFile.fileName; if (!newProgram.getSourceFile(fileName) || changesInCompilationSettingsAffectSyntax) { documentRegistry.releaseDocument(fileName, oldSettings); } @@ -2267,7 +2268,7 @@ module ts { // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. - var hostFileInformation = hostCache.getOrCreateEntry(fileName); + let hostFileInformation = hostCache.getOrCreateEntry(fileName); if (!hostFileInformation) { return undefined; } @@ -2277,7 +2278,7 @@ module ts { // can not be reused. we have to dump all syntax trees and create new ones. if (!changesInCompilationSettingsAffectSyntax) { // Check if the old program had this file already - var oldSourceFile = program && program.getSourceFile(fileName); + let oldSourceFile = program && program.getSourceFile(fileName); if (oldSourceFile) { // We already had a source file for this file name. Go to the registry to // ensure that we get the right up to date version of it. We need this to @@ -2321,7 +2322,7 @@ module ts { } // If number of files in the program do not match, it is not up-to-date - var rootFileNames = hostCache.getRootFileNames(); + let rootFileNames = hostCache.getRootFileNames(); if (program.getSourceFiles().length !== rootFileNames.length) { return false; } @@ -2376,18 +2377,18 @@ module ts { function getSemanticDiagnostics(fileName: string) { synchronizeHostData(); - var targetSourceFile = getValidSourceFile(fileName); + let targetSourceFile = getValidSourceFile(fileName); // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file. // Therefore only get diagnostics for given file. - var semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile); + let semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile); if (!program.getCompilerOptions().declaration) { return semanticDiagnostics; } // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface - var declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile); + let declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile); return semanticDiagnostics.concat(declarationDiagnostics); } @@ -2398,13 +2399,13 @@ module ts { /// Completion function getValidCompletionEntryDisplayName(symbol: Symbol, target: ScriptTarget): string { - var displayName = symbol.getName(); + let displayName = symbol.getName(); if (displayName && displayName.length > 0) { - var firstCharCode = displayName.charCodeAt(0); + let firstCharCode = displayName.charCodeAt(0); // First check of the displayName is not external module; if it is an external module, it is not valid entry if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) { // If the symbol is external module, don't show it in the completion list - // (i.e declare module "http" { var x; } | // <= request completion here, "http" should not be there) + // (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there) return undefined; } @@ -2415,8 +2416,8 @@ module ts { displayName = displayName.substring(1, displayName.length - 1); } - var isValid = isIdentifierStart(displayName.charCodeAt(0), target); - for (var i = 1, n = displayName.length; isValid && i < n; i++) { + let isValid = isIdentifierStart(displayName.charCodeAt(0), target); + for (let i = 1, n = displayName.length; isValid && i < n; i++) { isValid = isIdentifierPart(displayName.charCodeAt(i), target); } @@ -2433,7 +2434,7 @@ module ts { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can // not be accessed with a dot (a.1 <- invalid) - var displayName = getValidCompletionEntryDisplayName(symbol, program.getCompilerOptions().target); + let displayName = getValidCompletionEntryDisplayName(symbol, program.getCompilerOptions().target); if (!displayName) { return undefined; } @@ -2452,16 +2453,16 @@ module ts { function getCompletionsAtPosition(fileName: string, position: number) { synchronizeHostData(); - var syntacticStart = new Date().getTime(); - var sourceFile = getValidSourceFile(fileName); + let syntacticStart = new Date().getTime(); + let sourceFile = getValidSourceFile(fileName); - var start = new Date().getTime(); - var currentToken = getTokenAtPosition(sourceFile, position); + let start = new Date().getTime(); + let currentToken = getTokenAtPosition(sourceFile, position); log("getCompletionsAtPosition: Get current token: " + (new Date().getTime() - start)); - var start = new Date().getTime(); + start = new Date().getTime(); // Completion not allowed inside comments, bail out if this is the case - var insideComment = isInsideComment(sourceFile, currentToken, position); + let insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionsAtPosition: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { @@ -2471,14 +2472,14 @@ module ts { // The decision to provide completion depends on the previous token, so find it // Note: previousToken can be undefined if we are the beginning of the file - var start = new Date().getTime(); - var previousToken = findPrecedingToken(position, sourceFile); + start = new Date().getTime(); + let previousToken = findPrecedingToken(position, sourceFile); log("getCompletionsAtPosition: Get previous token 1: " + (new Date().getTime() - start)); // The caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier to the previous token if (previousToken && position <= previousToken.end && previousToken.kind === SyntaxKind.Identifier) { - var start = new Date().getTime(); + let start = new Date().getTime(); previousToken = findPrecedingToken(previousToken.pos, sourceFile); log("getCompletionsAtPosition: Get previous token 2: " + (new Date().getTime() - start)); } @@ -2491,8 +2492,8 @@ module ts { // Find the node where completion is requested on, in the case of a completion after a dot, it is the member access expression // other wise, it is a request for all visible symbols in the scope, and the node is the current location - var node: Node; - var isRightOfDot: boolean; + let node: Node; + let isRightOfDot: boolean; if (previousToken && previousToken.kind === SyntaxKind.DotToken && previousToken.parent.kind === SyntaxKind.PropertyAccessExpression) { node = (previousToken.parent).expression; isRightOfDot = true; @@ -2516,17 +2517,20 @@ module ts { }; log("getCompletionsAtPosition: Syntactic work: " + (new Date().getTime() - syntacticStart)); - var location = getTouchingPropertyName(sourceFile, position); + let location = getTouchingPropertyName(sourceFile, position); // Populate the completion list - var semanticStart = new Date().getTime(); + let semanticStart = new Date().getTime(); + let isMemberCompletion: boolean; + let isNewIdentifierLocation: boolean; + if (isRightOfDot) { // Right of dot member completion list - var symbols: Symbol[] = []; - var isMemberCompletion = true; - var isNewIdentifierLocation = false; + let symbols: Symbol[] = []; + isMemberCompletion = true; + isNewIdentifierLocation = false; if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.PropertyAccessExpression) { - var symbol = typeInfoResolver.getSymbolAtLocation(node); + let symbol = typeInfoResolver.getSymbolAtLocation(node); // This is an alias, follow what it aliases if (symbol && symbol.flags & SymbolFlags.Alias) { @@ -2543,7 +2547,7 @@ module ts { } } - var type = typeInfoResolver.getTypeAtLocation(node); + let type = typeInfoResolver.getTypeAtLocation(node); if (type) { // Filter private properties forEach(type.getApparentProperties(), symbol => { @@ -2556,21 +2560,21 @@ module ts { getCompletionEntriesFromSymbols(symbols, activeCompletionSession); } else { - var containingObjectLiteral = getContainingObjectLiteralApplicableForCompletion(previousToken); + let containingObjectLiteral = getContainingObjectLiteralApplicableForCompletion(previousToken); if (containingObjectLiteral) { // Object literal expression, look up possible property names from contextual type isMemberCompletion = true; isNewIdentifierLocation = true; - var contextualType = typeInfoResolver.getContextualType(containingObjectLiteral); + let contextualType = typeInfoResolver.getContextualType(containingObjectLiteral); if (!contextualType) { return undefined; } - var contextualTypeMembers = typeInfoResolver.getPropertiesOfType(contextualType); + let contextualTypeMembers = typeInfoResolver.getPropertiesOfType(contextualType); if (contextualTypeMembers && contextualTypeMembers.length > 0) { // Add filtered items to the completion list - var filteredMembers = filterContextualMembersList(contextualTypeMembers, containingObjectLiteral.properties); + let filteredMembers = filterContextualMembersList(contextualTypeMembers, containingObjectLiteral.properties); getCompletionEntriesFromSymbols(filteredMembers, activeCompletionSession); } } @@ -2580,10 +2584,10 @@ module ts { isMemberCompletion = true; isNewIdentifierLocation = true; if (showCompletionsInImportsClause(previousToken)) { - var importDeclaration = getAncestor(previousToken, SyntaxKind.ImportDeclaration); + let importDeclaration = getAncestor(previousToken, SyntaxKind.ImportDeclaration); Debug.assert(importDeclaration !== undefined); - var exports = typeInfoResolver.getExportsOfExternalModule(importDeclaration); - var filteredExports = filterModuleExports(exports, importDeclaration); + let exports = typeInfoResolver.getExportsOfExternalModule(importDeclaration); + let filteredExports = filterModuleExports(exports, importDeclaration); getCompletionEntriesFromSymbols(filteredExports, activeCompletionSession); } } @@ -2593,8 +2597,8 @@ module ts { isNewIdentifierLocation = isNewIdentifierDefinitionLocation(previousToken); /// TODO filter meaning based on the current context - var symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; - var symbols = typeInfoResolver.getSymbolsInScope(node, symbolMeanings); + let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; + let symbols = typeInfoResolver.getSymbolsInScope(node, symbolMeanings); getCompletionEntriesFromSymbols(symbols, activeCompletionSession); } @@ -2614,11 +2618,11 @@ module ts { }; function getCompletionEntriesFromSymbols(symbols: Symbol[], session: CompletionSession): void { - var start = new Date().getTime(); + let start = new Date().getTime(); forEach(symbols, symbol => { - var entry = createCompletionEntry(symbol, session.typeChecker, location); + let entry = createCompletionEntry(symbol, session.typeChecker, location); if (entry) { - var id = escapeIdentifier(entry.name); + let id = escapeIdentifier(entry.name); if (!lookUp(session.symbols, id)) { session.entries.push(entry); session.symbols[id] = symbol; @@ -2629,8 +2633,8 @@ module ts { } function isCompletionListBlocker(previousToken: Node): boolean { - var start = new Date().getTime(); - var result = isInStringOrRegularExpressionOrTemplateLiteral(previousToken) || + let start = new Date().getTime(); + let result = isInStringOrRegularExpressionOrTemplateLiteral(previousToken) || isIdentifierDefinitionLocation(previousToken) || isRightOfIllegalDot(previousToken); log("getCompletionsAtPosition: isCompletionListBlocker: " + (new Date().getTime() - start)); @@ -2651,21 +2655,21 @@ module ts { function isNewIdentifierDefinitionLocation(previousToken: Node): boolean { if (previousToken) { - var containingNodeKind = previousToken.parent.kind; + let containingNodeKind = previousToken.parent.kind; switch (previousToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.CallExpression // func( a, | || containingNodeKind === SyntaxKind.Constructor // constructor( a, | public, protected, private keywords are allowed here, so show completion || containingNodeKind === SyntaxKind.NewExpression // new C(a, | || containingNodeKind === SyntaxKind.ArrayLiteralExpression // [a, | - || containingNodeKind === SyntaxKind.BinaryExpression; // var x = (a, | + || containingNodeKind === SyntaxKind.BinaryExpression; // let x = (a, | case SyntaxKind.OpenParenToken: return containingNodeKind === SyntaxKind.CallExpression // func( | || containingNodeKind === SyntaxKind.Constructor // constructor( | || containingNodeKind === SyntaxKind.NewExpression // new C(a| - || containingNodeKind === SyntaxKind.ParenthesizedExpression; // var x = (a| + || containingNodeKind === SyntaxKind.ParenthesizedExpression; // let x = (a| case SyntaxKind.OpenBracketToken: return containingNodeKind === SyntaxKind.ArrayLiteralExpression; // [ | @@ -2680,7 +2684,7 @@ module ts { return containingNodeKind === SyntaxKind.ClassDeclaration; // class A{ | case SyntaxKind.EqualsToken: - return containingNodeKind === SyntaxKind.VariableDeclaration // var x = a| + return containingNodeKind === SyntaxKind.VariableDeclaration // let x = a| || containingNodeKind === SyntaxKind.BinaryExpression; // x = a| case SyntaxKind.TemplateHead: @@ -2713,8 +2717,8 @@ module ts { || isTemplateLiteralKind(previousToken.kind)) { // The position has to be either: 1. entirely within the token text, or // 2. at the end position of an unterminated token. - var start = previousToken.getStart(); - var end = previousToken.getEnd(); + let start = previousToken.getStart(); + let end = previousToken.getEnd(); if (start < position && position < end) { return true; @@ -2731,11 +2735,11 @@ module ts { // The locations in an object literal expression that are applicable for completion are property name definition locations. if (previousToken) { - var parent = previousToken.parent; + let parent = previousToken.parent; switch (previousToken.kind) { - case SyntaxKind.OpenBraceToken: // var x = { | - case SyntaxKind.CommaToken: // var x = { a: 0, | + case SyntaxKind.OpenBraceToken: // let x = { | + case SyntaxKind.CommaToken: // let x = { a: 0, | if (parent && parent.kind === SyntaxKind.ObjectLiteralExpression) { return parent; } @@ -2765,7 +2769,7 @@ module ts { function isIdentifierDefinitionLocation(previousToken: Node): boolean { if (previousToken) { - var containingNodeKind = previousToken.parent.kind; + let containingNodeKind = previousToken.parent.kind; switch (previousToken.kind) { case SyntaxKind.CommaToken: return containingNodeKind === SyntaxKind.VariableDeclaration || @@ -2792,13 +2796,13 @@ module ts { case SyntaxKind.OpenBraceToken: return containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { | containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface a { | - containingNodeKind === SyntaxKind.TypeLiteral || // var x : { | + containingNodeKind === SyntaxKind.TypeLiteral || // let x : { | containingNodeKind === SyntaxKind.ObjectBindingPattern; // function func({ x| case SyntaxKind.SemicolonToken: return containingNodeKind === SyntaxKind.PropertySignature && (previousToken.parent.parent.kind === SyntaxKind.InterfaceDeclaration || // interface a { f; | - previousToken.parent.parent.kind === SyntaxKind.TypeLiteral); // var x : { a; | + previousToken.parent.parent.kind === SyntaxKind.TypeLiteral); // let x : { a; | case SyntaxKind.LessThanToken: return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< | @@ -2853,7 +2857,7 @@ module ts { function isRightOfIllegalDot(previousToken: Node): boolean { if (previousToken && previousToken.kind === SyntaxKind.NumericLiteral) { - var text = previousToken.getFullText(); + let text = previousToken.getFullText(); return text.charAt(text.length - 1) === "."; } @@ -2861,7 +2865,7 @@ module ts { } function filterModuleExports(exports: Symbol[], importDeclaration: ImportDeclaration): Symbol[] { - var exisingImports: Map = {}; + let exisingImports: Map = {}; if (!importDeclaration.importClause) { return exports; @@ -2871,7 +2875,7 @@ module ts { importDeclaration.importClause.namedBindings.kind === SyntaxKind.NamedImports) { forEach((importDeclaration.importClause.namedBindings).elements, el => { - var name = el.propertyName || el.name; + let name = el.propertyName || el.name; exisingImports[name.text] = true; }); } @@ -2887,7 +2891,7 @@ module ts { return contextualMemberSymbols; } - var existingMemberNames: Map = {}; + let existingMemberNames: Map = {}; forEach(existingMembers, m => { if (m.kind !== SyntaxKind.PropertyAssignment && m.kind !== SyntaxKind.ShorthandPropertyAssignment) { // Ignore omitted expressions for missing members in the object literal @@ -2903,7 +2907,7 @@ module ts { existingMemberNames[(m.name).text] = true; }); - var filteredMembers: Symbol[] = []; + let filteredMembers: Symbol[] = []; forEach(contextualMemberSymbols, s => { if (!existingMemberNames[s.name]) { filteredMembers.push(s); @@ -2917,25 +2921,25 @@ module ts { function getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails { // Note: No need to call synchronizeHostData, as we have captured all the data we need // in the getCompletionsAtPosition earlier - var sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - var session = activeCompletionSession; + let session = activeCompletionSession; // Ensure that the current active completion session is still valid for this request if (!session || session.fileName !== fileName || session.position !== position) { return undefined; } - var symbol = lookUp(activeCompletionSession.symbols, escapeIdentifier(entryName)); + let symbol = lookUp(activeCompletionSession.symbols, escapeIdentifier(entryName)); if (symbol) { - var location = getTouchingPropertyName(sourceFile, position); - var completionEntry = createCompletionEntry(symbol, session.typeChecker, location); + let location = getTouchingPropertyName(sourceFile, position); + let completionEntry = createCompletionEntry(symbol, session.typeChecker, location); // TODO(drosen): Right now we just permit *all* semantic meanings when calling 'getSymbolKind' // which is permissible given that it is backwards compatible; but really we should consider // passing the meaning for the node so that we don't report that a suggestion for a value is an interface. // We COULD also just do what 'getSymbolModifiers' does, which is to use the first declaration. Debug.assert(session.typeChecker.getTypeOfSymbolAtLocation(symbol, location) !== undefined, "Could not find type for symbol"); - var displayPartsDocumentationsAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, session.typeChecker, location, SemanticMeaning.All); + let displayPartsDocumentationsAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, session.typeChecker, location, SemanticMeaning.All); return { name: entryName, kind: displayPartsDocumentationsAndSymbolKind.symbolKind, @@ -2958,7 +2962,7 @@ module ts { // TODO(drosen): use contextual SemanticMeaning. function getSymbolKind(symbol: Symbol, typeResolver: TypeChecker, location: Node): string { - var flags = symbol.getFlags(); + let flags = symbol.getFlags(); if (flags & SymbolFlags.Class) return ScriptElementKind.classElement; if (flags & SymbolFlags.Enum) return ScriptElementKind.enumElement; @@ -2966,7 +2970,7 @@ module ts { if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement; if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; - var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, typeResolver, location); + let result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, typeResolver, location); if (result === ScriptElementKind.unknown) { if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement; @@ -3005,8 +3009,8 @@ module ts { if (flags & SymbolFlags.Property) { if (flags & SymbolFlags.UnionProperty) { // If union property is result of union of non method (property/accessors/variables), it is labeled as property - var unionPropertyKind = forEach(typeInfoResolver.getRootSymbols(symbol), rootSymbol => { - var rootSymbolFlags = rootSymbol.getFlags(); + let unionPropertyKind = forEach(typeInfoResolver.getRootSymbols(symbol), rootSymbol => { + let rootSymbolFlags = rootSymbol.getFlags(); if (rootSymbolFlags & (SymbolFlags.PropertyOrAccessor | SymbolFlags.Variable)) { return ScriptElementKind.memberVariableElement; } @@ -3015,7 +3019,7 @@ module ts { if (!unionPropertyKind) { // If this was union of all methods, //make sure it has call signatures before we can label it as method - var typeOfUnionProperty = typeInfoResolver.getTypeOfSymbolAtLocation(symbol, location); + let typeOfUnionProperty = typeInfoResolver.getTypeOfSymbolAtLocation(symbol, location); if (typeOfUnionProperty.getCallSignatures().length) { return ScriptElementKind.memberFunctionElement; } @@ -3030,7 +3034,7 @@ module ts { } function getTypeKind(type: Type): string { - var flags = type.getFlags(); + let flags = type.getFlags(); if (flags & TypeFlags.Enum) return ScriptElementKind.enumElement; if (flags & TypeFlags.Class) return ScriptElementKind.classElement; @@ -3052,11 +3056,12 @@ module ts { typeResolver: TypeChecker, location: Node, // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location semanticMeaning = getMeaningFromLocation(location)) { - var displayParts: SymbolDisplayPart[] = []; - var documentation: SymbolDisplayPart[]; - var symbolFlags = symbol.flags; - var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, typeResolver, location); - var hasAddedSymbolInfo: boolean; + let displayParts: SymbolDisplayPart[] = []; + let documentation: SymbolDisplayPart[]; + let symbolFlags = symbol.flags; + let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, typeResolver, location); + let hasAddedSymbolInfo: boolean; + let type: Type; // Class at constructor site need to be shown as constructor apart from property,method, vars if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Alias) { // If it is accessor they are allowed only if location is at name of the accessor @@ -3064,10 +3069,11 @@ module ts { symbolKind = ScriptElementKind.memberVariableElement; } - var type = typeResolver.getTypeOfSymbolAtLocation(symbol, location); + let signature: Signature; + type = typeResolver.getTypeOfSymbolAtLocation(symbol, location); if (type) { if (location.parent && location.parent.kind === SyntaxKind.PropertyAccessExpression) { - var right = (location.parent).name; + let right = (location.parent).name; // Either the location is on the right of a property access, or on the left and the right is missing if (right === location || (right && right.getFullWidth() === 0)) { location = location.parent; @@ -3075,7 +3081,7 @@ module ts { } // try get the call/construct signature from the type if it matches - var callExpression: CallExpression; + let callExpression: CallExpression; if (location.kind === SyntaxKind.CallExpression || location.kind === SyntaxKind.NewExpression) { callExpression = location; } @@ -3084,15 +3090,15 @@ module ts { } if (callExpression) { - var candidateSignatures: Signature[] = []; + let candidateSignatures: Signature[] = []; signature = typeResolver.getResolvedSignature(callExpression, candidateSignatures); if (!signature && candidateSignatures.length) { // Use the first candidate: signature = candidateSignatures[0]; } - var useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; - var allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); + let useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; + let allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); if (!contains(allSignatures, signature.target || signature)) { // Get the first signature if there @@ -3151,9 +3157,8 @@ module ts { else if ((isNameOfFunctionDeclaration(location) && !(symbol.flags & SymbolFlags.Accessor)) || // name of function declaration (location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration // get the signature from the declaration and write it - var signature: Signature; - var functionDeclaration = location.parent; - var allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); + let functionDeclaration = location.parent; + let allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures(); if (!typeResolver.isImplementationOfOverload(functionDeclaration)) { signature = typeResolver.getSignatureFromDeclaration(functionDeclaration); } @@ -3233,8 +3238,8 @@ module ts { } else { // Method/function type parameter - var signatureDeclaration = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent; - var signature = typeResolver.getSignatureFromDeclaration(signatureDeclaration); + let signatureDeclaration = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter).parent; + let signature = typeResolver.getSignatureFromDeclaration(signatureDeclaration); if (signatureDeclaration.kind === SyntaxKind.ConstructSignature) { displayParts.push(keywordPart(SyntaxKind.NewKeyword)); displayParts.push(spacePart()); @@ -3247,9 +3252,9 @@ module ts { } if (symbolFlags & SymbolFlags.EnumMember) { addPrefixForAnyFunctionOrVar(symbol, "enum member"); - var declaration = symbol.declarations[0]; + let declaration = symbol.declarations[0]; if (declaration.kind === SyntaxKind.EnumMember) { - var constantValue = typeResolver.getConstantValue(declaration); + let constantValue = typeResolver.getConstantValue(declaration); if (constantValue !== undefined) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -3265,7 +3270,7 @@ module ts { addFullSymbolName(symbol); ts.forEach(symbol.declarations, declaration => { if (declaration.kind === SyntaxKind.ImportEqualsDeclaration) { - var importEqualsDeclaration = declaration; + let importEqualsDeclaration = declaration; if (isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -3276,7 +3281,7 @@ module ts { displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } else { - var internalAliasSymbol = typeResolver.getSymbolAtLocation(importEqualsDeclaration.moduleReference); + let internalAliasSymbol = typeResolver.getSymbolAtLocation(importEqualsDeclaration.moduleReference); if (internalAliasSymbol) { displayParts.push(spacePart()); displayParts.push(operatorPart(SyntaxKind.EqualsToken)); @@ -3300,7 +3305,7 @@ module ts { displayParts.push(spacePart()); // If the type is type parameter, format it specially if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { - var typeParameterParts = mapToDisplayParts(writer => { + let typeParameterParts = mapToDisplayParts(writer => { typeResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration); }); displayParts.push.apply(displayParts, typeParameterParts); @@ -3315,7 +3320,7 @@ module ts { symbolFlags & SymbolFlags.Signature || symbolFlags & SymbolFlags.Accessor || symbolKind === ScriptElementKind.memberFunctionElement) { - var allSignatures = type.getCallSignatures(); + let allSignatures = type.getCallSignatures(); addSignatureDisplayParts(allSignatures[0], allSignatures); } } @@ -3338,7 +3343,7 @@ module ts { } function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) { - var fullSymbolDisplayParts = symbolToDisplayParts(typeResolver, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, + let fullSymbolDisplayParts = symbolToDisplayParts(typeResolver, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing); displayParts.push.apply(displayParts, fullSymbolDisplayParts); } @@ -3369,7 +3374,7 @@ module ts { } function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) { - var typeParameterParts = mapToDisplayParts(writer => { + let typeParameterParts = mapToDisplayParts(writer => { typeResolver.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration); }); displayParts.push.apply(displayParts, typeParameterParts); @@ -3379,13 +3384,13 @@ module ts { function getQuickInfoAtPosition(fileName: string, position: number): QuickInfo { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); - var node = getTouchingPropertyName(sourceFile, position); + let sourceFile = getValidSourceFile(fileName); + let node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } - var symbol = typeInfoResolver.getSymbolAtLocation(node); + let symbol = typeInfoResolver.getSymbolAtLocation(node); if (!symbol) { // Try getting just type at this position and show switch (node.kind) { @@ -3395,7 +3400,7 @@ module ts { case SyntaxKind.ThisKeyword: case SyntaxKind.SuperKeyword: // For the identifiers/this/super etc get the type at position - var type = typeInfoResolver.getTypeAtLocation(node); + let type = typeInfoResolver.getTypeAtLocation(node); if (type) { return { kind: ScriptElementKind.unknown, @@ -3410,7 +3415,7 @@ module ts { return undefined; } - var displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), typeInfoResolver, node); + let displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), typeInfoResolver, node); return { kind: displayPartsDocumentationsAndKind.symbolKind, kindModifiers: getSymbolModifiers(symbol), @@ -3424,24 +3429,24 @@ module ts { function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - var node = getTouchingPropertyName(sourceFile, position); + let node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } // Labels if (isJumpStatementTarget(node)) { - var labelName = (node).text; - var label = getTargetLabel((node.parent), (node).text); + let labelName = (node).text; + let label = getTargetLabel((node.parent), (node).text); return label ? [getDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined; } /// Triple slash reference comments - var comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); + let comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); if (comment) { - var referenceFile = tryResolveScriptReference(program, sourceFile, comment); + let referenceFile = tryResolveScriptReference(program, sourceFile, comment); if (referenceFile) { return [{ fileName: referenceFile.fileName, @@ -3455,7 +3460,7 @@ module ts { return undefined; } - var symbol = typeInfoResolver.getSymbolAtLocation(node); + let symbol = typeInfoResolver.getSymbolAtLocation(node); // Could not find a symbol e.g. node is string or number keyword, // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol @@ -3468,13 +3473,13 @@ module ts { // import {A, B} from "mod"; // to jump to the implementation directelly. if (symbol.flags & SymbolFlags.Alias) { - var declaration = symbol.declarations[0]; + let declaration = symbol.declarations[0]; if (node.kind === SyntaxKind.Identifier && node.parent === declaration) { symbol = typeInfoResolver.getAliasedSymbol(symbol); } } - var result: DefinitionInfo[] = []; + let result: DefinitionInfo[] = []; // Because name in short-hand property assignment has two different meanings: property name and property value, // using go-to-definition at such position should go to the variable declaration of the property value rather than @@ -3482,22 +3487,22 @@ module ts { // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { - var shorthandSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); - var shorthandDeclarations = shorthandSymbol.getDeclarations(); - var shorthandSymbolKind = getSymbolKind(shorthandSymbol, typeInfoResolver, node); - var shorthandSymbolName = typeInfoResolver.symbolToString(shorthandSymbol); - var shorthandContainerName = typeInfoResolver.symbolToString(symbol.parent, node); + let shorthandSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); + let shorthandDeclarations = shorthandSymbol.getDeclarations(); + let shorthandSymbolKind = getSymbolKind(shorthandSymbol, typeInfoResolver, node); + let shorthandSymbolName = typeInfoResolver.symbolToString(shorthandSymbol); + let shorthandContainerName = typeInfoResolver.symbolToString(symbol.parent, node); forEach(shorthandDeclarations, declaration => { result.push(getDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName)); }); return result } - var declarations = symbol.getDeclarations(); - var symbolName = typeInfoResolver.symbolToString(symbol); // Do not get scoped name, just the name of the symbol - var symbolKind = getSymbolKind(symbol, typeInfoResolver, node); - var containerSymbol = symbol.parent; - var containerName = containerSymbol ? typeInfoResolver.symbolToString(containerSymbol, node) : ""; + let declarations = symbol.getDeclarations(); + let symbolName = typeInfoResolver.symbolToString(symbol); // Do not get scoped name, just the name of the symbol + let symbolKind = getSymbolKind(symbol, typeInfoResolver, node); + let containerSymbol = symbol.parent; + let containerName = containerSymbol ? typeInfoResolver.symbolToString(containerSymbol, node) : ""; if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) && !tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) { @@ -3521,8 +3526,8 @@ module ts { } function tryAddSignature(signatureDeclarations: Declaration[], selectConstructors: boolean, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) { - var declarations: Declaration[] = []; - var definition: Declaration; + let declarations: Declaration[] = []; + let definition: Declaration; forEach(signatureDeclarations, d => { if ((selectConstructors && d.kind === SyntaxKind.Constructor) || @@ -3549,7 +3554,7 @@ module ts { // and in either case the symbol has a construct signature definition, i.e. class if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) { if (symbol.flags & SymbolFlags.Class) { - var classDeclaration = symbol.getDeclarations()[0]; + let classDeclaration = symbol.getDeclarations()[0]; Debug.assert(classDeclaration && classDeclaration.kind === SyntaxKind.ClassDeclaration); return tryAddSignature(classDeclaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); @@ -3570,9 +3575,9 @@ module ts { function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - var node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); if (!node) { return undefined; } @@ -3660,7 +3665,7 @@ module ts { return undefined; function getIfElseOccurrences(ifStatement: IfStatement): ReferenceEntry[] { - var keywords: Node[] = []; + let keywords: Node[] = []; // Traverse upwards through all parent if-statements linked by their else-branches. while (hasKind(ifStatement.parent, SyntaxKind.IfStatement) && (ifStatement.parent).elseStatement === ifStatement) { @@ -3669,11 +3674,11 @@ module ts { // Now traverse back down through the else branches, aggregating if/else keywords of if-statements. while (ifStatement) { - var children = ifStatement.getChildren(); + let children = ifStatement.getChildren(); pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword); // Generally the 'else' keyword is second-to-last, so we traverse backwards. - for (var i = children.length - 1; i >= 0; i--) { + for (let i = children.length - 1; i >= 0; i--) { if (pushKeywordIf(keywords, children[i], SyntaxKind.ElseKeyword)) { break; } @@ -3686,19 +3691,19 @@ module ts { ifStatement = ifStatement.elseStatement; } - var result: ReferenceEntry[] = []; + let result: ReferenceEntry[] = []; // We'd like to highlight else/ifs together if they are only separated by whitespace // (i.e. the keywords are separated by no comments, no newlines). - for (var i = 0; i < keywords.length; i++) { + for (let i = 0; i < keywords.length; i++) { if (keywords[i].kind === SyntaxKind.ElseKeyword && i < keywords.length - 1) { - var elseKeyword = keywords[i]; - var ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. + let elseKeyword = keywords[i]; + let ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. - var shouldHighlightNextKeyword = true; + let shouldHighlightNextKeyword = true; // Avoid recalculating getStart() by iterating backwards. - for (var j = ifKeyword.getStart() - 1; j >= elseKeyword.end; j--) { + for (let j = ifKeyword.getStart() - 1; j >= elseKeyword.end; j--) { if (!isWhiteSpace(sourceFile.text.charCodeAt(j))) { shouldHighlightNextKeyword = false; break; @@ -3724,14 +3729,14 @@ module ts { } function getReturnOccurrences(returnStatement: ReturnStatement): ReferenceEntry[] { - var func = getContainingFunction(returnStatement); + let func = getContainingFunction(returnStatement); // If we didn't find a containing function with a block body, bail out. if (!(func && hasKind(func.body, SyntaxKind.Block))) { return undefined; } - var keywords: Node[] = [] + let keywords: Node[] = [] forEachReturnStatement(func.body, returnStatement => { pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword); }); @@ -3745,13 +3750,13 @@ module ts { } function getThrowOccurrences(throwStatement: ThrowStatement) { - var owner = getThrowStatementOwner(throwStatement); + let owner = getThrowStatementOwner(throwStatement); if (!owner) { return undefined; } - var keywords: Node[] = []; + let keywords: Node[] = []; forEach(aggregateOwnedThrowStatements(owner), throwStatement => { pushKeywordIf(keywords, throwStatement.getFirstToken(), SyntaxKind.ThrowKeyword); @@ -3773,7 +3778,7 @@ module ts { * into function boundaries and try-blocks with catch-clauses. */ function aggregateOwnedThrowStatements(node: Node): ThrowStatement[] { - var statementAccumulator: ThrowStatement[] = [] + let statementAccumulator: ThrowStatement[] = [] aggregate(node); return statementAccumulator; @@ -3782,7 +3787,7 @@ module ts { statementAccumulator.push(node); } else if (node.kind === SyntaxKind.TryStatement) { - var tryStatement = node; + let tryStatement = node; if (tryStatement.catchClause) { aggregate(tryStatement.catchClause); @@ -3810,10 +3815,10 @@ module ts { * function-block, or source file. */ function getThrowStatementOwner(throwStatement: ThrowStatement): Node { - var child: Node = throwStatement; + let child: Node = throwStatement; while (child.parent) { - var parent = child.parent; + let parent = child.parent; if (isFunctionBlock(parent) || parent.kind === SyntaxKind.SourceFile) { return parent; @@ -3822,7 +3827,7 @@ module ts { // A throw-statement is only owned by a try-statement if the try-statement has // a catch clause, and if the throw-statement occurs within the try block. if (parent.kind === SyntaxKind.TryStatement) { - var tryStatement = parent; + let tryStatement = parent; if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; @@ -3836,7 +3841,7 @@ module ts { } function getTryCatchFinallyOccurrences(tryStatement: TryStatement): ReferenceEntry[] { - var keywords: Node[] = []; + let keywords: Node[] = []; pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); @@ -3845,7 +3850,7 @@ module ts { } if (tryStatement.finallyBlock) { - var finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); + let finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile); pushKeywordIf(keywords, finallyKeyword, SyntaxKind.FinallyKeyword); } @@ -3853,14 +3858,14 @@ module ts { } function getLoopBreakContinueOccurrences(loopNode: IterationStatement): ReferenceEntry[] { - var keywords: Node[] = []; + let keywords: Node[] = []; if (pushKeywordIf(keywords, loopNode.getFirstToken(), SyntaxKind.ForKeyword, SyntaxKind.WhileKeyword, SyntaxKind.DoKeyword)) { // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. if (loopNode.kind === SyntaxKind.DoStatement) { - var loopTokens = loopNode.getChildren(); + let loopTokens = loopNode.getChildren(); - for (var i = loopTokens.length - 1; i >= 0; i--) { + for (let i = loopTokens.length - 1; i >= 0; i--) { if (pushKeywordIf(keywords, loopTokens[i], SyntaxKind.WhileKeyword)) { break; } @@ -3868,7 +3873,7 @@ module ts { } } - var breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); + let breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(loopNode, statement)) { @@ -3880,7 +3885,7 @@ module ts { } function getSwitchCaseDefaultOccurrences(switchStatement: SwitchStatement) { - var keywords: Node[] = []; + let keywords: Node[] = []; pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword); @@ -3888,7 +3893,7 @@ module ts { forEach(switchStatement.caseBlock.clauses, clause => { pushKeywordIf(keywords, clause.getFirstToken(), SyntaxKind.CaseKeyword, SyntaxKind.DefaultKeyword); - var breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); + let breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); forEach(breaksAndContinues, statement => { if (ownsBreakOrContinueStatement(switchStatement, statement)) { @@ -3901,7 +3906,7 @@ module ts { } function getBreakOrContinueStatementOccurences(breakOrContinueStatement: BreakOrContinueStatement): ReferenceEntry[] { - var owner = getBreakOrContinueOwner(breakOrContinueStatement); + let owner = getBreakOrContinueOwner(breakOrContinueStatement); if (owner) { switch (owner.kind) { @@ -3921,7 +3926,7 @@ module ts { } function aggregateAllBreakAndContinueStatements(node: Node): BreakOrContinueStatement[] { - var statementAccumulator: BreakOrContinueStatement[] = [] + let statementAccumulator: BreakOrContinueStatement[] = [] aggregate(node); return statementAccumulator; @@ -3937,13 +3942,13 @@ module ts { } function ownsBreakOrContinueStatement(owner: Node, statement: BreakOrContinueStatement): boolean { - var actualOwner = getBreakOrContinueOwner(statement); + let actualOwner = getBreakOrContinueOwner(statement); return actualOwner && actualOwner === owner; } function getBreakOrContinueOwner(statement: BreakOrContinueStatement): Node { - for (var node = statement.parent; node; node = node.parent) { + for (let node = statement.parent; node; node = node.parent) { switch (node.kind) { case SyntaxKind.SwitchStatement: if (statement.kind === SyntaxKind.ContinueStatement) { @@ -3972,9 +3977,9 @@ module ts { } function getConstructorOccurrences(constructorDeclaration: ConstructorDeclaration): ReferenceEntry[] { - var declarations = constructorDeclaration.symbol.getDeclarations() + let declarations = constructorDeclaration.symbol.getDeclarations() - var keywords: Node[] = []; + let keywords: Node[] = []; forEach(declarations, declaration => { forEach(declaration.getChildren(), token => { @@ -3986,7 +3991,7 @@ module ts { } function getGetAndSetOccurrences(accessorDeclaration: AccessorDeclaration): ReferenceEntry[] { - var keywords: Node[] = []; + let keywords: Node[] = []; tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.GetAccessor); tryPushAccessorKeyword(accessorDeclaration.symbol, SyntaxKind.SetAccessor); @@ -3994,7 +3999,7 @@ module ts { return map(keywords, getReferenceEntryFromNode); function tryPushAccessorKeyword(accessorSymbol: Symbol, accessorKind: SyntaxKind): void { - var accessor = getDeclarationOfKind(accessorSymbol, accessorKind); + let accessor = getDeclarationOfKind(accessorSymbol, accessorKind); if (accessor) { forEach(accessor.getChildren(), child => pushKeywordIf(keywords, child, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword)); @@ -4003,7 +4008,7 @@ module ts { } function getModifierOccurrences(modifier: SyntaxKind, declaration: Node) { - var container = declaration.parent; + let container = declaration.parent; // Make sure we only highlight the keyword when it makes sense to do so. if (declaration.flags & NodeFlags.AccessibilityModifier) { @@ -4027,10 +4032,10 @@ module ts { return undefined; } - var keywords: Node[] = []; - var modifierFlag: NodeFlags = getFlagFromModifier(modifier); + let keywords: Node[] = []; + let modifierFlag: NodeFlags = getFlagFromModifier(modifier); - var nodes: Node[]; + let nodes: Node[]; switch (container.kind) { case SyntaxKind.ModuleBlock: case SyntaxKind.SourceFile: @@ -4046,7 +4051,7 @@ module ts { // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & NodeFlags.AccessibilityModifier) { - var constructor = forEach((container).members, member => { + let constructor = forEach((container).members, member => { return member.kind === SyntaxKind.Constructor && member; }); @@ -4118,9 +4123,9 @@ module ts { function findReferences(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ReferenceEntry[] { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - var node = getTouchingPropertyName(sourceFile, position); + let node = getTouchingPropertyName(sourceFile, position); if (!node) { return undefined; } @@ -4142,7 +4147,7 @@ module ts { // Labels if (isLabelName(node)) { if (isJumpStatementTarget(node)) { - var labelDefinition = getTargetLabel((node.parent), (node).text); + let labelDefinition = getTargetLabel((node.parent), (node).text); // if we have a label definition, look within its statement for references, if not, then // the label is undefined, just return a set of one for the current node. return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : [getReferenceEntryFromNode(node)]; @@ -4161,7 +4166,7 @@ module ts { return getReferencesForSuperKeyword(node); } - var symbol = typeInfoResolver.getSymbolAtLocation(node); + let symbol = typeInfoResolver.getSymbolAtLocation(node); // Could not find a symbol e.g. unknown identifier if (!symbol) { @@ -4170,24 +4175,24 @@ module ts { return [getReferenceEntryFromNode(node)]; } - var declarations = symbol.declarations; + let declarations = symbol.declarations; // The symbol was an internal symbol and does not have a declaration e.g.undefined symbol if (!declarations || !declarations.length) { return undefined; } - var result: ReferenceEntry[]; + let result: ReferenceEntry[]; // Compute the meaning from the location and the symbol it references - var searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); + let searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations); // Get the text to search for, we need to normalize it as external module names will have quote - var declaredName = getDeclaredName(symbol, node); + let declaredName = getDeclaredName(symbol, node); // Try to get the smallest valid scope that we can limit our search to; // otherwise we'll need to search globally (i.e. include each file). - var scope = getSymbolScope(symbol); + let scope = getSymbolScope(symbol); if (scope) { result = []; @@ -4200,11 +4205,11 @@ module ts { getReferencesInNode(sourceFiles[0], symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result); } else { - var internedName = getInternedName(symbol, node, declarations) + let internedName = getInternedName(symbol, node, declarations) forEach(sourceFiles, sourceFile => { cancellationToken.throwIfCancellationRequested(); - var nameTable = getNameTable(sourceFile); + let nameTable = getNameTable(sourceFile); if (lookUp(nameTable, internedName)) { result = result || []; @@ -4230,15 +4235,16 @@ module ts { function getDeclaredName(symbol: Symbol, location: Node) { // Special case for function expressions, whose names are solely local to their bodies. - var functionExpression = forEach(symbol.declarations, d => d.kind === SyntaxKind.FunctionExpression ? d : undefined); + let functionExpression = forEach(symbol.declarations, d => d.kind === SyntaxKind.FunctionExpression ? d : undefined); // When a name gets interned into a SourceFile's 'identifiers' Map, // its name is escaped and stored in the same way its symbol name/identifier // name should be stored. Function expressions, however, are a special case, // because despite sometimes having a name, the binder unconditionally binds them // to a symbol with the name "__function". + let name: string; if (functionExpression && functionExpression.name) { - var name = functionExpression.name.text; + name = functionExpression.name.text; } // If this is an export or import specifier it could have been renamed using the as syntax. @@ -4248,7 +4254,7 @@ module ts { return location.getText(); } - var name = typeInfoResolver.symbolToString(symbol); + name = typeInfoResolver.symbolToString(symbol); return stripQuotes(name); } @@ -4262,25 +4268,22 @@ module ts { } // Special case for function expressions, whose names are solely local to their bodies. - var functionExpression = forEach(declarations, d => d.kind === SyntaxKind.FunctionExpression ? d : undefined); + let functionExpression = forEach(declarations, d => d.kind === SyntaxKind.FunctionExpression ? d : undefined); // When a name gets interned into a SourceFile's 'identifiers' Map, // its name is escaped and stored in the same way its symbol name/identifier // name should be stored. Function expressions, however, are a special case, // because despite sometimes having a name, the binder unconditionally binds them // to a symbol with the name "__function". - if (functionExpression && functionExpression.name) { - var name = functionExpression.name.text; - } - else { - var name = symbol.name; - } + let name = functionExpression && functionExpression.name + ? functionExpression.name.text + : symbol.name; return stripQuotes(name); } function stripQuotes(name: string) { - var length = name.length; + let length = name.length; if (length >= 2 && name.charCodeAt(0) === CharacterCodes.doubleQuote && name.charCodeAt(length - 1) === CharacterCodes.doubleQuote) { return name.substring(1, length - 1); }; @@ -4290,7 +4293,7 @@ module ts { function getSymbolScope(symbol: Symbol): Node { // If this is private property or method, the scope is the containing class if (symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) { - var privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); + let privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined); if (privateDeclaration) { return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration); } @@ -4308,12 +4311,12 @@ module ts { return undefined; } - var scope: Node = undefined; + let scope: Node = undefined; - var declarations = symbol.getDeclarations(); + let declarations = symbol.getDeclarations(); if (declarations) { for (let declaration of declarations) { - var container = getContainerNode(declaration); + let container = getContainerNode(declaration); if (!container) { return undefined; @@ -4339,7 +4342,7 @@ module ts { } function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, start: number, end: number): number[] { - var positions: number[] = []; + let positions: number[] = []; /// TODO: Cache symbol existence for files to save text search // Also, need to make this work for unicode escapes. @@ -4349,11 +4352,11 @@ module ts { return positions; } - var text = sourceFile.text; - var sourceLength = text.length; - var symbolNameLength = symbolName.length; + let text = sourceFile.text; + let sourceLength = text.length; + let symbolNameLength = symbolName.length; - var position = text.indexOf(symbolName, start); + let position = text.indexOf(symbolName, start); while (position >= 0) { cancellationToken.throwIfCancellationRequested(); @@ -4362,7 +4365,7 @@ module ts { // We found a match. Make sure it's not part of a larger word (i.e. the char // before and after it have to be a non-identifier char). - var endPosition = position + symbolNameLength; + let endPosition = position + symbolNameLength; if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) && (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) { @@ -4376,14 +4379,14 @@ module ts { } function getLabelReferencesInNode(container: Node, targetLabel: Identifier): ReferenceEntry[] { - var result: ReferenceEntry[] = []; - var sourceFile = container.getSourceFile(); - var labelName = targetLabel.text; - var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); + let result: ReferenceEntry[] = []; + let sourceFile = container.getSourceFile(); + let labelName = targetLabel.text; + let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - var node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); if (!node || node.getWidth() !== labelName.length) { return; } @@ -4435,19 +4438,19 @@ module ts { findInStrings: boolean, findInComments: boolean, result: ReferenceEntry[]): void { - var sourceFile = container.getSourceFile(); - var tripleSlashDirectivePrefixRegex = /^\/\/\/\s* { cancellationToken.throwIfCancellationRequested(); - var referenceLocation = getTouchingPropertyName(sourceFile, position); + let referenceLocation = getTouchingPropertyName(sourceFile, position); if (!isValidReferencePosition(referenceLocation, searchText)) { // This wasn't the start of a token. Check to see if it might be a // match in a comment or string if that's what the caller is asking @@ -4467,10 +4470,10 @@ module ts { return; } - var referenceSymbol = typeInfoResolver.getSymbolAtLocation(referenceLocation); + let referenceSymbol = typeInfoResolver.getSymbolAtLocation(referenceLocation); if (referenceSymbol) { - var referenceSymbolDeclaration = referenceSymbol.valueDeclaration; - var shorthandValueSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); + let referenceSymbolDeclaration = referenceSymbol.valueDeclaration; + let shorthandValueSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration); if (isRelatableToSearchSet(searchSymbols, referenceSymbol, referenceLocation)) { result.push(getReferenceEntryFromNode(referenceLocation)); } @@ -4488,21 +4491,21 @@ module ts { } function isInString(position: number) { - var token = getTokenAtPosition(sourceFile, position); + let token = getTokenAtPosition(sourceFile, position); return token && token.kind === SyntaxKind.StringLiteral && position > token.getStart(); } function isInComment(position: number) { - var token = getTokenAtPosition(sourceFile, position); + let token = getTokenAtPosition(sourceFile, position); if (token && position < token.getStart()) { // First, we have to see if this position actually landed in a comment. - var commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos); + let commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos); // Then we want to make sure that it wasn't in a "///<" directive comment // We don't want to unintentionally update a file name. return forEach(commentRanges, c => { if (c.pos < position && position < c.end) { - var commentText = sourceFile.text.substring(c.pos, c.end); + let commentText = sourceFile.text.substring(c.pos, c.end); if (!tripleSlashDirectivePrefixRegex.test(commentText)) { return true; } @@ -4515,12 +4518,12 @@ module ts { } function getReferencesForSuperKeyword(superKeyword: Node): ReferenceEntry[] { - var searchSpaceNode = getSuperContainer(superKeyword, /*includeFunctions*/ false); + let searchSpaceNode = getSuperContainer(superKeyword, /*includeFunctions*/ false); if (!searchSpaceNode) { return undefined; } // Whether 'super' occurs in a static context within a class. - var staticFlag = NodeFlags.Static; + let staticFlag = NodeFlags.Static; switch (searchSpaceNode.kind) { case SyntaxKind.PropertyDeclaration: @@ -4537,20 +4540,20 @@ module ts { return undefined; } - var result: ReferenceEntry[] = []; + let result: ReferenceEntry[] = []; - var sourceFile = searchSpaceNode.getSourceFile(); - var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); + let sourceFile = searchSpaceNode.getSourceFile(); + let possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - var node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); if (!node || node.kind !== SyntaxKind.SuperKeyword) { return; } - var container = getSuperContainer(node, /*includeFunctions*/ false); + let container = getSuperContainer(node, /*includeFunctions*/ false); // If we have a 'super' container, we must have an enclosing class. // Now make sure the owning class is the same as the search-space @@ -4564,10 +4567,10 @@ module ts { } function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: SourceFile[]): ReferenceEntry[] { - var searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false); + let searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false); // Whether 'this' occurs in a static context within a class. - var staticFlag = NodeFlags.Static; + let staticFlag = NodeFlags.Static; switch (searchSpaceNode.kind) { case SyntaxKind.MethodDeclaration: @@ -4598,17 +4601,18 @@ module ts { return undefined; } - var result: ReferenceEntry[] = []; + let result: ReferenceEntry[] = []; + let possiblePositions: number[]; if (searchSpaceNode.kind === SyntaxKind.SourceFile) { forEach(sourceFiles, sourceFile => { - var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", sourceFile.getStart(), sourceFile.getEnd()); + possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", sourceFile.getStart(), sourceFile.getEnd()); getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, result); }); } else { - var sourceFile = searchSpaceNode.getSourceFile(); - var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); + let sourceFile = searchSpaceNode.getSourceFile(); + possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd()); getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, result); } @@ -4618,12 +4622,12 @@ module ts { forEach(possiblePositions, position => { cancellationToken.throwIfCancellationRequested(); - var node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); if (!node || node.kind !== SyntaxKind.ThisKeyword) { return; } - var container = getThisContainer(node, /* includeArrowFunctions */ false); + let container = getThisContainer(node, /* includeArrowFunctions */ false); switch (searchSpaceNode.kind) { case SyntaxKind.FunctionExpression: @@ -4657,7 +4661,7 @@ module ts { function populateSearchSymbolSet(symbol: Symbol, location: Node): Symbol[] { // The search set contains at least the current symbol - var result = [symbol]; + let result = [symbol]; // If the symbol is an alias, add what it alaises to the list if (isImportOrExportSpecifierImportSymbol(symbol)) { @@ -4677,13 +4681,13 @@ module ts { * property name and variable declaration of the identifier. * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service * should show both 'name' in 'obj' and 'name' in variable declaration - * var name = "Foo"; - * var obj = { name }; + * let name = "Foo"; + * let obj = { name }; * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration * will be included correctly. */ - var shorthandValueSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(location.parent); + let shorthandValueSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(location.parent); if (shorthandValueSymbol) { result.push(shorthandValueSymbol); } @@ -4721,9 +4725,9 @@ module ts { function getPropertySymbolFromTypeReference(typeReference: TypeReferenceNode) { if (typeReference) { - var type = typeInfoResolver.getTypeAtLocation(typeReference); + let type = typeInfoResolver.getTypeAtLocation(typeReference); if (type) { - var propertySymbol = typeInfoResolver.getPropertyOfType(type, propertyName); + let propertySymbol = typeInfoResolver.getPropertyOfType(type, propertyName); if (propertySymbol) { result.push(propertySymbol); } @@ -4767,7 +4771,7 @@ module ts { // Finally, try all properties with the same name in any type the containing type extended or implemented, and // see if any is in the list if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - var result: Symbol[] = []; + let result: Symbol[] = []; getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result); return forEach(result, s => searchSymbols.indexOf(s) >= 0); } @@ -4778,21 +4782,21 @@ module ts { function getPropertySymbolsFromContextualType(node: Node): Symbol[] { if (isNameOfPropertyAssignment(node)) { - var objectLiteral = node.parent.parent; - var contextualType = typeInfoResolver.getContextualType(objectLiteral); - var name = (node).text; + let objectLiteral = node.parent.parent; + let contextualType = typeInfoResolver.getContextualType(objectLiteral); + let name = (node).text; if (contextualType) { if (contextualType.flags & TypeFlags.Union) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - var unionProperty = contextualType.getProperty(name) + let unionProperty = contextualType.getProperty(name) if (unionProperty) { return [unionProperty]; } else { - var result: Symbol[] = []; + let result: Symbol[] = []; forEach((contextualType).types, t => { - var symbol = t.getProperty(name); + let symbol = t.getProperty(name); if (symbol) { result.push(symbol); } @@ -4801,7 +4805,7 @@ module ts { } } else { - var symbol = contextualType.getProperty(name); + let symbol = contextualType.getProperty(name); if (symbol) { return [symbol]; } @@ -4820,6 +4824,7 @@ module ts { */ function getIntersectingMeaningFromDeclarations(meaning: SemanticMeaning, declarations: Declaration[]): SemanticMeaning { if (declarations) { + let lastIterationMeaning: SemanticMeaning; do { // The result is order-sensitive, for instance if initialMeaning === Namespace, and declarations = [class, instantiated module] // we need to consider both as they initialMeaning intersects with the module in the namespace space, and the module @@ -4827,24 +4832,25 @@ module ts { // To achieve that we will keep iterating until the result stabilizes. // Remember the last meaning - var lastIterationMeaning = meaning; + lastIterationMeaning = meaning; for (let declaration of declarations) { - var declarationMeaning = getMeaningFromDeclaration(declaration); + let declarationMeaning = getMeaningFromDeclaration(declaration); if (declarationMeaning & meaning) { meaning |= declarationMeaning; } } - } while (meaning !== lastIterationMeaning); + } + while (meaning !== lastIterationMeaning); } return meaning; } } function getReferenceEntryFromNode(node: Node): ReferenceEntry { - var start = node.getStart(); - var end = node.getEnd(); + let start = node.getStart(); + let end = node.getEnd(); if (node.kind === SyntaxKind.StringLiteral) { start += 1; @@ -4864,13 +4870,13 @@ module ts { return true; } - var parent = node.parent; + let parent = node.parent; if (parent) { if (parent.kind === SyntaxKind.PostfixUnaryExpression || parent.kind === SyntaxKind.PrefixUnaryExpression) { return true; } else if (parent.kind === SyntaxKind.BinaryExpression && (parent).left === node) { - var operator = (parent).operatorToken.kind; + let operator = (parent).operatorToken.kind; return SyntaxKind.FirstAssignment <= operator && operator <= SyntaxKind.LastAssignment; } } @@ -4892,9 +4898,9 @@ module ts { function getEmitOutput(fileName: string): EmitOutput { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - var outputFiles: OutputFile[] = []; + let outputFiles: OutputFile[] = []; function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) { outputFiles.push({ @@ -4904,7 +4910,7 @@ module ts { }); } - var emitOutput = program.emit(sourceFile, writeFile); + let emitOutput = program.emit(sourceFile, writeFile); return { outputFiles, @@ -4981,8 +4987,8 @@ module ts { } function isNamespaceReference(node: Node): boolean { - var root = node; - var isLastClause = true; + let root = node; + let isLastClause = true; if (root.parent.kind === SyntaxKind.QualifiedName) { while (root.parent && root.parent.kind === SyntaxKind.QualifiedName) root = root.parent; @@ -5043,7 +5049,7 @@ module ts { function getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); return SignatureHelp.getSignatureHelpItems(sourceFile, position, typeInfoResolver, cancellationToken); } @@ -5054,10 +5060,10 @@ module ts { } function getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan { - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Get node at the location - var node = getTouchingPropertyName(sourceFile, startPos); + let node = getTouchingPropertyName(sourceFile, startPos); if (!node) { return; @@ -5080,7 +5086,7 @@ module ts { return; } - var nodeForStartPos = node; + let nodeForStartPos = node; while (true) { if (isRightSideOfPropertyAccess(nodeForStartPos) || isRightSideOfQualifiedName(nodeForStartPos)) { // If on the span is in right side of the the property or qualified name, return the span from the qualified name pos to end of this node @@ -5111,13 +5117,13 @@ module ts { function getBreakpointStatementAtPosition(fileName: string, position: number) { // doesn't use compiler - no need to synchronize with host - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position); } function getNavigationBarItems(fileName: string): NavigationBarItem[]{ - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return NavigationBar.getNavigationBarItems(sourceFile); } @@ -5125,15 +5131,15 @@ module ts { function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - var result: ClassifiedSpan[] = []; + let result: ClassifiedSpan[] = []; processNode(sourceFile); return result; function classifySymbol(symbol: Symbol, meaningAtPosition: SemanticMeaning) { - var flags = symbol.getFlags(); + let flags = symbol.getFlags(); if (flags & SymbolFlags.Class) { return ClassificationTypeNames.className; @@ -5178,9 +5184,9 @@ module ts { // Only walk into nodes that intersect the requested span. if (node && textSpanIntersectsWith(span, node.getStart(), node.getWidth())) { if (node.kind === SyntaxKind.Identifier && node.getWidth() > 0) { - var symbol = typeInfoResolver.getSymbolAtLocation(node); + let symbol = typeInfoResolver.getSymbolAtLocation(node); if (symbol) { - var type = classifySymbol(symbol, getMeaningFromLocation(node)); + let type = classifySymbol(symbol, getMeaningFromLocation(node)); if (type) { result.push({ textSpan: createTextSpan(node.getStart(), node.getWidth()), @@ -5197,19 +5203,19 @@ module ts { function getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] { // doesn't use compiler - no need to synchronize with host - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Make a scanner we can get trivia from. - var triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text); - var mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text); + let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text); + let mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text); - var result: ClassifiedSpan[] = []; + let result: ClassifiedSpan[] = []; processElement(sourceFile); return result; function classifyLeadingTrivia(token: Node): void { - var tokenStart = skipTrivia(sourceFile.text, token.pos, /*stopAfterLineBreak:*/ false); + let tokenStart = skipTrivia(sourceFile.text, token.pos, /*stopAfterLineBreak:*/ false); if (tokenStart === token.pos) { return; } @@ -5217,10 +5223,10 @@ module ts { // token has trivia. Classify them appropriately. triviaScanner.setTextPos(token.pos); while (true) { - var start = triviaScanner.getTextPos(); - var kind = triviaScanner.scan(); - var end = triviaScanner.getTextPos(); - var width = end - start; + let start = triviaScanner.getTextPos(); + let kind = triviaScanner.scan(); + let end = triviaScanner.getTextPos(); + let width = end - start; if (textSpanIntersectsWith(span, start, width)) { if (!isTrivia(kind)) { @@ -5237,8 +5243,8 @@ module ts { } if (kind === SyntaxKind.ConflictMarkerTrivia) { - var text = sourceFile.text; - var ch = text.charCodeAt(start); + let text = sourceFile.text; + let ch = text.charCodeAt(start); // for the <<<<<<< and >>>>>>> markers, we just add them in as comments // in the classification stream. @@ -5280,11 +5286,11 @@ module ts { } function classifyDisabledCodeToken() { - var start = mergeConflictScanner.getTextPos(); - var tokenKind = mergeConflictScanner.scan(); - var end = mergeConflictScanner.getTextPos(); + let start = mergeConflictScanner.getTextPos(); + let tokenKind = mergeConflictScanner.scan(); + let end = mergeConflictScanner.getTextPos(); - var type = classifyTokenType(tokenKind); + let type = classifyTokenType(tokenKind); if (type) { result.push({ textSpan: createTextSpanFromBounds(start, end), @@ -5297,7 +5303,7 @@ module ts { classifyLeadingTrivia(token); if (token.getWidth() > 0) { - var type = classifyTokenType(token.kind, token); + let type = classifyTokenType(token.kind, token); if (type) { result.push({ textSpan: createTextSpan(token.getStart(), token.getWidth()), @@ -5398,7 +5404,7 @@ module ts { function processElement(element: Node) { // Ignore nodes that don't intersect the original span to classify. if (textSpanIntersectsWith(span, element.getFullStart(), element.getFullWidth())) { - var children = element.getChildren(); + let children = element.getChildren(); for (let child of children) { if (isToken(child)) { classifyToken(child); @@ -5414,28 +5420,28 @@ module ts { function getOutliningSpans(fileName: string): OutliningSpan[] { // doesn't use compiler - no need to synchronize with host - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return OutliningElementsCollector.collectElements(sourceFile); } function getBraceMatchingAtPosition(fileName: string, position: number) { - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - var result: TextSpan[] = []; + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let result: TextSpan[] = []; - var token = getTouchingToken(sourceFile, position); + let token = getTouchingToken(sourceFile, position); if (token.getStart(sourceFile) === position) { - var matchKind = getMatchingTokenKind(token); + let matchKind = getMatchingTokenKind(token); // Ensure that there is a corresponding token to match ours. if (matchKind) { - var parentElement = token.parent; + let parentElement = token.parent; - var childNodes = parentElement.getChildren(sourceFile); + let childNodes = parentElement.getChildren(sourceFile); for (let current of childNodes) { if (current.kind === matchKind) { - var range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); - var range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); + let range1 = createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); + let range2 = createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); // We want to order the braces when we return the result. if (range1.start < range2.start) { @@ -5470,30 +5476,30 @@ module ts { } function getIndentationAtPosition(fileName: string, position: number, editorOptions: EditorOptions) { - var start = new Date().getTime(); - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let start = new Date().getTime(); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); log("getIndentationAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start)); - var start = new Date().getTime(); + start = new Date().getTime(); - var result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); + let result = formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions); log("getIndentationAtPosition: computeIndentation : " + (new Date().getTime() - start)); return result; } function getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[] { - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatSelection(start, end, sourceFile, getRuleProvider(options), options); } function getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[] { - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return formatting.formatDocument(sourceFile, getRuleProvider(options), options); } function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[] { - var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); if (key === "}") { return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(options), options); @@ -5517,17 +5523,17 @@ module ts { // anything away. synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); cancellationToken.throwIfCancellationRequested(); - var fileContents = sourceFile.text; - var result: TodoComment[] = []; + let fileContents = sourceFile.text; + let result: TodoComment[] = []; if (descriptors.length > 0) { - var regExp = getTodoCommentsRegExp(); + let regExp = getTodoCommentsRegExp(); - var matchArray: RegExpExecArray; + let matchArray: RegExpExecArray; while (matchArray = regExp.exec(fileContents)) { cancellationToken.throwIfCancellationRequested(); @@ -5548,21 +5554,21 @@ module ts { // // i.e. 'undefined' in position 3 above means TODO(jason) didn't match. // "hack" in position 4 means HACK did match. - var firstDescriptorCaptureIndex = 3; + let firstDescriptorCaptureIndex = 3; Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex); - var preamble = matchArray[1]; - var matchPosition = matchArray.index + preamble.length; + let preamble = matchArray[1]; + let matchPosition = matchArray.index + preamble.length; // OK, we have found a match in the file. This is only an acceptable match if // it is contained within a comment. - var token = getTokenAtPosition(sourceFile, matchPosition); + let token = getTokenAtPosition(sourceFile, matchPosition); if (!isInsideComment(sourceFile, token, matchPosition)) { continue; } - var descriptor: TodoCommentDescriptor = undefined; - for (var i = 0, n = descriptors.length; i < n; i++) { + let descriptor: TodoCommentDescriptor = undefined; + for (let i = 0, n = descriptors.length; i < n; i++) { if (matchArray[i + firstDescriptorCaptureIndex]) { descriptor = descriptors[i]; } @@ -5575,7 +5581,7 @@ module ts { continue; } - var message = matchArray[2]; + let message = matchArray[2]; result.push({ descriptor: descriptor, message: message, @@ -5606,14 +5612,14 @@ module ts { // // The following three regexps are used to match the start of the text up to the TODO // comment portion. - var singleLineCommentStart = /(?:\/\/+\s*)/.source; - var multiLineCommentStart = /(?:\/\*+\s*)/.source; - var anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; + let singleLineCommentStart = /(?:\/\/+\s*)/.source; + let multiLineCommentStart = /(?:\/\*+\s*)/.source; + let anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source; // Match any of the above three TODO comment start regexps. // Note that the outermost group *is* a capture group. We want to capture the preamble // so that we can determine the starting position of the TODO comment match. - var preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; + let preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; // Takes the descriptors and forms a regexp that matches them as if they were literals. // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be: @@ -5623,17 +5629,17 @@ module ts { // Note that the outermost group is *not* a capture group, but the innermost groups // *are* capture groups. By capturing the inner literals we can determine after // matching which descriptor we are dealing with. - var literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; + let literals = "(?:" + map(descriptors, d => "(" + escapeRegExp(d.text) + ")").join("|") + ")"; // After matching a descriptor literal, the following regexp matches the rest of the // text up to the end of the line (or */). - var endOfLineOrEndOfComment = /(?:$|\*\/)/.source - var messageRemainder = /(?:.*?)/.source + let endOfLineOrEndOfComment = /(?:$|\*\/)/.source + let messageRemainder = /(?:.*?)/.source // This is the portion of the match we'll return as part of the TODO comment result. We // match the literal portion up to the end of the line or end of comment. - var messagePortion = "(" + literals + messageRemainder + ")"; - var regExpString = preamble + messagePortion + endOfLineOrEndOfComment; + let messagePortion = "(" + literals + messageRemainder + ")"; + let regExpString = preamble + messagePortion + endOfLineOrEndOfComment; // The final regexp will look like this: // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim @@ -5659,30 +5665,30 @@ module ts { function getRenameInfo(fileName: string, position: number): RenameInfo { synchronizeHostData(); - var sourceFile = getValidSourceFile(fileName); + let sourceFile = getValidSourceFile(fileName); - var node = getTouchingWord(sourceFile, position); + let node = getTouchingWord(sourceFile, position); // Can only rename an identifier. if (node && node.kind === SyntaxKind.Identifier) { - var symbol = typeInfoResolver.getSymbolAtLocation(node); + let symbol = typeInfoResolver.getSymbolAtLocation(node); // Only allow a symbol to be renamed if it actually has at least one declaration. if (symbol) { - var declarations = symbol.getDeclarations(); + let declarations = symbol.getDeclarations(); if (declarations && declarations.length > 0) { // Disallow rename for elements that are defined in the standard TypeScript library. - var defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); + let defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); if (defaultLibFileName) { for (let current of declarations) { - var sourceFile = current.getSourceFile(); + let sourceFile = current.getSourceFile(); if (sourceFile && getCanonicalFileName(ts.normalizePath(sourceFile.fileName)) === getCanonicalFileName(ts.normalizePath(defaultLibFileName))) { return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library.key)); } } } - var kind = getSymbolKind(symbol, typeInfoResolver, node); + let kind = getSymbolKind(symbol, typeInfoResolver, node); if (kind) { return { canRename: true, @@ -5757,7 +5763,7 @@ module ts { } function initializeNameTable(sourceFile: SourceFile): void { - var nameTable: Map = {}; + let nameTable: Map = {}; walk(sourceFile); sourceFile.nameTable = nameTable; @@ -5795,13 +5801,13 @@ module ts { /// Classifier export function createClassifier(): Classifier { - var scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); + let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); /// We do not have a full parser support to know when we should parse a regex or not /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where /// we have a series of divide operator. this list allows us to be more accurate by ruling out /// locations where a regexp cannot exist. - var noRegexTable: boolean[] = []; + let noRegexTable: boolean[] = []; noRegexTable[SyntaxKind.Identifier] = true; noRegexTable[SyntaxKind.StringLiteral] = true; noRegexTable[SyntaxKind.NumericLiteral] = true; @@ -5835,7 +5841,7 @@ module ts { // // Where on the second line, you will get the 'return' keyword, // a string literal, and a template end consisting of '} } `'. - var templateStack: SyntaxKind[] = []; + let templateStack: SyntaxKind[] = []; function isAccessibilityModifier(kind: SyntaxKind) { switch (kind) { @@ -5874,9 +5880,9 @@ module ts { // If there is a syntactic classifier ('syntacticClassifierAbsent' is false), // we will be more conservative in order to avoid conflicting with the syntactic classifier. function getClassificationsForLine(text: string, lexState: EndOfLineState, syntacticClassifierAbsent: boolean): ClassificationResult { - var offset = 0; - var token = SyntaxKind.Unknown; - var lastNonTriviaToken = SyntaxKind.Unknown; + let offset = 0; + let token = SyntaxKind.Unknown; + let lastNonTriviaToken = SyntaxKind.Unknown; // Empty out the template stack for reuse. while (templateStack.length > 0) { @@ -5916,7 +5922,7 @@ module ts { scanner.setText(text); - var result: ClassificationResult = { + let result: ClassificationResult = { finalLexState: EndOfLineState.Start, entries: [] }; @@ -5940,7 +5946,7 @@ module ts { // In order to determine if the user is potentially typing something generic, we use a // weak heuristic where we track < and > tokens. It's a weak heuristic, but should // work well enough in practice. - var angleBracketStack = 0; + let angleBracketStack = 0; do { token = scanner.scan(); @@ -5998,7 +6004,7 @@ module ts { // If we don't have anything on the template stack, // then we aren't trying to keep track of a previously scanned template head. if (templateStack.length > 0) { - var lastTemplateStackToken = lastOrUndefined(templateStack); + let lastTemplateStackToken = lastOrUndefined(templateStack); if (lastTemplateStackToken === SyntaxKind.TemplateHead) { token = scanner.reScanTemplateToken(); @@ -6028,26 +6034,26 @@ module ts { return result; function processToken(): void { - var start = scanner.getTokenPos(); - var end = scanner.getTextPos(); + let start = scanner.getTokenPos(); + let end = scanner.getTextPos(); addResult(end - start, classFromKind(token)); if (end >= text.length) { if (token === SyntaxKind.StringLiteral) { // Check to see if we finished up on a multiline string literal. - var tokenText = scanner.getTokenText(); + let tokenText = scanner.getTokenText(); if (scanner.isUnterminated()) { - var lastCharIndex = tokenText.length - 1; + let lastCharIndex = tokenText.length - 1; - var numBackslashes = 0; + let numBackslashes = 0; while (tokenText.charCodeAt(lastCharIndex - numBackslashes) === CharacterCodes.backslash) { numBackslashes++; } // If we have an odd number of backslashes, then the multiline string is unclosed if (numBackslashes & 1) { - var quoteChar = tokenText.charCodeAt(0); + let quoteChar = tokenText.charCodeAt(0); result.finalLexState = quoteChar === CharacterCodes.doubleQuote ? EndOfLineState.InDoubleQuoteStringLiteral : EndOfLineState.InSingleQuoteStringLiteral; @@ -6192,7 +6198,7 @@ module ts { } /// getDefaultLibraryFilePath - declare var __dirname: string; + declare let __dirname: string; /** * Get the path of the default library file (lib.d.ts) as distributed with the typescript @@ -6213,7 +6219,7 @@ module ts { getNodeConstructor: kind => { function Node() { } - var proto = kind === SyntaxKind.SourceFile ? new SourceFileObject() : new NodeObject(); + let proto = kind === SyntaxKind.SourceFile ? new SourceFileObject() : new NodeObject(); proto.kind = kind; proto.pos = 0; proto.end = 0; diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 3a677c9506c..419d4819ba6 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -8,15 +8,15 @@ module ts.SignatureHelp { // will return the generic identifier that started the expression (e.g. "foo" in "foo[]; - var resolvedSignature = typeInfoResolver.getResolvedSignature(call, candidates); + let call = argumentInfo.invocation; + let candidates = []; + let resolvedSignature = typeInfoResolver.getResolvedSignature(call, candidates); cancellationToken.throwIfCancellationRequested(); if (!candidates.length) { @@ -211,7 +211,7 @@ module ts.SignatureHelp { */ function getImmediatelyContainingArgumentInfo(node: Node): ArgumentListInfo { if (node.parent.kind === SyntaxKind.CallExpression || node.parent.kind === SyntaxKind.NewExpression) { - var callExpression = node.parent; + let callExpression = node.parent; // There are 3 cases to handle: // 1. The token introduces a list, and should begin a sig help session // 2. The token is either not associated with a list, or ends a list, so the session should end @@ -230,8 +230,8 @@ module ts.SignatureHelp { node.kind === SyntaxKind.OpenParenToken) { // Find the list that starts right *after* the < or ( token. // If the user has just opened a list, consider this item 0. - var list = getChildListThatStartsWithOpenerToken(callExpression, node, sourceFile); - var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos; + let list = getChildListThatStartsWithOpenerToken(callExpression, node, sourceFile); + let isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos; Debug.assert(list !== undefined); return { kind: isTypeArgList ? ArgumentListKind.TypeArguments : ArgumentListKind.CallArguments, @@ -248,13 +248,13 @@ module ts.SignatureHelp { // - Between the type arguments and the arguments (greater than token) // - On the target of the call (parent.func) // - On the 'new' keyword in a 'new' expression - var listItemInfo = findListItemInfo(node); + let listItemInfo = findListItemInfo(node); if (listItemInfo) { - var list = listItemInfo.list; - var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos; + let list = listItemInfo.list; + let isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos; - var argumentIndex = getArgumentIndex(list, node); - var argumentCount = getArgumentCount(list); + let argumentIndex = getArgumentIndex(list, node); + let argumentCount = getArgumentCount(list); Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, `argumentCount < argumentIndex, ${argumentCount} < ${argumentIndex}`); @@ -276,18 +276,18 @@ module ts.SignatureHelp { } } else if (node.kind === SyntaxKind.TemplateHead && node.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) { - var templateExpression = node.parent; - var tagExpression = templateExpression.parent; + let templateExpression = node.parent; + let tagExpression = templateExpression.parent; Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression); - var argumentIndex = isInsideTemplateLiteral(node, position) ? 0 : 1; + let argumentIndex = isInsideTemplateLiteral(node, position) ? 0 : 1; return getArgumentListInfoForTemplate(tagExpression, argumentIndex); } else if (node.parent.kind === SyntaxKind.TemplateSpan && node.parent.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) { - var templateSpan = node.parent; - var templateExpression = templateSpan.parent; - var tagExpression = templateExpression.parent; + let templateSpan = node.parent; + let templateExpression = templateSpan.parent; + let tagExpression = templateExpression.parent; Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression); // If we're just after a template tail, don't show signature help. @@ -295,8 +295,8 @@ module ts.SignatureHelp { return undefined; } - var spanIndex = templateExpression.templateSpans.indexOf(templateSpan); - var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node); + let spanIndex = templateExpression.templateSpans.indexOf(templateSpan); + let argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node); return getArgumentListInfoForTemplate(tagExpression, argumentIndex); } @@ -316,8 +316,8 @@ module ts.SignatureHelp { // on. In that case, even if we're after the trailing comma, we'll still see // that trailing comma in the list, and we'll have generated the appropriate // arg index. - var argumentIndex = 0; - var listChildren = argumentsList.getChildren(); + let argumentIndex = 0; + let listChildren = argumentsList.getChildren(); for (let child of listChildren) { if (child === node) { break; @@ -342,9 +342,9 @@ module ts.SignatureHelp { // we'll have: 'a' '' '' // That will give us 2 non-commas. We then add one for the last comma, givin us an // arg count of 3. - var listChildren = argumentsList.getChildren(); + let listChildren = argumentsList.getChildren(); - var argumentCount = countWhere(listChildren, arg => arg.kind !== SyntaxKind.CommaToken); + let argumentCount = countWhere(listChildren, arg => arg.kind !== SyntaxKind.CommaToken); if (listChildren.length > 0 && lastOrUndefined(listChildren).kind === SyntaxKind.CommaToken) { argumentCount++; } @@ -378,7 +378,7 @@ module ts.SignatureHelp { function getArgumentListInfoForTemplate(tagExpression: TaggedTemplateExpression, argumentIndex: number): ArgumentListInfo { // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument. - var argumentCount = tagExpression.template.kind === SyntaxKind.NoSubstitutionTemplateLiteral + let argumentCount = tagExpression.template.kind === SyntaxKind.NoSubstitutionTemplateLiteral ? 1 : (tagExpression.template).templateSpans.length + 1; @@ -402,15 +402,15 @@ module ts.SignatureHelp { // // The applicable span is from the first bar to the second bar (inclusive, // but not including parentheses) - var applicableSpanStart = argumentsList.getFullStart(); - var applicableSpanEnd = skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false); + let applicableSpanStart = argumentsList.getFullStart(); + let applicableSpanEnd = skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false); return createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); } function getApplicableSpanForTaggedTemplate(taggedTemplate: TaggedTemplateExpression): TextSpan { - var template = taggedTemplate.template; - var applicableSpanStart = template.getStart(); - var applicableSpanEnd = template.getEnd(); + let template = taggedTemplate.template; + let applicableSpanStart = template.getStart(); + let applicableSpanEnd = template.getEnd(); // We need to adjust the end position for the case where the template does not have a tail. // Otherwise, we will not show signature help past the expression. @@ -422,7 +422,7 @@ module ts.SignatureHelp { // This is because a Missing node has no width. However, what we actually want is to include trivia // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail. if (template.kind === SyntaxKind.TemplateExpression) { - var lastSpan = lastOrUndefined((template).templateSpans); + let lastSpan = lastOrUndefined((template).templateSpans); if (lastSpan.literal.getFullWidth() === 0) { applicableSpanEnd = skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false); } @@ -432,7 +432,7 @@ module ts.SignatureHelp { } function getContainingArgumentInfo(node: Node): ArgumentListInfo { - for (var n = node; n.kind !== SyntaxKind.SourceFile; n = n.parent) { + for (let n = node; n.kind !== SyntaxKind.SourceFile; n = n.parent) { if (isFunctionBlock(n)) { return undefined; } @@ -443,7 +443,7 @@ module ts.SignatureHelp { Debug.fail("Node of kind " + n.kind + " is not a subspan of its parent of kind " + n.parent.kind); } - var argumentInfo = getImmediatelyContainingArgumentInfo(n); + let argumentInfo = getImmediatelyContainingArgumentInfo(n); if (argumentInfo) { return argumentInfo; } @@ -455,8 +455,8 @@ module ts.SignatureHelp { } function getChildListThatStartsWithOpenerToken(parent: Node, openerToken: Node, sourceFile: SourceFile): Node { - var children = parent.getChildren(sourceFile); - var indexOfOpenerToken = children.indexOf(openerToken); + let children = parent.getChildren(sourceFile); + let indexOfOpenerToken = children.indexOf(openerToken); Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1); return children[indexOfOpenerToken + 1]; } @@ -470,10 +470,10 @@ module ts.SignatureHelp { * or the one with the most parameters. */ function selectBestInvalidOverloadIndex(candidates: Signature[], argumentCount: number): number { - var maxParamsSignatureIndex = -1; - var maxParams = -1; - for (var i = 0; i < candidates.length; i++) { - var candidate = candidates[i]; + let maxParamsSignatureIndex = -1; + let maxParams = -1; + for (let i = 0; i < candidates.length; i++) { + let candidate = candidates[i]; if (candidate.hasRestParameter || candidate.parameters.length >= argumentCount) { return i; @@ -489,17 +489,17 @@ module ts.SignatureHelp { } function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentListInfo: ArgumentListInfo): SignatureHelpItems { - var applicableSpan = argumentListInfo.argumentsSpan; - var isTypeParameterList = argumentListInfo.kind === ArgumentListKind.TypeArguments; + let applicableSpan = argumentListInfo.argumentsSpan; + let isTypeParameterList = argumentListInfo.kind === ArgumentListKind.TypeArguments; - var invocation = argumentListInfo.invocation; - var callTarget = getInvokedExpression(invocation) - var callTargetSymbol = typeInfoResolver.getSymbolAtLocation(callTarget); - var callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined); - var items: SignatureHelpItem[] = map(candidates, candidateSignature => { - var signatureHelpParameters: SignatureHelpParameter[]; - var prefixDisplayParts: SymbolDisplayPart[] = []; - var suffixDisplayParts: SymbolDisplayPart[] = []; + let invocation = argumentListInfo.invocation; + let callTarget = getInvokedExpression(invocation) + let callTargetSymbol = typeInfoResolver.getSymbolAtLocation(callTarget); + let callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined); + let items: SignatureHelpItem[] = map(candidates, candidateSignature => { + let signatureHelpParameters: SignatureHelpParameter[]; + let prefixDisplayParts: SymbolDisplayPart[] = []; + let suffixDisplayParts: SymbolDisplayPart[] = []; if (callTargetDisplayParts) { prefixDisplayParts.push.apply(prefixDisplayParts, callTargetDisplayParts); @@ -507,25 +507,25 @@ module ts.SignatureHelp { if (isTypeParameterList) { prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken)); - var typeParameters = candidateSignature.typeParameters; + let typeParameters = candidateSignature.typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken)); - var parameterParts = mapToDisplayParts(writer => + let parameterParts = mapToDisplayParts(writer => typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, invocation)); suffixDisplayParts.push.apply(suffixDisplayParts, parameterParts); } else { - var typeParameterParts = mapToDisplayParts(writer => + let typeParameterParts = mapToDisplayParts(writer => typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation)); prefixDisplayParts.push.apply(prefixDisplayParts, typeParameterParts); prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); - var parameters = candidateSignature.parameters; + let parameters = candidateSignature.parameters; signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } - var returnTypeParts = mapToDisplayParts(writer => + let returnTypeParts = mapToDisplayParts(writer => typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation)); suffixDisplayParts.push.apply(suffixDisplayParts, returnTypeParts); @@ -539,12 +539,12 @@ module ts.SignatureHelp { }; }); - var argumentIndex = argumentListInfo.argumentIndex; + let argumentIndex = argumentListInfo.argumentIndex; // argumentCount is the *apparent* number of arguments. - var argumentCount = argumentListInfo.argumentCount; + let argumentCount = argumentListInfo.argumentCount; - var selectedItemIndex = candidates.indexOf(bestSignature); + let selectedItemIndex = candidates.indexOf(bestSignature); if (selectedItemIndex < 0) { selectedItemIndex = selectBestInvalidOverloadIndex(candidates, argumentCount); } @@ -560,10 +560,10 @@ module ts.SignatureHelp { }; function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter { - var displayParts = mapToDisplayParts(writer => + let displayParts = mapToDisplayParts(writer => typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation)); - var isOptional = hasQuestionToken(parameter.valueDeclaration); + let isOptional = hasQuestionToken(parameter.valueDeclaration); return { name: parameter.name, @@ -574,7 +574,7 @@ module ts.SignatureHelp { } function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter { - var displayParts = mapToDisplayParts(writer => + let displayParts = mapToDisplayParts(writer => typeInfoResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation)); return { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 332ddffc910..452395f454a 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -7,18 +7,18 @@ module ts { export function getEndLinePosition(line: number, sourceFile: SourceFile): number { Debug.assert(line >= 0); - var lineStarts = sourceFile.getLineStarts(); + let lineStarts = sourceFile.getLineStarts(); - var lineIndex = line; + let lineIndex = line; if (lineIndex + 1 === lineStarts.length) { // last line - return EOF return sourceFile.text.length - 1; } else { // current line start - var start = lineStarts[lineIndex]; + let start = lineStarts[lineIndex]; // take the start position of the next line -1 = it should be some line break - var pos = lineStarts[lineIndex + 1] - 1; + let pos = lineStarts[lineIndex + 1] - 1; Debug.assert(isLineBreak(sourceFile.text.charCodeAt(pos))); // walk backwards skipping line breaks, stop the the beginning of current line. // i.e: @@ -32,8 +32,8 @@ module ts { } export function getLineStartPositionForPosition(position: number, sourceFile: SourceFile): number { - var lineStarts = sourceFile.getLineStarts(); - var line = sourceFile.getLineAndCharacterOfPosition(position).line; + let lineStarts = sourceFile.getLineStarts(); + let line = sourceFile.getLineAndCharacterOfPosition(position).line; return lineStarts[line]; } @@ -54,13 +54,13 @@ module ts { } export function startEndOverlapsWithStartEnd(start1: number, end1: number, start2: number, end2: number) { - var start = Math.max(start1, start2); - var end = Math.min(end1, end2); + let start = Math.max(start1, start2); + let end = Math.min(end1, end2); return start < end; } export function findListItemInfo(node: Node): ListItemInfo { - var list = findContainingList(node); + let list = findContainingList(node); // It is possible at this point for syntaxList to be undefined, either if // node.parent had no list child, or if none of its list children contained @@ -70,8 +70,8 @@ module ts { return undefined; } - var children = list.getChildren(); - var listItemIndex = indexOf(children, node); + let children = list.getChildren(); + let listItemIndex = indexOf(children, node); return { listItemIndex, @@ -88,7 +88,7 @@ module ts { // be parented by the container of the SyntaxList, not the SyntaxList itself. // In order to find the list item index, we first need to locate SyntaxList itself and then search // for the position of the relevant node (or comma). - var syntaxList = forEach(node.parent.getChildren(), c => { + let syntaxList = forEach(node.parent.getChildren(), c => { // find syntax list that covers the span of the node if (c.kind === SyntaxKind.SyntaxList && c.pos <= node.pos && c.end >= node.end) { return c; @@ -126,7 +126,7 @@ module ts { /** Get the token whose text contains the position */ function getTokenAtPositionWorker(sourceFile: SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeItemAtEndPosition: (n: Node) => boolean): Node { - var current: Node = sourceFile; + let current: Node = sourceFile; outer: while (true) { if (isToken(current)) { // exit early @@ -134,17 +134,17 @@ module ts { } // find the child that contains 'position' - for (var i = 0, n = current.getChildCount(sourceFile); i < n; i++) { - var child = current.getChildAt(i); - var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile); + for (let i = 0, n = current.getChildCount(sourceFile); i < n; i++) { + let child = current.getChildAt(i); + let start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile); if (start <= position) { - var end = child.getEnd(); + let end = child.getEnd(); if (position < end || (position === end && child.kind === SyntaxKind.EndOfFileToken)) { current = child; continue outer; } else if (includeItemAtEndPosition && end === position) { - var previousToken = findPrecedingToken(position, sourceFile, child); + let previousToken = findPrecedingToken(position, sourceFile, child); if (previousToken && includeItemAtEndPosition(previousToken)) { return previousToken; } @@ -166,7 +166,7 @@ module ts { export function findTokenOnLeftOfPosition(file: SourceFile, position: number): Node { // Ideally, getTokenAtPosition should return a token. However, it is currently // broken, so we do a check to make sure the result was indeed a token. - var tokenAtPosition = getTokenAtPosition(file, position); + let tokenAtPosition = getTokenAtPosition(file, position); if (isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) { return tokenAtPosition; } @@ -183,9 +183,9 @@ module ts { return n; } - var children = n.getChildren(); + let children = n.getChildren(); for (let child of children) { - var shouldDiveInChildNode = + let shouldDiveInChildNode = // previous token is enclosed somewhere in the child (child.pos <= previousToken.pos && child.end > previousToken.end) || // previous token ends exactly at the beginning of child @@ -208,8 +208,8 @@ module ts { return n; } - var children = n.getChildren(); - var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length); + let children = n.getChildren(); + let candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length); return candidate && findRightmostToken(candidate); } @@ -219,14 +219,14 @@ module ts { return n; } - var children = n.getChildren(); - for (var i = 0, len = children.length; i < len; i++) { + let children = n.getChildren(); + for (let i = 0, len = children.length; i < len; i++) { let child = children[i]; if (nodeHasTokens(child)) { if (position <= child.end) { if (child.getStart(sourceFile) >= position) { // actual start of the node is past the position - previous token should be at the end of previous child - var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i); + let candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i); return candidate && findRightmostToken(candidate) } else { @@ -244,14 +244,14 @@ module ts { // Try to find the rightmost token in the file without filtering. // Namely we are skipping the check: 'position < node.end' if (children.length) { - var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length); + let candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length); return candidate && findRightmostToken(candidate); } } /// finds last node that is considered as candidate for search (isCandidate(node) === true) starting from 'exclusiveStartPosition' function findRightmostChildNodeWithTokens(children: Node[], exclusiveStartPosition: number): Node { - for (var i = exclusiveStartPosition - 1; i >= 0; --i) { + for (let i = exclusiveStartPosition - 1; i >= 0; --i) { if (nodeHasTokens(children[i])) { return children[i]; } @@ -266,8 +266,8 @@ module ts { } export function getNodeModifiers(node: Node): string { - var flags = getCombinedNodeFlags(node); - var result: string[] = []; + let flags = getCombinedNodeFlags(node); + let result: string[] = []; if (flags & NodeFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier); if (flags & NodeFlags.Protected) result.push(ScriptElementKindModifier.protectedMemberModifier); @@ -317,7 +317,7 @@ module ts { } export function compareDataObjects(dst: any, src: any): boolean { - for (var e in dst) { + for (let e in dst) { if (typeof dst[e] === "object") { if (!compareDataObjects(dst[e], src[e])) { return false; @@ -339,11 +339,11 @@ module ts { return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === SyntaxKind.Parameter; } - var displayPartWriter = getDisplayPartWriter(); + let displayPartWriter = getDisplayPartWriter(); function getDisplayPartWriter(): DisplayPartsSymbolWriter { - var displayParts: SymbolDisplayPart[]; - var lineStart: boolean; - var indent: number; + let displayParts: SymbolDisplayPart[]; + let lineStart: boolean; + let indent: number; resetWriter(); return { @@ -364,7 +364,7 @@ module ts { function writeIndent() { if (lineStart) { - var indentString = getIndentString(indent); + let indentString = getIndentString(indent); if (indentString) { displayParts.push(displayPart(indentString, SymbolDisplayPartKind.space)); } @@ -398,7 +398,7 @@ module ts { return displayPart(text, displayPartKind(symbol), symbol); function displayPartKind(symbol: Symbol): SymbolDisplayPartKind { - var flags = symbol.flags; + let flags = symbol.flags; if (flags & SymbolFlags.Variable) { return isFirstDeclarationOfSymbolParameter(symbol) ? SymbolDisplayPartKind.parameterName : SymbolDisplayPartKind.localName; @@ -455,7 +455,7 @@ module ts { export function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbolWriter) => void): SymbolDisplayPart[] { writeDisplayParts(displayPartWriter); - var result = displayPartWriter.displayParts(); + let result = displayPartWriter.displayParts(); displayPartWriter.clear(); return result; }