diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index df515e7a8c..b227939daf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -65,7 +65,8 @@ module ts { symbolToString: symbolToString, getAugmentedPropertiesOfApparentType: getAugmentedPropertiesOfApparentType, getRootSymbol: getRootSymbol, - getContextualType: getContextualType + getContextualType: getContextualType, + getFullyQualifiedName: getFullyQualifiedName }; var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined"); @@ -2431,7 +2432,7 @@ module ts { case SyntaxKind.Identifier: case SyntaxKind.QualifiedName: var symbol = getSymbolInfo(node); - return getDeclaredTypeOfSymbol(symbol); + return symbol && getDeclaredTypeOfSymbol(symbol); default: return unknownType; } @@ -3471,41 +3472,6 @@ module ts { return getAncestor(node, kind) !== undefined; } - function getAncestor(node: Node, kind: SyntaxKind): Node { - switch (kind) { - // special-cases that can be come first - case SyntaxKind.ClassDeclaration: - while (node) { - switch (node.kind) { - case SyntaxKind.ClassDeclaration: - return node; - case SyntaxKind.EnumDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ImportDeclaration: - // early exit cases - declarations cannot be nested in classes - return undefined; - default: - node = node.parent; - continue; - } - } - break; - default: - while (node) { - if (node.kind === kind) { - return node; - } - else { - node = node.parent; - } - } - break; - } - - return undefined; - } - // EXPRESSION TYPE CHECKING function checkIdentifier(node: Identifier): Type { @@ -3852,6 +3818,11 @@ module ts { // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. function getContextualType(node: Expression): Type { + if (isInsideWithStatementBody(node)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return undefined; + } + if (node.contextualType) { return node.contextualType; } @@ -6717,7 +6688,20 @@ module ts { return findChildAtPosition(sourceFile); } - function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] { + function isInsideWithStatementBody(node: Node): boolean { + if (node) { + while (node.parent) { + if (node.parent.kind === SyntaxKind.WithStatement && (node.parent).statement === node) { + return true; + } + node = node.parent; + } + } + + return false; + } + + function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]{ var symbols: SymbolTable = {}; var memberFlags: NodeFlags = 0; function copySymbol(symbol: Symbol, meaning: SymbolFlags) { @@ -6737,6 +6721,12 @@ module ts { } } } + + if (isInsideWithStatementBody(location)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return []; + } + while (location) { if (location.locals && !isGlobalSourceFile(location)) { copySymbols(location.locals, meaning); @@ -7009,6 +6999,11 @@ module ts { } function getSymbolInfo(node: Node) { + if (isInsideWithStatementBody(node)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return undefined; + } + if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) { // This is a declaration, call getSymbolOfNode return getSymbolOfNode(node.parent); @@ -7063,9 +7058,15 @@ module ts { } function getTypeOfNode(node: Node): Type { + if (isInsideWithStatementBody(node)) { + // We cannot answer semantic questions within a with block, do not proceed any further + return unknownType; + } + if (isExpression(node)) { return getTypeOfExpression(node); } + if (isTypeNode(node)) { return getTypeFromTypeNode(node); } @@ -7078,7 +7079,7 @@ module ts { if (isTypeDeclarationName(node)) { var symbol = getSymbolInfo(node); - return getDeclaredTypeOfSymbol(symbol); + return symbol && getDeclaredTypeOfSymbol(symbol); } if (isDeclaration(node)) { @@ -7089,12 +7090,12 @@ module ts { if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) { var symbol = getSymbolInfo(node); - return getTypeOfSymbol(symbol); + return symbol && getTypeOfSymbol(symbol); } if (isInRightSideOfImportOrExportAssignment(node)) { var symbol = getSymbolInfo(node); - var declaredType = getDeclaredTypeOfSymbol(symbol); + var declaredType = symbol && getDeclaredTypeOfSymbol(symbol); return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol); } @@ -7146,7 +7147,7 @@ module ts { } function getRootSymbol(symbol: Symbol) { - return (symbol.flags & SymbolFlags.Transient) ? getSymbolLinks(symbol).target : symbol; + return ((symbol.flags & SymbolFlags.Transient) && getSymbolLinks(symbol).target) || symbol; } // Emitter support diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7d24a133b8..61cb6628f2 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -531,6 +531,39 @@ module ts { return false; } + export function getAncestor(node: Node, kind: SyntaxKind): Node { + switch (kind) { + // special-cases that can be come first + case SyntaxKind.ClassDeclaration: + while (node) { + switch (node.kind) { + case SyntaxKind.ClassDeclaration: + return node; + case SyntaxKind.EnumDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.ImportDeclaration: + // early exit cases - declarations cannot be nested in classes + return undefined; + default: + node = node.parent; + continue; + } + } + break; + default: + while (node) { + if (node.kind === kind) { + return node; + } + node = node.parent; + } + break; + } + + return undefined; + } + enum ParsingContext { SourceElements, // Elements in source file ModuleElements, // Elements in module declaration @@ -2200,10 +2233,38 @@ module ts { function parseCallAndAccess(expr: Expression, inNewExpression: boolean): Expression { while (true) { + var dotStart = scanner.getTokenPos(); if (parseOptional(SyntaxKind.DotToken)) { var propertyAccess = createNode(SyntaxKind.PropertyAccess, expr.pos); + // Technically a keyword is valid here as all keywords are identifier names. + // However, often we'll encounter this in error situations when the keyword + // is actually starting another valid construct. + // + // So, we check for the following specific case: + // + // name. + // keyword identifierNameOrKeyword + // + // Note: the newlines are important here. For example, if that above code + // were rewritten into: + // + // name.keyword + // identifierNameOrKeyword + // + // Then we would consider it valid. That's because ASI would take effect and + // the code would be implicitly: "name.keyword; identifierNameOrKeyword". + // In the first case though, ASI will not take effect because there is not a + // line terminator after the keyword. + if (scanner.hasPrecedingLineBreak() && scanner.isReservedWord() && lookAhead(() => scanner.isReservedWord())) { + grammarErrorAtPos(dotStart, scanner.getStartPos() - dotStart, Diagnostics.Identifier_expected); + var id = createMissingNode(); + } + else { + var id = parseIdentifierName(); + } + propertyAccess.left = expr; - propertyAccess.right = parseIdentifierName(); + propertyAccess.right = id; expr = finishNode(propertyAccess); continue; } @@ -3754,7 +3815,7 @@ module ts { : undefined); } - scanner = createScanner(languageVersion, sourceText, scanError, onComment); + scanner = createScanner(languageVersion, /*skipTrivia*/ true, sourceText, scanError, onComment); var rootNodeFlags: NodeFlags = 0; if (fileExtensionIs(filename, ".d.ts")) { rootNodeFlags = NodeFlags.DeclarationFile; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 59c7913e24..f627bee6c5 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -460,7 +460,7 @@ module ts { ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion); } - export function createScanner(languageVersion: ScriptTarget, text?: string, onError?: ErrorCallback, onComment?: CommentCallback): Scanner { + export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, text?: string, onError?: ErrorCallback, onComment?: CommentCallback): Scanner { var pos: number; // Current position (end position of text of current token) var len: number; // Length of text var startPos: number; // Start position of whitespace before current token @@ -694,12 +694,34 @@ module ts { case CharacterCodes.lineFeed: case CharacterCodes.carriageReturn: precedingLineBreak = true; + if (skipTrivia) { + pos++; + continue; + } + else { + if (ch === CharacterCodes.carriageReturn && pos + 1 < len && text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) { + // consume both CR and LF + pos += 2; + } + else { + pos++; + } + return token = SyntaxKind.NewLineTrivia; + } case CharacterCodes.tab: case CharacterCodes.verticalTab: case CharacterCodes.formFeed: case CharacterCodes.space: - pos++; - continue; + if (skipTrivia) { + pos++; + continue; + } + else { + while (pos < len && isWhiteSpace(text.charCodeAt(pos))) { + pos++; + } + return token = SyntaxKind.WhitespaceTrivia; + } case CharacterCodes.exclamation: if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { @@ -776,7 +798,13 @@ module ts { if (onComment) { onComment(tokenPos, pos); } - continue; + + if (skipTrivia) { + continue; + } + else { + return token = SyntaxKind.SingleLineCommentTrivia; + } } // Multi-line comment if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { @@ -806,7 +834,12 @@ module ts { onComment(tokenPos, pos); } - continue; + if (skipTrivia) { + continue; + } + else { + return token = SyntaxKind.MultiLineCommentTrivia; + } } if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c7893f8d99..e1116150e3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -12,6 +12,10 @@ module ts { export enum SyntaxKind { Unknown, EndOfFileToken, + SingleLineCommentTrivia, + MultiLineCommentTrivia, + NewLineTrivia, + WhitespaceTrivia, // Literals NumericLiteral, StringLiteral, @@ -634,6 +638,7 @@ module ts { getApparentType(type: Type): ApparentType; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + getFullyQualifiedName(symbol: Symbol): string; getAugmentedPropertiesOfApparentType(type: Type): Symbol[]; getRootSymbol(symbol: Symbol): Symbol; getContextualType(node: Node): Type; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 360dc3df51..ed6dc1a71f 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -898,6 +898,44 @@ module FourSlash { } } + private validate(name: string, expected: string, actual: string) { + if (expected && expected !== actual) { + throw new Error("Expected " + name + " '" + expected + "'. Got '" + actual + "' instead."); + } + } + + public verifyRenameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) { + var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + if (!renameInfo.canRename) { + throw new Error("Rename did not succeed"); + } + + this.validate("displayName", displayName, renameInfo.displayName); + this.validate("fullDisplayName", fullDisplayName, renameInfo.fullDisplayName); + this.validate("kind", kind, renameInfo.kind); + this.validate("kindModifiers", kindModifiers, renameInfo.kindModifiers); + + if (this.getRanges().length !== 1) { + throw new Error("Expected a single range to be selected in the test file."); + } + + var expectedRange = this.getRanges()[0]; + if (renameInfo.triggerSpan.start() !== expectedRange.start || + renameInfo.triggerSpan.end() !== expectedRange.end) { + throw new Error("Expected triggerSpan [" + expectedRange.start + "," + expectedRange.end + "). Got [" + + renameInfo.triggerSpan.start() + "," + renameInfo.triggerSpan.end() + ") instead."); + } + } + + public verifyRenameInfoFailed(message?: string) { + var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + if (renameInfo.canRename) { + throw new Error("Rename was expected to fail"); + } + + this.validate("error", message, renameInfo.localizedErrorMessage); + } + //private getFormalParameter() { // var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); // return help.formal; diff --git a/src/lib/extensions.d.ts b/src/lib/extensions.d.ts index 87b78018c7..82cc129ecb 100644 --- a/src/lib/extensions.d.ts +++ b/src/lib/extensions.d.ts @@ -63,14 +63,14 @@ interface Int8Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Int8Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -121,14 +121,14 @@ interface Uint8Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Uint8Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -179,14 +179,14 @@ interface Int16Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Int16Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -237,14 +237,14 @@ interface Uint16Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Uint16Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -295,14 +295,14 @@ interface Int32Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Int32Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -353,14 +353,14 @@ interface Uint32Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Uint32Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -411,14 +411,14 @@ interface Float32Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Float32Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; @@ -469,14 +469,14 @@ interface Float64Array extends ArrayBufferView { /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: Float64Array, offset?: number): void; /** * Sets a value or an array of values. - * @param A typed or untyped array of values to set. + * @param array A typed or untyped array of values to set. * @param offset The index in the current array at which the values are to be written. */ set(array: number[], offset?: number): void; diff --git a/src/services/services.ts b/src/services/services.ts index 4e1d908985..04e63f6dbe 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -75,7 +75,7 @@ module ts { update(scriptSnapshot: TypeScript.IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TypeScript.TextChangeRange): SourceFile; } - var scanner: Scanner = createScanner(ScriptTarget.ES5); + var scanner: Scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ true); var emptyArray: any[] = []; @@ -770,7 +770,6 @@ module ts { InMultiLineCommentTrivia, InSingleQuoteStringLiteral, InDoubleQuoteStringLiteral, - EndingWithDotToken, } export enum TokenClass { @@ -1684,14 +1683,20 @@ module ts { /// Completion function getValidCompletionEntryDisplayName(displayName: string, target: ScriptTarget): string { if (displayName && displayName.length > 0) { - var firstChar = displayName.charCodeAt(0); - if (firstChar === TypeScript.CharacterCodes.singleQuote || firstChar === TypeScript.CharacterCodes.doubleQuote) { + var firstCharCode = displayName.charCodeAt(0); + if (displayName && displayName.length >= 2 && firstCharCode === displayName.charCodeAt(displayName.length - 1) && + (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) { // If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an - // invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name. - displayName = TypeScript.stripStartAndEndQuotes(displayName); + // invalid identifer name. We need to check if whatever was inside the quotes is actually a valid identifier name. + 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++) { + isValid = isIdentifierPart(displayName.charCodeAt(i), target); } - if (TypeScript.Scanner.isValidIdentifier(TypeScript.SimpleText.fromString(displayName), target)) { + if (isValid) { return displayName; } } @@ -1709,7 +1714,6 @@ module ts { } var declarations = symbol.getDeclarations(); - var firstDeclaration = [0]; return { name: displayName, kind: getSymbolKind(symbol), @@ -1721,7 +1725,7 @@ module ts { function getCompletionEntriesFromSymbols(symbols: Symbol[], session: CompletionSession): void { forEach(symbols, (symbol) => { var entry = createCompletionEntry(symbol); - if (entry) { + if (entry && !lookUp(session.symbols, entry.name)) { session.entries.push(entry); session.symbols[entry.name] = symbol; } @@ -1851,6 +1855,49 @@ module ts { return false; } + function isPunctuation(kind: SyntaxKind) { + return (SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation); + } + + function isVisibleWithinClassDeclaration(symbol: Symbol, containingClass: Declaration): boolean { + var declaration = symbol.declarations && symbol.declarations[0]; + if (declaration && (declaration.flags & NodeFlags.Private)) { + var declarationClass = getAncestor(declaration, SyntaxKind.ClassDeclaration); + return containingClass === declarationClass; + } + return true; + } + + function filterContextualMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] { + if (!existingMembers || existingMembers.length === 0) { + return contextualMemberSymbols; + } + + var existingMemberNames: Map = {}; + forEach(existingMembers, m => { + if (m.kind !== SyntaxKind.PropertyAssignment) { + // Ignore omitted expressions for missing members in the object literal + return; + } + + if (m.getStart() <= position && position <= m.getEnd()) { + // If this is the current item we are editing right now, do not filter it out + return; + } + + existingMemberNames[m.name.text] = true; + }); + + var filteredMembers: Symbol[] = []; + forEach(contextualMemberSymbols, s => { + if (!existingMemberNames[s.name]) { + filteredMembers.push(s); + } + }); + + return filteredMembers; + } + synchronizeHostData(); filename = TypeScript.switchToForwardSlashes(filename); @@ -1905,6 +1952,9 @@ module ts { // TODO: this is a hack for now, we need a proper walking mechanism to verify that we have the correct node var mappedNode = getNodeAtPosition(sourceFile, TypeScript.end(node) - 1); + if (isPunctuation(mappedNode.kind)) { + mappedNode = mappedNode.parent; + } Debug.assert(mappedNode, "Could not map a Fidelity node to an AST node"); @@ -1920,13 +1970,33 @@ module ts { // Right of dot member completion list if (isRightOfDot) { - var type: ApparentType = typeInfoResolver.getApparentType(typeInfoResolver.getTypeOfNode(mappedNode)); - if (!type) { - return undefined; + var symbols: Symbol[] = []; + var containingClass = getAncestor(mappedNode, SyntaxKind.ClassDeclaration); + isMemberCompletion = true; + + if (mappedNode.kind === SyntaxKind.Identifier || mappedNode.kind === SyntaxKind.QualifiedName || mappedNode.kind === SyntaxKind.PropertyAccess) { + var symbol = typeInfoResolver.getSymbolInfo(mappedNode); + if (symbol && symbol.flags & SymbolFlags.HasExports) { + // Extract module or enum members + forEachValue(symbol.exports, symbol => { + if (isVisibleWithinClassDeclaration(symbol, containingClass)) { + symbols.push(symbol); + } + }); + } + } + + var type = typeInfoResolver.getTypeOfNode(mappedNode); + var apparentType = type && typeInfoResolver.getApparentType(type); + if (apparentType) { + // Filter private properties + forEach(apparentType.getApparentProperties(), symbol => { + if (isVisibleWithinClassDeclaration(symbol, containingClass)) { + symbols.push(symbol); + } + }); } - var symbols = type.getApparentProperties(); - isMemberCompletion = true; getCompletionEntriesFromSymbols(symbols, activeCompletionSession); } else { @@ -1934,34 +2004,23 @@ module ts { // Object literal expression, look up possible property names from contextual type if (containingObjectLiteral) { - var searchPosition = Math.min(position, TypeScript.end(containingObjectLiteral)); - var path = TypeScript.ASTHelpers.getAstAtPosition(sourceUnit, searchPosition); - // Get the object literal node + var objectLiteral = (mappedNode.kind === SyntaxKind.ObjectLiteral ? mappedNode : getAncestor(mappedNode, SyntaxKind.ObjectLiteral)); - while (node && node.kind() !== TypeScript.SyntaxKind.ObjectLiteralExpression) { - node = node.parent; - } - - if (!node || node.kind() !== TypeScript.SyntaxKind.ObjectLiteralExpression) { - // AST Path look up did not result in the same node as Fidelity Syntax Tree look up. - // Once we remove AST this will no longer be a problem. - return null; - } + Debug.assert(objectLiteral); isMemberCompletion = true; - //// Try to get the object members form contextual typing - //var contextualMembers = compiler.getContextualMembersFromAST(node, document); - //if (contextualMembers && contextualMembers.symbols && contextualMembers.symbols.length > 0) { - // // get existing members - // var existingMembers = compiler.getVisibleMemberSymbolsFromAST(node, document); + var contextualType = typeInfoResolver.getContextualType(objectLiteral); + if (!contextualType) { + return undefined; + } - // // Add filtered items to the completion list - // getCompletionEntriesFromSymbols({ - // symbols: filterContextualMembersList(contextualMembers.symbols, existingMembers, filename, position), - // enclosingScopeSymbol: contextualMembers.enclosingScopeSymbol - // }, entries); - //} + var contextualTypeMembers = typeInfoResolver.getPropertiesOfType(contextualType); + if (contextualTypeMembers && contextualTypeMembers.length > 0) { + // Add filtered items to the completion list + var filteredMembers = filterContextualMembersList(contextualTypeMembers, objectLiteral.properties); + getCompletionEntriesFromSymbols(filteredMembers, activeCompletionSession); + } } // Get scope members else { @@ -2024,6 +2083,7 @@ module ts { } } + /** Get the token whose text contains the position, or the containing node. */ function getNodeAtPosition(sourceFile: SourceFile, position: number) { var current: Node = sourceFile; outer: while (true) { @@ -2034,9 +2094,24 @@ module ts { current = child; continue outer; } - if (child.end > position) { - break; - } + } + return current; + } + } + + /** Get a token that contains the position. This is guaranteed to return a token, the position can be in the + * leading trivia or within the token text. + */ + function getTokenAtPosition(sourceFile: SourceFile, position: number) { + var current: Node = sourceFile; + outer: while (true) { + // find the child that has this + for (var i = 0, n = current.getChildCount(); i < n; i++) { + var child = current.getChildAt(i); + if (child.getFullStart() <= position && position < child.getEnd()) { + current = child; + continue outer; + } } return current; } @@ -2065,7 +2140,7 @@ module ts { } function getSymbolKind(symbol: Symbol): string { - var flags = symbol.getFlags(); + var flags = typeInfoResolver.getRootSymbol(symbol).getFlags(); if (flags & SymbolFlags.Module) return ScriptElementKind.moduleElement; if (flags & SymbolFlags.Class) return ScriptElementKind.classElement; @@ -3751,83 +3826,21 @@ module ts { return []; } - function escapeRegExp(str: string): string { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - } + function getTodoComments(filename: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { + filename = TypeScript.switchToForwardSlashes(filename); - function getTodoCommentsRegExp(descriptors: TodoCommentDescriptor[]): RegExp { - // NOTE: ?: means 'non-capture group'. It allows us to have groups without having to - // filter them out later in the final result array. + var sourceFile = getCurrentSourceFile(filename); - // TODO comments can appear in one of the following forms: - // - // 1) // TODO or /////////// TODO - // - // 2) /* TODO or /********** TODO - // - // 3) /* - // * TODO - // */ - // - // 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; - - // 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 + ")"; - - // 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: - // - // (?:(TODO\(jason\))|(HACK)) - // - // 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 = "(?:" + descriptors.map(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 - - // 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; - - // The final regexp will look like this: - // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim - - // The flags of the regexp are important here. - // 'g' is so that we are doing a global search and can find matches several times - // in the input. - // - // 'i' is for case insensitivity (We do this to match C# TODO comment code). - // - // 'm' is so we can find matches in a multiline input. - return new RegExp(regExpString, "gim"); - } - - function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { - fileName = TypeScript.switchToForwardSlashes(fileName); - - var sourceFile = getCurrentSourceFile(fileName); - var syntaxTree = sourceFile.getSyntaxTree(); cancellationToken.throwIfCancellationRequested(); - var text = syntaxTree.text; - var fileContents = text.substr(0, text.length()); + var fileContents = sourceFile.text; + cancellationToken.throwIfCancellationRequested(); var result: TodoComment[] = []; if (descriptors.length > 0) { - var regExp = getTodoCommentsRegExp(descriptors); + var regExp = getTodoCommentsRegExp(); var matchArray: RegExpExecArray; while (matchArray = regExp.exec(fileContents)) { @@ -3842,7 +3855,7 @@ module ts { // ["// hack 1", "// ", "hack 1", undefined, "hack"] // // Here are the relevant capture groups: - // 0) The full match for the entire regex. + // 0) The full match for the entire regexp. // 1) The preamble to the message portion. // 2) The message portion. // 3...N) The descriptor that was matched - by index. 'undefined' for each @@ -3856,20 +3869,19 @@ module ts { var preamble = matchArray[1]; var matchPosition = matchArray.index + preamble.length; - // Ok, we have found a match in the file. This is only an acceptable match if + // OK, we have found a match in the file. This is only an acceptable match if // it is contained within a comment. - var token = TypeScript.findToken(syntaxTree.sourceUnit(), matchPosition); + var token = getTokenAtPosition(sourceFile, matchPosition); - if (matchPosition >= TypeScript.start(token) && matchPosition < TypeScript.end(token)) { + if (token.getStart() <= matchPosition && matchPosition < token.getEnd()) { // match was within the token itself. Not in the comment. Keep searching // descriptor. continue; } - // Looks to be within the trivia. See if we can find the comment containing it. - var triviaList = matchPosition < TypeScript.start(token) ? token.leadingTrivia(syntaxTree.text) : token.trailingTrivia(syntaxTree.text); - var trivia = findContainingComment(triviaList, matchPosition); - if (trivia === null) { + // Looks to be within the trivia. See if we can find the comment containing it. + if (!getContainingComment(getTrailingComments(fileContents, token.getFullStart()), matchPosition) && + !getContainingComment(getLeadingComments(fileContents, token.getFullStart()), matchPosition)) { continue; } @@ -3893,24 +3905,114 @@ module ts { } return result; - } - function isLetterOrDigit(char: number): boolean { - return (char >= TypeScript.CharacterCodes.a && char <= TypeScript.CharacterCodes.z) || - (char >= TypeScript.CharacterCodes.A && char <= TypeScript.CharacterCodes.Z) || - (char >= TypeScript.CharacterCodes._0 && char <= TypeScript.CharacterCodes._9); - } + function escapeRegExp(str: string): string { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + } - function findContainingComment(triviaList: TypeScript.ISyntaxTriviaList, position: number): TypeScript.ISyntaxTrivia { - for (var i = 0, n = triviaList.count(); i < n; i++) { - var trivia = triviaList.syntaxTriviaAt(i); - var fullEnd = trivia.fullStart() + trivia.fullWidth(); - if (trivia.isComment() && trivia.fullStart() <= position && position < fullEnd) { - return trivia; + function getTodoCommentsRegExp(): RegExp { + // NOTE: ?: means 'non-capture group'. It allows us to have groups without having to + // filter them out later in the final result array. + + // TODO comments can appear in one of the following forms: + // + // 1) // TODO or /////////// TODO + // + // 2) /* TODO or /********** TODO + // + // 3) /* + // * TODO + // */ + // + // 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; + + // 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 + ")"; + + // 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: + // + // (?:(TODO\(jason\))|(HACK)) + // + // 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("|") + ")"; + + // 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 + + // 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; + + // The final regexp will look like this: + // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim + + // The flags of the regexp are important here. + // 'g' is so that we are doing a global search and can find matches several times + // in the input. + // + // 'i' is for case insensitivity (We do this to match C# TODO comment code). + // + // 'm' is so we can find matches in a multi-line input. + return new RegExp(regExpString, "gim"); + } + + function getContainingComment(comments: Comment[], position: number): Comment { + if (comments) { + for (var i = 0, n = comments.length; i < n; i++) { + var comment = comments[i]; + if (comment.pos <= position && position < comment.end) { + return comment; + } + } + } + + return undefined; + } + + function isLetterOrDigit(char: number): boolean { + return (char >= TypeScript.CharacterCodes.a && char <= TypeScript.CharacterCodes.z) || + (char >= TypeScript.CharacterCodes.A && char <= TypeScript.CharacterCodes.Z) || + (char >= TypeScript.CharacterCodes._0 && char <= TypeScript.CharacterCodes._9); + } + } + + + function getRenameInfo(fileName: string, position: number): RenameInfo { + synchronizeHostData(); + + fileName = TypeScript.switchToForwardSlashes(fileName); + var sourceFile = getSourceFile(fileName); + + var node = getNodeAtPosition(sourceFile, position); + + // Can only rename an identifier. + if (node && node.kind === SyntaxKind.Identifier) { + var symbol = typeInfoResolver.getSymbolInfo(node); + + // Only allow a symbol to be renamed if it actually has at least one declaration. + if (symbol && symbol.getDeclarations() && symbol.getDeclarations().length > 0) { + var kind = getSymbolKind(symbol); + if (kind) { + return RenameInfo.Create(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind, + getNodeModifiers(symbol.getDeclarations()[0]), + new TypeScript.TextSpan(node.getStart(), node.getWidth())); + } } } - return null; + return RenameInfo.CreateError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key)); } return { @@ -3933,7 +4035,7 @@ module ts { getNameOrDottedNameSpan: getNameOrDottedNameSpan, getBreakpointStatementAtPosition: getBreakpointStatementAtPosition, getNavigateToItems: getNavigateToItems, - getRenameInfo: (fileName, position): RenameInfo => RenameInfo.CreateError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key)), + getRenameInfo: getRenameInfo, getNavigationBarItems: getNavigationBarItems, getOutliningSpans: getOutliningSpans, getTodoComments: getTodoComments, @@ -3995,9 +4097,6 @@ module ts { text = "/*\n" + text; offset = 3; break; - case EndOfLineState.EndingWithDotToken: - lastToken = SyntaxKind.DotToken; - break; } var result: ClassificationResult = { @@ -4005,7 +4104,7 @@ module ts { entries: [] }; - scanner = createScanner(ScriptTarget.ES5, text, onError, processComment); + scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ true, text, onError, processComment); var token = SyntaxKind.Unknown; do { @@ -4065,9 +4164,6 @@ module ts { : EndOfLineState.InSingleQuoteStringLiteral; } } - else if (token === SyntaxKind.DotToken) { - result.finalLexState = EndOfLineState.EndingWithDotToken; - } } } diff --git a/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt b/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt index 0bdb52e52c..235b665cdc 100644 --- a/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt +++ b/tests/baselines/reference/enumConflictsWithGlobalIdentifier.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(5,5): error TS1005: ',' expected. +tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(4,28): error TS1003: Identifier expected. tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(4,9): error TS2304: Cannot find name 'IgnoreRulesSpecific'. @@ -7,9 +7,9 @@ tests/cases/compiler/enumConflictsWithGlobalIdentifier.ts(4,9): error TS2304: Ca IgnoreRulesSpecific = 0, } var x = IgnoreRulesSpecific. + ~ +!!! error TS1003: Identifier expected. ~~~~~~~~~~~~~~~~~~~ !!! error TS2304: Cannot find name 'IgnoreRulesSpecific'. var y = Position.IgnoreRulesSpecific; - ~ -!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/enumMemberResolution.errors.txt b/tests/baselines/reference/enumMemberResolution.errors.txt index 74fa7aec1e..5c84c08d98 100644 --- a/tests/baselines/reference/enumMemberResolution.errors.txt +++ b/tests/baselines/reference/enumMemberResolution.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/enumMemberResolution.ts(5,5): error TS1005: ',' expected. +tests/cases/compiler/enumMemberResolution.ts(4,28): error TS1003: Identifier expected. tests/cases/compiler/enumMemberResolution.ts(4,9): error TS2304: Cannot find name 'IgnoreRulesSpecific'. @@ -7,10 +7,10 @@ tests/cases/compiler/enumMemberResolution.ts(4,9): error TS2304: Cannot find nam IgnoreRulesSpecific = 0 } var x = IgnoreRulesSpecific. // error + ~ +!!! error TS1003: Identifier expected. ~~~~~~~~~~~~~~~~~~~ !!! error TS2304: Cannot find name 'IgnoreRulesSpecific'. var y = 1; - ~ -!!! error TS1005: ',' expected. var z = Position2.IgnoreRulesSpecific; // no error \ No newline at end of file diff --git a/tests/baselines/reference/getEmitOutputDeclarationMultiFiles.baseline b/tests/baselines/reference/getEmitOutputDeclarationMultiFiles.baseline index 6aec1296d8..4b89414059 100644 --- a/tests/baselines/reference/getEmitOutputDeclarationMultiFiles.baseline +++ b/tests/baselines/reference/getEmitOutputDeclarationMultiFiles.baseline @@ -1,30 +1,30 @@ EmitOutputStatus : Succeeded Filename : tests/cases/fourslash/inputFile1.js -var x = 5; -var Bar = (function () { - function Bar() { - } - return Bar; -})(); +var x = 5; +var Bar = (function () { + function Bar() { + } + return Bar; +})(); Filename : tests/cases/fourslash/inputFile1.d.ts -declare var x: number; -declare class Bar { - x: string; - y: number; -} +declare var x: number; +declare class Bar { + x: string; + y: number; +} EmitOutputStatus : Succeeded Filename : tests/cases/fourslash/inputFile2.js -var x1 = "hello world"; -var Foo = (function () { - function Foo() { - } - return Foo; -})(); +var x1 = "hello world"; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); Filename : tests/cases/fourslash/inputFile2.d.ts -declare var x1: string; -declare class Foo { - x: string; - y: number; -} +declare var x1: string; +declare class Foo { + x: string; + y: number; +} diff --git a/tests/baselines/reference/getEmitOutputDeclarationSingleFile.baseline b/tests/baselines/reference/getEmitOutputDeclarationSingleFile.baseline index ba40a69e39..545c37a072 100644 --- a/tests/baselines/reference/getEmitOutputDeclarationSingleFile.baseline +++ b/tests/baselines/reference/getEmitOutputDeclarationSingleFile.baseline @@ -1,26 +1,26 @@ EmitOutputStatus : Succeeded Filename : declSingleFile.js -var x = 5; -var Bar = (function () { - function Bar() { - } - return Bar; -})(); -var x1 = "hello world"; -var Foo = (function () { - function Foo() { - } - return Foo; -})(); +var x = 5; +var Bar = (function () { + function Bar() { + } + return Bar; +})(); +var x1 = "hello world"; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); Filename : declSingleFile.d.ts -declare var x: number; -declare class Bar { - x: string; - y: number; -} -declare var x1: string; -declare class Foo { - x: string; - y: number; -} +declare var x: number; +declare class Bar { + x: string; + y: number; +} +declare var x1: string; +declare class Foo { + x: string; + y: number; +} diff --git a/tests/baselines/reference/getEmitOutputMapRoots.baseline b/tests/baselines/reference/getEmitOutputMapRoots.baseline index 2630257b03..93dab28e6f 100644 --- a/tests/baselines/reference/getEmitOutputMapRoots.baseline +++ b/tests/baselines/reference/getEmitOutputMapRoots.baseline @@ -1,11 +1,11 @@ EmitOutputStatus : Succeeded Filename : declSingleFile.js.map {"version":3,"file":"declSingleFile.js","sourceRoot":"","sources":["../tests/cases/fourslash/inputFile.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : declSingleFile.js -var x = 109; -var foo = "hello world"; -var M = (function () { - function M() { - } - return M; -})(); +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); //# sourceMappingURL=mapRootDir/declSingleFile.js.map diff --git a/tests/baselines/reference/getEmitOutputNoErrors.baseline b/tests/baselines/reference/getEmitOutputNoErrors.baseline index 000ddb29ef..47ba143531 100644 --- a/tests/baselines/reference/getEmitOutputNoErrors.baseline +++ b/tests/baselines/reference/getEmitOutputNoErrors.baseline @@ -1,9 +1,9 @@ EmitOutputStatus : Succeeded Filename : tests/cases/fourslash/inputFile.js -var x; -var M = (function () { - function M() { - } - return M; -})(); +var x; +var M = (function () { + function M() { + } + return M; +})(); diff --git a/tests/baselines/reference/getEmitOutputOnlyOneFile.baseline b/tests/baselines/reference/getEmitOutputOnlyOneFile.baseline index eaca7cda67..1f61d57c81 100644 --- a/tests/baselines/reference/getEmitOutputOnlyOneFile.baseline +++ b/tests/baselines/reference/getEmitOutputOnlyOneFile.baseline @@ -1,9 +1,9 @@ EmitOutputStatus : Succeeded Filename : tests/cases/fourslash/inputFile2.js -var x; -var Foo = (function () { - function Foo() { - } - return Foo; -})(); +var x; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); diff --git a/tests/baselines/reference/getEmitOutputSingleFile.baseline b/tests/baselines/reference/getEmitOutputSingleFile.baseline index fd3d2af4a5..dd8f2be807 100644 --- a/tests/baselines/reference/getEmitOutputSingleFile.baseline +++ b/tests/baselines/reference/getEmitOutputSingleFile.baseline @@ -1,15 +1,15 @@ EmitOutputStatus : Succeeded Filename : outputDir/singleFile.js -var x; -var Bar = (function () { - function Bar() { - } - return Bar; -})(); -var x; -var Foo = (function () { - function Foo() { - } - return Foo; -})(); +var x; +var Bar = (function () { + function Bar() { + } + return Bar; +})(); +var x; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); diff --git a/tests/baselines/reference/getEmitOutputSingleFile2.baseline b/tests/baselines/reference/getEmitOutputSingleFile2.baseline index aac50ee87c..77fa6b9acd 100644 --- a/tests/baselines/reference/getEmitOutputSingleFile2.baseline +++ b/tests/baselines/reference/getEmitOutputSingleFile2.baseline @@ -1,32 +1,32 @@ EmitOutputStatus : Succeeded Filename : tests/cases/fourslash/inputFile3.js -exports.foo = 10; -exports.bar = "hello world"; +exports.foo = 10; +exports.bar = "hello world"; Filename : tests/cases/fourslash/inputFile3.d.ts -export declare var foo: number; -export declare var bar: string; +export declare var foo: number; +export declare var bar: string; Filename : declSingleFile.js -var x = 5; -var Bar = (function () { - function Bar() { - } - return Bar; -})(); -var x1 = "hello world"; -var Foo = (function () { - function Foo() { - } - return Foo; -})(); +var x = 5; +var Bar = (function () { + function Bar() { + } + return Bar; +})(); +var x1 = "hello world"; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); Filename : declSingleFile.d.ts -declare var x: number; -declare class Bar { - x: string; - y: number; -} -declare var x1: string; -declare class Foo { - x: string; - y: number; -} +declare var x: number; +declare class Bar { + x: string; + y: number; +} +declare var x1: string; +declare class Foo { + x: string; + y: number; +} diff --git a/tests/baselines/reference/getEmitOutputSourceMap.baseline b/tests/baselines/reference/getEmitOutputSourceMap.baseline index e3b7a47e12..75ee2a2661 100644 --- a/tests/baselines/reference/getEmitOutputSourceMap.baseline +++ b/tests/baselines/reference/getEmitOutputSourceMap.baseline @@ -1,11 +1,11 @@ EmitOutputStatus : Succeeded Filename : tests/cases/fourslash/inputFile.js.map {"version":3,"file":"inputFile.js","sourceRoot":"","sources":["inputFile.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile.js -var x = 109; -var foo = "hello world"; -var M = (function () { - function M() { - } - return M; -})(); +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); //# sourceMappingURL=inputFile.js.map diff --git a/tests/baselines/reference/getEmitOutputSourceMap2.baseline b/tests/baselines/reference/getEmitOutputSourceMap2.baseline index d6745389e3..2c132d8cd6 100644 --- a/tests/baselines/reference/getEmitOutputSourceMap2.baseline +++ b/tests/baselines/reference/getEmitOutputSourceMap2.baseline @@ -1,19 +1,19 @@ EmitOutputStatus : Succeeded Filename : sample/outDir/inputFile1.js.map {"version":3,"file":"inputFile1.js","sourceRoot":"","sources":["../../tests/cases/fourslash/inputFile1.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : sample/outDir/inputFile1.js -var x = 109; -var foo = "hello world"; -var M = (function () { - function M() { - } - return M; -})(); +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); //# sourceMappingURL=inputFile1.js.map EmitOutputStatus : Succeeded Filename : sample/outDir/inputFile2.js.map {"version":3,"file":"inputFile2.js","sourceRoot":"","sources":["../../tests/cases/fourslash/inputFile2.ts"],"names":[],"mappings":"AAAA,IAAI,KAAK,GAAG,aAAa,CAAC;AAC1B,EAAE,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,GAAG,EAAE,CAAC;AACd,CAAC"}Filename : sample/outDir/inputFile2.js -var intro = "hello world"; -if (intro !== undefined) { - var k = 10; -} +var intro = "hello world"; +if (intro !== undefined) { + var k = 10; +} //# sourceMappingURL=inputFile2.js.map diff --git a/tests/baselines/reference/getEmitOutputSourceRoot.baseline b/tests/baselines/reference/getEmitOutputSourceRoot.baseline index d8cba7ddd9..9252163165 100644 --- a/tests/baselines/reference/getEmitOutputSourceRoot.baseline +++ b/tests/baselines/reference/getEmitOutputSourceRoot.baseline @@ -1,11 +1,11 @@ EmitOutputStatus : Succeeded Filename : tests/cases/fourslash/inputFile.js.map {"version":3,"file":"inputFile.js","sourceRoot":"sourceRootDir/","sources":["inputFile.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile.js -var x = 109; -var foo = "hello world"; -var M = (function () { - function M() { - } - return M; -})(); +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); //# sourceMappingURL=inputFile.js.map diff --git a/tests/baselines/reference/getEmitOutputSourceRootMultiFiles.baseline b/tests/baselines/reference/getEmitOutputSourceRootMultiFiles.baseline index eec0b05eca..5c26a1920f 100644 --- a/tests/baselines/reference/getEmitOutputSourceRootMultiFiles.baseline +++ b/tests/baselines/reference/getEmitOutputSourceRootMultiFiles.baseline @@ -1,21 +1,21 @@ EmitOutputStatus : Succeeded Filename : tests/cases/fourslash/inputFile1.js.map {"version":3,"file":"inputFile1.js","sourceRoot":"sourceRootDir/","sources":["inputFile1.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile1.js -var x = 109; -var foo = "hello world"; -var M = (function () { - function M() { - } - return M; -})(); +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); //# sourceMappingURL=inputFile1.js.map EmitOutputStatus : Succeeded Filename : tests/cases/fourslash/inputFile2.js.map {"version":3,"file":"inputFile2.js","sourceRoot":"sourceRootDir/","sources":["inputFile2.ts"],"names":["C","C.constructor"],"mappings":"AAAA,IAAI,GAAG,GAAG,wBAAwB,CAAC;AACnC,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile2.js -var bar = "hello world Typescript"; -var C = (function () { - function C() { - } - return C; -})(); +var bar = "hello world Typescript"; +var C = (function () { + function C() { + } + return C; +})(); //# sourceMappingURL=inputFile2.js.map diff --git a/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline b/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline index 13df5b18c3..f16e381059 100644 --- a/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline +++ b/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline @@ -1,12 +1,12 @@ EmitOutputStatus : EmitErrorsEncountered Filename : tests/cases/fourslash/inputFile.js -var M; -(function (M) { - var C = (function () { - function C() { - } - return C; - })(); - M.foo = new C(); -})(M || (M = {})); +var M; +(function (M) { + var C = (function () { + function C() { + } + return C; + })(); + M.foo = new C(); +})(M || (M = {})); diff --git a/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline b/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline index c05c01eb91..4befff0466 100644 --- a/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline +++ b/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline @@ -1,14 +1,14 @@ EmitOutputStatus : EmitErrorsEncountered Filename : tests/cases/fourslash/inputFile.js -define(["require", "exports"], function (require, exports) { - var C = (function () { - function C() { - } - return C; - })(); - var M; - (function (M) { - M.foo = new C(); - })(M = exports.M || (exports.M = {})); -}); +define(["require", "exports"], function (require, exports) { + var C = (function () { + function C() { + } + return C; + })(); + var M; + (function (M) { + M.foo = new C(); + })(M = exports.M || (exports.M = {})); +}); diff --git a/tests/baselines/reference/getEmitOutputWithSemanticErrors.baseline b/tests/baselines/reference/getEmitOutputWithSemanticErrors.baseline index dabcd85e85..fed9a4d208 100644 --- a/tests/baselines/reference/getEmitOutputWithSemanticErrors.baseline +++ b/tests/baselines/reference/getEmitOutputWithSemanticErrors.baseline @@ -1,4 +1,4 @@ EmitOutputStatus : JSGeneratedWithSemanticErrors Filename : tests/cases/fourslash/inputFile.js -var x = "hello world"; +var x = "hello world"; diff --git a/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline b/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline index 0dd36c7455..a2e296b85e 100644 --- a/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline +++ b/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline @@ -1,4 +1,4 @@ EmitOutputStatus : DeclarationGenerationSkipped Filename : tests/cases/fourslash/inputFile.js -var x = "hello world"; +var x = "hello world"; diff --git a/tests/cases/fourslash_old/completionEntryForPrimitive.ts b/tests/cases/fourslash/completionEntryForPrimitive.ts similarity index 88% rename from tests/cases/fourslash_old/completionEntryForPrimitive.ts rename to tests/cases/fourslash/completionEntryForPrimitive.ts index d5beda9327..9b800c7b7e 100644 --- a/tests/cases/fourslash_old/completionEntryForPrimitive.ts +++ b/tests/cases/fourslash/completionEntryForPrimitive.ts @@ -6,4 +6,4 @@ diagnostics.setEditValidation(IncrementalEditValidation.None); goTo.marker(); verify.not.completionListIsEmpty(); edit.insert("nu"); -verify.completionListContains("number", undefined, undefined, undefined, "primitive type"); \ No newline at end of file +verify.completionListContains("number", undefined, undefined, undefined, "keyword"); \ No newline at end of file diff --git a/tests/cases/fourslash_old/completionInTypeOf1.ts b/tests/cases/fourslash/completionInTypeOf1.ts similarity index 100% rename from tests/cases/fourslash_old/completionInTypeOf1.ts rename to tests/cases/fourslash/completionInTypeOf1.ts diff --git a/tests/cases/fourslash_old/completionListAfterNumericLiteral.ts b/tests/cases/fourslash/completionListAfterNumericLiteral.ts similarity index 100% rename from tests/cases/fourslash_old/completionListAfterNumericLiteral.ts rename to tests/cases/fourslash/completionListAfterNumericLiteral.ts diff --git a/tests/cases/fourslash_old/completionListAfterObjectLiteral1.ts b/tests/cases/fourslash/completionListAfterObjectLiteral1.ts similarity index 100% rename from tests/cases/fourslash_old/completionListAfterObjectLiteral1.ts rename to tests/cases/fourslash/completionListAfterObjectLiteral1.ts diff --git a/tests/cases/fourslash_old/completionListAtEOF2.ts b/tests/cases/fourslash/completionListAtEOF2.ts similarity index 100% rename from tests/cases/fourslash_old/completionListAtEOF2.ts rename to tests/cases/fourslash/completionListAtEOF2.ts diff --git a/tests/cases/fourslash_old/completionListAtNodeBoundry.ts b/tests/cases/fourslash/completionListAtNodeBoundry.ts similarity index 100% rename from tests/cases/fourslash_old/completionListAtNodeBoundry.ts rename to tests/cases/fourslash/completionListAtNodeBoundry.ts diff --git a/tests/cases/fourslash_old/completionListBeforeKeyword.ts b/tests/cases/fourslash/completionListBeforeKeyword.ts similarity index 100% rename from tests/cases/fourslash_old/completionListBeforeKeyword.ts rename to tests/cases/fourslash/completionListBeforeKeyword.ts diff --git a/tests/cases/fourslash_old/completionListCladule.ts b/tests/cases/fourslash/completionListCladule.ts similarity index 100% rename from tests/cases/fourslash_old/completionListCladule.ts rename to tests/cases/fourslash/completionListCladule.ts diff --git a/tests/cases/fourslash_old/completionListClassMembers.ts b/tests/cases/fourslash/completionListClassMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListClassMembers.ts rename to tests/cases/fourslash/completionListClassMembers.ts diff --git a/tests/cases/fourslash_old/completionListEnumMembers.ts b/tests/cases/fourslash/completionListEnumMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListEnumMembers.ts rename to tests/cases/fourslash/completionListEnumMembers.ts diff --git a/tests/cases/fourslash_old/completionListEnumValues.ts b/tests/cases/fourslash/completionListEnumValues.ts similarity index 100% rename from tests/cases/fourslash_old/completionListEnumValues.ts rename to tests/cases/fourslash/completionListEnumValues.ts diff --git a/tests/cases/fourslash_old/completionListForDerivedType1.ts b/tests/cases/fourslash/completionListForDerivedType1.ts similarity index 73% rename from tests/cases/fourslash_old/completionListForDerivedType1.ts rename to tests/cases/fourslash/completionListForDerivedType1.ts index a3dd192a75..0c514713c2 100644 --- a/tests/cases/fourslash_old/completionListForDerivedType1.ts +++ b/tests/cases/fourslash/completionListForDerivedType1.ts @@ -12,10 +12,10 @@ ////f2./*2*/ // here bar has return type any, but bar2 is Foo2 goTo.marker('1'); -verify.completionListContains('bar', '(): IFoo'); +verify.completionListContains('bar', '() => IFoo'); verify.not.completionListContains('bar2'); edit.insert('bar();'); // just to make the file valid before checking next completion location goTo.marker('2'); -verify.completionListContains('bar', '(): IFoo'); -verify.completionListContains('bar2', '(): IFoo2'); \ No newline at end of file +verify.completionListContains('bar', '() => IFoo'); +verify.completionListContains('bar2', '() => IFoo2'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/completionListForNonExportedMemberInAmbientModuleWithExportAssignment1.ts b/tests/cases/fourslash/completionListForNonExportedMemberInAmbientModuleWithExportAssignment1.ts similarity index 100% rename from tests/cases/fourslash_old/completionListForNonExportedMemberInAmbientModuleWithExportAssignment1.ts rename to tests/cases/fourslash/completionListForNonExportedMemberInAmbientModuleWithExportAssignment1.ts diff --git a/tests/cases/fourslash_old/completionListFunctionExpression.ts b/tests/cases/fourslash/completionListFunctionExpression.ts similarity index 100% rename from tests/cases/fourslash_old/completionListFunctionExpression.ts rename to tests/cases/fourslash/completionListFunctionExpression.ts diff --git a/tests/cases/fourslash_old/completionListGenericConstraints.ts b/tests/cases/fourslash/completionListGenericConstraints.ts similarity index 100% rename from tests/cases/fourslash_old/completionListGenericConstraints.ts rename to tests/cases/fourslash/completionListGenericConstraints.ts diff --git a/tests/cases/fourslash_old/completionListInContextuallyTypedArgument.ts b/tests/cases/fourslash/completionListInContextuallyTypedArgument.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInContextuallyTypedArgument.ts rename to tests/cases/fourslash/completionListInContextuallyTypedArgument.ts diff --git a/tests/cases/fourslash_old/completionListInExtendsClause.ts b/tests/cases/fourslash/completionListInExtendsClause.ts similarity index 54% rename from tests/cases/fourslash_old/completionListInExtendsClause.ts rename to tests/cases/fourslash/completionListInExtendsClause.ts index 0ffb083606..97ebc51701 100644 --- a/tests/cases/fourslash_old/completionListInExtendsClause.ts +++ b/tests/cases/fourslash/completionListInExtendsClause.ts @@ -18,8 +18,15 @@ ////interface test4 implements Foo./*4*/ {} -test.markers().forEach((marker) => { - goTo.position(marker.position, marker.fileName); +goTo.marker("1"); +verify.completionListIsEmpty(); - verify.completionListIsEmpty(); -}); +goTo.marker("2"); +verify.completionListIsEmpty(); + +goTo.marker("3"); +verify.completionListIsEmpty(); + +// This needs comletion list filtering based on location to work +goTo.marker("4"); +verify.not.completionListIsEmpty(); \ No newline at end of file diff --git a/tests/cases/fourslash_old/completionListInExtendsClauseAtEOF.ts b/tests/cases/fourslash/completionListInExtendsClauseAtEOF.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInExtendsClauseAtEOF.ts rename to tests/cases/fourslash/completionListInExtendsClauseAtEOF.ts diff --git a/tests/cases/fourslash_old/completionListInNamedFunctionExpression.ts b/tests/cases/fourslash/completionListInNamedFunctionExpression.ts similarity index 85% rename from tests/cases/fourslash_old/completionListInNamedFunctionExpression.ts rename to tests/cases/fourslash/completionListInNamedFunctionExpression.ts index 6023cfee44..a4dd328e1e 100644 --- a/tests/cases/fourslash_old/completionListInNamedFunctionExpression.ts +++ b/tests/cases/fourslash/completionListInNamedFunctionExpression.ts @@ -24,9 +24,9 @@ goTo.marker("insideFunctionExpression"); verify.memberListContains("foo"); goTo.marker("referenceInsideFunctionExpression"); -verify.quickInfoIs("(): number"); +verify.quickInfoIs("() => number"); goTo.marker("referenceInGlobalScope"); -verify.quickInfoIs("(a: number): string"); +verify.quickInfoIs("(a: number) => string"); diff --git a/tests/cases/fourslash_old/completionListInObjectLiteral3.ts b/tests/cases/fourslash/completionListInObjectLiteral3.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInObjectLiteral3.ts rename to tests/cases/fourslash/completionListInObjectLiteral3.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiterals2.ts b/tests/cases/fourslash/completionListInTypedObjectLiterals2.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiterals2.ts rename to tests/cases/fourslash/completionListInTypedObjectLiterals2.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiterals3.ts b/tests/cases/fourslash/completionListInTypedObjectLiterals3.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiterals3.ts rename to tests/cases/fourslash/completionListInTypedObjectLiterals3.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiterals4.ts b/tests/cases/fourslash/completionListInTypedObjectLiterals4.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiterals4.ts rename to tests/cases/fourslash/completionListInTypedObjectLiterals4.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiteralsWithPartialPropertyNames.ts b/tests/cases/fourslash/completionListInTypedObjectLiteralsWithPartialPropertyNames.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiteralsWithPartialPropertyNames.ts rename to tests/cases/fourslash/completionListInTypedObjectLiteralsWithPartialPropertyNames.ts diff --git a/tests/cases/fourslash_old/completionListInTypedObjectLiteralsWithPartialPropertyNames2.ts b/tests/cases/fourslash/completionListInTypedObjectLiteralsWithPartialPropertyNames2.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInTypedObjectLiteralsWithPartialPropertyNames2.ts rename to tests/cases/fourslash/completionListInTypedObjectLiteralsWithPartialPropertyNames2.ts diff --git a/tests/cases/fourslash_old/completionListInsideTargetTypedFunction.ts b/tests/cases/fourslash/completionListInsideTargetTypedFunction.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInsideTargetTypedFunction.ts rename to tests/cases/fourslash/completionListInsideTargetTypedFunction.ts diff --git a/tests/cases/fourslash_old/completionListInvalidMemberNames.ts b/tests/cases/fourslash/completionListInvalidMemberNames.ts similarity index 91% rename from tests/cases/fourslash_old/completionListInvalidMemberNames.ts rename to tests/cases/fourslash/completionListInvalidMemberNames.ts index 7091850bb3..7fff46e2a8 100644 --- a/tests/cases/fourslash_old/completionListInvalidMemberNames.ts +++ b/tests/cases/fourslash/completionListInvalidMemberNames.ts @@ -19,7 +19,7 @@ verify.completionListContains("bar"); verify.completionListContains("break"); verify.completionListContains("any"); verify.completionListContains("$"); -verify.completionListContains("\\u0062"); +verify.completionListContains("b"); // Nothing else should show up verify.memberListCount(5); diff --git a/tests/cases/fourslash_old/completionListInvalidMemberNames2.ts b/tests/cases/fourslash/completionListInvalidMemberNames2.ts similarity index 100% rename from tests/cases/fourslash_old/completionListInvalidMemberNames2.ts rename to tests/cases/fourslash/completionListInvalidMemberNames2.ts diff --git a/tests/cases/fourslash_old/completionListModuleMembers.ts b/tests/cases/fourslash/completionListModuleMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListModuleMembers.ts rename to tests/cases/fourslash/completionListModuleMembers.ts diff --git a/tests/cases/fourslash_old/completionListObjectMembers.ts b/tests/cases/fourslash/completionListObjectMembers.ts similarity index 80% rename from tests/cases/fourslash_old/completionListObjectMembers.ts rename to tests/cases/fourslash/completionListObjectMembers.ts index 63c0e96bc0..c23eff12db 100644 --- a/tests/cases/fourslash_old/completionListObjectMembers.ts +++ b/tests/cases/fourslash/completionListObjectMembers.ts @@ -11,4 +11,4 @@ goTo.marker(); verify.memberListContains("bar", 'any'); -verify.memberListContains("foo", '(bar: any): any'); +verify.memberListContains("foo", '(bar: any) => any'); diff --git a/tests/cases/fourslash/completionListOfGnericSymbol.ts b/tests/cases/fourslash/completionListOfGnericSymbol.ts new file mode 100644 index 0000000000..fd223b68ca --- /dev/null +++ b/tests/cases/fourslash/completionListOfGnericSymbol.ts @@ -0,0 +1,11 @@ +/// + +// Ensure kind is set correctelly on completions of a generic symbol + +////var a = [1,2,3]; +////a./**/ + +goTo.marker(); +verify.memberListContains('length', "number", /*docComments*/ undefined, /*fullSymbolName*/ undefined,/*kind*/ "property"); +verify.memberListContains('toString', "() => string", /*docComments*/ undefined, /*fullSymbolName*/ undefined,/*kind*/ "method"); + diff --git a/tests/cases/fourslash_old/completionListOnFunctionCallWithOptionalArgument.ts b/tests/cases/fourslash/completionListOnFunctionCallWithOptionalArgument.ts similarity index 100% rename from tests/cases/fourslash_old/completionListOnFunctionCallWithOptionalArgument.ts rename to tests/cases/fourslash/completionListOnFunctionCallWithOptionalArgument.ts diff --git a/tests/cases/fourslash_old/completionListOnParam.ts b/tests/cases/fourslash/completionListOnParam.ts similarity index 100% rename from tests/cases/fourslash_old/completionListOnParam.ts rename to tests/cases/fourslash/completionListOnParam.ts diff --git a/tests/cases/fourslash_old/completionListOnVarBetweenModules.ts b/tests/cases/fourslash/completionListOnVarBetweenModules.ts similarity index 100% rename from tests/cases/fourslash_old/completionListOnVarBetweenModules.ts rename to tests/cases/fourslash/completionListOnVarBetweenModules.ts diff --git a/tests/cases/fourslash_old/completionListPrimitives.ts b/tests/cases/fourslash/completionListPrimitives.ts similarity index 100% rename from tests/cases/fourslash_old/completionListPrimitives.ts rename to tests/cases/fourslash/completionListPrimitives.ts diff --git a/tests/cases/fourslash_old/completionListPrivateMembers.ts b/tests/cases/fourslash/completionListPrivateMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListPrivateMembers.ts rename to tests/cases/fourslash/completionListPrivateMembers.ts diff --git a/tests/cases/fourslash/completionListPrivateMembers2.ts b/tests/cases/fourslash/completionListPrivateMembers2.ts new file mode 100644 index 0000000000..1b19d042cb --- /dev/null +++ b/tests/cases/fourslash/completionListPrivateMembers2.ts @@ -0,0 +1,17 @@ +/// + +////class Foo { +//// private y; +//// constructor(private x) {} +//// method() { this./*1*/; } +////} +////var f:Foo; +////f./*2*/ + +goTo.marker("1"); +verify.memberListContains("y"); +verify.memberListContains("x"); + +goTo.marker("2"); +verify.not.memberListContains("x"); +verify.not.memberListContains("y"); \ No newline at end of file diff --git a/tests/cases/fourslash_old/completionListSuperMembers.ts b/tests/cases/fourslash/completionListSuperMembers.ts similarity index 100% rename from tests/cases/fourslash_old/completionListSuperMembers.ts rename to tests/cases/fourslash/completionListSuperMembers.ts diff --git a/tests/cases/fourslash_old/completionListWithUnresolvedModule.ts b/tests/cases/fourslash/completionListWithUnresolvedModule.ts similarity index 100% rename from tests/cases/fourslash_old/completionListWithUnresolvedModule.ts rename to tests/cases/fourslash/completionListWithUnresolvedModule.ts diff --git a/tests/cases/fourslash/findAllRefsInsideWithBlock.ts b/tests/cases/fourslash/findAllRefsInsideWithBlock.ts new file mode 100644 index 0000000000..394d30d89d --- /dev/null +++ b/tests/cases/fourslash/findAllRefsInsideWithBlock.ts @@ -0,0 +1,16 @@ +/// + +////var x = 0; +//// +////with ({}) { +//// var y = x; // Reference of x here should not be picked +//// /*2*/y++; // also reference for y should be ignored +////} +//// +////x = /*1*/x + 1; + +goTo.marker('1'); +verify.referencesCountIs(3); + +goTo.marker('2'); +verify.referencesCountIs(1); \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index ccbaa34b90..f9476ee4d9 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -404,6 +404,14 @@ module FourSlashInterface { public semanticClassificationsAre(...classifications: { classificationType: string; text: string }[]) { FourSlash.currentTestState.verifySemanticClassifications(classifications); } + + public renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) { + FourSlash.currentTestState.verifyRenameInfoSucceeded(displayName, fullDisplayName, kind, kindModifiers) + } + + public renameInfoFailed(message?: string) { + FourSlash.currentTestState.verifyRenameInfoFailed(message) + } } export class edit { diff --git a/tests/cases/fourslash/getRenameInfoTests1.ts b/tests/cases/fourslash/getRenameInfoTests1.ts new file mode 100644 index 0000000000..6f4300282d --- /dev/null +++ b/tests/cases/fourslash/getRenameInfoTests1.ts @@ -0,0 +1,8 @@ +/// + +////class [|/**/C|] { +//// +////} + +goTo.marker(""); +verify.renameInfoSucceeded("C"); \ No newline at end of file diff --git a/tests/cases/fourslash/getRenameInfoTests2.ts b/tests/cases/fourslash/getRenameInfoTests2.ts new file mode 100644 index 0000000000..93e8e451b4 --- /dev/null +++ b/tests/cases/fourslash/getRenameInfoTests2.ts @@ -0,0 +1,8 @@ +/// + +/////**/class C { +//// +////} + +goTo.marker(""); +verify.renameInfoFailed(); \ No newline at end of file diff --git a/tests/cases/fourslash_old/memberCompletionFromFunctionCall.ts b/tests/cases/fourslash/memberCompletionFromFunctionCall.ts similarity index 100% rename from tests/cases/fourslash_old/memberCompletionFromFunctionCall.ts rename to tests/cases/fourslash/memberCompletionFromFunctionCall.ts diff --git a/tests/cases/fourslash_old/memberCompletionInForEach1.ts b/tests/cases/fourslash/memberCompletionInForEach1.ts similarity index 100% rename from tests/cases/fourslash_old/memberCompletionInForEach1.ts rename to tests/cases/fourslash/memberCompletionInForEach1.ts diff --git a/tests/cases/fourslash_old/memberCompletionOnTypeParameters.ts b/tests/cases/fourslash/memberCompletionOnTypeParameters.ts similarity index 67% rename from tests/cases/fourslash_old/memberCompletionOnTypeParameters.ts rename to tests/cases/fourslash/memberCompletionOnTypeParameters.ts index 117b6e48c4..7b415c4b3e 100644 --- a/tests/cases/fourslash_old/memberCompletionOnTypeParameters.ts +++ b/tests/cases/fourslash/memberCompletionOnTypeParameters.ts @@ -1,11 +1,11 @@ -/// - -////interface IFoo { -//// x: number; -//// y: string; -////} -//// -////function foo() { +/// + +////interface IFoo { +//// x: number; +//// y: string; +////} +//// +////function foo() { //// var s:S, t: T, u: U, v: V; //// s./*S*/; // no constraint, no completion //// t./*T*/; // IFoo @@ -22,9 +22,8 @@ verify.memberListContains("y", "string"); verify.memberListCount(2); goTo.marker("U"); -verify.memberListContains("x", "number"); -verify.memberListContains("y", "string"); -verify.memberListCount(2); +verify.memberListContains("toString", "() => string"); +verify.memberListCount(7); // constructor, toString, toLocaleString, valueOf, hasOwnProperty, isPrototypeOf, propertyIsEnumerable goTo.marker("V"); verify.memberListContains("x", "number"); diff --git a/tests/cases/fourslash_old/memberCompletionOnTypeParameters2.ts b/tests/cases/fourslash/memberCompletionOnTypeParameters2.ts similarity index 84% rename from tests/cases/fourslash_old/memberCompletionOnTypeParameters2.ts rename to tests/cases/fourslash/memberCompletionOnTypeParameters2.ts index 8d97b7089c..e7f6c5c651 100644 --- a/tests/cases/fourslash_old/memberCompletionOnTypeParameters2.ts +++ b/tests/cases/fourslash/memberCompletionOnTypeParameters2.ts @@ -1,5 +1,5 @@ -/// - +/// + ////class A { //// foo(): string { return ''; } ////} @@ -10,7 +10,7 @@ //// } ////} //// -////class C { +////class C { //// x: U; //// y = this.x./**/ // completion list here ////} diff --git a/tests/cases/fourslash/memberListInReopenedEnum.ts b/tests/cases/fourslash/memberListInReopenedEnum.ts new file mode 100644 index 0000000000..ede924b678 --- /dev/null +++ b/tests/cases/fourslash/memberListInReopenedEnum.ts @@ -0,0 +1,18 @@ +/// + +////module M { +//// enum E { +//// A, B +//// } +//// enum E { +//// C = 0, D +//// } +//// var x = E./*1*/ +////} + + +goTo.marker('1'); +verify.memberListContains('A', 'E', undefined, "E.A"); +verify.memberListContains('B', 'E', undefined, "E.B"); +verify.memberListContains('C', 'E', undefined, "E.C"); +verify.memberListContains('D', 'E', undefined, "E.D"); \ No newline at end of file diff --git a/tests/cases/fourslash_old/memberListInWithBlock.ts b/tests/cases/fourslash/memberListInWithBlock.ts similarity index 79% rename from tests/cases/fourslash_old/memberListInWithBlock.ts rename to tests/cases/fourslash/memberListInWithBlock.ts index 973f4612cd..a37c20dadf 100644 --- a/tests/cases/fourslash_old/memberListInWithBlock.ts +++ b/tests/cases/fourslash/memberListInWithBlock.ts @@ -15,8 +15,10 @@ goTo.marker('1'); verify.memberListIsEmpty(); goTo.marker('2'); +// Only keywords should show in completion, no members or types verify.not.completionListContains("foo"); verify.not.completionListContains("f"); verify.not.completionListContains("c"); verify.not.completionListContains("d"); verify.not.completionListContains("x"); +verify.not.completionListContains("Object"); diff --git a/tests/cases/fourslash/memberListInWithBlock2.ts b/tests/cases/fourslash/memberListInWithBlock2.ts new file mode 100644 index 0000000000..72bccb6926 --- /dev/null +++ b/tests/cases/fourslash/memberListInWithBlock2.ts @@ -0,0 +1,12 @@ +/// + +////interface IFoo { +//// a: number; +////} +//// +////with (x) { +//// var y: IFoo = { /*1*/ }; +////} + +goTo.marker('1'); +verify.memberListIsEmpty(); \ No newline at end of file diff --git a/tests/cases/fourslash/memberListInWithBlock3.ts b/tests/cases/fourslash/memberListInWithBlock3.ts new file mode 100644 index 0000000000..a007b08cd0 --- /dev/null +++ b/tests/cases/fourslash/memberListInWithBlock3.ts @@ -0,0 +1,7 @@ +/// + +////var x = { a: 0 }; +////with(x./*1*/ + +goTo.marker('1'); +verify.memberListContains("a"); diff --git a/tests/cases/fourslash_old/memberListInsideObjectLiterals.ts b/tests/cases/fourslash/memberListInsideObjectLiterals.ts similarity index 100% rename from tests/cases/fourslash_old/memberListInsideObjectLiterals.ts rename to tests/cases/fourslash/memberListInsideObjectLiterals.ts diff --git a/tests/cases/fourslash_old/memberListOfClass.ts b/tests/cases/fourslash/memberListOfClass.ts similarity index 85% rename from tests/cases/fourslash_old/memberListOfClass.ts rename to tests/cases/fourslash/memberListOfClass.ts index c6ac4973fb..567dfc0ddc 100644 --- a/tests/cases/fourslash_old/memberListOfClass.ts +++ b/tests/cases/fourslash/memberListOfClass.ts @@ -11,5 +11,5 @@ goTo.marker(); verify.memberListCount(2); -verify.memberListContains('pubMeth', '(): void'); +verify.memberListContains('pubMeth', '() => void'); verify.memberListContains('pubProp', 'number'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/memberListOfEnumFromExternalModule.ts b/tests/cases/fourslash/memberListOfEnumFromExternalModule.ts similarity index 100% rename from tests/cases/fourslash_old/memberListOfEnumFromExternalModule.ts rename to tests/cases/fourslash/memberListOfEnumFromExternalModule.ts diff --git a/tests/cases/fourslash_old/memberListOfExportedClass.ts b/tests/cases/fourslash/memberListOfExportedClass.ts similarity index 100% rename from tests/cases/fourslash_old/memberListOfExportedClass.ts rename to tests/cases/fourslash/memberListOfExportedClass.ts diff --git a/tests/cases/fourslash_old/memberListOfModule.ts b/tests/cases/fourslash/memberListOfModule.ts similarity index 100% rename from tests/cases/fourslash_old/memberListOfModule.ts rename to tests/cases/fourslash/memberListOfModule.ts diff --git a/tests/cases/fourslash_old/memberListOfModuleBeforeKeyword.ts b/tests/cases/fourslash/memberListOfModuleBeforeKeyword.ts similarity index 67% rename from tests/cases/fourslash_old/memberListOfModuleBeforeKeyword.ts rename to tests/cases/fourslash/memberListOfModuleBeforeKeyword.ts index 2356a35d94..33f085cde0 100644 --- a/tests/cases/fourslash_old/memberListOfModuleBeforeKeyword.ts +++ b/tests/cases/fourslash/memberListOfModuleBeforeKeyword.ts @@ -16,9 +16,9 @@ // Verify the memberlist of module when the following line has a keyword goTo.marker('namedType'); -verify.completionListContains('C1', 'TypeModule1.C1'); -verify.completionListContains('C2', 'TypeModule1.C2'); +verify.completionListContains('C1'); +verify.completionListContains('C2'); goTo.marker('dotedExpression'); -verify.completionListContains('C1', 'TypeModule1.C1'); -verify.completionListContains('C2', 'TypeModule1.C2'); \ No newline at end of file +verify.completionListContains('C1'); +verify.completionListContains('C2'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/memberListOnFunctionParameter.ts b/tests/cases/fourslash/memberListOnFunctionParameter.ts similarity index 100% rename from tests/cases/fourslash_old/memberListOnFunctionParameter.ts rename to tests/cases/fourslash/memberListOnFunctionParameter.ts diff --git a/tests/cases/fourslash_old/memberListOnThisInClassWithPrivates.ts b/tests/cases/fourslash/memberListOnThisInClassWithPrivates.ts similarity index 71% rename from tests/cases/fourslash_old/memberListOnThisInClassWithPrivates.ts rename to tests/cases/fourslash/memberListOnThisInClassWithPrivates.ts index 1b77948f17..6df5b55577 100644 --- a/tests/cases/fourslash_old/memberListOnThisInClassWithPrivates.ts +++ b/tests/cases/fourslash/memberListOnThisInClassWithPrivates.ts @@ -8,6 +8,6 @@ ////} goTo.marker(); -verify.memberListContains('privMeth', '(): void'); -verify.memberListContains('pubMeth', '(): void'); +verify.memberListContains('privMeth', '() => void'); +verify.memberListContains('pubMeth', '() => void'); verify.memberListContains('pubProp', 'number'); \ No newline at end of file diff --git a/tests/cases/fourslash_old/quickInfoInWithBlock.ts b/tests/cases/fourslash/quickInfoInWithBlock.ts similarity index 100% rename from tests/cases/fourslash_old/quickInfoInWithBlock.ts rename to tests/cases/fourslash/quickInfoInWithBlock.ts diff --git a/tests/cases/fourslash/todoComments1.ts b/tests/cases/fourslash/todoComments1.ts index 900b4694c6..b1e0086b93 100644 --- a/tests/cases/fourslash/todoComments1.ts +++ b/tests/cases/fourslash/todoComments1.ts @@ -1,3 +1,3 @@ //// // [|TODO|] -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments10.ts b/tests/cases/fourslash/todoComments10.ts index 26ee7a4014..cde41dd6fb 100644 --- a/tests/cases/fourslash/todoComments10.ts +++ b/tests/cases/fourslash/todoComments10.ts @@ -2,5 +2,5 @@ //// [|todo 1|] //// [|hack 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments11.ts b/tests/cases/fourslash/todoComments11.ts index 976368315d..dd69091130 100644 --- a/tests/cases/fourslash/todoComments11.ts +++ b/tests/cases/fourslash/todoComments11.ts @@ -2,5 +2,5 @@ //// [|TODO(jason) 1|] //// [|HACK 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments12.ts b/tests/cases/fourslash/todoComments12.ts index d9cd3dea4d..7f9a0a0cd7 100644 --- a/tests/cases/fourslash/todoComments12.ts +++ b/tests/cases/fourslash/todoComments12.ts @@ -2,5 +2,5 @@ //// [|TODO(jason) 1|] //// [|HACK 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["HACK", "TODO(jason)"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments13.ts b/tests/cases/fourslash/todoComments13.ts index 93147b30e4..82304e2ab8 100644 --- a/tests/cases/fourslash/todoComments13.ts +++ b/tests/cases/fourslash/todoComments13.ts @@ -1,4 +1,3 @@ //// TODO -debugger; verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments14.ts b/tests/cases/fourslash/todoComments14.ts index 46f8f48fe3..3a3294f4bb 100644 --- a/tests/cases/fourslash/todoComments14.ts +++ b/tests/cases/fourslash/todoComments14.ts @@ -1,3 +1,3 @@ //// BAR // [|TODO|] -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments15.ts b/tests/cases/fourslash/todoComments15.ts index 22cee54d0f..6bb327ecdf 100644 --- a/tests/cases/fourslash/todoComments15.ts +++ b/tests/cases/fourslash/todoComments15.ts @@ -1,3 +1,3 @@ //// "// HACK 1"; -debugger; + verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments16.ts b/tests/cases/fourslash/todoComments16.ts index bbdeac0c5e..d980034090 100644 --- a/tests/cases/fourslash/todoComments16.ts +++ b/tests/cases/fourslash/todoComments16.ts @@ -1,3 +1,3 @@ //// //// [|HACK 1|] -debugger; + verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments17.ts b/tests/cases/fourslash/todoComments17.ts index 5231694160..a751bb10dd 100644 --- a/tests/cases/fourslash/todoComments17.ts +++ b/tests/cases/fourslash/todoComments17.ts @@ -1,3 +1,3 @@ //// /**** [|HACK 1 |]*/ a -debugger; + verify.todoCommentsInCurrentFile(["TODO(jason)", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments2.ts b/tests/cases/fourslash/todoComments2.ts index b58b0fda7a..ddf8520c48 100644 --- a/tests/cases/fourslash/todoComments2.ts +++ b/tests/cases/fourslash/todoComments2.ts @@ -1,3 +1,3 @@ //// // not TODO -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments3.ts b/tests/cases/fourslash/todoComments3.ts index 62eb02642e..f38b80ae8f 100644 --- a/tests/cases/fourslash/todoComments3.ts +++ b/tests/cases/fourslash/todoComments3.ts @@ -1,3 +1,3 @@ //// // [|TODO with stuff|] -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments4.ts b/tests/cases/fourslash/todoComments4.ts index c9ec94785f..86d6ce2407 100644 --- a/tests/cases/fourslash/todoComments4.ts +++ b/tests/cases/fourslash/todoComments4.ts @@ -1,3 +1,3 @@ //// // TODOnomatch -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments5.ts b/tests/cases/fourslash/todoComments5.ts index 157ac162a8..05db2aca16 100644 --- a/tests/cases/fourslash/todoComments5.ts +++ b/tests/cases/fourslash/todoComments5.ts @@ -2,5 +2,5 @@ //// [|TODO 1|] //// [|TODO 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments6.ts b/tests/cases/fourslash/todoComments6.ts index 0d2692511c..84e0542811 100644 --- a/tests/cases/fourslash/todoComments6.ts +++ b/tests/cases/fourslash/todoComments6.ts @@ -2,5 +2,5 @@ //// * [|TODO 1|] //// * [|TODO 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments7.ts b/tests/cases/fourslash/todoComments7.ts index ffb5bcf660..10b18a53bc 100644 --- a/tests/cases/fourslash/todoComments7.ts +++ b/tests/cases/fourslash/todoComments7.ts @@ -2,5 +2,5 @@ //// [|TODO 1|] //// [|HACK 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments8.ts b/tests/cases/fourslash/todoComments8.ts index 5d53b7b57c..e63c07d631 100644 --- a/tests/cases/fourslash/todoComments8.ts +++ b/tests/cases/fourslash/todoComments8.ts @@ -2,5 +2,5 @@ //// [|HACK 1|] //// [|TODO 2|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/todoComments9.ts b/tests/cases/fourslash/todoComments9.ts index 36cba71cec..107f6c279a 100644 --- a/tests/cases/fourslash/todoComments9.ts +++ b/tests/cases/fourslash/todoComments9.ts @@ -2,5 +2,5 @@ //// [|TODO HACK|] //// [|HACK TODO|] //// */ -debugger; + verify.todoCommentsInCurrentFile(["TODO", "HACK"]); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInObjectLiteralThatIsParameterOfFunctionCall.ts b/tests/cases/fourslash_old/completionListInObjectLiteralThatIsParameterOfFunctionCall.ts similarity index 100% rename from tests/cases/fourslash/completionListInObjectLiteralThatIsParameterOfFunctionCall.ts rename to tests/cases/fourslash_old/completionListInObjectLiteralThatIsParameterOfFunctionCall.ts diff --git a/tests/cases/fourslash_old/memberListInReopenedEnum.ts b/tests/cases/fourslash_old/memberListInReopenedEnum.ts deleted file mode 100644 index b1168f54b1..0000000000 --- a/tests/cases/fourslash_old/memberListInReopenedEnum.ts +++ /dev/null @@ -1,18 +0,0 @@ -/// - -////module M { -//// enum E { -//// A, B -//// } -//// enum E { -//// C = 0, D -//// } -//// var x = E./*1*/ -////} - - -goTo.marker('1'); -verify.memberListContains('A', 'E', undefined, "M.E.A"); -verify.memberListContains('B', 'E', undefined, "M.E.B"); -verify.memberListContains('C', 'E', undefined, "M.E.C"); -verify.memberListContains('D', 'E', undefined, "M.E.D"); \ No newline at end of file diff --git a/tests/cases/unittests/services/colorization.ts b/tests/cases/unittests/services/colorization.ts index 414942bbde..7b8ee37606 100644 --- a/tests/cases/unittests/services/colorization.ts +++ b/tests/cases/unittests/services/colorization.ts @@ -170,8 +170,8 @@ describe('Colorization', function () { it("classifies keyword after a dot on previous line", function () { test("var", - ts.EndOfLineState.EndingWithDotToken, - identifier("var"), + ts.EndOfLineState.Start, + keyword("var"), finalEndOfLineState(ts.EndOfLineState.Start)); }); });