mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-13 06:20:23 -06:00
Merge pull request #11328 from Microsoft/FixTripleSlashCompletions
Fix triple slash completions
This commit is contained in:
commit
94d895587a
@ -1097,7 +1097,9 @@ namespace ts {
|
||||
return path.replace(/\\/g, "/");
|
||||
}
|
||||
|
||||
// Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
|
||||
/**
|
||||
* Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
|
||||
*/
|
||||
export function getRootLength(path: string): number {
|
||||
if (path.charCodeAt(0) === CharacterCodes.slash) {
|
||||
if (path.charCodeAt(1) !== CharacterCodes.slash) return 1;
|
||||
@ -1126,9 +1128,14 @@ namespace ts {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internally, we represent paths as strings with '/' as the directory separator.
|
||||
* When we make system calls (eg: LanguageServiceHost.getDirectory()),
|
||||
* we expect the host to correctly handle paths in our specified format.
|
||||
*/
|
||||
export const directorySeparator = "/";
|
||||
const directorySeparatorCharCode = CharacterCodes.slash;
|
||||
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number) {
|
||||
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number): string[] {
|
||||
const parts = normalizedSlashedPath.substr(rootLength).split(directorySeparator);
|
||||
const normalized: string[] = [];
|
||||
for (const part of parts) {
|
||||
@ -1168,6 +1175,11 @@ namespace ts {
|
||||
return path.charCodeAt(path.length - 1) === directorySeparatorCharCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path except for its basename. Eg:
|
||||
*
|
||||
* /path/to/file.ext -> /path/to
|
||||
*/
|
||||
export function getDirectoryPath(path: Path): Path;
|
||||
export function getDirectoryPath(path: string): string;
|
||||
export function getDirectoryPath(path: string): any {
|
||||
|
||||
@ -171,12 +171,16 @@ namespace ts.server {
|
||||
return this.host.fileExists(path);
|
||||
}
|
||||
|
||||
readFile(fileName: string): string {
|
||||
return this.host.readFile(fileName);
|
||||
}
|
||||
|
||||
directoryExists(path: string): boolean {
|
||||
return this.host.directoryExists(path);
|
||||
}
|
||||
|
||||
readFile(fileName: string): string {
|
||||
return this.host.readFile(fileName);
|
||||
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
|
||||
return this.host.readDirectory(path, extensions, exclude, include);
|
||||
}
|
||||
|
||||
getDirectories(path: string): string[] {
|
||||
|
||||
@ -325,15 +325,28 @@ namespace ts.Completions {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename.
|
||||
*/
|
||||
function getCompletionEntriesForDirectoryFragment(fragment: string, scriptPath: string, extensions: string[], includeExtensions: boolean, span: TextSpan, exclude?: string, result: CompletionEntry[] = []): CompletionEntry[] {
|
||||
if (fragment === undefined) {
|
||||
fragment = "";
|
||||
}
|
||||
|
||||
fragment = normalizeSlashes(fragment);
|
||||
|
||||
/**
|
||||
* Remove the basename from the path. Note that we don't use the basename to filter completions;
|
||||
* the client is responsible for refining completions.
|
||||
*/
|
||||
fragment = getDirectoryPath(fragment);
|
||||
if (!fragment) {
|
||||
fragment = "./";
|
||||
}
|
||||
else {
|
||||
fragment = ensureTrailingDirectorySeparator(fragment);
|
||||
|
||||
if (fragment === "") {
|
||||
fragment = "." + directorySeparator;
|
||||
}
|
||||
|
||||
fragment = ensureTrailingDirectorySeparator(fragment);
|
||||
|
||||
const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment));
|
||||
const baseDirectory = getDirectoryPath(absolutePath);
|
||||
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
||||
@ -343,6 +356,12 @@ namespace ts.Completions {
|
||||
const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]);
|
||||
|
||||
if (files) {
|
||||
/**
|
||||
* Multiple file entries might map to the same truncated name once we remove extensions
|
||||
* (happens iff includeExtensions === false)so we use a set-like data structure. Eg:
|
||||
*
|
||||
* both foo.ts and foo.tsx become foo
|
||||
*/
|
||||
const foundFiles = createMap<boolean>();
|
||||
for (let filePath of files) {
|
||||
filePath = normalizePath(filePath);
|
||||
@ -539,36 +558,44 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const completionInfo: CompletionInfo = {
|
||||
/**
|
||||
* We don't want the editor to offer any other completions, such as snippets, inside a comment.
|
||||
*/
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
/**
|
||||
* The user may type in a path that doesn't yet exist, creating a "new identifier"
|
||||
* with respect to the collection of identifiers the server is aware of.
|
||||
*/
|
||||
isNewIdentifierLocation: true,
|
||||
|
||||
entries: []
|
||||
};
|
||||
|
||||
const text = sourceFile.text.substr(range.pos, position - range.pos);
|
||||
|
||||
const match = tripleSlashDirectiveFragmentRegex.exec(text);
|
||||
|
||||
if (match) {
|
||||
const prefix = match[1];
|
||||
const kind = match[2];
|
||||
const toComplete = match[3];
|
||||
|
||||
const scriptPath = getDirectoryPath(sourceFile.path);
|
||||
let entries: CompletionEntry[];
|
||||
if (kind === "path") {
|
||||
// Give completions for a relative path
|
||||
const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
|
||||
entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, sourceFile.path);
|
||||
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, sourceFile.path);
|
||||
}
|
||||
else {
|
||||
// Give completions based on the typings available
|
||||
const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length };
|
||||
entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
|
||||
completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
|
||||
}
|
||||
|
||||
return {
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
isNewIdentifierLocation: true,
|
||||
entries
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return completionInfo;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] {
|
||||
@ -1674,9 +1701,15 @@ namespace ts.Completions {
|
||||
* Matches a triple slash reference directive with an incomplete string literal for its path. Used
|
||||
* to determine if the caret is currently within the string literal and capture the literal fragment
|
||||
* for completions.
|
||||
* For example, this matches /// <reference path="fragment
|
||||
* For example, this matches
|
||||
*
|
||||
* /// <reference path="fragment
|
||||
*
|
||||
* but not
|
||||
*
|
||||
* /// <reference path="fragment"
|
||||
*/
|
||||
const tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3]*)$/;
|
||||
const tripleSlashDirectiveFragmentRegex = /^(\/\/\/\s*<reference\s+(path|types)\s*=\s*(?:'|"))([^\3"]*)$/;
|
||||
|
||||
interface VisibleModuleInfo {
|
||||
moduleName: string;
|
||||
|
||||
@ -505,7 +505,11 @@ namespace ts {
|
||||
export interface CompletionInfo {
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
isNewIdentifierLocation: boolean; // true when the current location also allows for a new identifier
|
||||
|
||||
/**
|
||||
* true when the current location also allows for a new identifier
|
||||
*/
|
||||
isNewIdentifierLocation: boolean;
|
||||
entries: CompletionEntry[];
|
||||
}
|
||||
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Should give completions for ts files when allowJs is false
|
||||
|
||||
// @Filename: test0.ts
|
||||
//// import * as foo1 from "./*import_as0*/
|
||||
//// import * as foo2 from ".//*import_as1*/
|
||||
//// import * as foo4 from "./folder//*import_as2*/
|
||||
|
||||
//// import foo6 = require("./*import_equals0*/
|
||||
//// import foo7 = require(".//*import_equals1*/
|
||||
//// import foo9 = require("./folder//*import_equals2*/
|
||||
|
||||
//// var foo11 = require("./*require0*/
|
||||
//// var foo12 = require(".//*require1*/
|
||||
//// var foo14 = require("./folder//*require2*/
|
||||
|
||||
// @Filename: parentTest/sub/test5.ts
|
||||
//// import * as foo16 from "../g/*import_as3*/
|
||||
//// import foo17 = require("../g/*import_equals3*/
|
||||
//// var foo18 = require("../g/*require3*/
|
||||
|
||||
|
||||
// @Filename: f1.ts
|
||||
//// /*f1*/
|
||||
// @Filename: f1.js
|
||||
//// /*f1j*/
|
||||
// @Filename: f1.d.ts
|
||||
//// /*f1d*/
|
||||
// @Filename: f2.tsx
|
||||
//// /f2*/
|
||||
// @Filename: f3.js
|
||||
//// /*f3*/
|
||||
// @Filename: f4.jsx
|
||||
//// /*f4*/
|
||||
// @Filename: e1.ts
|
||||
//// /*e1*/
|
||||
// @Filename: folder/f3.ts
|
||||
//// /*subf1*/
|
||||
// @Filename: folder/h1.ts
|
||||
//// /*subh1*/
|
||||
// @Filename: parentTest/f4.ts
|
||||
//// /*parentf1*/
|
||||
// @Filename: parentTest/g1.ts
|
||||
//// /*parentg1*/
|
||||
const kinds = ["import_as", "import_equals", "require"];
|
||||
|
||||
for (const kind of kinds) {
|
||||
goTo.marker(kind + "0");
|
||||
verify.completionListIsEmpty();
|
||||
|
||||
goTo.marker(kind + "1");
|
||||
verify.completionListContains("f1");
|
||||
verify.completionListContains("f2");
|
||||
verify.completionListContains("e1");
|
||||
verify.completionListContains("folder");
|
||||
verify.completionListContains("parentTest");
|
||||
verify.not.completionListItemsCountIsGreaterThan(5);
|
||||
|
||||
goTo.marker(kind + "2");
|
||||
verify.completionListContains("f3");
|
||||
verify.completionListContains("h1");
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
|
||||
goTo.marker(kind + "3");
|
||||
verify.completionListContains("f4");
|
||||
verify.completionListContains("g1");
|
||||
verify.completionListContains("sub");
|
||||
verify.not.completionListItemsCountIsGreaterThan(3);
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Should give completions for ts files only when allowJs is false.
|
||||
|
||||
// @Filename: test0.ts
|
||||
//// import * as foo1 from "./*import_as0*/
|
||||
//// import * as foo2 from ".//*import_as1*/
|
||||
//// import * as foo4 from "./d1//*import_as2*/
|
||||
|
||||
//// import foo6 = require("./*import_equals0*/
|
||||
//// import foo7 = require(".//*import_equals1*/
|
||||
//// import foo9 = require("./d1//*import_equals2*/
|
||||
|
||||
//// var foo11 = require("./*require0*/
|
||||
//// var foo12 = require(".//*require1*/
|
||||
//// var foo14 = require("./d1//*require2*/
|
||||
|
||||
// @Filename: d2/d3/test1.ts
|
||||
//// import * as foo16 from "..//*import_as3*/
|
||||
//// import foo17 = require("..//*import_equals3*/
|
||||
//// var foo18 = require("..//*require3*/
|
||||
|
||||
|
||||
// @Filename: f1.ts
|
||||
//// /*f1*/
|
||||
// @Filename: f2.js
|
||||
//// /*f2*/
|
||||
// @Filename: f3.d.ts
|
||||
//// /*f3*/
|
||||
// @Filename: f4.tsx
|
||||
//// /f4*/
|
||||
// @Filename: f5.js
|
||||
//// /*f5*/
|
||||
// @Filename: f6.jsx
|
||||
//// /*f6*/
|
||||
// @Filename: f7.ts
|
||||
//// /*f7*/
|
||||
// @Filename: d1/f8.ts
|
||||
//// /*d1f1*/
|
||||
// @Filename: d1/f9.ts
|
||||
//// /*d1f9*/
|
||||
// @Filename: d2/f10.ts
|
||||
//// /*d2f1*/
|
||||
// @Filename: d2/f11.ts
|
||||
//// /*d2f11*/
|
||||
|
||||
const kinds = ["import_as", "import_equals", "require"];
|
||||
|
||||
for (const kind of kinds) {
|
||||
goTo.marker(kind + "0");
|
||||
verify.completionListIsEmpty();
|
||||
|
||||
goTo.marker(kind + "1");
|
||||
verify.completionListContains("f1");
|
||||
verify.completionListContains("f3");
|
||||
verify.completionListContains("f4");
|
||||
verify.completionListContains("f7");
|
||||
verify.completionListContains("d1");
|
||||
verify.completionListContains("d2");
|
||||
verify.not.completionListItemsCountIsGreaterThan(6);
|
||||
|
||||
goTo.marker(kind + "2");
|
||||
verify.completionListContains("f8");
|
||||
verify.completionListContains("f9");
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
|
||||
goTo.marker(kind + "3");
|
||||
verify.completionListContains("f10");
|
||||
verify.completionListContains("f11");
|
||||
verify.completionListContains("d3");
|
||||
verify.not.completionListItemsCountIsGreaterThan(3);
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Should give completions for ts and js files when allowJs is true
|
||||
// Should give completions for ts and js files when allowJs is true.
|
||||
|
||||
// @allowJs: true
|
||||
|
||||
@ -16,38 +16,33 @@
|
||||
|
||||
// @Filename: f1.ts
|
||||
//// /f1*/
|
||||
// @Filename: f1.js
|
||||
//// /*f1j*/
|
||||
// @Filename: f1.d.ts
|
||||
//// /*f1d*/
|
||||
// @Filename: f2.tsx
|
||||
// @Filename: f2.js
|
||||
//// /*f2*/
|
||||
// @Filename: f3.js
|
||||
// @Filename: f3.d.ts
|
||||
//// /*f3*/
|
||||
// @Filename: f4.jsx
|
||||
// @Filename: f4.tsx
|
||||
//// /*f4*/
|
||||
// @Filename: e1.ts
|
||||
//// /*e1*/
|
||||
// @Filename: e2.js
|
||||
//// /*e2*/
|
||||
// @Filename: f5.js
|
||||
//// /*f5*/
|
||||
// @Filename: f6.jsx
|
||||
//// /*f6*/
|
||||
// @Filename: g1.ts
|
||||
//// /*g1*/
|
||||
// @Filename: g2.js
|
||||
//// /*g2*/
|
||||
const kinds = ["import_as", "import_equals", "require"];
|
||||
|
||||
for (const kind of kinds) {
|
||||
goTo.marker(kind + "0");
|
||||
for(let i = 0; i < 2; ++i) {
|
||||
goTo.marker(kind + i);
|
||||
verify.completionListContains("f1");
|
||||
verify.completionListContains("f2");
|
||||
verify.completionListContains("f3");
|
||||
verify.completionListContains("f4");
|
||||
verify.completionListContains("e1");
|
||||
verify.completionListContains("e2");
|
||||
verify.not.completionListItemsCountIsGreaterThan(6);
|
||||
|
||||
goTo.marker(kind + "1");
|
||||
verify.completionListContains("f1");
|
||||
verify.completionListContains("f2");
|
||||
verify.completionListContains("f3");
|
||||
verify.completionListContains("f4");
|
||||
verify.completionListContains("e1");
|
||||
verify.completionListContains("e2");
|
||||
verify.not.completionListItemsCountIsGreaterThan(6);
|
||||
verify.completionListContains("f5");
|
||||
verify.completionListContains("f6");
|
||||
verify.completionListContains("g1");
|
||||
verify.completionListContains("g2");
|
||||
verify.not.completionListItemsCountIsGreaterThan(8);
|
||||
}
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Should give completions for relative references to ts files when allowJs is false
|
||||
|
||||
// @Filename: test0.ts
|
||||
//// /// <reference path="/*0*/
|
||||
//// /// <reference path="./*1*/
|
||||
//// /// <reference path="../*2*/
|
||||
//// /// <reference path=".//*3*/
|
||||
//// /// <reference path="./f/*4*/" />
|
||||
//// /// <reference path="./parentTest//*5*/
|
||||
|
||||
// @Filename: parentTest/sub/test1.ts
|
||||
//// /// <reference path="../g/*6*/
|
||||
|
||||
// @Filename: f1.ts
|
||||
//// /*f1*/
|
||||
// @Filename: f1.js
|
||||
//// /*f1j*/
|
||||
// @Filename: f1.d.ts
|
||||
//// /*f1d*/
|
||||
// @Filename: f2.tsx
|
||||
//// /f2*/
|
||||
// @Filename: f3.js
|
||||
//// /*f3*/
|
||||
// @Filename: f4.jsx
|
||||
//// /*f4*/
|
||||
// @Filename: e1.ts
|
||||
//// /*e1*/
|
||||
// @Filename: parentTest/g1.ts
|
||||
//// /*parentg1*/
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
goTo.marker("" + i);
|
||||
verify.completionListContains("f1.ts");
|
||||
verify.completionListContains("f1.d.ts");
|
||||
verify.completionListContains("f2.tsx");
|
||||
verify.completionListContains("e1.ts");
|
||||
verify.completionListContains("parentTest");
|
||||
verify.not.completionListItemsCountIsGreaterThan(5);
|
||||
}
|
||||
|
||||
goTo.marker("5");
|
||||
verify.completionListContains("g1.ts");
|
||||
verify.completionListContains("sub");
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
|
||||
goTo.marker("6");
|
||||
verify.completionListContains("g1.ts");
|
||||
verify.completionListContains("sub");
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
@ -1,6 +1,6 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Should give completions for absolute paths
|
||||
// Exercises completions for absolute paths.
|
||||
|
||||
// @Filename: tests/test0.ts
|
||||
//// /// <reference path="/tests/cases/f/*0*/
|
||||
@ -0,0 +1,70 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Exercises completions for hidden files (ie: those beginning with '.')
|
||||
|
||||
// @Filename: f.ts
|
||||
//// /*f1*/
|
||||
// @Filename: d1/g.ts
|
||||
//// /*g1*/
|
||||
// @Filename: d1/d2/h.ts
|
||||
//// /*h1*/
|
||||
// @Filename: d1/d2/d3/i.ts
|
||||
//// /// <reference path=".\..\..\/*28*/
|
||||
|
||||
// @Filename: test.ts
|
||||
//// /// <reference path="/*0*/
|
||||
//// /// <reference path=".//*1*/
|
||||
//// /// <reference path=".\/*2*/
|
||||
//// /// <reference path="./*3*/
|
||||
|
||||
//// /// <reference path="d1//*4*/
|
||||
//// /// <reference path="d1/.//*5*/
|
||||
//// /// <reference path="d1/.\/*6*/
|
||||
//// /// <reference path="d1/./*7*/
|
||||
|
||||
//// /// <reference path="d1\/*8*/
|
||||
//// /// <reference path="d1\.//*9*/
|
||||
//// /// <reference path="d1\.\/*10*/
|
||||
//// /// <reference path="d1\./*11*/
|
||||
|
||||
//// /// <reference path="d1/d2//*12*/
|
||||
//// /// <reference path="d1/d2/.//*13*/
|
||||
//// /// <reference path="d1/d2/.\/*14*/
|
||||
//// /// <reference path="d1/d2/./*15*/
|
||||
|
||||
//// /// <reference path="d1/d2\/*16*/
|
||||
//// /// <reference path="d1/d2\.//*17*/
|
||||
//// /// <reference path="d1/d2\.\/*18*/
|
||||
//// /// <reference path="d1/d2\./*19*/
|
||||
|
||||
//// /// <reference path="d1\d2//*20*/
|
||||
//// /// <reference path="d1\d2/.//*21*/
|
||||
//// /// <reference path="d1\d2/.\/*22*/
|
||||
//// /// <reference path="d1\d2/./*23*/
|
||||
|
||||
//// /// <reference path="d1\d2\/*24*/
|
||||
//// /// <reference path="d1\d2\.//*25*/
|
||||
//// /// <reference path="d1\d2\.\/*26*/
|
||||
//// /// <reference path="d1\d2\./*27*/
|
||||
|
||||
testBlock(0, 'f.ts', "d1");
|
||||
testBlock(4, 'g.ts', "d2");
|
||||
testBlock(8, 'g.ts', "d2");
|
||||
testBlock(12, 'h.ts', "d3");
|
||||
testBlock(16, 'h.ts', "d3");
|
||||
testBlock(20, 'h.ts', "d3");
|
||||
testBlock(24, 'h.ts', "d3");
|
||||
|
||||
goTo.marker("28");
|
||||
verify.completionListContains("g.ts");
|
||||
verify.completionListContains("d2");
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
|
||||
function testBlock(offset: number, fileName: string, dir: string) {
|
||||
for (let m = offset; m < offset + 4; ++m) {
|
||||
goTo.marker("" + m);
|
||||
verify.completionListContains(fileName);
|
||||
verify.completionListContains(dir);
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
}
|
||||
}
|
||||
21
tests/cases/fourslash/tripleSlashRefPathCompletionContext.ts
Normal file
21
tests/cases/fourslash/tripleSlashRefPathCompletionContext.ts
Normal file
@ -0,0 +1,21 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Exercises whether completions are supplied, conditional on the caret position in the ref comment.
|
||||
|
||||
// @Filename: f.ts
|
||||
//// /*f*/
|
||||
|
||||
// @Filename: test.ts
|
||||
//// /// <reference path/*0*/=/*1*/"/*8*/
|
||||
//// /// <reference path/*2*/=/*3*/"/*9*/"/*4*/ /*5*///*6*/>/*7*/
|
||||
|
||||
for(let m = 0; m < 8; ++m) {
|
||||
goTo.marker("" + m);
|
||||
verify.not.completionListItemsCountIsGreaterThan(0);
|
||||
}
|
||||
|
||||
for(let m of ["8", "9"]) {
|
||||
goTo.marker(m);
|
||||
verify.completionListContains("f.ts");
|
||||
verify.not.completionListItemsCountIsGreaterThan(1);
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Should give completions for relative references to ts files only when allowJs is false.
|
||||
|
||||
// @Filename: test0.ts
|
||||
//// /// <reference path="/*0*/
|
||||
//// /// <reference path=".//*1*/
|
||||
//// /// <reference path="./f/*2*/
|
||||
|
||||
// @Filename: f1.ts
|
||||
//// /*f1*/
|
||||
// @Filename: f1.js
|
||||
//// /*f1j*/
|
||||
// @Filename: f1.d.ts
|
||||
//// /*f1d*/
|
||||
// @Filename: f1.tsx
|
||||
//// /f2*/
|
||||
// @Filename: f1.js
|
||||
//// /*f3*/
|
||||
// @Filename: f1.jsx
|
||||
//// /*f4*/
|
||||
// @Filename: f1.cs
|
||||
//// /*f5*/
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
goTo.marker("" + i);
|
||||
verify.completionListContains("f1.ts");
|
||||
verify.completionListContains("f1.d.ts");
|
||||
verify.completionListContains("f1.tsx");
|
||||
verify.not.completionListItemsCountIsGreaterThan(3);
|
||||
}
|
||||
@ -1,15 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Should give completions for relative references to js and ts files when allowJs is true
|
||||
// Should give completions for relative references to ts and js files when allowJs is true.
|
||||
|
||||
// @allowJs: true
|
||||
|
||||
// @Filename: test0.ts
|
||||
//// /// <reference path="/*0*/
|
||||
//// /// <reference path="./*1*/
|
||||
//// /// <reference path="../*2*/
|
||||
//// /// <reference path=".//*3*/
|
||||
//// /// <reference path="./f/*4*/" />
|
||||
//// /// <reference path=".//*1*/
|
||||
//// /// <reference path="./f/*2*/
|
||||
|
||||
// @Filename: f1.ts
|
||||
//// /*f1*/
|
||||
@ -17,17 +15,21 @@
|
||||
//// /*f1j*/
|
||||
// @Filename: f1.d.ts
|
||||
//// /*f1d*/
|
||||
// @Filename: f2.tsx
|
||||
// @Filename: f1.tsx
|
||||
//// /f2*/
|
||||
// @Filename: f4.jsx
|
||||
// @Filename: f1.js
|
||||
//// /*f3*/
|
||||
// @Filename: f1.jsx
|
||||
//// /*f4*/
|
||||
// @Filename: f1.cs
|
||||
//// /*f5*/
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
goTo.marker("" + i);
|
||||
verify.completionListContains("f1.ts");
|
||||
verify.completionListContains("f1.js");
|
||||
verify.completionListContains("f1.d.ts");
|
||||
verify.completionListContains("f2.tsx");
|
||||
verify.completionListContains("f4.jsx");
|
||||
verify.completionListContains("f1.tsx");
|
||||
verify.completionListContains("f1.js");
|
||||
verify.completionListContains("f1.jsx");
|
||||
verify.not.completionListItemsCountIsGreaterThan(5);
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Exercises completions for hidden files (ie: those beginning with '.')
|
||||
|
||||
// @Filename: f.ts
|
||||
//// /*f*/
|
||||
// @Filename: .hidden.ts
|
||||
//// /*hidden*/
|
||||
|
||||
// @Filename: test.ts
|
||||
//// /// <reference path="/*0*/
|
||||
//// /// <reference path="./*1*/
|
||||
//// /// <reference path=".//*2*/
|
||||
//// /// <reference path=".\/*3*/
|
||||
|
||||
for(let m of ["0", "1", "2", "3"]) {
|
||||
goTo.marker(m);
|
||||
verify.completionListContains("f.ts");
|
||||
verify.not.completionListItemsCountIsGreaterThan(1);
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Exercises how changes in the basename change the completions offered.
|
||||
// They should have no effect, as filtering completions is the responsibility of the editor.
|
||||
|
||||
// @Filename: f1.ts
|
||||
//// /*f1*/
|
||||
// @Filename: f2.ts
|
||||
//// /*f2*/
|
||||
// @Filename: d/g.ts
|
||||
//// /*g*/
|
||||
|
||||
// @Filename: test.ts
|
||||
//// /// <reference path="f/*0*/
|
||||
//// /// <reference path="./f/*1*/
|
||||
|
||||
//// /// <reference path="./d/*2*/
|
||||
|
||||
//// /// <reference path="f1/*3*/
|
||||
//// /// <reference path="f1./*4*/
|
||||
//// /// <reference path="f1.t/*5*/
|
||||
//// /// <reference path="f1.ts/*6*/
|
||||
//// /// <reference path="./f1/*7*/
|
||||
//// /// <reference path="./f1./*8*/
|
||||
//// /// <reference path="./f1.t/*9*/
|
||||
//// /// <reference path="./f1.ts/*10*/
|
||||
|
||||
for (let m = 0; m < 11; ++m) {
|
||||
goTo.marker("" + m);
|
||||
verify.completionListContains("f1.ts");
|
||||
verify.completionListContains("f2.ts");
|
||||
verify.completionListContains("d");
|
||||
verify.not.completionListItemsCountIsGreaterThan(3);
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// Exercises relative path completions going up and down 2 directories
|
||||
// and the use of forward- and back-slashes and combinations thereof.
|
||||
|
||||
// @Filename: f.ts
|
||||
//// /*f1*/
|
||||
// @Filename: d1/g.ts
|
||||
//// /*g1*/
|
||||
// @Filename: d1/d2/h.ts
|
||||
//// /*h1*/
|
||||
// @Filename: d1/d2/d3/i.ts
|
||||
//// /*i1*/
|
||||
// @Filename: d1/d2/d3/d4/j.ts
|
||||
//// /*j1*/
|
||||
|
||||
// @Filename: d1/d2/test.ts
|
||||
//// /// <reference path="/*0*/
|
||||
//// /// <reference path=".//*1*/
|
||||
//// /// <reference path="./*2*/
|
||||
//// /// <reference path="../*3*/
|
||||
//// /// <reference path="d3/*4*/
|
||||
|
||||
//// /// <reference path="..//*5*/
|
||||
//// /// <reference path="..\/*6*/
|
||||
|
||||
//// /// <reference path="../..//*7*/
|
||||
|
||||
//// /// <reference path="d3//*8*/
|
||||
//// /// <reference path="./d3//*9*/
|
||||
|
||||
//// /// <reference path="d3/d4//*10*/
|
||||
//// /// <reference path="./d3/d4//*11*/
|
||||
|
||||
workingDirCompletions();
|
||||
parentDirCompletions();
|
||||
childDirCompletions();
|
||||
|
||||
function workingDirCompletions() {
|
||||
for (let m = 0; m < 5; ++m) {
|
||||
goTo.marker("" + m);
|
||||
verify.completionListContains("h.ts");
|
||||
verify.completionListContains("d3");
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
}
|
||||
}
|
||||
|
||||
function parentDirCompletions() {
|
||||
|
||||
for (let m of ["5", "6"]) {
|
||||
goTo.marker(m);
|
||||
verify.completionListContains("g.ts");
|
||||
verify.completionListContains("d2");
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
}
|
||||
|
||||
goTo.marker("7");
|
||||
verify.completionListContains("f.ts");
|
||||
verify.completionListContains("d1");
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
}
|
||||
|
||||
function childDirCompletions() {
|
||||
|
||||
for (let m of ["8", "9"]) {
|
||||
goTo.marker(m);
|
||||
verify.completionListContains("i.ts");
|
||||
verify.completionListContains("d4");
|
||||
verify.not.completionListItemsCountIsGreaterThan(2);
|
||||
}
|
||||
|
||||
for (let m of ["10", "11"]) {
|
||||
goTo.marker(m);
|
||||
verify.completionListContains("j.ts");
|
||||
verify.not.completionListItemsCountIsGreaterThan(1);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user