diff --git a/Jakefile b/Jakefile index 767387c5d86..dc8070fd751 100644 --- a/Jakefile +++ b/Jakefile @@ -382,6 +382,10 @@ compileFile(nodeDefinitionsFile, servicesSources,[builtLocalDirectory, copyright desc("Builds the full compiler and services"); task("local", ["generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile]); +// Local target to build only tsc.js +desc("Builds only the compiler"); +task("tsc", ["generate-diagnostics", "lib", tscFile]); + // Local target to build the compiler and services desc("Sets release mode flag"); task("release", function() { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 7bf95dcc846..1188d346191 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -451,6 +451,7 @@ module ts { _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." }, + You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." }, yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." }, Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported." }, The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression: { code: 9002, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b4944f56d77..b1a794716a4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1798,6 +1798,10 @@ "category": "Error", "code": 8000 }, + "You cannot rename elements that are defined in the standard TypeScript library.": { + "category": "Error", + "code": 8001 + }, "'yield' expressions are not currently supported.": { "category": "Error", "code": 9000 diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index cd9d4288cdd..d829ce0b83e 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -664,7 +664,16 @@ module FourSlash { Harness.IO.log(errorMsg); this.raiseError("Completion list is not empty at Caret"); + } + } + public verifyCompletionListAllowsNewIdentifier(negative: boolean) { + var completions = this.getCompletionListAtCaret(); + + if ((completions && !completions.isNewIdentifierLocation) && !negative) { + this.raiseError("Expected builder completion entry"); + } else if ((completions && completions.isNewIdentifierLocation) && negative) { + this.raiseError("Un-expected builder completion entry"); } } diff --git a/src/services/services.ts b/src/services/services.ts index cd69a4f2117..a39f59155f7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -406,7 +406,7 @@ module ts { return pos + name.length < end && sourceFile.text.substr(pos, name.length) === name && (isWhiteSpace(sourceFile.text.charCodeAt(pos + name.length)) || - isLineBreak(sourceFile.text.charCodeAt(pos + name.length))); + isLineBreak(sourceFile.text.charCodeAt(pos + name.length))); } function isParamTag(pos: number, end: number, sourceFile: SourceFile) { @@ -807,7 +807,7 @@ module ts { if ((node).name) { namedDeclarations.push(node); } - // fall through + // fall through case SyntaxKind.Constructor: case SyntaxKind.VariableStatement: case SyntaxKind.VariableDeclarationList: @@ -828,7 +828,7 @@ module ts { if (!(node.flags & NodeFlags.AccessibilityModifier)) { break; } - // fall through + // fall through case SyntaxKind.VariableDeclaration: case SyntaxKind.BindingElement: if (isBindingPattern((node).name)) { @@ -895,7 +895,7 @@ module ts { getRenameInfo(fileName: string, position: number): RenameInfo; findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; - + getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[]; getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[]; @@ -920,7 +920,7 @@ module ts { dispose(): void; } - + export interface ClassifiedSpan { textSpan: TextSpan; classificationType: string; // ClassificationTypeNames @@ -1031,7 +1031,7 @@ module ts { text: string; kind: string; } - + export interface QuickInfo { kind: string; kindModifiers: string; @@ -1086,6 +1086,7 @@ module ts { export interface CompletionInfo { isMemberCompletion: boolean; + isNewIdentifierLocation: boolean; // true when the current location also allows for a new identifier entries: CompletionEntry[]; } @@ -1432,9 +1433,9 @@ module ts { } export function getDefaultCompilerOptions(): CompilerOptions { - // Set "ScriptTarget.Latest" target by default for language service + // Always default to "ScriptTarget.ES5" for the language service return { - target: ScriptTarget.Latest, + target: ScriptTarget.ES5, module: ModuleKind.None, }; } @@ -1611,7 +1612,7 @@ module ts { function setSourceFileFields(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string) { sourceFile.version = version; sourceFile.scriptSnapshot = scriptSnapshot; - } + } 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); @@ -1934,7 +1935,7 @@ module ts { // The position has to be: 1. in the leading trivia (before token.getStart()), and 2. within a comment return position <= token.getStart(sourceFile) && (isInsideCommentRange(getTrailingCommentRanges(sourceFile.text, token.getFullStart())) || - isInsideCommentRange(getLeadingCommentRanges(sourceFile.text, token.getFullStart()))); + isInsideCommentRange(getLeadingCommentRanges(sourceFile.text, token.getFullStart()))); function isInsideCommentRange(comments: CommentRange[]): boolean { return forEach(comments, comment => { @@ -1976,7 +1977,7 @@ module ts { } // A cache of completion entries for keywords, these do not change between sessions - var keywordCompletions:CompletionEntry[] = []; + var keywordCompletions: CompletionEntry[] = []; for (var i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) { keywordCompletions.push({ name: tokenToString(i), @@ -2323,6 +2324,7 @@ module ts { // Right of dot member completion list var symbols: Symbol[] = []; var isMemberCompletion = true; + var isNewIdentifierLocation = false; if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.PropertyAccessExpression) { var symbol = typeInfoResolver.getSymbolAtLocation(node); @@ -2359,6 +2361,7 @@ module ts { if (containingObjectLiteral) { // Object literal expression, look up possible property names from contextual type isMemberCompletion = true; + isNewIdentifierLocation = true; var contextualType = typeInfoResolver.getContextualType(containingObjectLiteral); if (!contextualType) { @@ -2375,6 +2378,7 @@ module ts { else { // Get scope members isMemberCompletion = false; + isNewIdentifierLocation = isNewIdentifierDefinitionLocation(previousToken); /// TODO filter meaning based on the current context var symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Import; @@ -2392,6 +2396,8 @@ module ts { return { isMemberCompletion, + isNewIdentifierLocation, + isBuilder : isNewIdentifierDefinitionLocation, // temporary property used to match VS implementation entries: activeCompletionSession.entries }; @@ -2419,6 +2425,64 @@ module ts { return result; } + function isNewIdentifierDefinitionLocation(previousToken: Node): boolean { + if (previousToken) { + var 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, | + + + case SyntaxKind.OpenParenToken: + return containingNodeKind === SyntaxKind.CallExpression // func( | + || containingNodeKind === SyntaxKind.Constructor // constructor( | + || containingNodeKind === SyntaxKind.NewExpression // new C(a| + || containingNodeKind === SyntaxKind.ParenthesizedExpression; // var x = (a| + + case SyntaxKind.OpenBracketToken: + return containingNodeKind === SyntaxKind.ArrayLiteralExpression; // [ | + + case SyntaxKind.ModuleKeyword: // module | + return true; + + case SyntaxKind.DotToken: + return containingNodeKind === SyntaxKind.ModuleDeclaration; // module A.| + + case SyntaxKind.OpenBraceToken: + return containingNodeKind === SyntaxKind.ClassDeclaration; // class A{ | + + case SyntaxKind.EqualsToken: + return containingNodeKind === SyntaxKind.VariableDeclaration // var x = a| + || containingNodeKind === SyntaxKind.BinaryExpression; // x = a| + + case SyntaxKind.TemplateHead: + return containingNodeKind === SyntaxKind.TemplateExpression; // `aa ${| + + case SyntaxKind.TemplateMiddle: + return containingNodeKind === SyntaxKind.TemplateSpan; // `aa ${10} dd ${| + + case SyntaxKind.PublicKeyword: + case SyntaxKind.PrivateKeyword: + case SyntaxKind.ProtectedKeyword: + return containingNodeKind === SyntaxKind.PropertyDeclaration; // class A{ public | + } + + // Previous token may have been a keyword that was converted to an identifier. + switch (previousToken.getText()) { + case "public": + case "protected": + case "private": + return true; + } + } + + return false; + } + function isInStringOrRegularExpressionOrTemplateLiteral(previousToken: Node): boolean { if (previousToken.kind === SyntaxKind.StringLiteral || previousToken.kind === SyntaxKind.RegularExpressionLiteral @@ -2465,7 +2529,6 @@ module ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.CallSignature: @@ -2485,28 +2548,54 @@ module ts { containingNodeKind === SyntaxKind.VariableDeclarationList || containingNodeKind === SyntaxKind.VariableStatement || containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { foo, | - isFunction(containingNodeKind); + isFunction(containingNodeKind) || + containingNodeKind === SyntaxKind.ClassDeclaration || // class A 0) { - var kind = getSymbolKind(symbol, typeInfoResolver, node); - if (kind) { - return getRenameInfo(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind, - getSymbolModifiers(symbol), - createTextSpan(node.getStart(), node.getWidth())); + if (symbol) { + var declarations = symbol.getDeclarations(); + if (declarations && declarations.length > 0) { + // Disallow rename for elements that are defined in the standard TypeScript library. + var defaultLibFile = getDefaultLibFileName(host.getCompilationSettings()); + for (var i = 0; i < declarations.length; i++) { + var sourceFile = declarations[i].getSourceFile(); + if (sourceFile && endsWith(sourceFile.fileName, defaultLibFile)) { + return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library.key)); + } + } + + var kind = getSymbolKind(symbol, typeInfoResolver, node); + if (kind) { + return { + canRename: true, + localizedErrorMessage: undefined, + displayName: symbol.name, + fullDisplayName: typeInfoResolver.getFullyQualifiedName(symbol), + kind: kind, + kindModifiers: getSymbolModifiers(symbol), + triggerSpan: createTextSpan(node.getStart(), node.getWidth()) + }; + } } } } return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key)); + function endsWith(string: string, value: string): boolean { + return string.lastIndexOf(value) + value.length === string.length; + } + function getRenameInfoError(localizedErrorMessage: string): RenameInfo { return { canRename: false, - localizedErrorMessage: getLocaleSpecificMessage(Diagnostics.You_cannot_rename_this_element.key), + localizedErrorMessage: localizedErrorMessage, displayName: undefined, fullDisplayName: undefined, kind: undefined, @@ -5459,18 +5575,6 @@ module ts { triggerSpan: undefined }; } - - function getRenameInfo(displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, triggerSpan: TextSpan): RenameInfo { - return { - canRename: true, - localizedErrorMessage: undefined, - displayName, - fullDisplayName, - kind, - kindModifiers, - triggerSpan - }; - } } return { @@ -5622,41 +5726,41 @@ module ts { if (!isTrivia(token)) { if ((token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) && !noRegexTable[lastNonTriviaToken]) { - if (scanner.reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) { - token = SyntaxKind.RegularExpressionLiteral; - } + if (scanner.reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) { + token = SyntaxKind.RegularExpressionLiteral; + } } else if (lastNonTriviaToken === SyntaxKind.DotToken && isKeyword(token)) { - token = SyntaxKind.Identifier; + token = SyntaxKind.Identifier; } else if (isKeyword(lastNonTriviaToken) && isKeyword(token) && !canFollow(lastNonTriviaToken, token)) { - // We have two keywords in a row. Only treat the second as a keyword if - // it's a sequence that could legally occur in the language. Otherwise - // treat it as an identifier. This way, if someone writes "private var" - // we recognize that 'var' is actually an identifier here. - token = SyntaxKind.Identifier; + // We have two keywords in a row. Only treat the second as a keyword if + // it's a sequence that could legally occur in the language. Otherwise + // treat it as an identifier. This way, if someone writes "private var" + // we recognize that 'var' is actually an identifier here. + token = SyntaxKind.Identifier; } else if (lastNonTriviaToken === SyntaxKind.Identifier && token === SyntaxKind.LessThanToken) { - // Could be the start of something generic. Keep track of that by bumping - // up the current count of generic contexts we may be in. - angleBracketStack++; + // Could be the start of something generic. Keep track of that by bumping + // up the current count of generic contexts we may be in. + angleBracketStack++; } else if (token === SyntaxKind.GreaterThanToken && angleBracketStack > 0) { - // If we think we're currently in something generic, then mark that that - // generic entity is complete. - angleBracketStack--; + // If we think we're currently in something generic, then mark that that + // generic entity is complete. + angleBracketStack--; } else if (token === SyntaxKind.AnyKeyword || token === SyntaxKind.StringKeyword || token === SyntaxKind.NumberKeyword || token === SyntaxKind.BooleanKeyword) { - if (angleBracketStack > 0 && !classifyKeywordsInGenerics) { - // If it looks like we're could be in something generic, don't classify this - // as a keyword. We may just get overwritten by the syntactic classifier, - // causing a noisy experience for the user. - token = SyntaxKind.Identifier; - } + if (angleBracketStack > 0 && !classifyKeywordsInGenerics) { + // If it looks like we're could be in something generic, don't classify this + // as a keyword. We may just get overwritten by the syntactic classifier, + // causing a noisy experience for the user. + token = SyntaxKind.Identifier; + } } lastNonTriviaToken = token; diff --git a/tests/baselines/reference/APISample_compile.js b/tests/baselines/reference/APISample_compile.js index 26a59c433b9..23106996f12 100644 --- a/tests/baselines/reference/APISample_compile.js +++ b/tests/baselines/reference/APISample_compile.js @@ -1692,6 +1692,7 @@ declare module "typescript" { } interface CompletionInfo { isMemberCompletion: boolean; + isNewIdentifierLocation: boolean; entries: CompletionEntry[]; } interface CompletionEntry { diff --git a/tests/baselines/reference/APISample_compile.types b/tests/baselines/reference/APISample_compile.types index 43b79049e8b..18ca83b2114 100644 --- a/tests/baselines/reference/APISample_compile.types +++ b/tests/baselines/reference/APISample_compile.types @@ -5422,6 +5422,9 @@ declare module "typescript" { isMemberCompletion: boolean; >isMemberCompletion : boolean + isNewIdentifierLocation: boolean; +>isNewIdentifierLocation : boolean + entries: CompletionEntry[]; >entries : CompletionEntry[] >CompletionEntry : CompletionEntry diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index 89e9aed992c..8f0dde9a9fa 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -1723,6 +1723,7 @@ declare module "typescript" { } interface CompletionInfo { isMemberCompletion: boolean; + isNewIdentifierLocation: boolean; entries: CompletionEntry[]; } interface CompletionEntry { diff --git a/tests/baselines/reference/APISample_linter.types b/tests/baselines/reference/APISample_linter.types index 846781e64ad..a0c2bc590ed 100644 --- a/tests/baselines/reference/APISample_linter.types +++ b/tests/baselines/reference/APISample_linter.types @@ -5566,6 +5566,9 @@ declare module "typescript" { isMemberCompletion: boolean; >isMemberCompletion : boolean + isNewIdentifierLocation: boolean; +>isNewIdentifierLocation : boolean + entries: CompletionEntry[]; >entries : CompletionEntry[] >CompletionEntry : CompletionEntry diff --git a/tests/baselines/reference/APISample_transform.js b/tests/baselines/reference/APISample_transform.js index a4b102d8efb..542c79cb011 100644 --- a/tests/baselines/reference/APISample_transform.js +++ b/tests/baselines/reference/APISample_transform.js @@ -1724,6 +1724,7 @@ declare module "typescript" { } interface CompletionInfo { isMemberCompletion: boolean; + isNewIdentifierLocation: boolean; entries: CompletionEntry[]; } interface CompletionEntry { diff --git a/tests/baselines/reference/APISample_transform.types b/tests/baselines/reference/APISample_transform.types index 5f1859b13e7..85fdfbe9c9d 100644 --- a/tests/baselines/reference/APISample_transform.types +++ b/tests/baselines/reference/APISample_transform.types @@ -5518,6 +5518,9 @@ declare module "typescript" { isMemberCompletion: boolean; >isMemberCompletion : boolean + isNewIdentifierLocation: boolean; +>isNewIdentifierLocation : boolean + entries: CompletionEntry[]; >entries : CompletionEntry[] >CompletionEntry : CompletionEntry diff --git a/tests/baselines/reference/APISample_watcher.js b/tests/baselines/reference/APISample_watcher.js index 4f3fb5cdc47..e932573e415 100644 --- a/tests/baselines/reference/APISample_watcher.js +++ b/tests/baselines/reference/APISample_watcher.js @@ -1761,6 +1761,7 @@ declare module "typescript" { } interface CompletionInfo { isMemberCompletion: boolean; + isNewIdentifierLocation: boolean; entries: CompletionEntry[]; } interface CompletionEntry { diff --git a/tests/baselines/reference/APISample_watcher.types b/tests/baselines/reference/APISample_watcher.types index e990ec362ea..12776adac5f 100644 --- a/tests/baselines/reference/APISample_watcher.types +++ b/tests/baselines/reference/APISample_watcher.types @@ -5691,6 +5691,9 @@ declare module "typescript" { isMemberCompletion: boolean; >isMemberCompletion : boolean + isNewIdentifierLocation: boolean; +>isNewIdentifierLocation : boolean + entries: CompletionEntry[]; >entries : CompletionEntry[] >CompletionEntry : CompletionEntry diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts new file mode 100644 index 00000000000..0e92a3ae995 --- /dev/null +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_Generics.ts @@ -0,0 +1,18 @@ +/// + +////interface A { + goTo.position(m.position, m.fileName); + verify.completionListIsEmpty(); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts new file mode 100644 index 00000000000..143c884e177 --- /dev/null +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts @@ -0,0 +1,22 @@ +/// + +//// var [x/*variable1*/ + +//// var [x, y/*variable2*/ + +//// var [./*variable3*/ + +//// var [x, ...z/*variable4*/ + +//// var {x/*variable5*/ + +//// var {x, y/*variable6*/ + +//// function func1({ a/*parameter1*/ + +//// function func2({ a, b/*parameter2*/ + +test.markers().forEach((m) => { + goTo.position(m.position, m.fileName); + verify.completionListIsEmpty(); +}); diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts index 0fd66e9d091..10293c41a64 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_parameters.ts @@ -10,23 +10,17 @@ ////function testFunction(a, b/*parameterName4*/ -////class bar1{ constructor(/*constructorParamter1*/ +////class bar5{ constructor(public /*constructorParamter1*/ -////class bar2{ constructor(a/*constructorParamter2*/ +////class bar6{ constructor(public a/*constructorParamter2*/ -////class bar3{ constructor(a, /*constructorParamter3*/ +////class bar7{ constructor(protected a/*constructorParamter3*/ -////class bar4{ constructor(a, b/*constructorParamter4*/ +////class bar8{ constructor(private a/*constructorParamter4*/ -////class bar5{ constructor(public /*constructorParamter5*/ +////class bar9{ constructor(.../*constructorParamter5*/ -////class bar6{ constructor(public a/*constructorParamter6*/ - -////class bar7{ constructor(private a/*constructorParamter7*/ - -////class bar8{ constructor(.../*constructorParamter8*/ - -////class bar9{ constructor(...a/*constructorParamter9*/ +////class bar10{ constructor(...a/*constructorParamter6*/ test.markers().forEach((m) => { diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts new file mode 100644 index 00000000000..58fdc1d2342 --- /dev/null +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_properties.ts @@ -0,0 +1,37 @@ +/// + +////var aa = 1; + +////class A1 { +//// /*property1*/ +////} + +////class A2 { +//// p/*property2*/ +////} + +////class A3 { +//// public s/*property3*/ +////} + +////class A4 { +//// a/*property4*/ +////} + +////class A5 { +//// public a/*property5*/ +////} + +////class A6 { +//// protected a/*property6*/ +////} + +////class A7 { +//// private a/*property7*/ +////} + +test.markers().forEach((m) => { + goTo.position(m.position, m.fileName); + verify.not.completionListIsEmpty(); + verify.completionListAllowsNewIdentifier(); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts index 346a102faa8..2e85364ce3c 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_varDeclarations.ts @@ -11,7 +11,6 @@ ////var a2, a/*varName4*/ -debugger; test.markers().forEach((m) => { goTo.position(m.position, m.fileName); verify.completionListIsEmpty(); diff --git a/tests/cases/fourslash/completionListBuilderLocations_Modules.ts b/tests/cases/fourslash/completionListBuilderLocations_Modules.ts new file mode 100644 index 00000000000..eac7085ab66 --- /dev/null +++ b/tests/cases/fourslash/completionListBuilderLocations_Modules.ts @@ -0,0 +1,13 @@ +/// + +////module A/*moduleName1*/ + + +////module A./*moduleName2*/ + + +test.markers().forEach((m) => { + goTo.position(m.position, m.fileName); + verify.not.completionListIsEmpty(); + verify.completionListAllowsNewIdentifier(); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts b/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts new file mode 100644 index 00000000000..45f16090fd8 --- /dev/null +++ b/tests/cases/fourslash/completionListBuilderLocations_VariableDeclarations.ts @@ -0,0 +1,34 @@ +/// + +////var x = a/*var1*/ + +////var x = (b/*var2*/ + +////var x = (c, d/*var3*/ + +//// var y : any = "", x = a/*var4*/ + +//// var y : any = "", x = (a/*var5*/ + +////class C{} +////var y = new C( + +//// class C{} +//// var y = new C(0, /*var7*/ + +////var y = [/*var8*/ + +////var y = [0, /*var9*/ + +////var y = `${/*var10*/ + +////var y = `${10} dd ${ /*var11*/ + +////var y = 10; y=/*var12*/ + +test.markers().forEach((m) => { + goTo.position(m.position, m.fileName); + verify.completionListAllowsNewIdentifier(); +}); + + diff --git a/tests/cases/fourslash/completionListBuilderLocations_parameters.ts b/tests/cases/fourslash/completionListBuilderLocations_parameters.ts new file mode 100644 index 00000000000..12dba953d3d --- /dev/null +++ b/tests/cases/fourslash/completionListBuilderLocations_parameters.ts @@ -0,0 +1,22 @@ +/// + +////var aa = 1; + +////class bar1{ constructor(/*constructorParamter1*/ + +////class bar2{ constructor(a/*constructorParamter2*/ + +////class bar3{ constructor(a, /*constructorParamter3*/ + +////class bar4{ constructor(a, b/*constructorParamter4*/ + +////class bar6{ constructor(public a, /*constructorParamter5*/ + +////class bar7{ constructor(private a, /*constructorParamter6*/ + + +test.markers().forEach((m) => { + goTo.position(m.position, m.fileName); + verify.not.completionListIsEmpty(); + verify.completionListAllowsNewIdentifier(); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_modules.ts b/tests/cases/fourslash/completionListBuilderLocations_properties.ts similarity index 55% rename from tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_modules.ts rename to tests/cases/fourslash/completionListBuilderLocations_properties.ts index 4ebdf029a89..287ffd6746b 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_modules.ts +++ b/tests/cases/fourslash/completionListBuilderLocations_properties.ts @@ -2,12 +2,15 @@ ////var aa = 1; -////module /*moduleName1*/ - -////module a/*moduleName2*/ +////class A1 { +//// public static /*property1*/ +////} +////class A2 { +//// public static a/*property2*/ +////} test.markers().forEach((m) => { goTo.position(m.position, m.fileName); verify.completionListIsEmpty(); -}); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 5b88b15f9fa..267f2c14341 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -172,6 +172,10 @@ module FourSlashInterface { FourSlash.currentTestState.verifyCompletionListIsEmpty(this.negative); } + public completionListAllowsNewIdentifier() { + FourSlash.currentTestState.verifyCompletionListAllowsNewIdentifier(this.negative); + } + public memberListIsEmpty() { FourSlash.currentTestState.verifyMemberListIsEmpty(this.negative); }