diff --git a/Jakefile.js b/Jakefile.js
index 64a8553ef39..b548a0d3dd8 100644
--- a/Jakefile.js
+++ b/Jakefile.js
@@ -174,7 +174,7 @@ var serverCoreSources = [
"lsHost.ts",
"project.ts",
"editorServices.ts",
- "protocol.d.ts",
+ "protocol.ts",
"session.ts",
"server.ts"
].map(function (f) {
@@ -198,14 +198,13 @@ var typingsInstallerSources = [
var serverSources = serverCoreSources.concat(servicesSources);
var languageServiceLibrarySources = [
- "protocol.d.ts",
+ "protocol.ts",
"utilities.ts",
"scriptVersionCache.ts",
"scriptInfo.ts",
"lsHost.ts",
"project.ts",
"editorServices.ts",
- "protocol.d.ts",
"session.ts",
].map(function (f) {
@@ -259,7 +258,7 @@ var harnessSources = harnessCoreSources.concat([
].map(function (f) {
return path.join(unittestsDirectory, f);
})).concat([
- "protocol.d.ts",
+ "protocol.ts",
"utilities.ts",
"scriptVersionCache.ts",
"scriptInfo.ts",
@@ -267,7 +266,6 @@ var harnessSources = harnessCoreSources.concat([
"project.ts",
"typingsCache.ts",
"editorServices.ts",
- "protocol.d.ts",
"session.ts",
].map(function (f) {
return path.join(serverDirectory, f);
@@ -518,6 +516,40 @@ compileFile(processDiagnosticMessagesJs,
[],
/*useBuiltCompiler*/ false);
+var buildProtocolTs = path.join(scriptsDirectory, "buildProtocol.ts");
+var buildProtocolJs = path.join(scriptsDirectory, "buildProtocol.js");
+var buildProtocolDts = path.join(builtLocalDirectory, "protocol.d.ts");
+var typescriptServicesDts = path.join(builtLocalDirectory, "typescriptServices.d.ts");
+
+file(buildProtocolTs);
+
+compileFile(buildProtocolJs,
+ [buildProtocolTs],
+ [buildProtocolTs],
+ [],
+ /*useBuiltCompiler*/ false,
+ {noOutFile: true});
+
+file(buildProtocolDts, [buildProtocolTs, buildProtocolJs, typescriptServicesDts], function() {
+
+ var protocolTs = path.join(serverDirectory, "protocol.ts");
+
+ var cmd = host + " " + buildProtocolJs + " "+ protocolTs + " " + typescriptServicesDts + " " + buildProtocolDts;
+ console.log(cmd);
+ var ex = jake.createExec([cmd]);
+ // Add listeners for output and error
+ ex.addListener("stdout", function (output) {
+ process.stdout.write(output);
+ });
+ ex.addListener("stderr", function (error) {
+ process.stderr.write(error);
+ });
+ ex.addListener("cmdEnd", function () {
+ complete();
+ });
+ ex.run();
+}, { async: true })
+
// The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task
file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () {
var cmd = host + " " + processDiagnosticMessagesJs + " " + diagnosticMessagesJson;
@@ -655,6 +687,8 @@ compileFile(
inlineSourceMap: true
});
+file(typescriptServicesDts, [servicesFile]);
+
var cancellationTokenFile = path.join(builtLocalDirectory, "cancellationToken.js");
compileFile(cancellationTokenFile, cancellationTokenSources, [builtLocalDirectory].concat(cancellationTokenSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: true });
@@ -689,7 +723,7 @@ task("build-fold-end", [], function () {
// Local target to build the compiler and services
desc("Builds the full compiler and services");
-task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
+task("local", ["build-fold-start", "generate-diagnostics", "lib", tscFile, servicesFile, nodeDefinitionsFile, serverFile, buildProtocolDts, builtGeneratedDiagnosticMessagesJSON, "lssl", "build-fold-end"]);
// Local target to build only tsc.js
desc("Builds only the compiler");
@@ -745,7 +779,7 @@ task("generate-spec", [specMd]);
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
desc("Makes a new LKG out of the built js files");
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
- var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile].concat(libraryTargets);
+ var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts].concat(libraryTargets);
var missingFiles = expectedFiles.filter(function (f) {
return !fs.existsSync(f);
});
diff --git a/lib/lib.d.ts b/lib/lib.d.ts
index 586b3675305..d8be920dc0a 100644
--- a/lib/lib.d.ts
+++ b/lib/lib.d.ts
@@ -260,6 +260,9 @@ interface Function {
*/
bind(this: Function, thisArg: any, ...argArray: any[]): any;
+ /** Returns a string representation of an object. */
+ toString(): string;
+
prototype: any;
readonly length: number;
diff --git a/scripts/buildProtocol.ts b/scripts/buildProtocol.ts
new file mode 100644
index 00000000000..8d49262a470
--- /dev/null
+++ b/scripts/buildProtocol.ts
@@ -0,0 +1,143 @@
+///
+
+import * as ts from "../lib/typescript";
+import * as path from "path";
+
+function endsWith(s: string, suffix: string) {
+ return s.lastIndexOf(suffix, s.length - suffix.length) !== -1;
+}
+
+class DeclarationsWalker {
+ private visitedTypes: ts.Type[] = [];
+ private text = "";
+ private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
+ }
+
+ static getExtraDeclarations(typeChecker: ts.TypeChecker, protocolFile: ts.SourceFile): string {
+ let text = "declare namespace ts.server.protocol {\n";
+ var walker = new DeclarationsWalker(typeChecker, protocolFile);
+ walker.visitTypeNodes(protocolFile);
+ return walker.text
+ ? `declare namespace ts.server.protocol {\n${walker.text}}`
+ : "";
+ }
+
+ private processType(type: ts.Type): void {
+ if (this.visitedTypes.indexOf(type) >= 0) {
+ return;
+ }
+ this.visitedTypes.push(type);
+ let s = type.aliasSymbol || type.getSymbol();
+ if (!s) {
+ return;
+ }
+ if (s.name === "Array") {
+ // we should process type argument instead
+ return this.processType((type).typeArguments[0]);
+ }
+ else {
+ for (const decl of s.getDeclarations()) {
+ const sourceFile = decl.getSourceFile();
+ if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
+ return;
+ }
+ // splice declaration in final d.ts file
+ const text = decl.getFullText();
+ this.text += `${text}\n`;
+
+ // recursively pull all dependencies into result dts file
+ this.visitTypeNodes(decl);
+ }
+ }
+ }
+
+ private visitTypeNodes(node: ts.Node) {
+ if (node.parent) {
+ switch (node.parent.kind) {
+ case ts.SyntaxKind.VariableDeclaration:
+ case ts.SyntaxKind.MethodDeclaration:
+ case ts.SyntaxKind.MethodSignature:
+ case ts.SyntaxKind.PropertyDeclaration:
+ case ts.SyntaxKind.PropertySignature:
+ case ts.SyntaxKind.Parameter:
+ case ts.SyntaxKind.IndexSignature:
+ if (((node.parent).type) === node) {
+ const type = this.typeChecker.getTypeAtLocation(node);
+ if (type && !(type.flags & ts.TypeFlags.TypeParameter)) {
+ this.processType(type);
+ }
+ }
+ break;
+ }
+ }
+ ts.forEachChild(node, n => this.visitTypeNodes(n));
+ }
+}
+
+function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string): string {
+ const options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: true, types: [], stripInternal: true };
+
+ /**
+ * 1st pass - generate a program from protocol.ts and typescriptservices.d.ts and emit core version of protocol.d.ts with all internal members stripped
+ * @return text of protocol.d.t.s
+ */
+ function getInitialDtsFileForProtocol() {
+ const program = ts.createProgram([protocolTs, typeScriptServicesDts], options);
+
+ let protocolDts: string;
+ program.emit(program.getSourceFile(protocolTs), (file, content) => {
+ if (endsWith(file, ".d.ts")) {
+ protocolDts = content;
+ }
+ });
+ if (protocolDts === undefined) {
+ throw new Error(`Declaration file for protocol.ts is not generated`)
+ }
+ return protocolDts;
+ }
+
+ const protocolFileName = "protocol.d.ts";
+ /**
+ * Second pass - generate a program from protocol.d.ts and typescriptservices.d.ts, then augment core protocol.d.ts with extra types from typescriptservices.d.ts
+ */
+ function getProgramWithProtocolText(protocolDts: string, includeTypeScriptServices: boolean) {
+ const host = ts.createCompilerHost(options);
+ const originalGetSourceFile = host.getSourceFile;
+ host.getSourceFile = (fileName) => {
+ if (fileName === protocolFileName) {
+ return ts.createSourceFile(fileName, protocolDts, options.target);
+ }
+ return originalGetSourceFile.apply(host, [fileName]);
+ }
+ const rootFiles = includeTypeScriptServices ? [protocolFileName, typeScriptServicesDts] : [protocolFileName];
+ return ts.createProgram(rootFiles, options, host);
+ }
+
+ let protocolDts = getInitialDtsFileForProtocol();
+ const program = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ true);
+
+ const protocolFile = program.getSourceFile("protocol.d.ts");
+ const extraDeclarations = DeclarationsWalker.getExtraDeclarations(program.getTypeChecker(), protocolFile);
+ if (extraDeclarations) {
+ protocolDts += extraDeclarations;
+ }
+ // do sanity check and try to compile generated text as standalone program
+ const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
+ const diagnostics = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics(), ...program.getGlobalDiagnostics()];
+ if (diagnostics.length) {
+ const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
+ throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
+ }
+ return protocolDts;
+}
+
+if (process.argv.length < 5) {
+ console.log(`Expected 3 arguments: path to 'protocol.ts', path to 'typescriptservices.d.ts' and path to output file`);
+ process.exit(1);
+}
+
+const protocolTs = process.argv[2];
+const typeScriptServicesDts = process.argv[3];
+const outputFile = process.argv[4];
+const generatedProtocolDts = generateProtocolFile(protocolTs, typeScriptServicesDts);
+ts.sys.writeFile(outputFile, generatedProtocolDts);
diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index b17fe546f58..b2225e9333c 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -84,6 +84,7 @@ namespace ts {
IsFunctionExpression = 1 << 4,
HasLocals = 1 << 5,
IsInterface = 1 << 6,
+ IsObjectLiteralOrClassExpressionMethod = 1 << 7,
}
const binder = createBinder();
@@ -486,8 +487,8 @@ namespace ts {
}
else {
currentFlow = { flags: FlowFlags.Start };
- if (containerFlags & ContainerFlags.IsFunctionExpression) {
- (currentFlow).container = node;
+ if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) {
+ (currentFlow).container = node;
}
currentReturnTarget = undefined;
}
@@ -1237,9 +1238,12 @@ namespace ts {
case SyntaxKind.SourceFile:
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals;
+ case SyntaxKind.MethodDeclaration:
+ if (isObjectLiteralOrClassExpressionMethod(node)) {
+ return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsObjectLiteralOrClassExpressionMethod;
+ }
case SyntaxKind.Constructor:
case SyntaxKind.FunctionDeclaration:
- case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
@@ -2238,6 +2242,10 @@ namespace ts {
}
}
+ if (currentFlow && isObjectLiteralOrClassExpressionMethod(node)) {
+ node.flowNode = currentFlow;
+ }
+
return hasDynamicName(node)
? bindAnonymousDeclaration(node, symbolFlags, "__computed")
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index dfe6317e250..40332674567 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -922,7 +922,7 @@ namespace ts {
if (result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value) {
const decls = result.declarations;
if (decls && decls.length === 1 && decls[0].kind === SyntaxKind.NamespaceExportDeclaration) {
- error(errorLocation, Diagnostics.Identifier_0_must_be_imported_from_a_module, name);
+ error(errorLocation, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, name);
}
}
}
@@ -1465,6 +1465,10 @@ namespace ts {
function getExportsForModule(moduleSymbol: Symbol): SymbolTable {
const visitedSymbols: Symbol[] = [];
+
+ // A module defined by an 'export=' consists on one export that needs to be resolved
+ moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
+
return visit(moduleSymbol) || moduleSymbol.exports;
// The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
@@ -8457,6 +8461,28 @@ namespace ts {
return f(type) ? type : neverType;
}
+ function mapType(type: Type, f: (t: Type) => Type): Type {
+ return type.flags & TypeFlags.Union ? getUnionType(map((type).types, f)) : f(type);
+ }
+
+ function extractTypesOfKind(type: Type, kind: TypeFlags) {
+ return filterType(type, t => (t.flags & kind) !== 0);
+ }
+
+ // Return a new type in which occurrences of the string and number primitive types in
+ // typeWithPrimitives have been replaced with occurrences of string literals and numeric
+ // literals in typeWithLiterals, respectively.
+ function replacePrimitivesWithLiterals(typeWithPrimitives: Type, typeWithLiterals: Type) {
+ if (isTypeSubsetOf(stringType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.StringLiteral) ||
+ isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.NumberLiteral)) {
+ return mapType(typeWithPrimitives, t =>
+ t.flags & TypeFlags.String ? extractTypesOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.StringLiteral) :
+ t.flags & TypeFlags.Number ? extractTypesOfKind(typeWithLiterals, TypeFlags.Number | TypeFlags.NumberLiteral) :
+ t);
+ }
+ return typeWithPrimitives;
+ }
+
function isIncomplete(flowType: FlowType) {
return flowType.flags === 0;
}
@@ -8792,7 +8818,7 @@ namespace ts {
}
if (assumeTrue) {
const narrowedType = filterType(type, t => areTypesComparable(t, valueType));
- return narrowedType.flags & TypeFlags.Never ? type : narrowedType;
+ return narrowedType.flags & TypeFlags.Never ? type : replacePrimitivesWithLiterals(narrowedType, valueType);
}
if (isUnitType(valueType)) {
const regularType = getRegularTypeOfLiteralType(valueType);
@@ -8839,7 +8865,9 @@ namespace ts {
const clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
const hasDefaultClause = clauseStart === clauseEnd || contains(clauseTypes, neverType);
const discriminantType = getUnionType(clauseTypes);
- const caseType = discriminantType.flags & TypeFlags.Never ? neverType : filterType(type, t => isTypeComparableTo(discriminantType, t));
+ const caseType =
+ discriminantType.flags & TypeFlags.Never ? neverType :
+ replacePrimitivesWithLiterals(filterType(type, t => isTypeComparableTo(discriminantType, t)), discriminantType);
if (!hasDefaultClause) {
return caseType;
}
@@ -9163,7 +9191,9 @@ namespace ts {
// a const variable or parameter from an outer function, we extend the origin of the control flow
// analysis to include the immediately enclosing function.
while (flowContainer !== declarationContainer &&
- (flowContainer.kind === SyntaxKind.FunctionExpression || flowContainer.kind === SyntaxKind.ArrowFunction) &&
+ (flowContainer.kind === SyntaxKind.FunctionExpression ||
+ flowContainer.kind === SyntaxKind.ArrowFunction ||
+ isObjectLiteralOrClassExpressionMethod(flowContainer)) &&
(isReadonlySymbol(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
flowContainer = getControlFlowContainer(flowContainer);
}
@@ -17889,7 +17919,8 @@ namespace ts {
}
function isNotOverload(declaration: Declaration): boolean {
- return declaration.kind !== SyntaxKind.FunctionDeclaration || !!(declaration as FunctionDeclaration).body;
+ return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) ||
+ !!(declaration as FunctionDeclaration).body;
}
}
diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts
index 648447ac26a..72dd42b3997 100644
--- a/src/compiler/commandLineParser.ts
+++ b/src/compiler/commandLineParser.ts
@@ -975,7 +975,7 @@ namespace ts {
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {
const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json"
- ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true }
+ ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true }
: {};
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
return options;
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 1b8c995ea05..554bcc50865 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -1923,7 +1923,7 @@
"category": "Error",
"code": 2685
},
- "Identifier '{0}' must be imported from a module": {
+ "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead.": {
"category": "Error",
"code": 2686
},
diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts
index e7b3872f2e3..b79106766da 100644
--- a/src/compiler/scanner.ts
+++ b/src/compiler/scanner.ts
@@ -1190,7 +1190,7 @@ namespace ts {
}
function scanBinaryOrOctalDigits(base: number): number {
- Debug.assert(base !== 2 || base !== 8, "Expected either base 2 or base 8");
+ Debug.assert(base === 2 || base === 8, "Expected either base 2 or base 8");
let value = 0;
// For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts
index 7cf7d75bc02..1efa1e2b010 100644
--- a/src/compiler/sys.ts
+++ b/src/compiler/sys.ts
@@ -476,6 +476,10 @@ namespace ts {
// Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
// (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
let options: any;
+ if (!directoryExists(directoryName)) {
+ return;
+ }
+
if (isNode4OrLater() && (process.platform === "win32" || process.platform === "darwin")) {
options = { persistent: true, recursive: !!recursive };
}
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 638504e613f..34f4b0000f8 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -1922,7 +1922,7 @@ namespace ts {
// function, the container property references the function (which in turn has a flowNode
// property for the containing control flow).
export interface FlowStart extends FlowNode {
- container?: FunctionExpression | ArrowFunction;
+ container?: FunctionExpression | ArrowFunction | MethodDeclaration;
}
// FlowLabel represents a junction with multiple possible preceding control flows.
@@ -2644,7 +2644,7 @@ namespace ts {
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | StructuredType | TypeParameter | StringLike | NumberLike | BooleanLike | ESSymbol,
- NotUnionOrUnit = Any | String | Number | ESSymbol | ObjectType,
+ NotUnionOrUnit = Any | ESSymbol | ObjectType,
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
/* @internal */
@@ -2917,11 +2917,7 @@ namespace ts {
NodeJs = 2
}
- export type RootPaths = string[];
- export type PathSubstitutions = MapLike;
- export type TsConfigOnlyOptions = RootPaths | PathSubstitutions;
-
- export type CompilerOptionsValue = string | number | boolean | (string | number)[] | TsConfigOnlyOptions;
+ export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike;
export interface CompilerOptions {
allowJs?: boolean;
@@ -2973,14 +2969,14 @@ namespace ts {
out?: string;
outDir?: string;
outFile?: string;
- paths?: PathSubstitutions;
+ paths?: MapLike;
preserveConstEnums?: boolean;
project?: string;
/* @internal */ pretty?: DiagnosticStyle;
reactNamespace?: string;
removeComments?: boolean;
rootDir?: string;
- rootDirs?: RootPaths;
+ rootDirs?: string[];
skipLibCheck?: boolean;
skipDefaultLibCheck?: boolean;
sourceMap?: boolean;
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 558015bb0e3..498c195ea3a 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -895,6 +895,12 @@ namespace ts {
return node && node.kind === SyntaxKind.MethodDeclaration && node.parent.kind === SyntaxKind.ObjectLiteralExpression;
}
+ export function isObjectLiteralOrClassExpressionMethod(node: Node): node is MethodDeclaration {
+ return node.kind === SyntaxKind.MethodDeclaration &&
+ (node.parent.kind === SyntaxKind.ObjectLiteralExpression ||
+ node.parent.kind === SyntaxKind.ClassExpression);
+ }
+
export function isIdentifierTypePredicate(predicate: TypePredicate): predicate is IdentifierTypePredicate {
return predicate && predicate.kind === TypePredicateKind.Identifier;
}
diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts
index f54804c0eb5..af10f355e1f 100644
--- a/src/harness/fourslash.ts
+++ b/src/harness/fourslash.ts
@@ -2255,6 +2255,18 @@ namespace FourSlash {
}
}
+ public verifyNavigationTree(json: any) {
+ const tree = this.languageService.getNavigationTree(this.activeFile.fileName);
+ if (JSON.stringify(tree, replacer) !== JSON.stringify(json)) {
+ this.raiseError(`verifyNavigationTree failed - expected: ${stringify(json)}, got: ${stringify(tree, replacer)}`);
+ }
+
+ function replacer(key: string, value: any) {
+ // Don't check "spans", and omit falsy values.
+ return key === "spans" ? undefined : (value || undefined);
+ }
+ }
+
public printNavigationItems(searchValue: string) {
const items = this.languageService.getNavigateToItems(searchValue);
const length = items && items.length;
@@ -3343,6 +3355,10 @@ namespace FourSlashInterface {
this.state.verifyNavigationBar(json);
}
+ public navigationTree(json: any) {
+ this.state.verifyNavigationTree(json);
+ }
+
public navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string) {
this.state.verifyNavigationItemsCount(count, searchValue, matchKind, fileName);
}
diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts
index 99cee7dbd41..7cc4c2044ef 100644
--- a/src/harness/harnessLanguageService.ts
+++ b/src/harness/harnessLanguageService.ts
@@ -459,6 +459,10 @@ namespace Harness.LanguageService {
getNavigationBarItems(fileName: string): ts.NavigationBarItem[] {
return unwrapJSONCallResult(this.shim.getNavigationBarItems(fileName));
}
+ getNavigationTree(fileName: string): ts.NavigationTree {
+ return unwrapJSONCallResult(this.shim.getNavigationTree(fileName));
+ }
+
getOutliningSpans(fileName: string): ts.OutliningSpan[] {
return unwrapJSONCallResult(this.shim.getOutliningSpans(fileName));
}
diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts
index 24fd47ee0cb..797268000eb 100644
--- a/src/harness/unittests/compileOnSave.ts
+++ b/src/harness/unittests/compileOnSave.ts
@@ -3,6 +3,8 @@
///
namespace ts.projectSystem {
+ import CommandNames = server.CommandNames;
+
function createTestTypingsInstaller(host: server.ServerHost) {
return new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
}
@@ -75,7 +77,7 @@ namespace ts.projectSystem {
};
// Change the content of file1 to `export var T: number;export function Foo() { };`
- changeModuleFile1ShapeRequest1 = makeSessionRequest(server.CommandNames.Change, {
+ changeModuleFile1ShapeRequest1 = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -85,7 +87,7 @@ namespace ts.projectSystem {
});
// Change the content of file1 to `export var T: number;export function Foo() { };`
- changeModuleFile1InternalRequest1 = makeSessionRequest(server.CommandNames.Change, {
+ changeModuleFile1InternalRequest1 = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -95,7 +97,7 @@ namespace ts.projectSystem {
});
// Change the content of file1 to `export var T: number;export function Foo() { };`
- changeModuleFile1ShapeRequest2 = makeSessionRequest(server.CommandNames.Change, {
+ changeModuleFile1ShapeRequest2 = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -104,7 +106,7 @@ namespace ts.projectSystem {
insertString: `export var T2: number;`
});
- moduleFile1FileListRequest = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
+ moduleFile1FileListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
});
it("should contains only itself if a module file's shape didn't change, and all files referencing it if its shape changed", () => {
@@ -120,7 +122,7 @@ namespace ts.projectSystem {
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
// Change the content of file1 to `export var T: number;export function Foo() { console.log('hi'); };`
- const changeFile1InternalRequest = makeSessionRequest(server.CommandNames.Change, {
+ const changeFile1InternalRequest = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 46,
@@ -143,7 +145,7 @@ namespace ts.projectSystem {
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
// Change file2 content to `let y = Foo();`
- const removeFile1Consumer1ImportRequest = makeSessionRequest(server.CommandNames.Change, {
+ const removeFile1Consumer1ImportRequest = makeSessionRequest(CommandNames.Change, {
file: file1Consumer1.path,
line: 1,
offset: 1,
@@ -156,7 +158,7 @@ namespace ts.projectSystem {
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer2] }]);
// Add the import statements back to file2
- const addFile2ImportRequest = makeSessionRequest(server.CommandNames.Change, {
+ const addFile2ImportRequest = makeSessionRequest(CommandNames.Change, {
file: file1Consumer1.path,
line: 1,
offset: 1,
@@ -167,7 +169,7 @@ namespace ts.projectSystem {
session.executeCommand(addFile2ImportRequest);
// Change the content of file1 to `export var T2: string;export var T: number;export function Foo() { };`
- const changeModuleFile1ShapeRequest2 = makeSessionRequest(server.CommandNames.Change, {
+ const changeModuleFile1ShapeRequest2 = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 1,
@@ -272,7 +274,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([globalFile3], session);
- const changeGlobalFile3ShapeRequest = makeSessionRequest(server.CommandNames.Change, {
+ const changeGlobalFile3ShapeRequest = makeSessionRequest(CommandNames.Change, {
file: globalFile3.path,
line: 1,
offset: 1,
@@ -283,7 +285,7 @@ namespace ts.projectSystem {
// check after file1 shape changes
session.executeCommand(changeGlobalFile3ShapeRequest);
- const globalFile3FileListRequest = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path });
+ const globalFile3FileListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: globalFile3.path });
sendAffectedFileRequestAndCheckResult(session, globalFile3FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2, globalFile3, moduleFile2] }]);
});
@@ -316,7 +318,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([moduleFile1], session);
- const file1ChangeShapeRequest = makeSessionRequest(server.CommandNames.Change, {
+ const file1ChangeShapeRequest = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 27,
@@ -345,7 +347,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([moduleFile1], session);
- const file1ChangeShapeRequest = makeSessionRequest(server.CommandNames.Change, {
+ const file1ChangeShapeRequest = makeSessionRequest(CommandNames.Change, {
file: moduleFile1.path,
line: 1,
offset: 27,
@@ -369,7 +371,7 @@ namespace ts.projectSystem {
openFilesForSession([moduleFile1, file1Consumer1], session);
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer1Consumer1] }]);
- const changeFile1Consumer1ShapeRequest = makeSessionRequest(server.CommandNames.Change, {
+ const changeFile1Consumer1ShapeRequest = makeSessionRequest(CommandNames.Change, {
file: file1Consumer1.path,
line: 2,
offset: 1,
@@ -400,7 +402,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([file1, file2], session);
- const file1AffectedListRequest = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
+ const file1AffectedListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [{ projectFileName: configFile.path, files: [file1, file2] }]);
});
@@ -415,7 +417,7 @@ namespace ts.projectSystem {
const session = createSession(host);
openFilesForSession([file1, file2, file3], session);
- const file1AffectedListRequest = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
+ const file1AffectedListRequest = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: file1.path });
sendAffectedFileRequestAndCheckResult(session, file1AffectedListRequest, [
{ projectFileName: configFile1.path, files: [file1, file2] },
@@ -437,11 +439,11 @@ namespace ts.projectSystem {
host.reloadFS([referenceFile1, configFile]);
host.triggerFileWatcherCallback(moduleFile1.path, /*removed*/ true);
- const request = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
+ const request = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
sendAffectedFileRequestAndCheckResult(session, request, [
{ projectFileName: configFile.path, files: [referenceFile1] }
]);
- const requestForMissingFile = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path });
+ const requestForMissingFile = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path });
sendAffectedFileRequestAndCheckResult(session, requestForMissingFile, []);
});
@@ -456,7 +458,7 @@ namespace ts.projectSystem {
const session = createSession(host);
openFilesForSession([referenceFile1], session);
- const request = makeSessionRequest(server.CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
+ const request = makeSessionRequest(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
sendAffectedFileRequestAndCheckResult(session, request, [
{ projectFileName: configFile.path, files: [referenceFile1] }
]);
@@ -483,7 +485,7 @@ namespace ts.projectSystem {
const session = new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ false);
openFilesForSession([file1, file2], session);
- const compileFileRequest = makeSessionRequest(server.CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path });
+ const compileFileRequest = makeSessionRequest(CommandNames.CompileOnSaveEmitFile, { file: file1.path, projectFileName: configFile.path });
session.executeCommand(compileFileRequest);
const expectedEmittedFileName = "/a/b/f1.js";
diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts
index ba25409a9b4..33cad7130c7 100644
--- a/src/harness/unittests/convertCompilerOptionsFromJson.ts
+++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts
@@ -405,6 +405,7 @@ namespace ts {
allowJs: true,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true,
+ skipLibCheck: true,
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
@@ -433,6 +434,7 @@ namespace ts {
allowJs: false,
maxNodeModuleJsDepth: 2,
allowSyntheticDefaultImports: true,
+ skipLibCheck: true,
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
noImplicitAny: false,
@@ -456,7 +458,8 @@ namespace ts {
{
allowJs: true,
maxNodeModuleJsDepth: 2,
- allowSyntheticDefaultImports: true
+ allowSyntheticDefaultImports: true,
+ skipLibCheck: true
},
errors: [{
file: undefined,
@@ -477,7 +480,8 @@ namespace ts {
{
allowJs: true,
maxNodeModuleJsDepth: 2,
- allowSyntheticDefaultImports: true
+ allowSyntheticDefaultImports: true,
+ skipLibCheck: true
},
errors: []
}
diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts
index b758761ee76..dc4cdd08520 100644
--- a/src/harness/unittests/tsserverProjectSystem.ts
+++ b/src/harness/unittests/tsserverProjectSystem.ts
@@ -3,6 +3,8 @@
namespace ts.projectSystem {
import TI = server.typingsInstaller;
+ import protocol = server.protocol;
+ import CommandNames = server.CommandNames;
const safeList = {
path: "/safeList.json",
@@ -128,7 +130,7 @@ namespace ts.projectSystem {
return combinePaths(getDirectoryPath(libFile.path), "tsc.js");
}
- export function toExternalFile(fileName: string): server.protocol.ExternalFile {
+ export function toExternalFile(fileName: string): protocol.ExternalFile {
return { fileName };
}
@@ -527,7 +529,7 @@ namespace ts.projectSystem {
}
export function makeSessionRequest(command: string, args: T) {
- const newRequest: server.protocol.Request = {
+ const newRequest: protocol.Request = {
seq: 0,
type: "request",
command,
@@ -538,7 +540,7 @@ namespace ts.projectSystem {
export function openFilesForSession(files: FileOrFolder[], session: server.Session) {
for (const file of files) {
- const request = makeSessionRequest(server.CommandNames.Open, { file: file.path });
+ const request = makeSessionRequest(CommandNames.Open, { file: file.path });
session.executeCommand(request);
}
}
@@ -1751,7 +1753,7 @@ namespace ts.projectSystem {
});
describe("navigate-to for javascript project", () => {
- function containsNavToItem(items: server.protocol.NavtoItem[], itemName: string, itemKind: string) {
+ function containsNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) {
return find(items, item => item.name === itemName && item.kind === itemKind) !== undefined;
}
@@ -1769,12 +1771,12 @@ namespace ts.projectSystem {
openFilesForSession([file1], session);
// Try to find some interface type defined in lib.d.ts
- const libTypeNavToRequest = makeSessionRequest(server.CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path });
- const items: server.protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response;
+ const libTypeNavToRequest = makeSessionRequest(CommandNames.Navto, { searchValue: "Document", file: file1.path, projectFileName: configFile.path });
+ const items: protocol.NavtoItem[] = session.executeCommand(libTypeNavToRequest).response;
assert.isFalse(containsNavToItem(items, "Document", "interface"), `Found lib.d.ts symbol in JavaScript project nav to request result.`);
- const localFunctionNavToRequst = makeSessionRequest(server.CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
- const items2: server.protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response;
+ const localFunctionNavToRequst = makeSessionRequest(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
+ const items2: protocol.NavtoItem[] = session.executeCommand(localFunctionNavToRequst).response;
assert.isTrue(containsNavToItem(items2, "foo", "function"), `Cannot find function symbol "foo".`);
});
});
@@ -2309,4 +2311,109 @@ namespace ts.projectSystem {
serverEventManager.checkEventCountOfType("configFileDiag", 1);
});
});
+
+ describe("skipLibCheck", () => {
+ it("should be turned on for js-only inferred projects", () => {
+ const file1 = {
+ path: "/a/b/file1.js",
+ content: `
+ ///
+ var x = 1;`
+ };
+ const file2 = {
+ path: "/a/b/file2.d.ts",
+ content: `
+ interface T {
+ name: string;
+ };
+ interface T {
+ name: number;
+ };`
+ };
+ const host = createServerHost([file1, file2]);
+ const session = createSession(host);
+ openFilesForSession([file1, file2], session);
+
+ const file2GetErrRequest = makeSessionRequest(
+ CommandNames.SemanticDiagnosticsSync,
+ { file: file2.path }
+ );
+ let errorResult = session.executeCommand(file2GetErrRequest).response;
+ assert.isTrue(errorResult.length === 0);
+
+ const closeFileRequest = makeSessionRequest(CommandNames.Close, { file: file1.path });
+ session.executeCommand(closeFileRequest);
+ errorResult = session.executeCommand(file2GetErrRequest).response;
+ assert.isTrue(errorResult.length !== 0);
+
+ openFilesForSession([file1], session);
+ errorResult = session.executeCommand(file2GetErrRequest).response;
+ assert.isTrue(errorResult.length === 0);
+ });
+
+ it("should be turned on for js-only external projects", () => {
+ const jsFile = {
+ path: "/a/b/file1.js",
+ content: "let x =1;"
+ };
+ const dTsFile = {
+ path: "/a/b/file2.d.ts",
+ content: `
+ interface T {
+ name: string;
+ };
+ interface T {
+ name: number;
+ };`
+ };
+ const host = createServerHost([jsFile, dTsFile]);
+ const session = createSession(host);
+
+ const openExternalProjectRequest = makeSessionRequest(
+ CommandNames.OpenExternalProject,
+ {
+ projectFileName: "project1",
+ rootFiles: toExternalFiles([jsFile.path, dTsFile.path]),
+ options: {}
+ }
+ );
+ session.executeCommand(openExternalProjectRequest);
+
+ const dTsFileGetErrRequest = makeSessionRequest(
+ CommandNames.SemanticDiagnosticsSync,
+ { file: dTsFile.path }
+ );
+ const errorResult = session.executeCommand(dTsFileGetErrRequest).response;
+ assert.isTrue(errorResult.length === 0);
+ });
+ });
+
+ describe("non-existing directories listed in config file input array", () => {
+ it("should be tolerated without crashing the server", () => {
+ const configFile = {
+ path: "/a/b/tsconfig.json",
+ content: `{
+ "compilerOptions": {},
+ "include": ["app/*", "test/**/*", "something"]
+ }`
+ };
+ const file1 = {
+ path: "/a/b/file1.ts",
+ content: "let t = 10;"
+ };
+
+ const host = createServerHost([file1, configFile]);
+ const projectService = createProjectService(host);
+ projectService.openClientFile(file1.path);
+ host.runQueuedTimeoutCallbacks();
+ checkNumberOfConfiguredProjects(projectService, 1);
+ checkNumberOfInferredProjects(projectService, 1);
+
+ const configuredProject = projectService.configuredProjects[0];
+ assert.isTrue(configuredProject.getFileNames().length == 0);
+
+ const inferredProject = projectService.inferredProjects[0];
+ assert.isTrue(inferredProject.containsFile(file1.path));
+ });
+ });
}
\ No newline at end of file
diff --git a/src/lib/es2015.core.d.ts b/src/lib/es2015.core.d.ts
index 5d570bb0866..356512ecf58 100644
--- a/src/lib/es2015.core.d.ts
+++ b/src/lib/es2015.core.d.ts
@@ -201,7 +201,7 @@ interface NumberConstructor {
/**
* Returns true if passed value is finite.
- * Unlike the global isFininte, Number.isFinite doesn't forcibly convert the parameter to a
+ * Unlike the global isFinite, Number.isFinite doesn't forcibly convert the parameter to a
* number. Only finite values of the type number, result in true.
* @param number A numeric value.
*/
diff --git a/src/server/builder.ts b/src/server/builder.ts
index 639c41d2b63..475202a0aab 100644
--- a/src/server/builder.ts
+++ b/src/server/builder.ts
@@ -1,6 +1,5 @@
///
///
-///
///
///
diff --git a/src/server/client.ts b/src/server/client.ts
index 2acc0a58cad..b0bc2c5dac0 100644
--- a/src/server/client.ts
+++ b/src/server/client.ts
@@ -1,7 +1,6 @@
///
namespace ts.server {
-
export interface SessionClientHost extends LanguageServiceHost {
writeMessage(message: string): void;
}
@@ -512,7 +511,7 @@ namespace ts.server {
return this.lastRenameEntry.locations;
}
- decodeNavigationBarItems(items: protocol.NavigationBarItem[], fileName: string, lineMap: number[]): NavigationBarItem[] {
+ private decodeNavigationBarItems(items: protocol.NavigationBarItem[], fileName: string, lineMap: number[]): NavigationBarItem[] {
if (!items) {
return [];
}
@@ -521,10 +520,7 @@ namespace ts.server {
text: item.text,
kind: item.kind,
kindModifiers: item.kindModifiers || "",
- spans: item.spans.map(span =>
- createTextSpanFromBounds(
- this.lineOffsetToPosition(fileName, span.start, lineMap),
- this.lineOffsetToPosition(fileName, span.end, lineMap))),
+ spans: item.spans.map(span => this.decodeSpan(span, fileName, lineMap)),
childItems: this.decodeNavigationBarItems(item.childItems, fileName, lineMap),
indent: item.indent,
bolded: false,
@@ -533,17 +529,37 @@ namespace ts.server {
}
getNavigationBarItems(fileName: string): NavigationBarItem[] {
- const args: protocol.FileRequestArgs = {
- file: fileName
- };
-
- const request = this.processRequest(CommandNames.NavBar, args);
+ const request = this.processRequest(CommandNames.NavBar, { file: fileName });
const response = this.processResponse(request);
const lineMap = this.getLineMap(fileName);
return this.decodeNavigationBarItems(response.body, fileName, lineMap);
}
+ private decodeNavigationTree(tree: protocol.NavigationTree, fileName: string, lineMap: number[]): NavigationTree {
+ return {
+ text: tree.text,
+ kind: tree.kind,
+ kindModifiers: tree.kindModifiers,
+ spans: tree.spans.map(span => this.decodeSpan(span, fileName, lineMap)),
+ childItems: map(tree.childItems, item => this.decodeNavigationTree(item, fileName, lineMap))
+ };
+ }
+
+ getNavigationTree(fileName: string): NavigationTree {
+ const request = this.processRequest(CommandNames.NavTree, { file: fileName });
+ const response = this.processResponse(request);
+
+ const lineMap = this.getLineMap(fileName);
+ return this.decodeNavigationTree(response.body, fileName, lineMap);
+ }
+
+ private decodeSpan(span: protocol.TextSpan, fileName: string, lineMap: number[]) {
+ return createTextSpanFromBounds(
+ this.lineOffsetToPosition(fileName, span.start, lineMap),
+ this.lineOffsetToPosition(fileName, span.end, lineMap));
+ }
+
getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan {
throw new Error("Not Implemented Yet.");
}
diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts
index dc2c45156cd..91b9f90c88b 100644
--- a/src/server/editorServices.ts
+++ b/src/server/editorServices.ts
@@ -1,6 +1,5 @@
///
///
-///
///
///
///
@@ -711,7 +710,7 @@ namespace ts.server {
Debug.assert(!!parsedCommandLine.fileNames);
if (parsedCommandLine.fileNames.length === 0) {
- errors.push(createCompilerDiagnostic(Diagnostics.The_config_file_0_found_doesn_t_contain_any_source_files, configFilename));
+ (errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.The_config_file_0_found_doesn_t_contain_any_source_files, configFilename));
return { success: false, configFileErrors: errors };
}
diff --git a/src/server/project.ts b/src/server/project.ts
index b59efb03cfd..a355d75f942 100644
--- a/src/server/project.ts
+++ b/src/server/project.ts
@@ -20,16 +20,42 @@ namespace ts.server {
}
}
- function isJsOrDtsFile(info: ScriptInfo) {
- return info.scriptKind === ScriptKind.JS || info.scriptKind == ScriptKind.JSX || fileExtensionIs(info.fileName, ".d.ts");
+ function countEachFileTypes(infos: ScriptInfo[]): { js: number, jsx: number, ts: number, tsx: number, dts: number } {
+ const result = { js: 0, jsx: 0, ts: 0, tsx: 0, dts: 0 };
+ for (const info of infos) {
+ switch (info.scriptKind) {
+ case ScriptKind.JS:
+ result.js += 1;
+ break;
+ case ScriptKind.JSX:
+ result.jsx += 1;
+ break;
+ case ScriptKind.TS:
+ fileExtensionIs(info.fileName, ".d.ts")
+ ? result.dts += 1
+ : result.ts += 1;
+ break;
+ case ScriptKind.TSX:
+ result.tsx += 1;
+ break;
+ }
+ }
+ return result;
+ }
+
+ function hasOneOrMoreJsAndNoTsFiles(project: Project) {
+ const counts = countEachFileTypes(project.getScriptInfos());
+ return counts.js > 0 && counts.ts === 0 && counts.tsx === 0;
}
export function allRootFilesAreJsOrDts(project: Project): boolean {
- return project.getRootScriptInfos().every(isJsOrDtsFile);
+ const counts = countEachFileTypes(project.getRootScriptInfos());
+ return counts.ts === 0 && counts.tsx === 0;
}
export function allFilesAreJsOrDts(project: Project): boolean {
- return project.getScriptInfos().every(isJsOrDtsFile);
+ const counts = countEachFileTypes(project.getScriptInfos());
+ return counts.ts === 0 && counts.tsx === 0;
}
export interface ProjectFilesWithTSDiagnostics extends protocol.ProjectFiles {
@@ -71,11 +97,16 @@ namespace ts.server {
public typesVersion = 0;
- public isJsOnlyProject() {
+ public isNonTsProject() {
this.updateGraph();
return allFilesAreJsOrDts(this);
}
+ public isJsOnlyProject() {
+ this.updateGraph();
+ return hasOneOrMoreJsAndNoTsFiles(this);
+ }
+
constructor(
readonly projectKind: ProjectKind,
readonly projectService: ProjectService,
diff --git a/src/server/protocol.d.ts b/src/server/protocol.ts
similarity index 79%
rename from src/server/protocol.d.ts
rename to src/server/protocol.ts
index 0ae54b8e0cf..80623f05aec 100644
--- a/src/server/protocol.d.ts
+++ b/src/server/protocol.ts
@@ -1,7 +1,102 @@
/**
* Declaration module describing the TypeScript Server protocol
*/
-declare namespace ts.server.protocol {
+namespace ts.server.protocol {
+ export namespace CommandTypes {
+ export type Brace = "brace";
+ /* @internal */
+ export type BraceFull = "brace-full";
+ export type BraceCompletion = "braceCompletion";
+ export type Change = "change";
+ export type Close = "close";
+ export type Completions = "completions";
+ /* @internal */
+ export type CompletionsFull = "completions-full";
+ export type CompletionDetails = "completionEntryDetails";
+ export type CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList";
+ export type CompileOnSaveEmitFile = "compileOnSaveEmitFile";
+ export type Configure = "configure";
+ export type Definition = "definition";
+ /* @internal */
+ export type DefinitionFull = "definition-full";
+ export type Implementation = "implementation";
+ /* @internal */
+ export type ImplementationFull = "implementation-full";
+ export type Exit = "exit";
+ export type Format = "format";
+ export type Formatonkey = "formatonkey";
+ /* @internal */
+ export type FormatFull = "format-full";
+ /* @internal */
+ export type FormatonkeyFull = "formatonkey-full";
+ /* @internal */
+ export type FormatRangeFull = "formatRange-full";
+ export type Geterr = "geterr";
+ export type GeterrForProject = "geterrForProject";
+ export type SemanticDiagnosticsSync = "semanticDiagnosticsSync";
+ export type SyntacticDiagnosticsSync = "syntacticDiagnosticsSync";
+ export type NavBar = "navbar";
+ /* @internal */
+ export type NavBarFull = "navbar-full";
+ export type Navto = "navto";
+ /* @internal */
+ export type NavtoFull = "navto-full";
+ export type NavTree = "navtree";
+ export type NavTreeFull = "navtree-full";
+ export type Occurrences = "occurrences";
+ export type DocumentHighlights = "documentHighlights";
+ /* @internal */
+ export type DocumentHighlightsFull = "documentHighlights-full";
+ export type Open = "open";
+ export type Quickinfo = "quickinfo";
+ /* @internal */
+ export type QuickinfoFull = "quickinfo-full";
+ export type References = "references";
+ /* @internal */
+ export type ReferencesFull = "references-full";
+ export type Reload = "reload";
+ export type Rename = "rename";
+ /* @internal */
+ export type RenameInfoFull = "rename-full";
+ /* @internal */
+ export type RenameLocationsFull = "renameLocations-full";
+ export type Saveto = "saveto";
+ export type SignatureHelp = "signatureHelp";
+ /* @internal */
+ export type SignatureHelpFull = "signatureHelp-full";
+ export type TypeDefinition = "typeDefinition";
+ export type ProjectInfo = "projectInfo";
+ export type ReloadProjects = "reloadProjects";
+ export type Unknown = "unknown";
+ export type OpenExternalProject = "openExternalProject";
+ export type OpenExternalProjects = "openExternalProjects";
+ export type CloseExternalProject = "closeExternalProject";
+ /* @internal */
+ export type SynchronizeProjectList = "synchronizeProjectList";
+ /* @internal */
+ export type ApplyChangedToOpenFiles = "applyChangedToOpenFiles";
+ /* @internal */
+ export type EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full";
+ /* @internal */
+ export type Cleanup = "cleanup";
+ /* @internal */
+ export type OutliningSpans = "outliningSpans";
+ export type TodoComments = "todoComments";
+ export type Indentation = "indentation";
+ export type DocCommentTemplate = "docCommentTemplate";
+ /* @internal */
+ export type CompilerOptionsDiagnosticsFull = "compilerOptionsDiagnostics-full";
+ /* @internal */
+ export type NameOrDottedNameSpan = "nameOrDottedNameSpan";
+ /* @internal */
+ export type BreakpointStatement = "breakpointStatement";
+ export type CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects";
+ export type GetCodeFixes = "getCodeFixes";
+ /* @internal */
+ export type GetCodeFixesFull = "getCodeFixes-full";
+ export type GetSupportedCodeFixes = "getSupportedCodeFixes";
+ }
+
/**
* A TypeScript Server message
*/
@@ -36,6 +131,7 @@ declare namespace ts.server.protocol {
* Request to reload the project structure for all the opened files
*/
export interface ReloadProjectsRequest extends Message {
+ command: CommandTypes.ReloadProjects;
}
/**
@@ -98,10 +194,25 @@ declare namespace ts.server.protocol {
projectFileName?: string;
}
+ /**
+ * Requests a JS Doc comment template for a given position
+ */
+ export interface DocCommentTemplateRequest extends FileLocationRequest {
+ command: CommandTypes.DocCommentTemplate;
+ }
+
+ /**
+ * Response to DocCommentTemplateRequest
+ */
+ export interface DocCommandTemplateResponse extends Response {
+ body?: TextInsertion;
+ }
+
/**
* A request to get TODO comments from the file
*/
export interface TodoCommentRequest extends FileRequest {
+ command: CommandTypes.TodoComments;
arguments: TodoCommentRequestArgs;
}
@@ -110,18 +221,63 @@ declare namespace ts.server.protocol {
*/
export interface TodoCommentRequestArgs extends FileRequestArgs {
/**
- * Array of target TodoCommentDescriptors that describes TODO comments to be found
+ * Array of target TodoCommentDescriptors that describes TODO comments to be found
*/
descriptors: TodoCommentDescriptor[];
}
+ /**
+ * Response for TodoCommentRequest request.
+ */
+ export interface TodoCommentsResponse extends Response {
+ body?: TodoComment[];
+ }
+
+ /**
+ * Request to obtain outlining spans in file.
+ */
+ /* @internal */
+ export interface OutliningSpansRequest extends FileRequest {
+ command: CommandTypes.OutliningSpans;
+ }
+
+ /**
+ * Response to OutliningSpansRequest request.
+ */
+ /* @internal */
+ export interface OutliningSpansResponse extends Response {
+ body?: OutliningSpan[];
+ }
+
/**
* A request to get indentation for a location in file
*/
export interface IndentationRequest extends FileLocationRequest {
+ command: CommandTypes.Indentation;
arguments: IndentationRequestArgs;
}
+ /**
+ * Response for IndentationRequest request.
+ */
+ export interface IndentationResponse extends Response {
+ body?: IndentationResult;
+ }
+
+ /**
+ * Indentation result representing where indentation should be placed
+ */
+ export interface IndentationResult {
+ /**
+ * The base position in the document that the indent should be relative to
+ */
+ position: number;
+ /**
+ * The number of columns the indent should be at relative to the position's column.
+ */
+ indentation: number;
+ }
+
/**
* Arguments for IndentationRequest request.
*/
@@ -147,6 +303,7 @@ declare namespace ts.server.protocol {
* A request to get the project information of the current file.
*/
export interface ProjectInfoRequest extends Request {
+ command: CommandTypes.ProjectInfo;
arguments: ProjectInfoRequestArgs;
}
@@ -223,16 +380,17 @@ declare namespace ts.server.protocol {
/**
* The line number for the request (1-based).
*/
- line?: number;
+ line: number;
/**
* The character offset (on the line) for the request (1-based).
*/
- offset?: number;
+ offset: number;
/**
- * Position (can be specified instead of line/offset pair)
+ * Position (can be specified instead of line/offset pair)
*/
+ /* @internal */
position?: number;
}
@@ -240,6 +398,7 @@ declare namespace ts.server.protocol {
* Request for the available codefixes at a specific position.
*/
export interface CodeFixRequest extends Request {
+ command: CommandTypes.GetCodeFixes;
arguments: CodeFixRequestArgs;
}
@@ -250,31 +409,33 @@ declare namespace ts.server.protocol {
/**
* The line number for the request (1-based).
*/
- startLine?: number;
+ startLine: number;
/**
* The character offset (on the line) for the request (1-based).
*/
- startOffset?: number;
+ startOffset: number;
/**
* Position (can be specified instead of line/offset pair)
*/
+ /* @internal */
startPosition?: number;
/**
* The line number for the request (1-based).
*/
- endLine?: number;
+ endLine: number;
/**
* The character offset (on the line) for the request (1-based).
*/
- endOffset?: number;
+ endOffset: number;
/**
* Position (can be specified instead of line/offset pair)
*/
+ /* @internal */
endPosition?: number;
/**
@@ -283,6 +444,13 @@ declare namespace ts.server.protocol {
errorCodes?: number[];
}
+ /**
+ * Response for GetCodeFixes request.
+ */
+ export interface GetCodeFixesResponse extends Response {
+ body?: CodeAction[];
+ }
+
/**
* A request whose arguments specify a file location (file, line, col).
*/
@@ -291,16 +459,34 @@ declare namespace ts.server.protocol {
}
/**
- * A request to get semantic diagnostics for a span in the file
+ * A request to get codes of supported code fixes.
*/
- export interface SemanticDiagnosticsRequest extends FileRequest {
- arguments: SemanticDiagnosticsRequestArgs;
+ export interface GetSupportedCodeFixesRequest extends Request {
+ command: CommandTypes.GetSupportedCodeFixes;
}
/**
- * Arguments for SemanticDiagnosticsRequest request.
+ * A response for GetSupportedCodeFixesRequest request.
*/
- export interface SemanticDiagnosticsRequestArgs extends FileRequestArgs {
+ export interface GetSupportedCodeFixesResponse extends Response {
+ /**
+ * List of error codes supported by the server.
+ */
+ body?: string[];
+ }
+
+ /**
+ * A request to get encoded semantic classifications for a span in the file
+ */
+ /** @internal */
+ export interface EncodedSemanticClassificationsRequest extends FileRequest {
+ arguments: EncodedSemanticClassificationsRequestArgs;
+ }
+
+ /**
+ * Arguments for EncodedSemanticClassificationsRequest request.
+ */
+ export interface EncodedSemanticClassificationsRequestArgs extends FileRequestArgs {
/**
* Start position of the span.
*/
@@ -328,6 +514,7 @@ declare namespace ts.server.protocol {
* define the symbol found in file at location line, col.
*/
export interface DefinitionRequest extends FileLocationRequest {
+ command: CommandTypes.Definition;
}
/**
@@ -336,6 +523,7 @@ declare namespace ts.server.protocol {
* define the type for the symbol found in file at location line, col.
*/
export interface TypeDefinitionRequest extends FileLocationRequest {
+ command: CommandTypes.TypeDefinition;
}
/**
@@ -344,6 +532,7 @@ declare namespace ts.server.protocol {
* implement the symbol found in file at location line, col.
*/
export interface ImplementationRequest extends FileLocationRequest {
+ command: CommandTypes.Implementation;
}
/**
@@ -404,6 +593,7 @@ declare namespace ts.server.protocol {
* Request to get brace completion for a location in the file.
*/
export interface BraceCompletionRequest extends FileLocationRequest {
+ command: CommandTypes.BraceCompletion;
arguments: BraceCompletionRequestArgs;
}
@@ -423,6 +613,7 @@ declare namespace ts.server.protocol {
* in the file at a given line and column.
*/
export interface OccurrencesRequest extends FileLocationRequest {
+ command: CommandTypes.Occurrences;
}
export interface OccurrencesResponseItem extends FileSpan {
@@ -442,6 +633,7 @@ declare namespace ts.server.protocol {
* in the file at a given line and column.
*/
export interface DocumentHighlightsRequest extends FileLocationRequest {
+ command: CommandTypes.DocumentHighlights;
arguments: DocumentHighlightsRequestArgs;
}
@@ -481,6 +673,7 @@ declare namespace ts.server.protocol {
* reference the symbol found in file at location line, col.
*/
export interface ReferencesRequest extends FileLocationRequest {
+ command: CommandTypes.References;
}
export interface ReferencesResponseItem extends FileSpan {
@@ -555,6 +748,7 @@ declare namespace ts.server.protocol {
* name of the symbol so that client can print it unambiguously.
*/
export interface RenameRequest extends FileLocationRequest {
+ command: CommandTypes.Rename;
arguments: RenameRequestArgs;
}
@@ -624,12 +818,12 @@ declare namespace ts.server.protocol {
/**
* Represents a file in external project.
- * External project is project whose set of files, compilation options and open\close state
+ * External project is project whose set of files, compilation options and open\close state
* is maintained by the client (i.e. if all this data come from .csproj file in Visual Studio).
* External project will exist even if all files in it are closed and should be closed explicity.
- * If external project includes one or more tsconfig.json/jsconfig.json files then tsserver will
+ * If external project includes one or more tsconfig.json/jsconfig.json files then tsserver will
* create configured project for every config file but will maintain a link that these projects were created
- * as a result of opening external project so they should be removed once external project is closed.
+ * as a result of opening external project so they should be removed once external project is closed.
*/
export interface ExternalFile {
/**
@@ -754,6 +948,7 @@ declare namespace ts.server.protocol {
/**
* Represents set of changes in open file
*/
+ /* @internal */
export interface ChangedOpenFile {
/**
* Name of file
@@ -765,65 +960,6 @@ declare namespace ts.server.protocol {
changes: ts.TextChange[];
}
- /**
- * Editor options
- */
- export interface EditorOptions {
-
- /** Number of spaces for each tab. Default value is 4. */
- tabSize?: number;
-
- /** Number of spaces to indent during formatting. Default value is 4. */
- indentSize?: number;
-
- /** Number of additional spaces to indent during formatting to preserve base indentation (ex. script block indentation). Default value is 0. */
- baseIndentSize?: number;
-
- /** The new line character to be used. Default value is the OS line delimiter. */
- newLineCharacter?: string;
-
- /** Whether tabs should be converted to spaces. Default value is true. */
- convertTabsToSpaces?: boolean;
- }
-
- /**
- * Format options
- */
- export interface FormatOptions extends EditorOptions {
-
- /** Defines space handling after a comma delimiter. Default value is true. */
- insertSpaceAfterCommaDelimiter?: boolean;
-
- /** Defines space handling after a semicolon in a for statement. Default value is true */
- insertSpaceAfterSemicolonInForStatements?: boolean;
-
- /** Defines space handling after a binary operator. Default value is true. */
- insertSpaceBeforeAndAfterBinaryOperators?: boolean;
-
- /** Defines space handling after keywords in control flow statement. Default value is true. */
- insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
-
- /** Defines space handling after function keyword for anonymous functions. Default value is false. */
- insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
-
- /** Defines space handling after opening and before closing non empty parenthesis. Default value is false. */
- insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
-
- /** Defines space handling after opening and before closing non empty brackets. Default value is false. */
- insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
-
- /** Defines space handling before and after template string braces. Default value is false. */
- insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
-
- /** Defines space handling before and after JSX expression braces. Default value is false. */
- insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
-
- /** Defines whether an open brace is put onto a new line for functions or not. Default value is false. */
- placeOpenBraceOnNewLineForFunctions?: boolean;
-
- /** Defines whether an open brace is put onto a new line for control blocks or not. Default value is false. */
- placeOpenBraceOnNewLineForControlBlocks?: boolean;
- }
/**
* Information found in a configure request.
@@ -844,12 +980,7 @@ declare namespace ts.server.protocol {
/**
* The format options to use during formatting and other code editing features.
*/
- formatOptions?: FormatOptions;
-
- /**
- * If set to true - then all loose files will land into one inferred project
- */
- useOneInferredProject?: boolean;
+ formatOptions?: FormatCodeSettings;
}
/**
@@ -857,6 +988,7 @@ declare namespace ts.server.protocol {
* host information, such as host type, tab size, and indent size.
*/
export interface ConfigureRequest extends Request {
+ command: CommandTypes.Configure;
arguments: ConfigureRequestArguments;
}
@@ -892,6 +1024,7 @@ declare namespace ts.server.protocol {
* send a response to an open request.
*/
export interface OpenRequest extends Request {
+ command: CommandTypes.Open;
arguments: OpenRequestArgs;
}
@@ -899,18 +1032,20 @@ declare namespace ts.server.protocol {
* Request to open or update external project
*/
export interface OpenExternalProjectRequest extends Request {
+ command: CommandTypes.OpenExternalProject;
arguments: OpenExternalProjectArgs;
}
/**
* Arguments to OpenExternalProjectRequest request
*/
- type OpenExternalProjectArgs = ExternalProject;
+ export type OpenExternalProjectArgs = ExternalProject;
/**
* Request to open multiple external projects
*/
export interface OpenExternalProjectsRequest extends Request {
+ command: CommandTypes.OpenExternalProjects;
arguments: OpenExternalProjectsArgs;
}
@@ -924,10 +1059,25 @@ declare namespace ts.server.protocol {
projects: ExternalProject[];
}
+ /**
+ * Response to OpenExternalProjectRequest request. This is just an acknowledgement, so
+ * no body field is required.
+ */
+ export interface OpenExternalProjectResponse extends Response {
+ }
+
+ /**
+ * Response to OpenExternalProjectsRequest request. This is just an acknowledgement, so
+ * no body field is required.
+ */
+ export interface OpenExternalProjectsResponse extends Response {
+ }
+
/**
* Request to close external project.
*/
export interface CloseExternalProjectRequest extends Request {
+ command: CommandTypes.CloseExternalProject;
arguments: CloseExternalProjectRequestArgs;
}
@@ -941,9 +1091,17 @@ declare namespace ts.server.protocol {
projectFileName: string;
}
+ /**
+ * Response to CloseExternalProjectRequest request. This is just an acknowledgement, so
+ * no body field is required.
+ */
+ export interface CloseExternalProjectResponse extends Response {
+ }
+
/**
* Request to check if given list of projects is up-to-date and synchronize them if necessary
*/
+ /* @internal */
export interface SynchronizeProjectListRequest extends Request {
arguments: SynchronizeProjectListRequestArgs;
}
@@ -961,6 +1119,7 @@ declare namespace ts.server.protocol {
/**
* Request to synchronize list of open files with the client
*/
+ /* @internal */
export interface ApplyChangedToOpenFilesRequest extends Request {
arguments: ApplyChangedToOpenFilesRequestArgs;
}
@@ -968,6 +1127,7 @@ declare namespace ts.server.protocol {
/**
* Arguments to ApplyChangedToOpenFilesRequest
*/
+ /* @internal */
export interface ApplyChangedToOpenFilesRequestArgs {
/**
* List of newly open files
@@ -993,6 +1153,7 @@ declare namespace ts.server.protocol {
* or all open loose files and its transitive closure of referenced files if 'useOneInferredProject' is true.
*/
export interface SetCompilerOptionsForInferredProjectsRequest extends Request {
+ command: CommandTypes.CompilerOptionsForInferredProjects;
arguments: SetCompilerOptionsForInferredProjectsArgs;
}
@@ -1006,11 +1167,19 @@ declare namespace ts.server.protocol {
options: ExternalProjectCompilerOptions;
}
+ /**
+ * Response to SetCompilerOptionsForInferredProjectsResponse request. This is just an acknowledgement, so
+ * no body field is required.
+ */
+ export interface SetCompilerOptionsForInferredProjectsResponse extends Response {
+ }
+
/**
* Exit request; value of command field is "exit". Ask the server process
* to exit.
*/
export interface ExitRequest extends Request {
+ command: CommandTypes.Exit;
}
/**
@@ -1021,6 +1190,7 @@ declare namespace ts.server.protocol {
* currently send a response to a close request.
*/
export interface CloseRequest extends FileRequest {
+ command: CommandTypes.Close;
}
/**
@@ -1028,6 +1198,7 @@ declare namespace ts.server.protocol {
* NOTE: this us query-only operation and does not generate any output on disk.
*/
export interface CompileOnSaveAffectedFileListRequest extends FileRequest {
+ command: CommandTypes.CompileOnSaveAffectedFileList;
}
/**
@@ -1045,7 +1216,7 @@ declare namespace ts.server.protocol {
}
/**
- * Response for CompileOnSaveAffectedFileListRequest request;
+ * Response for CompileOnSaveAffectedFileListRequest request;
*/
export interface CompileOnSaveAffectedFileListResponse extends Response {
body: CompileOnSaveAffectedFileListSingleProject[];
@@ -1055,7 +1226,8 @@ declare namespace ts.server.protocol {
* Request to recompile the file. All generated outputs (.js, .d.ts or .js.map files) is written on disk.
*/
export interface CompileOnSaveEmitFileRequest extends FileRequest {
- args: CompileOnSaveEmitFileRequestArgs;
+ command: CommandTypes.CompileOnSaveEmitFile;
+ arguments: CompileOnSaveEmitFileRequestArgs;
}
/**
@@ -1075,6 +1247,7 @@ declare namespace ts.server.protocol {
* line, col.
*/
export interface QuickInfoRequest extends FileLocationRequest {
+ command: CommandTypes.Quickinfo;
}
/**
@@ -1136,12 +1309,12 @@ declare namespace ts.server.protocol {
/**
* End position of the range for which to format text in file.
*/
+ /* @internal */
endPosition?: number;
-
/**
* Format options to be used.
*/
- options?: ts.FormatCodeOptions;
+ options?: FormatCodeSettings;
}
/**
@@ -1152,6 +1325,7 @@ declare namespace ts.server.protocol {
* reformatted text.
*/
export interface FormatRequest extends FileLocationRequest {
+ command: CommandTypes.Format;
arguments: FormatRequestArgs;
}
@@ -1213,7 +1387,7 @@ declare namespace ts.server.protocol {
*/
key: string;
- options?: ts.FormatCodeOptions;
+ options?: FormatCodeSettings;
}
/**
@@ -1225,6 +1399,7 @@ declare namespace ts.server.protocol {
* reformatted text.
*/
export interface FormatOnKeyRequest extends FileLocationRequest {
+ command: CommandTypes.Formatonkey;
arguments: FormatOnKeyRequestArgs;
}
@@ -1245,6 +1420,7 @@ declare namespace ts.server.protocol {
* begin with prefix.
*/
export interface CompletionsRequest extends FileLocationRequest {
+ command: CommandTypes.Completions;
arguments: CompletionsRequestArgs;
}
@@ -1265,6 +1441,7 @@ declare namespace ts.server.protocol {
* detailed information for each completion entry.
*/
export interface CompletionDetailsRequest extends FileLocationRequest {
+ command: CommandTypes.CompletionDetails;
arguments: CompletionDetailsRequestArgs;
}
@@ -1451,6 +1628,7 @@ declare namespace ts.server.protocol {
* help.
*/
export interface SignatureHelpRequest extends FileLocationRequest {
+ command: CommandTypes.SignatureHelp;
arguments: SignatureHelpRequestArgs;
}
@@ -1465,6 +1643,7 @@ declare namespace ts.server.protocol {
* Synchronous request for semantic diagnostics of one file.
*/
export interface SemanticDiagnosticsSyncRequest extends FileRequest {
+ command: CommandTypes.SemanticDiagnosticsSync;
arguments: SemanticDiagnosticsSyncRequestArgs;
}
@@ -1483,6 +1662,7 @@ declare namespace ts.server.protocol {
* Synchronous request for syntactic diagnostics of one file.
*/
export interface SyntacticDiagnosticsSyncRequest extends FileRequest {
+ command: CommandTypes.SyntacticDiagnosticsSync;
arguments: SyntacticDiagnosticsSyncRequestArgs;
}
@@ -1519,6 +1699,7 @@ declare namespace ts.server.protocol {
* it request for every file in this project.
*/
export interface GeterrForProjectRequest extends Request {
+ command: CommandTypes.GeterrForProject;
arguments: GeterrForProjectRequestArgs;
}
@@ -1550,6 +1731,7 @@ declare namespace ts.server.protocol {
* file that is currently visible, in most-recently-used order.
*/
export interface GeterrRequest extends Request {
+ command: CommandTypes.Geterr;
arguments: GeterrRequestArgs;
}
@@ -1642,11 +1824,12 @@ declare namespace ts.server.protocol {
* The two names can be identical.
*/
export interface ReloadRequest extends FileRequest {
+ command: CommandTypes.Reload;
arguments: ReloadRequestArgs;
}
/**
- * Response to "reload" request. This is just an acknowledgement, so
+ * Response to "reload" request. This is just an acknowledgement, so
* no body field is required.
*/
export interface ReloadResponse extends Response {
@@ -1671,6 +1854,7 @@ declare namespace ts.server.protocol {
* "saveto" request.
*/
export interface SavetoRequest extends FileRequest {
+ command: CommandTypes.Saveto;
arguments: SavetoRequestArgs;
}
@@ -1703,6 +1887,7 @@ declare namespace ts.server.protocol {
* context for the search is given by the named file.
*/
export interface NavtoRequest extends FileRequest {
+ command: CommandTypes.Navto;
arguments: NavtoRequestArgs;
}
@@ -1786,6 +1971,7 @@ declare namespace ts.server.protocol {
* Server does not currently send a response to a change request.
*/
export interface ChangeRequest extends FileLocationRequest {
+ command: CommandTypes.Change;
arguments: ChangeRequestArgs;
}
@@ -1802,6 +1988,7 @@ declare namespace ts.server.protocol {
* found in file at location line, offset.
*/
export interface BraceRequest extends FileLocationRequest {
+ command: CommandTypes.Brace;
}
/**
@@ -1810,6 +1997,15 @@ declare namespace ts.server.protocol {
* extracted from the requested file.
*/
export interface NavBarRequest extends FileRequest {
+ command: CommandTypes.NavBar;
+ }
+
+ /**
+ * NavTree request; value of command field is "navtree".
+ * Return response giving the navigation tree of the requested file.
+ */
+ export interface NavTreeRequest extends FileRequest {
+ command: CommandTypes.NavTree;
}
export interface NavigationBarItem {
@@ -1844,7 +2040,20 @@ declare namespace ts.server.protocol {
indent: number;
}
+ /** protocol.NavigationTree is identical to ts.NavigationTree, except using protocol.TextSpan instead of ts.TextSpan */
+ export interface NavigationTree {
+ text: string;
+ kind: string;
+ kindModifiers: string;
+ spans: TextSpan[];
+ childItems?: NavigationTree[];
+ }
+
export interface NavBarResponse extends Response {
body?: NavigationBarItem[];
}
+
+ export interface NavTreeResponse extends Response {
+ body?: NavigationTree;
+ }
}
diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts
index 410382a9ca4..68dd59d2d32 100644
--- a/src/server/scriptInfo.ts
+++ b/src/server/scriptInfo.ts
@@ -4,7 +4,7 @@ namespace ts.server {
export class ScriptInfo {
/**
- * All projects that include this file
+ * All projects that include this file
*/
readonly containingProjects: Project[] = [];
private formatCodeSettings: ts.FormatCodeSettings;
@@ -91,7 +91,7 @@ namespace ts.server {
return this.containingProjects[0];
}
- setFormatOptions(formatSettings: protocol.FormatOptions): void {
+ setFormatOptions(formatSettings: FormatCodeSettings): void {
if (formatSettings) {
if (!this.formatCodeSettings) {
this.formatCodeSettings = getDefaultFormatCodeSettings(this.host);
diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts
index 1508187c13e..8d0efa081ad 100644
--- a/src/server/scriptVersionCache.ts
+++ b/src/server/scriptVersionCache.ts
@@ -1,6 +1,5 @@
///
///
-///
///
namespace ts.server {
diff --git a/src/server/session.ts b/src/server/session.ts
index a80b1bea2f3..111ba53a700 100644
--- a/src/server/session.ts
+++ b/src/server/session.ts
@@ -1,6 +1,6 @@
///
///
-///
+///
///
namespace ts.server {
@@ -14,6 +14,17 @@ namespace ts.server {
return ((1e9 * seconds) + nanoseconds) / 1000000.0;
}
+ function shouldSkipSematicCheck(project: Project) {
+ if (project.getCompilerOptions().skipLibCheck !== undefined) {
+ return false;
+ }
+
+ if ((project.projectKind === ProjectKind.Inferred || project.projectKind === ProjectKind.External) && project.isJsOnlyProject()) {
+ return true;
+ }
+ return false;
+ }
+
interface FileStart {
file: string;
start: ILineInfo;
@@ -72,72 +83,74 @@ namespace ts.server {
}
export namespace CommandNames {
- export const Brace = "brace";
- export const BraceFull = "brace-full";
- export const BraceCompletion = "braceCompletion";
- export const Change = "change";
- export const Close = "close";
- export const Completions = "completions";
- export const CompletionsFull = "completions-full";
- export const CompletionDetails = "completionEntryDetails";
- export const CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList";
- export const CompileOnSaveEmitFile = "compileOnSaveEmitFile";
- export const Configure = "configure";
- export const Definition = "definition";
- export const DefinitionFull = "definition-full";
- export const Exit = "exit";
- export const Format = "format";
- export const Formatonkey = "formatonkey";
- export const FormatFull = "format-full";
- export const FormatonkeyFull = "formatonkey-full";
- export const FormatRangeFull = "formatRange-full";
- export const Geterr = "geterr";
- export const GeterrForProject = "geterrForProject";
- export const Implementation = "implementation";
- export const ImplementationFull = "implementation-full";
- export const SemanticDiagnosticsSync = "semanticDiagnosticsSync";
- export const SyntacticDiagnosticsSync = "syntacticDiagnosticsSync";
- export const NavBar = "navbar";
- export const NavBarFull = "navbar-full";
- export const Navto = "navto";
- export const NavtoFull = "navto-full";
- export const Occurrences = "occurrences";
- export const DocumentHighlights = "documentHighlights";
- export const DocumentHighlightsFull = "documentHighlights-full";
- export const Open = "open";
- export const Quickinfo = "quickinfo";
- export const QuickinfoFull = "quickinfo-full";
- export const References = "references";
- export const ReferencesFull = "references-full";
- export const Reload = "reload";
- export const Rename = "rename";
- export const RenameInfoFull = "rename-full";
- export const RenameLocationsFull = "renameLocations-full";
- export const Saveto = "saveto";
- export const SignatureHelp = "signatureHelp";
- export const SignatureHelpFull = "signatureHelp-full";
- export const TypeDefinition = "typeDefinition";
- export const ProjectInfo = "projectInfo";
- export const ReloadProjects = "reloadProjects";
- export const Unknown = "unknown";
- export const OpenExternalProject = "openExternalProject";
- export const OpenExternalProjects = "openExternalProjects";
- export const CloseExternalProject = "closeExternalProject";
- export const SynchronizeProjectList = "synchronizeProjectList";
- export const ApplyChangedToOpenFiles = "applyChangedToOpenFiles";
- export const EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full";
- export const Cleanup = "cleanup";
- export const OutliningSpans = "outliningSpans";
- export const TodoComments = "todoComments";
- export const Indentation = "indentation";
- export const DocCommentTemplate = "docCommentTemplate";
- export const CompilerOptionsDiagnosticsFull = "compilerOptionsDiagnostics-full";
- export const NameOrDottedNameSpan = "nameOrDottedNameSpan";
- export const BreakpointStatement = "breakpointStatement";
- export const CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects";
- export const GetCodeFixes = "getCodeFixes";
- export const GetCodeFixesFull = "getCodeFixes-full";
- export const GetSupportedCodeFixes = "getSupportedCodeFixes";
+ export const Brace: protocol.CommandTypes.Brace = "brace";
+ export const BraceFull: protocol.CommandTypes.BraceFull = "brace-full";
+ export const BraceCompletion: protocol.CommandTypes.BraceCompletion = "braceCompletion";
+ export const Change: protocol.CommandTypes.Change = "change";
+ export const Close: protocol.CommandTypes.Close = "close";
+ export const Completions: protocol.CommandTypes.Completions = "completions";
+ export const CompletionsFull: protocol.CommandTypes.CompletionsFull = "completions-full";
+ export const CompletionDetails: protocol.CommandTypes.CompletionDetails = "completionEntryDetails";
+ export const CompileOnSaveAffectedFileList: protocol.CommandTypes.CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList";
+ export const CompileOnSaveEmitFile: protocol.CommandTypes.CompileOnSaveEmitFile = "compileOnSaveEmitFile";
+ export const Configure: protocol.CommandTypes.Configure = "configure";
+ export const Definition: protocol.CommandTypes.Definition = "definition";
+ export const DefinitionFull: protocol.CommandTypes.DefinitionFull = "definition-full";
+ export const Exit: protocol.CommandTypes.Exit = "exit";
+ export const Format: protocol.CommandTypes.Format = "format";
+ export const Formatonkey: protocol.CommandTypes.Formatonkey = "formatonkey";
+ export const FormatFull: protocol.CommandTypes.FormatFull = "format-full";
+ export const FormatonkeyFull: protocol.CommandTypes.FormatonkeyFull = "formatonkey-full";
+ export const FormatRangeFull: protocol.CommandTypes.FormatRangeFull = "formatRange-full";
+ export const Geterr: protocol.CommandTypes.Geterr = "geterr";
+ export const GeterrForProject: protocol.CommandTypes.GeterrForProject = "geterrForProject";
+ export const Implementation: protocol.CommandTypes.Implementation = "implementation";
+ export const ImplementationFull: protocol.CommandTypes.ImplementationFull = "implementation-full";
+ export const SemanticDiagnosticsSync: protocol.CommandTypes.SemanticDiagnosticsSync = "semanticDiagnosticsSync";
+ export const SyntacticDiagnosticsSync: protocol.CommandTypes.SyntacticDiagnosticsSync = "syntacticDiagnosticsSync";
+ export const NavBar: protocol.CommandTypes.NavBar = "navbar";
+ export const NavBarFull: protocol.CommandTypes.NavBarFull = "navbar-full";
+ export const NavTree: protocol.CommandTypes.NavTree = "navtree";
+ export const NavTreeFull: protocol.CommandTypes.NavTreeFull = "navtree-full";
+ export const Navto: protocol.CommandTypes.Navto = "navto";
+ export const NavtoFull: protocol.CommandTypes.NavtoFull = "navto-full";
+ export const Occurrences: protocol.CommandTypes.Occurrences = "occurrences";
+ export const DocumentHighlights: protocol.CommandTypes.DocumentHighlights = "documentHighlights";
+ export const DocumentHighlightsFull: protocol.CommandTypes.DocumentHighlightsFull = "documentHighlights-full";
+ export const Open: protocol.CommandTypes.Open = "open";
+ export const Quickinfo: protocol.CommandTypes.Quickinfo = "quickinfo";
+ export const QuickinfoFull: protocol.CommandTypes.QuickinfoFull = "quickinfo-full";
+ export const References: protocol.CommandTypes.References = "references";
+ export const ReferencesFull: protocol.CommandTypes.ReferencesFull = "references-full";
+ export const Reload: protocol.CommandTypes.Reload = "reload";
+ export const Rename: protocol.CommandTypes.Rename = "rename";
+ export const RenameInfoFull: protocol.CommandTypes.RenameInfoFull = "rename-full";
+ export const RenameLocationsFull: protocol.CommandTypes.RenameLocationsFull = "renameLocations-full";
+ export const Saveto: protocol.CommandTypes.Saveto = "saveto";
+ export const SignatureHelp: protocol.CommandTypes.SignatureHelp = "signatureHelp";
+ export const SignatureHelpFull: protocol.CommandTypes.SignatureHelpFull = "signatureHelp-full";
+ export const TypeDefinition: protocol.CommandTypes.TypeDefinition = "typeDefinition";
+ export const ProjectInfo: protocol.CommandTypes.ProjectInfo = "projectInfo";
+ export const ReloadProjects: protocol.CommandTypes.ReloadProjects = "reloadProjects";
+ export const Unknown: protocol.CommandTypes.Unknown = "unknown";
+ export const OpenExternalProject: protocol.CommandTypes.OpenExternalProject = "openExternalProject";
+ export const OpenExternalProjects: protocol.CommandTypes.OpenExternalProjects = "openExternalProjects";
+ export const CloseExternalProject: protocol.CommandTypes.CloseExternalProject = "closeExternalProject";
+ export const SynchronizeProjectList: protocol.CommandTypes.SynchronizeProjectList = "synchronizeProjectList";
+ export const ApplyChangedToOpenFiles: protocol.CommandTypes.ApplyChangedToOpenFiles = "applyChangedToOpenFiles";
+ export const EncodedSemanticClassificationsFull: protocol.CommandTypes.EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full";
+ export const Cleanup: protocol.CommandTypes.Cleanup = "cleanup";
+ export const OutliningSpans: protocol.CommandTypes.OutliningSpans = "outliningSpans";
+ export const TodoComments: protocol.CommandTypes.TodoComments = "todoComments";
+ export const Indentation: protocol.CommandTypes.Indentation = "indentation";
+ export const DocCommentTemplate: protocol.CommandTypes.DocCommentTemplate = "docCommentTemplate";
+ export const CompilerOptionsDiagnosticsFull: protocol.CommandTypes.CompilerOptionsDiagnosticsFull = "compilerOptionsDiagnostics-full";
+ export const NameOrDottedNameSpan: protocol.CommandTypes.NameOrDottedNameSpan = "nameOrDottedNameSpan";
+ export const BreakpointStatement: protocol.CommandTypes.BreakpointStatement = "breakpointStatement";
+ export const CompilerOptionsForInferredProjects: protocol.CommandTypes.CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects";
+ export const GetCodeFixes: protocol.CommandTypes.GetCodeFixes = "getCodeFixes";
+ export const GetCodeFixesFull: protocol.CommandTypes.GetCodeFixesFull = "getCodeFixes-full";
+ export const GetSupportedCodeFixes: protocol.CommandTypes.GetSupportedCodeFixes = "getSupportedCodeFixes";
}
export function formatMessage(msg: T, logger: server.Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string {
@@ -259,12 +272,13 @@ namespace ts.server {
private semanticCheck(file: NormalizedPath, project: Project) {
try {
- const diags = project.getLanguageService().getSemanticDiagnostics(file);
-
- if (diags) {
- const bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
- this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag");
+ let diags: Diagnostic[] = [];
+ if (!shouldSkipSematicCheck(project)) {
+ diags = project.getLanguageService().getSemanticDiagnostics(file);
}
+
+ const bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
+ this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag");
}
catch (err) {
this.logError(err, "semantic check");
@@ -349,7 +363,7 @@ namespace ts.server {
}
}
- private getEncodedSemanticClassifications(args: protocol.SemanticDiagnosticsRequestArgs) {
+ private getEncodedSemanticClassifications(args: protocol.EncodedSemanticClassificationsRequestArgs) {
const { file, project } = this.getFileAndProject(args);
return project.getLanguageService().getEncodedSemanticClassifications(file, args);
}
@@ -377,6 +391,9 @@ namespace ts.server {
private getDiagnosticsWorker(args: protocol.FileRequestArgs, selector: (project: Project, file: string) => Diagnostic[], includeLinePosition: boolean) {
const { project, file } = this.getFileAndProject(args);
+ if (shouldSkipSematicCheck(project)) {
+ return [];
+ }
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const diagnostics = selector(project, file);
return includeLinePosition
@@ -554,7 +571,7 @@ namespace ts.server {
const scriptInfo = this.projectService.getScriptInfo(args.file);
projects = scriptInfo.containingProjects;
}
- // ts.filter handles case when 'projects' is undefined
+ // ts.filter handles case when 'projects' is undefined
projects = filter(projects, p => p.languageServiceEnabled);
if (!projects || !projects.length) {
return Errors.ThrowNoProject();
@@ -945,15 +962,8 @@ namespace ts.server {
return completions.entries.reduce((result: protocol.CompletionEntry[], entry: ts.CompletionEntry) => {
if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) {
const { name, kind, kindModifiers, sortText, replacementSpan } = entry;
-
- let convertedSpan: protocol.TextSpan = undefined;
- if (replacementSpan) {
- convertedSpan = {
- start: scriptInfo.positionToLineOffset(replacementSpan.start),
- end: scriptInfo.positionToLineOffset(replacementSpan.start + replacementSpan.length)
- };
- }
-
+ const convertedSpan: protocol.TextSpan =
+ replacementSpan ? this.decorateSpan(replacementSpan, scriptInfo) : undefined;
result.push({ name, kind, kindModifiers, sortText, replacementSpan: convertedSpan });
}
return result;
@@ -1091,22 +1101,13 @@ namespace ts.server {
this.projectService.closeClientFile(file);
}
- private decorateNavigationBarItem(project: Project, fileName: NormalizedPath, items: ts.NavigationBarItem[]): protocol.NavigationBarItem[] {
- if (!items) {
- return undefined;
- }
-
- const scriptInfo = project.getScriptInfoForNormalizedPath(fileName);
-
- return items.map(item => ({
+ private decorateNavigationBarItems(items: ts.NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] {
+ return map(items, item => ({
text: item.text,
kind: item.kind,
kindModifiers: item.kindModifiers,
- spans: item.spans.map(span => ({
- start: scriptInfo.positionToLineOffset(span.start),
- end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span))
- })),
- childItems: this.decorateNavigationBarItem(project, fileName, item.childItems),
+ spans: item.spans.map(span => this.decorateSpan(span, scriptInfo)),
+ childItems: this.decorateNavigationBarItems(item.childItems, scriptInfo),
indent: item.indent
}));
}
@@ -1114,15 +1115,40 @@ namespace ts.server {
private getNavigationBarItems(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationBarItem[] | NavigationBarItem[] {
const { file, project } = this.getFileAndProject(args);
const items = project.getLanguageService(/*ensureSynchronized*/ false).getNavigationBarItems(file);
- if (!items) {
- return undefined;
- }
-
- return simplifiedResult
- ? this.decorateNavigationBarItem(project, file, items)
+ return !items
+ ? undefined
+ : simplifiedResult
+ ? this.decorateNavigationBarItems(items, project.getScriptInfoForNormalizedPath(file))
: items;
}
+ private decorateNavigationTree(tree: ts.NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree {
+ return {
+ text: tree.text,
+ kind: tree.kind,
+ kindModifiers: tree.kindModifiers,
+ spans: tree.spans.map(span => this.decorateSpan(span, scriptInfo)),
+ childItems: map(tree.childItems, item => this.decorateNavigationTree(item, scriptInfo))
+ };
+ }
+
+ private decorateSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan {
+ return {
+ start: scriptInfo.positionToLineOffset(span.start),
+ end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span))
+ };
+ }
+
+ private getNavigationTree(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationTree | NavigationTree {
+ const { file, project } = this.getFileAndProject(args);
+ const tree = project.getLanguageService(/*ensureSynchronized*/ false).getNavigationTree(file);
+ return !tree
+ ? undefined
+ : simplifiedResult
+ ? this.decorateNavigationTree(tree, project.getScriptInfoForNormalizedPath(file))
+ : tree;
+ }
+
private getNavigateToItems(args: protocol.NavtoRequestArgs, simplifiedResult: boolean): protocol.NavtoItem[] | NavigateToItem[] {
const projects = this.getProjects(args);
@@ -1131,7 +1157,7 @@ namespace ts.server {
return combineProjectOutput(
projects,
project => {
- const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isJsOnlyProject());
+ const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject());
if (!navItems) {
return [];
}
@@ -1169,7 +1195,7 @@ namespace ts.server {
else {
return combineProjectOutput(
projects,
- project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isJsOnlyProject()),
+ project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()),
/*comparer*/ undefined,
navigateToItemIsEqualTo);
}
@@ -1259,19 +1285,11 @@ namespace ts.server {
const position = this.getPosition(args, scriptInfo);
const spans = project.getLanguageService(/*ensureSynchronized*/ false).getBraceMatchingAtPosition(file, position);
- if (!spans) {
- return undefined;
- }
- if (simplifiedResult) {
-
- return spans.map(span => ({
- start: scriptInfo.positionToLineOffset(span.start),
- end: scriptInfo.positionToLineOffset(span.start + span.length)
- }));
- }
- else {
- return spans;
- }
+ return !spans
+ ? undefined
+ : simplifiedResult
+ ? spans.map(span => this.decorateSpan(span, scriptInfo))
+ : spans;
}
getDiagnosticsForProject(delay: number, fileName: string) {
@@ -1452,7 +1470,7 @@ namespace ts.server {
[CommandNames.BraceCompletion]: (request: protocol.BraceCompletionRequest) => {
return this.requiredResponse(this.isValidBraceCompletion(request.arguments));
},
- [CommandNames.DocCommentTemplate]: (request: protocol.FileLocationRequest) => {
+ [CommandNames.DocCommentTemplate]: (request: protocol.DocCommentTemplateRequest) => {
return this.requiredResponse(this.getDocCommentTemplate(request.arguments));
},
[CommandNames.Format]: (request: protocol.FormatRequest) => {
@@ -1494,7 +1512,7 @@ namespace ts.server {
[CommandNames.CompilerOptionsDiagnosticsFull]: (request: protocol.CompilerOptionsDiagnosticsRequest) => {
return this.requiredResponse(this.getCompilerOptionsDiagnostics(request.arguments));
},
- [CommandNames.EncodedSemanticClassificationsFull]: (request: protocol.SemanticDiagnosticsRequest) => {
+ [CommandNames.EncodedSemanticClassificationsFull]: (request: protocol.EncodedSemanticClassificationsRequest) => {
return this.requiredResponse(this.getEncodedSemanticClassifications(request.arguments));
},
[CommandNames.Cleanup]: (request: protocol.Request) => {
@@ -1556,6 +1574,12 @@ namespace ts.server {
[CommandNames.NavBarFull]: (request: protocol.FileRequest) => {
return this.requiredResponse(this.getNavigationBarItems(request.arguments, /*simplifiedResult*/ false));
},
+ [CommandNames.NavTree]: (request: protocol.FileRequest) => {
+ return this.requiredResponse(this.getNavigationTree(request.arguments, /*simplifiedResult*/ true));
+ },
+ [CommandNames.NavTreeFull]: (request: protocol.FileRequest) => {
+ return this.requiredResponse(this.getNavigationTree(request.arguments, /*simplifiedResult*/ false));
+ },
[CommandNames.Occurrences]: (request: protocol.FileLocationRequest) => {
return this.requiredResponse(this.getOccurrences(request.arguments));
},
diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json
index 7eb8c28f383..9f907446c03 100644
--- a/src/server/tsconfig.json
+++ b/src/server/tsconfig.json
@@ -22,7 +22,7 @@
"typingsCache.ts",
"project.ts",
"editorServices.ts",
- "protocol.d.ts",
+ "protocol.ts",
"session.ts",
"server.ts"
]
diff --git a/src/server/utilities.ts b/src/server/utilities.ts
index beceab79229..5bd3423e570 100644
--- a/src/server/utilities.ts
+++ b/src/server/utilities.ts
@@ -157,52 +157,53 @@ namespace ts.server {
}
};
}
- function throwLanguageServiceIsDisabledError() {
+ function throwLanguageServiceIsDisabledError(): never {
throw new Error("LanguageService is disabled");
}
export const nullLanguageService: LanguageService = {
- cleanupSemanticCache: (): any => throwLanguageServiceIsDisabledError(),
- getSyntacticDiagnostics: (): any => throwLanguageServiceIsDisabledError(),
- getSemanticDiagnostics: (): any => throwLanguageServiceIsDisabledError(),
- getCompilerOptionsDiagnostics: (): any => throwLanguageServiceIsDisabledError(),
- getSyntacticClassifications: (): any => throwLanguageServiceIsDisabledError(),
- getEncodedSyntacticClassifications: (): any => throwLanguageServiceIsDisabledError(),
- getSemanticClassifications: (): any => throwLanguageServiceIsDisabledError(),
- getEncodedSemanticClassifications: (): any => throwLanguageServiceIsDisabledError(),
- getCompletionsAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- findReferences: (): any => throwLanguageServiceIsDisabledError(),
- getCompletionEntryDetails: (): any => throwLanguageServiceIsDisabledError(),
- getQuickInfoAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- findRenameLocations: (): any => throwLanguageServiceIsDisabledError(),
- getNameOrDottedNameSpan: (): any => throwLanguageServiceIsDisabledError(),
- getBreakpointStatementAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- getBraceMatchingAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- getSignatureHelpItems: (): any => throwLanguageServiceIsDisabledError(),
- getDefinitionAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- getRenameInfo: (): any => throwLanguageServiceIsDisabledError(),
- getTypeDefinitionAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- getReferencesAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- getDocumentHighlights: (): any => throwLanguageServiceIsDisabledError(),
- getOccurrencesAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- getNavigateToItems: (): any => throwLanguageServiceIsDisabledError(),
- getNavigationBarItems: (): any => throwLanguageServiceIsDisabledError(),
- getOutliningSpans: (): any => throwLanguageServiceIsDisabledError(),
- getTodoComments: (): any => throwLanguageServiceIsDisabledError(),
- getIndentationAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- getFormattingEditsForRange: (): any => throwLanguageServiceIsDisabledError(),
- getFormattingEditsForDocument: (): any => throwLanguageServiceIsDisabledError(),
- getFormattingEditsAfterKeystroke: (): any => throwLanguageServiceIsDisabledError(),
- getDocCommentTemplateAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- isValidBraceCompletionAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- getEmitOutput: (): any => throwLanguageServiceIsDisabledError(),
- getProgram: (): any => throwLanguageServiceIsDisabledError(),
- getNonBoundSourceFile: (): any => throwLanguageServiceIsDisabledError(),
- dispose: (): any => throwLanguageServiceIsDisabledError(),
- getCompletionEntrySymbol: (): any => throwLanguageServiceIsDisabledError(),
- getImplementationAtPosition: (): any => throwLanguageServiceIsDisabledError(),
- getSourceFile: (): any => throwLanguageServiceIsDisabledError(),
- getCodeFixesAtPosition: (): any => throwLanguageServiceIsDisabledError()
+ cleanupSemanticCache: throwLanguageServiceIsDisabledError,
+ getSyntacticDiagnostics: throwLanguageServiceIsDisabledError,
+ getSemanticDiagnostics: throwLanguageServiceIsDisabledError,
+ getCompilerOptionsDiagnostics: throwLanguageServiceIsDisabledError,
+ getSyntacticClassifications: throwLanguageServiceIsDisabledError,
+ getEncodedSyntacticClassifications: throwLanguageServiceIsDisabledError,
+ getSemanticClassifications: throwLanguageServiceIsDisabledError,
+ getEncodedSemanticClassifications: throwLanguageServiceIsDisabledError,
+ getCompletionsAtPosition: throwLanguageServiceIsDisabledError,
+ findReferences: throwLanguageServiceIsDisabledError,
+ getCompletionEntryDetails: throwLanguageServiceIsDisabledError,
+ getQuickInfoAtPosition: throwLanguageServiceIsDisabledError,
+ findRenameLocations: throwLanguageServiceIsDisabledError,
+ getNameOrDottedNameSpan: throwLanguageServiceIsDisabledError,
+ getBreakpointStatementAtPosition: throwLanguageServiceIsDisabledError,
+ getBraceMatchingAtPosition: throwLanguageServiceIsDisabledError,
+ getSignatureHelpItems: throwLanguageServiceIsDisabledError,
+ getDefinitionAtPosition: throwLanguageServiceIsDisabledError,
+ getRenameInfo: throwLanguageServiceIsDisabledError,
+ getTypeDefinitionAtPosition: throwLanguageServiceIsDisabledError,
+ getReferencesAtPosition: throwLanguageServiceIsDisabledError,
+ getDocumentHighlights: throwLanguageServiceIsDisabledError,
+ getOccurrencesAtPosition: throwLanguageServiceIsDisabledError,
+ getNavigateToItems: throwLanguageServiceIsDisabledError,
+ getNavigationBarItems: throwLanguageServiceIsDisabledError,
+ getNavigationTree: throwLanguageServiceIsDisabledError,
+ getOutliningSpans: throwLanguageServiceIsDisabledError,
+ getTodoComments: throwLanguageServiceIsDisabledError,
+ getIndentationAtPosition: throwLanguageServiceIsDisabledError,
+ getFormattingEditsForRange: throwLanguageServiceIsDisabledError,
+ getFormattingEditsForDocument: throwLanguageServiceIsDisabledError,
+ getFormattingEditsAfterKeystroke: throwLanguageServiceIsDisabledError,
+ getDocCommentTemplateAtPosition: throwLanguageServiceIsDisabledError,
+ isValidBraceCompletionAtPosition: throwLanguageServiceIsDisabledError,
+ getEmitOutput: throwLanguageServiceIsDisabledError,
+ getProgram: throwLanguageServiceIsDisabledError,
+ getNonBoundSourceFile: throwLanguageServiceIsDisabledError,
+ dispose: throwLanguageServiceIsDisabledError,
+ getCompletionEntrySymbol: throwLanguageServiceIsDisabledError,
+ getImplementationAtPosition: throwLanguageServiceIsDisabledError,
+ getSourceFile: throwLanguageServiceIsDisabledError,
+ getCodeFixesAtPosition: throwLanguageServiceIsDisabledError
};
export interface ServerLanguageServiceHost {
@@ -249,7 +250,7 @@ namespace ts.server {
// another operation was already scheduled for this id - cancel it
this.host.clearTimeout(this.pendingTimeouts[operationId]);
}
- // schedule new operation, pass arguments
+ // schedule new operation, pass arguments
this.pendingTimeouts[operationId] = this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb);
}
diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts
index 0397ae73229..18881ae7660 100644
--- a/src/services/navigationBar.ts
+++ b/src/services/navigationBar.ts
@@ -21,6 +21,13 @@ namespace ts.NavigationBar {
return result;
}
+ export function getNavigationTree(sourceFile: SourceFile): NavigationTree {
+ curSourceFile = sourceFile;
+ const result = convertToTree(rootNavigationBarNode(sourceFile));
+ curSourceFile = undefined;
+ return result;
+ }
+
// Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
let curSourceFile: SourceFile;
function nodeText(node: Node): string {
@@ -502,6 +509,16 @@ namespace ts.NavigationBar {
// NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
const emptyChildItemArray: NavigationBarItem[] = [];
+ function convertToTree(n: NavigationBarNode): NavigationTree {
+ return {
+ text: getItemName(n.node),
+ kind: getNodeKind(n.node),
+ kindModifiers: getNodeModifiers(n.node),
+ spans: getSpans(n),
+ childItems: map(n.children, convertToTree)
+ };
+ }
+
function convertToTopLevelItem(n: NavigationBarNode): NavigationBarItem {
return {
text: getItemName(n.node),
@@ -526,16 +543,16 @@ namespace ts.NavigationBar {
grayed: false
};
}
+ }
- function getSpans(n: NavigationBarNode): TextSpan[] {
- const spans = [getNodeSpan(n.node)];
- if (n.additionalNodes) {
- for (const node of n.additionalNodes) {
- spans.push(getNodeSpan(node));
- }
+ function getSpans(n: NavigationBarNode): TextSpan[] {
+ const spans = [getNodeSpan(n.node)];
+ if (n.additionalNodes) {
+ for (const node of n.additionalNodes) {
+ spans.push(getNodeSpan(node));
}
- return spans;
}
+ return spans;
}
function getModuleName(moduleDeclaration: ModuleDeclaration): string {
diff --git a/src/services/services.ts b/src/services/services.ts
index cdad39477ce..666644aca1b 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -1523,9 +1523,11 @@ namespace ts {
}
function getNavigationBarItems(fileName: string): NavigationBarItem[] {
- const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
+ return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName));
+ }
- return NavigationBar.getNavigationBarItems(sourceFile);
+ function getNavigationTree(fileName: string): NavigationTree {
+ return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName));
}
function isTsOrTsxFile(fileName: string): boolean {
@@ -1903,6 +1905,7 @@ namespace ts {
getRenameInfo,
findRenameLocations,
getNavigationBarItems,
+ getNavigationTree,
getOutliningSpans,
getTodoComments,
getBraceMatchingAtPosition,
diff --git a/src/services/shims.ts b/src/services/shims.ts
index 56ab852606c..7ed1786640d 100644
--- a/src/services/shims.ts
+++ b/src/services/shims.ts
@@ -224,6 +224,9 @@ namespace ts {
*/
getNavigationBarItems(fileName: string): string;
+ /** Returns a JSON-encoded value of the type ts.NavigationTree. */
+ getNavigationTree(fileName: string): string;
+
/**
* Returns a JSON-encoded value of the type:
* { textSpan: { start: number, length: number }; hintSpan: { start: number, length: number }; bannerText: string; autoCollapse: boolean } [] = [];
@@ -971,6 +974,13 @@ namespace ts {
);
}
+ public getNavigationTree(fileName: string): string {
+ return this.forwardJSONCall(
+ `getNavigationTree('${fileName}')`,
+ () => this.languageService.getNavigationTree(fileName)
+ );
+ }
+
public getOutliningSpans(fileName: string): string {
return this.forwardJSONCall(
`getOutliningSpans('${fileName}')`,
diff --git a/src/services/types.ts b/src/services/types.ts
index fafe274bce1..3d2bcf4c360 100644
--- a/src/services/types.ts
+++ b/src/services/types.ts
@@ -225,6 +225,7 @@ namespace ts {
getNavigateToItems(searchValue: string, maxResultCount?: number, fileName?: string, excludeDtsFiles?: boolean): NavigateToItem[];
getNavigationBarItems(fileName: string): NavigationBarItem[];
+ getNavigationTree(fileName: string): NavigationTree;
getOutliningSpans(fileName: string): OutliningSpan[];
getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[];
@@ -266,6 +267,12 @@ namespace ts {
classificationType: string; // ClassificationTypeNames
}
+ /**
+ * Navigation bar interface designed for visual studio's dual-column layout.
+ * This does not form a proper tree.
+ * The navbar is returned as a list of top-level items, each of which has a list of child items.
+ * Child items always have an empty array for their `childItems`.
+ */
export interface NavigationBarItem {
text: string;
kind: string;
@@ -277,6 +284,26 @@ namespace ts {
grayed: boolean;
}
+ /**
+ * Node in a tree of nested declarations in a file.
+ * The top node is always a script or module node.
+ */
+ export interface NavigationTree {
+ /** Name of the declaration, or a short description, e.g. "". */
+ text: string;
+ /** A ScriptElementKind */
+ kind: string;
+ /** ScriptElementKindModifier separated by commas, e.g. "public,abstract" */
+ kindModifiers: string;
+ /**
+ * Spans of the nodes that generated this declaration.
+ * There will be more than one if this is the result of merging.
+ */
+ spans: TextSpan[];
+ /** Present if non-empty */
+ childItems?: NavigationTree[];
+ }
+
export interface TodoCommentDescriptor {
text: string;
priority: number;
@@ -376,11 +403,11 @@ namespace ts {
export interface EditorSettings {
baseIndentSize?: number;
- indentSize: number;
- tabSize: number;
- newLineCharacter: string;
- convertTabsToSpaces: boolean;
- indentStyle: IndentStyle;
+ indentSize?: number;
+ tabSize?: number;
+ newLineCharacter?: string;
+ convertTabsToSpaces?: boolean;
+ indentStyle?: IndentStyle;
}
/* @deprecated - consider using FormatCodeSettings instead */
@@ -401,19 +428,19 @@ namespace ts {
}
export interface FormatCodeSettings extends EditorSettings {
- insertSpaceAfterCommaDelimiter: boolean;
- insertSpaceAfterSemicolonInForStatements: boolean;
- insertSpaceBeforeAndAfterBinaryOperators: boolean;
- insertSpaceAfterKeywordsInControlFlowStatements: boolean;
- insertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
- insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
- insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
+ insertSpaceAfterCommaDelimiter?: boolean;
+ insertSpaceAfterSemicolonInForStatements?: boolean;
+ insertSpaceBeforeAndAfterBinaryOperators?: boolean;
+ insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
+ insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
+ insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
+ insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
- insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
- insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: boolean;
+ insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
+ insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
insertSpaceAfterTypeAssertion?: boolean;
- placeOpenBraceOnNewLineForFunctions: boolean;
- placeOpenBraceOnNewLineForControlBlocks: boolean;
+ placeOpenBraceOnNewLineForFunctions?: boolean;
+ placeOpenBraceOnNewLineForControlBlocks?: boolean;
}
export interface DefinitionInfo {
diff --git a/tests/baselines/reference/declFileTypeAnnotationStringLiteral.types b/tests/baselines/reference/declFileTypeAnnotationStringLiteral.types
index 6d9c17b4ab9..b1a85f3fc30 100644
--- a/tests/baselines/reference/declFileTypeAnnotationStringLiteral.types
+++ b/tests/baselines/reference/declFileTypeAnnotationStringLiteral.types
@@ -23,7 +23,7 @@ function foo(a: string): string | number {
return a.length;
>a.length : number
->a : string
+>a : "hello"
>length : number
}
diff --git a/tests/baselines/reference/literalTypes1.types b/tests/baselines/reference/literalTypes1.types
index faff485d45a..1baaad3ff88 100644
--- a/tests/baselines/reference/literalTypes1.types
+++ b/tests/baselines/reference/literalTypes1.types
@@ -129,7 +129,7 @@ function f4(x: 0 | 1 | true | string) {
>"def" : "def"
x;
->x : string
+>x : "abc" | "def"
break;
case null:
@@ -163,7 +163,7 @@ function f5(x: string | number | boolean) {
>"abc" : "abc"
x;
->x : string
+>x : "abc"
break;
case 0:
@@ -173,7 +173,7 @@ function f5(x: string | number | boolean) {
>1 : 1
x;
->x : number
+>x : 0 | 1
break;
case true:
@@ -190,7 +190,7 @@ function f5(x: string | number | boolean) {
>123 : 123
x;
->x : string | number
+>x : "hello" | 123
break;
default:
diff --git a/tests/baselines/reference/literalTypes3.js b/tests/baselines/reference/literalTypes3.js
new file mode 100644
index 00000000000..1989bb1d5a1
--- /dev/null
+++ b/tests/baselines/reference/literalTypes3.js
@@ -0,0 +1,125 @@
+//// [literalTypes3.ts]
+
+function f1(s: string) {
+ if (s === "foo") {
+ s; // "foo"
+ }
+ if (s === "foo" || s === "bar") {
+ s; // "foo" | "bar"
+ }
+}
+
+function f2(s: string) {
+ switch (s) {
+ case "foo":
+ case "bar":
+ s; // "foo" | "bar"
+ case "baz":
+ s; // "foo" | "bar" | "baz"
+ break;
+ default:
+ s; // string
+ }
+}
+
+function f3(s: string) {
+ return s === "foo" || s === "bar" ? s : undefined; // "foo" | "bar" | undefined
+}
+
+function f4(x: number) {
+ if (x === 1 || x === 2) {
+ return x; // 1 | 2
+ }
+ throw new Error();
+}
+
+function f5(x: number, y: 1 | 2) {
+ if (x === 0 || x === y) {
+ x; // 0 | 1 | 2
+ }
+}
+
+function f6(x: number, y: 1 | 2) {
+ if (y === x || 0 === x) {
+ x; // 0 | 1 | 2
+ }
+}
+
+function f7(x: number | "foo" | "bar", y: 1 | 2 | string) {
+ if (x === y) {
+ x; // "foo" | "bar" | 1 | 2
+ }
+}
+
+function f8(x: number | "foo" | "bar") {
+ switch (x) {
+ case 1:
+ case 2:
+ x; // 1 | 2
+ break;
+ case "foo":
+ x; // "foo"
+ break;
+ default:
+ x; // number | "bar"
+ }
+}
+
+//// [literalTypes3.js]
+function f1(s) {
+ if (s === "foo") {
+ s; // "foo"
+ }
+ if (s === "foo" || s === "bar") {
+ s; // "foo" | "bar"
+ }
+}
+function f2(s) {
+ switch (s) {
+ case "foo":
+ case "bar":
+ s; // "foo" | "bar"
+ case "baz":
+ s; // "foo" | "bar" | "baz"
+ break;
+ default:
+ s; // string
+ }
+}
+function f3(s) {
+ return s === "foo" || s === "bar" ? s : undefined; // "foo" | "bar" | undefined
+}
+function f4(x) {
+ if (x === 1 || x === 2) {
+ return x; // 1 | 2
+ }
+ throw new Error();
+}
+function f5(x, y) {
+ if (x === 0 || x === y) {
+ x; // 0 | 1 | 2
+ }
+}
+function f6(x, y) {
+ if (y === x || 0 === x) {
+ x; // 0 | 1 | 2
+ }
+}
+function f7(x, y) {
+ if (x === y) {
+ x; // "foo" | "bar" | 1 | 2
+ }
+}
+function f8(x) {
+ switch (x) {
+ case 1:
+ case 2:
+ x; // 1 | 2
+ break;
+ case "foo":
+ x; // "foo"
+ break;
+ default:
+ x; // number | "bar"
+ }
+}
diff --git a/tests/baselines/reference/literalTypes3.symbols b/tests/baselines/reference/literalTypes3.symbols
new file mode 100644
index 00000000000..6cc7ab007e6
--- /dev/null
+++ b/tests/baselines/reference/literalTypes3.symbols
@@ -0,0 +1,137 @@
+=== tests/cases/conformance/types/literal/literalTypes3.ts ===
+
+function f1(s: string) {
+>f1 : Symbol(f1, Decl(literalTypes3.ts, 0, 0))
+>s : Symbol(s, Decl(literalTypes3.ts, 1, 12))
+
+ if (s === "foo") {
+>s : Symbol(s, Decl(literalTypes3.ts, 1, 12))
+
+ s; // "foo"
+>s : Symbol(s, Decl(literalTypes3.ts, 1, 12))
+ }
+ if (s === "foo" || s === "bar") {
+>s : Symbol(s, Decl(literalTypes3.ts, 1, 12))
+>s : Symbol(s, Decl(literalTypes3.ts, 1, 12))
+
+ s; // "foo" | "bar"
+>s : Symbol(s, Decl(literalTypes3.ts, 1, 12))
+ }
+}
+
+function f2(s: string) {
+>f2 : Symbol(f2, Decl(literalTypes3.ts, 8, 1))
+>s : Symbol(s, Decl(literalTypes3.ts, 10, 12))
+
+ switch (s) {
+>s : Symbol(s, Decl(literalTypes3.ts, 10, 12))
+
+ case "foo":
+ case "bar":
+ s; // "foo" | "bar"
+>s : Symbol(s, Decl(literalTypes3.ts, 10, 12))
+
+ case "baz":
+ s; // "foo" | "bar" | "baz"
+>s : Symbol(s, Decl(literalTypes3.ts, 10, 12))
+
+ break;
+ default:
+ s; // string
+>s : Symbol(s, Decl(literalTypes3.ts, 10, 12))
+ }
+}
+
+function f3(s: string) {
+>f3 : Symbol(f3, Decl(literalTypes3.ts, 21, 1))
+>s : Symbol(s, Decl(literalTypes3.ts, 23, 12))
+
+ return s === "foo" || s === "bar" ? s : undefined; // "foo" | "bar" | undefined
+>s : Symbol(s, Decl(literalTypes3.ts, 23, 12))
+>s : Symbol(s, Decl(literalTypes3.ts, 23, 12))
+>s : Symbol(s, Decl(literalTypes3.ts, 23, 12))
+>undefined : Symbol(undefined)
+}
+
+function f4(x: number) {
+>f4 : Symbol(f4, Decl(literalTypes3.ts, 25, 1))
+>x : Symbol(x, Decl(literalTypes3.ts, 27, 12))
+
+ if (x === 1 || x === 2) {
+>x : Symbol(x, Decl(literalTypes3.ts, 27, 12))
+>x : Symbol(x, Decl(literalTypes3.ts, 27, 12))
+
+ return x; // 1 | 2
+>x : Symbol(x, Decl(literalTypes3.ts, 27, 12))
+ }
+ throw new Error();
+>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
+}
+
+function f5(x: number, y: 1 | 2) {
+>f5 : Symbol(f5, Decl(literalTypes3.ts, 32, 1))
+>x : Symbol(x, Decl(literalTypes3.ts, 34, 12))
+>y : Symbol(y, Decl(literalTypes3.ts, 34, 22))
+
+ if (x === 0 || x === y) {
+>x : Symbol(x, Decl(literalTypes3.ts, 34, 12))
+>x : Symbol(x, Decl(literalTypes3.ts, 34, 12))
+>y : Symbol(y, Decl(literalTypes3.ts, 34, 22))
+
+ x; // 0 | 1 | 2
+>x : Symbol(x, Decl(literalTypes3.ts, 34, 12))
+ }
+}
+
+function f6(x: number, y: 1 | 2) {
+>f6 : Symbol(f6, Decl(literalTypes3.ts, 38, 1))
+>x : Symbol(x, Decl(literalTypes3.ts, 40, 12))
+>y : Symbol(y, Decl(literalTypes3.ts, 40, 22))
+
+ if (y === x || 0 === x) {
+>y : Symbol(y, Decl(literalTypes3.ts, 40, 22))
+>x : Symbol(x, Decl(literalTypes3.ts, 40, 12))
+>x : Symbol(x, Decl(literalTypes3.ts, 40, 12))
+
+ x; // 0 | 1 | 2
+>x : Symbol(x, Decl(literalTypes3.ts, 40, 12))
+ }
+}
+
+function f7(x: number | "foo" | "bar", y: 1 | 2 | string) {
+>f7 : Symbol(f7, Decl(literalTypes3.ts, 44, 1))
+>x : Symbol(x, Decl(literalTypes3.ts, 46, 12))
+>y : Symbol(y, Decl(literalTypes3.ts, 46, 38))
+
+ if (x === y) {
+>x : Symbol(x, Decl(literalTypes3.ts, 46, 12))
+>y : Symbol(y, Decl(literalTypes3.ts, 46, 38))
+
+ x; // "foo" | "bar" | 1 | 2
+>x : Symbol(x, Decl(literalTypes3.ts, 46, 12))
+ }
+}
+
+function f8(x: number | "foo" | "bar") {
+>f8 : Symbol(f8, Decl(literalTypes3.ts, 50, 1))
+>x : Symbol(x, Decl(literalTypes3.ts, 52, 12))
+
+ switch (x) {
+>x : Symbol(x, Decl(literalTypes3.ts, 52, 12))
+
+ case 1:
+ case 2:
+ x; // 1 | 2
+>x : Symbol(x, Decl(literalTypes3.ts, 52, 12))
+
+ break;
+ case "foo":
+ x; // "foo"
+>x : Symbol(x, Decl(literalTypes3.ts, 52, 12))
+
+ break;
+ default:
+ x; // number | "bar"
+>x : Symbol(x, Decl(literalTypes3.ts, 52, 12))
+ }
+}
diff --git a/tests/baselines/reference/literalTypes3.types b/tests/baselines/reference/literalTypes3.types
new file mode 100644
index 00000000000..6161bc4b72a
--- /dev/null
+++ b/tests/baselines/reference/literalTypes3.types
@@ -0,0 +1,177 @@
+=== tests/cases/conformance/types/literal/literalTypes3.ts ===
+
+function f1(s: string) {
+>f1 : (s: string) => void
+>s : string
+
+ if (s === "foo") {
+>s === "foo" : boolean
+>s : string
+>"foo" : "foo"
+
+ s; // "foo"
+>s : "foo"
+ }
+ if (s === "foo" || s === "bar") {
+>s === "foo" || s === "bar" : boolean
+>s === "foo" : boolean
+>s : string
+>"foo" : "foo"
+>s === "bar" : boolean
+>s : string
+>"bar" : "bar"
+
+ s; // "foo" | "bar"
+>s : "foo" | "bar"
+ }
+}
+
+function f2(s: string) {
+>f2 : (s: string) => void
+>s : string
+
+ switch (s) {
+>s : string
+
+ case "foo":
+>"foo" : "foo"
+
+ case "bar":
+>"bar" : "bar"
+
+ s; // "foo" | "bar"
+>s : "foo" | "bar"
+
+ case "baz":
+>"baz" : "baz"
+
+ s; // "foo" | "bar" | "baz"
+>s : "foo" | "bar" | "baz"
+
+ break;
+ default:
+ s; // string
+>s : string
+ }
+}
+
+function f3(s: string) {
+>f3 : (s: string) => "foo" | "bar" | undefined
+>s : string
+
+ return s === "foo" || s === "bar" ? s : undefined; // "foo" | "bar" | undefined
+>s === "foo" || s === "bar" ? s : undefined : "foo" | "bar" | undefined
+>s === "foo" || s === "bar" : boolean
+>s === "foo" : boolean
+>s : string
+>"foo" : "foo"
+>s === "bar" : boolean
+>s : string
+>"bar" : "bar"
+>s : "foo" | "bar"
+>undefined : undefined
+}
+
+function f4(x: number) {
+>f4 : (x: number) => 1 | 2
+>x : number
+
+ if (x === 1 || x === 2) {
+>x === 1 || x === 2 : boolean
+>x === 1 : boolean
+>x : number
+>1 : 1
+>x === 2 : boolean
+>x : number
+>2 : 2
+
+ return x; // 1 | 2
+>x : 1 | 2
+ }
+ throw new Error();
+>new Error() : Error
+>Error : ErrorConstructor
+}
+
+function f5(x: number, y: 1 | 2) {
+>f5 : (x: number, y: 1 | 2) => void
+>x : number
+>y : 1 | 2
+
+ if (x === 0 || x === y) {
+>x === 0 || x === y : boolean
+>x === 0 : boolean
+>x : number
+>0 : 0
+>x === y : boolean
+>x : number
+>y : 1 | 2
+
+ x; // 0 | 1 | 2
+>x : 1 | 2 | 0
+ }
+}
+
+function f6(x: number, y: 1 | 2) {
+>f6 : (x: number, y: 1 | 2) => void
+>x : number
+>y : 1 | 2
+
+ if (y === x || 0 === x) {
+>y === x || 0 === x : boolean
+>y === x : boolean
+>y : 1 | 2
+>x : number
+>0 === x : boolean
+>0 : 0
+>x : number
+
+ x; // 0 | 1 | 2
+>x : 1 | 2 | 0
+ }
+}
+
+function f7(x: number | "foo" | "bar", y: 1 | 2 | string) {
+>f7 : (x: number | "foo" | "bar", y: string | 1 | 2) => void
+>x : number | "foo" | "bar"
+>y : string | 1 | 2
+
+ if (x === y) {
+>x === y : boolean
+>x : number | "foo" | "bar"
+>y : string | 1 | 2
+
+ x; // "foo" | "bar" | 1 | 2
+>x : "foo" | "bar" | 1 | 2
+ }
+}
+
+function f8(x: number | "foo" | "bar") {
+>f8 : (x: number | "foo" | "bar") => void
+>x : number | "foo" | "bar"
+
+ switch (x) {
+>x : number | "foo" | "bar"
+
+ case 1:
+>1 : 1
+
+ case 2:
+>2 : 2
+
+ x; // 1 | 2
+>x : 1 | 2
+
+ break;
+ case "foo":
+>"foo" : "foo"
+
+ x; // "foo"
+>x : "foo"
+
+ break;
+ default:
+ x; // number | "bar"
+>x : number | "bar"
+ }
+}
diff --git a/tests/baselines/reference/narrowedConstInMethod.js b/tests/baselines/reference/narrowedConstInMethod.js
new file mode 100644
index 00000000000..f4cdc3def91
--- /dev/null
+++ b/tests/baselines/reference/narrowedConstInMethod.js
@@ -0,0 +1,40 @@
+//// [narrowedConstInMethod.ts]
+
+function f() {
+ const x: string | null = {};
+ if (x !== null) {
+ return {
+ bar() { return x.length; } // Error: possibly null x
+ };
+ }
+}
+
+function f2() {
+ const x: string | null = {};
+ if (x !== null) {
+ return class {
+ bar() { return x.length; } // Error: possibly null x
+ };
+ }
+}
+
+//// [narrowedConstInMethod.js]
+function f() {
+ var x = {};
+ if (x !== null) {
+ return {
+ bar: function () { return x.length; } // Error: possibly null x
+ };
+ }
+}
+function f2() {
+ var x = {};
+ if (x !== null) {
+ return (function () {
+ function class_1() {
+ }
+ class_1.prototype.bar = function () { return x.length; }; // Error: possibly null x
+ return class_1;
+ }());
+ }
+}
diff --git a/tests/baselines/reference/narrowedConstInMethod.symbols b/tests/baselines/reference/narrowedConstInMethod.symbols
new file mode 100644
index 00000000000..1fd05dcea5e
--- /dev/null
+++ b/tests/baselines/reference/narrowedConstInMethod.symbols
@@ -0,0 +1,41 @@
+=== tests/cases/compiler/narrowedConstInMethod.ts ===
+
+function f() {
+>f : Symbol(f, Decl(narrowedConstInMethod.ts, 0, 0))
+
+ const x: string | null = {};
+>x : Symbol(x, Decl(narrowedConstInMethod.ts, 2, 9))
+
+ if (x !== null) {
+>x : Symbol(x, Decl(narrowedConstInMethod.ts, 2, 9))
+
+ return {
+ bar() { return x.length; } // Error: possibly null x
+>bar : Symbol(bar, Decl(narrowedConstInMethod.ts, 4, 16))
+>x.length : Symbol(String.length, Decl(lib.d.ts, --, --))
+>x : Symbol(x, Decl(narrowedConstInMethod.ts, 2, 9))
+>length : Symbol(String.length, Decl(lib.d.ts, --, --))
+
+ };
+ }
+}
+
+function f2() {
+>f2 : Symbol(f2, Decl(narrowedConstInMethod.ts, 8, 1))
+
+ const x: string | null = {};
+>x : Symbol(x, Decl(narrowedConstInMethod.ts, 11, 9))
+
+ if (x !== null) {
+>x : Symbol(x, Decl(narrowedConstInMethod.ts, 11, 9))
+
+ return class {
+ bar() { return x.length; } // Error: possibly null x
+>bar : Symbol((Anonymous class).bar, Decl(narrowedConstInMethod.ts, 13, 22))
+>x.length : Symbol(String.length, Decl(lib.d.ts, --, --))
+>x : Symbol(x, Decl(narrowedConstInMethod.ts, 11, 9))
+>length : Symbol(String.length, Decl(lib.d.ts, --, --))
+
+ };
+ }
+}
diff --git a/tests/baselines/reference/narrowedConstInMethod.types b/tests/baselines/reference/narrowedConstInMethod.types
new file mode 100644
index 00000000000..a73f2edfccb
--- /dev/null
+++ b/tests/baselines/reference/narrowedConstInMethod.types
@@ -0,0 +1,55 @@
+=== tests/cases/compiler/narrowedConstInMethod.ts ===
+
+function f() {
+>f : () => { bar(): number; } | undefined
+
+ const x: string | null = {};
+>x : string | null
+>null : null
+>{} : any
+>{} : {}
+
+ if (x !== null) {
+>x !== null : boolean
+>x : string | null
+>null : null
+
+ return {
+>{ bar() { return x.length; } // Error: possibly null x } : { bar(): number; }
+
+ bar() { return x.length; } // Error: possibly null x
+>bar : () => number
+>x.length : number
+>x : string
+>length : number
+
+ };
+ }
+}
+
+function f2() {
+>f2 : () => typeof (Anonymous class) | undefined
+
+ const x: string | null = {};
+>x : string | null
+>null : null
+>{} : any
+>{} : {}
+
+ if (x !== null) {
+>x !== null : boolean
+>x : string | null
+>null : null
+
+ return class {
+>class { bar() { return x.length; } // Error: possibly null x } : typeof (Anonymous class)
+
+ bar() { return x.length; } // Error: possibly null x
+>bar : () => number
+>x.length : number
+>x : string
+>length : number
+
+ };
+ }
+}
diff --git a/tests/baselines/reference/sourceMapValidationIfElse.types b/tests/baselines/reference/sourceMapValidationIfElse.types
index b4a76d55647..87103b792e7 100644
--- a/tests/baselines/reference/sourceMapValidationIfElse.types
+++ b/tests/baselines/reference/sourceMapValidationIfElse.types
@@ -10,7 +10,7 @@ if (i == 10) {
i++;
>i++ : number
->i : number
+>i : 10
} else
{
@@ -22,7 +22,7 @@ if (i == 10)
{
i++;
>i++ : number
->i : number
+>i : 10
}
else if (i == 20) {
>i == 20 : boolean
@@ -31,7 +31,7 @@ else if (i == 20) {
i--;
>i-- : number
->i : number
+>i : 20
} else if (i == 30) {
>i == 30 : boolean
diff --git a/tests/baselines/reference/sourceMapValidationSwitch.types b/tests/baselines/reference/sourceMapValidationSwitch.types
index 9df86ee2132..359cabbfabe 100644
--- a/tests/baselines/reference/sourceMapValidationSwitch.types
+++ b/tests/baselines/reference/sourceMapValidationSwitch.types
@@ -11,7 +11,7 @@ switch (x) {
x++;
>x++ : number
->x : number
+>x : 5
break;
case 10:
@@ -19,7 +19,7 @@ switch (x) {
{
x--;
>x-- : number
->x : number
+>x : 10
break;
}
@@ -39,7 +39,7 @@ switch (x)
x++;
>x++ : number
->x : number
+>x : 5
break;
case 10:
@@ -47,7 +47,7 @@ switch (x)
{
x--;
>x-- : number
->x : number
+>x : 10
break;
}
diff --git a/tests/baselines/reference/sourceMapValidationWhile.types b/tests/baselines/reference/sourceMapValidationWhile.types
index 71b50d86736..8769d98ef25 100644
--- a/tests/baselines/reference/sourceMapValidationWhile.types
+++ b/tests/baselines/reference/sourceMapValidationWhile.types
@@ -10,7 +10,7 @@ while (a == 10) {
a++;
>a++ : number
->a : number
+>a : 10
}
while (a == 10)
>a == 10 : boolean
@@ -19,5 +19,5 @@ while (a == 10)
{
a++;
>a++ : number
->a : number
+>a : 10
}
diff --git a/tests/baselines/reference/stringLiteralTypesInUnionTypes02.types b/tests/baselines/reference/stringLiteralTypesInUnionTypes02.types
index 0be891ade44..85378108298 100644
--- a/tests/baselines/reference/stringLiteralTypesInUnionTypes02.types
+++ b/tests/baselines/reference/stringLiteralTypesInUnionTypes02.types
@@ -19,7 +19,7 @@ if (x === "foo") {
let a = x;
>a : string
->x : string
+>x : "foo"
}
else if (x !== "bar") {
>x !== "bar" : boolean
@@ -35,7 +35,7 @@ else if (x !== "bar") {
else {
let c = x;
>c : string
->x : string
+>x : "bar"
let d = y;
>d : string
@@ -43,7 +43,7 @@ else {
let e: (typeof x) | (typeof y) = c || d;
>e : string
->x : string
+>x : "bar"
>y : string
>c || d : string
>c : string
diff --git a/tests/baselines/reference/throwInEnclosingStatements.types b/tests/baselines/reference/throwInEnclosingStatements.types
index 4955b9243ae..2d99ac435ae 100644
--- a/tests/baselines/reference/throwInEnclosingStatements.types
+++ b/tests/baselines/reference/throwInEnclosingStatements.types
@@ -25,7 +25,7 @@ switch (y) {
>'a' : "a"
throw y;
->y : string
+>y : "a"
default:
throw y;
diff --git a/tests/baselines/reference/umd5.errors.txt b/tests/baselines/reference/umd5.errors.txt
index 9628ad738db..5595de8de29 100644
--- a/tests/baselines/reference/umd5.errors.txt
+++ b/tests/baselines/reference/umd5.errors.txt
@@ -1,4 +1,4 @@
-tests/cases/conformance/externalModules/a.ts(6,9): error TS2686: Identifier 'Foo' must be imported from a module
+tests/cases/conformance/externalModules/a.ts(6,9): error TS2686: 'Foo' refers to a UMD global, but the current file is a module. Consider adding an import instead.
==== tests/cases/conformance/externalModules/a.ts (1 errors) ====
@@ -9,7 +9,7 @@ tests/cases/conformance/externalModules/a.ts(6,9): error TS2686: Identifier 'Foo
// should error
let z = Foo;
~~~
-!!! error TS2686: Identifier 'Foo' must be imported from a module
+!!! error TS2686: 'Foo' refers to a UMD global, but the current file is a module. Consider adding an import instead.
==== tests/cases/conformance/externalModules/foo.d.ts (0 errors) ====
diff --git a/tests/baselines/reference/umd8.errors.txt b/tests/baselines/reference/umd8.errors.txt
index 9396c8c5450..26c8adef561 100644
--- a/tests/baselines/reference/umd8.errors.txt
+++ b/tests/baselines/reference/umd8.errors.txt
@@ -1,4 +1,4 @@
-tests/cases/conformance/externalModules/a.ts(7,14): error TS2686: Identifier 'Foo' must be imported from a module
+tests/cases/conformance/externalModules/a.ts(7,14): error TS2686: 'Foo' refers to a UMD global, but the current file is a module. Consider adding an import instead.
==== tests/cases/conformance/externalModules/a.ts (1 errors) ====
@@ -10,7 +10,7 @@ tests/cases/conformance/externalModules/a.ts(7,14): error TS2686: Identifier 'Fo
let z: Foo.SubThing; // OK in ns position
let x: any = Foo; // Not OK in value position
~~~
-!!! error TS2686: Identifier 'Foo' must be imported from a module
+!!! error TS2686: 'Foo' refers to a UMD global, but the current file is a module. Consider adding an import instead.
==== tests/cases/conformance/externalModules/foo.d.ts (0 errors) ====
diff --git a/tests/cases/compiler/narrowedConstInMethod.ts b/tests/cases/compiler/narrowedConstInMethod.ts
new file mode 100644
index 00000000000..3ddf97a8df3
--- /dev/null
+++ b/tests/cases/compiler/narrowedConstInMethod.ts
@@ -0,0 +1,19 @@
+// @strictNullChecks: true
+
+function f() {
+ const x: string | null = {};
+ if (x !== null) {
+ return {
+ bar() { return x.length; } // Error: possibly null x
+ };
+ }
+}
+
+function f2() {
+ const x: string | null = {};
+ if (x !== null) {
+ return class {
+ bar() { return x.length; } // Error: possibly null x
+ };
+ }
+}
\ No newline at end of file
diff --git a/tests/cases/conformance/types/literal/literalTypes3.ts b/tests/cases/conformance/types/literal/literalTypes3.ts
new file mode 100644
index 00000000000..2aa3f1020e2
--- /dev/null
+++ b/tests/cases/conformance/types/literal/literalTypes3.ts
@@ -0,0 +1,66 @@
+// @strictNullChecks: true
+
+function f1(s: string) {
+ if (s === "foo") {
+ s; // "foo"
+ }
+ if (s === "foo" || s === "bar") {
+ s; // "foo" | "bar"
+ }
+}
+
+function f2(s: string) {
+ switch (s) {
+ case "foo":
+ case "bar":
+ s; // "foo" | "bar"
+ case "baz":
+ s; // "foo" | "bar" | "baz"
+ break;
+ default:
+ s; // string
+ }
+}
+
+function f3(s: string) {
+ return s === "foo" || s === "bar" ? s : undefined; // "foo" | "bar" | undefined
+}
+
+function f4(x: number) {
+ if (x === 1 || x === 2) {
+ return x; // 1 | 2
+ }
+ throw new Error();
+}
+
+function f5(x: number, y: 1 | 2) {
+ if (x === 0 || x === y) {
+ x; // 0 | 1 | 2
+ }
+}
+
+function f6(x: number, y: 1 | 2) {
+ if (y === x || 0 === x) {
+ x; // 0 | 1 | 2
+ }
+}
+
+function f7(x: number | "foo" | "bar", y: 1 | 2 | string) {
+ if (x === y) {
+ x; // "foo" | "bar" | 1 | 2
+ }
+}
+
+function f8(x: number | "foo" | "bar") {
+ switch (x) {
+ case 1:
+ case 2:
+ x; // 1 | 2
+ break;
+ case "foo":
+ x; // "foo"
+ break;
+ default:
+ x; // number | "bar"
+ }
+}
\ No newline at end of file
diff --git a/tests/cases/fourslash/completionListInImportClause04.ts b/tests/cases/fourslash/completionListInImportClause04.ts
new file mode 100644
index 00000000000..672c754e807
--- /dev/null
+++ b/tests/cases/fourslash/completionListInImportClause04.ts
@@ -0,0 +1,20 @@
+///
+
+// @Filename: foo.d.ts
+//// declare class Foo {
+//// static prop1(x: number): number;
+//// static prop1(x: string): string;
+//// static prop2(x: boolean): boolean;
+//// }
+//// export = Foo; /*2*/
+
+// @Filename: app.ts
+////import {/*1*/} from './foo';
+
+goTo.marker('1');
+verify.completionListContains('prop1');
+verify.completionListContains('prop2');
+verify.not.completionListContains('Foo');
+verify.numberOfErrorsInCurrentFile(0);
+goTo.marker('2');
+verify.numberOfErrorsInCurrentFile(0);
diff --git a/tests/cases/fourslash/deleteClassWithEnumPresent.ts b/tests/cases/fourslash/deleteClassWithEnumPresent.ts
index eb40a27bcd7..8914e0020a0 100644
--- a/tests/cases/fourslash/deleteClassWithEnumPresent.ts
+++ b/tests/cases/fourslash/deleteClassWithEnumPresent.ts
@@ -5,6 +5,32 @@
goTo.marker();
edit.deleteAtCaret('class Bar { }'.length);
+
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "Foo",
+ "kind": "enum",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "const"
+ },
+ {
+ "text": "b",
+ "kind": "const"
+ },
+ {
+ "text": "c",
+ "kind": "const"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts
index 5e8666e8670..0a72d295295 100644
--- a/tests/cases/fourslash/fourslash.ts
+++ b/tests/cases/fourslash/fourslash.ts
@@ -212,6 +212,7 @@ declare namespace FourSlashInterface {
codeFixAtPosition(expectedText: string, errorCode?: number): void;
navigationBar(json: any): void;
+ navigationTree(json: any): void;
navigationItemsListCount(count: number, searchValue: string, matchKind?: string, fileName?: string): void;
navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parentName?: string): void;
occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void;
diff --git a/tests/cases/fourslash/getNavigationBarItems.ts b/tests/cases/fourslash/getNavigationBarItems.ts
index 8041ba3b464..4bcfc3e18aa 100644
--- a/tests/cases/fourslash/getNavigationBarItems.ts
+++ b/tests/cases/fourslash/getNavigationBarItems.ts
@@ -5,6 +5,27 @@
//// ["bar"]: string;
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "C",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "[\"bar\"]",
+ "kind": "property"
+ },
+ {
+ "text": "foo",
+ "kind": "property"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
@@ -31,4 +52,4 @@ verify.navigationBar([
],
"indent": 1
}
-])
+]);
diff --git a/tests/cases/fourslash/navbar_const.ts b/tests/cases/fourslash/navbar_const.ts
index faaedb54482..2d3e3b919d0 100644
--- a/tests/cases/fourslash/navbar_const.ts
+++ b/tests/cases/fourslash/navbar_const.ts
@@ -2,6 +2,17 @@
//// const c = 0;
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "c",
+ "kind": "const"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navbar_contains-no-duplicates.ts b/tests/cases/fourslash/navbar_contains-no-duplicates.ts
index ba48c4a93dd..f4b52bb09a1 100644
--- a/tests/cases/fourslash/navbar_contains-no-duplicates.ts
+++ b/tests/cases/fourslash/navbar_contains-no-duplicates.ts
@@ -27,6 +27,83 @@
//// export var x = 3;
//// }
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "ABC",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "foo",
+ "kind": "method",
+ "kindModifiers": "public"
+ }
+ ]
+ },
+ {
+ "text": "ABC",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "x",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+ },
+ {
+ "text": "Windows",
+ "kind": "module",
+ "kindModifiers": "declare",
+ "childItems": [
+ {
+ "text": "Foundation",
+ "kind": "module",
+ "kindModifiers": "export,declare",
+ "childItems": [
+ {
+ "text": "A",
+ "kind": "var",
+ "kindModifiers": "export,declare"
+ },
+ {
+ "text": "B",
+ "kind": "var",
+ "kindModifiers": "export,declare"
+ },
+ {
+ "text": "Test",
+ "kind": "class",
+ "kindModifiers": "export,declare",
+ "childItems": [
+ {
+ "text": "wow",
+ "kind": "method",
+ "kindModifiers": "public,declare"
+ }
+ ]
+ },
+ {
+ "text": "Test",
+ "kind": "module",
+ "kindModifiers": "export,declare",
+ "childItems": [
+ {
+ "text": "Boom",
+ "kind": "function",
+ "kindModifiers": "export,declare"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navbar_exportDefault.ts b/tests/cases/fourslash/navbar_exportDefault.ts
index e547c9129a6..84f50610e6b 100644
--- a/tests/cases/fourslash/navbar_exportDefault.ts
+++ b/tests/cases/fourslash/navbar_exportDefault.ts
@@ -13,6 +13,17 @@
////export default function Func { }
goTo.file("a.ts");
+verify.navigationTree({
+ "text": "\"a\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "default",
+ "kind": "class",
+ "kindModifiers": "export"
+ }
+ ]
+});
verify.navigationBar([
{
"text": "\"a\"",
@@ -34,6 +45,17 @@ verify.navigationBar([
]);
goTo.file("b.ts");
+verify.navigationTree({
+ "text": "\"b\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "C",
+ "kind": "class",
+ "kindModifiers": "export"
+ }
+ ]
+});
verify.navigationBar([
{
"text": "\"b\"",
@@ -55,6 +77,17 @@ verify.navigationBar([
]);
goTo.file("c.ts");
+verify.navigationTree({
+ "text": "\"c\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "default",
+ "kind": "function",
+ "kindModifiers": "export"
+ }
+ ]
+});
verify.navigationBar([
{
"text": "\"c\"",
@@ -76,6 +109,17 @@ verify.navigationBar([
]);
goTo.file("d.ts");
+verify.navigationTree({
+ "text": "\"d\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "Func",
+ "kind": "function",
+ "kindModifiers": "export"
+ }
+ ]
+});
verify.navigationBar([
{
"text": "\"d\"",
diff --git a/tests/cases/fourslash/navbar_let.ts b/tests/cases/fourslash/navbar_let.ts
index bd0e702bbf9..77e00ad7300 100644
--- a/tests/cases/fourslash/navbar_let.ts
+++ b/tests/cases/fourslash/navbar_let.ts
@@ -2,6 +2,17 @@
////let c = 0;
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "c",
+ "kind": "let"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions.ts b/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions.ts
index 30e96739ab0..69fa697f7bc 100644
--- a/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions.ts
+++ b/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions.ts
@@ -26,6 +26,85 @@
//// (class { });
////})
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "nest",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "moreNest",
+ "kind": "function"
+ }
+ ]
+ },
+ {
+ "text": "x",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "xx",
+ "kind": "function"
+ }
+ ]
+ },
+ {
+ "text": "y",
+ "kind": "const",
+ "childItems": [
+ {
+ "text": "foo",
+ "kind": "function"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "text": "",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "function"
+ },
+ {
+ "text": "z",
+ "kind": "function"
+ }
+ ]
+ },
+ {
+ "text": "classes",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "class"
+ },
+ {
+ "text": "cls2",
+ "kind": "class"
+ },
+ {
+ "text": "cls3",
+ "kind": "class"
+ }
+ ]
+ },
+ {
+ "text": "global.cls",
+ "kind": "class"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions2.ts b/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions2.ts
index 36b1e07cd8a..f6ce02e0dd0 100644
--- a/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions2.ts
+++ b/tests/cases/fourslash/navigationBarAnonymousClassAndFunctionExpressions2.ts
@@ -3,6 +3,39 @@
////console.log(console.log(class Y {}, class X {}), console.log(class B {}, class A {}));
////console.log(class Cls { meth() {} });
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "A",
+ "kind": "class"
+ },
+ {
+ "text": "B",
+ "kind": "class"
+ },
+ {
+ "text": "Cls",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "meth",
+ "kind": "method"
+ }
+ ]
+ },
+ {
+ "text": "X",
+ "kind": "class"
+ },
+ {
+ "text": "Y",
+ "kind": "class"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarFunctionIndirectlyInVariableDeclaration.ts b/tests/cases/fourslash/navigationBarFunctionIndirectlyInVariableDeclaration.ts
index f14419a121a..a0ed5174f56 100644
--- a/tests/cases/fourslash/navigationBarFunctionIndirectlyInVariableDeclaration.ts
+++ b/tests/cases/fourslash/navigationBarFunctionIndirectlyInVariableDeclaration.ts
@@ -8,39 +8,64 @@
//// propB: function() {}
////};
-verify.navigationBar([
- {
+verify.navigationTree({
"text": "",
"kind": "script",
"childItems": [
- {
- "text": "a",
- "kind": "var"
- },
- {
- "text": "b",
- "kind": "var"
- },
- {
- "text": "propB",
- "kind": "function"
- }
+ {
+ "text": "a",
+ "kind": "var",
+ "childItems": [
+ {
+ "text": "propA",
+ "kind": "function"
+ }
+ ]
+ },
+ {
+ "text": "b",
+ "kind": "var"
+ },
+ {
+ "text": "propB",
+ "kind": "function"
+ }
]
- },
- {
- "text": "a",
- "kind": "var",
- "childItems": [
- {
- "text": "propA",
- "kind": "function"
- }
- ],
- "indent": 1
- },
- {
- "text": "propB",
- "kind": "function",
- "indent": 1
- }
+});
+
+verify.navigationBar([
+ {
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "var"
+ },
+ {
+ "text": "b",
+ "kind": "var"
+ },
+ {
+ "text": "propB",
+ "kind": "function"
+ }
+ ]
+ },
+ {
+ "text": "a",
+ "kind": "var",
+ "childItems": [
+ {
+ "text": "propA",
+ "kind": "function"
+ }
+ ],
+ "indent": 1
+ },
+ {
+ "text": "propB",
+ "kind": "function",
+ "indent": 1
+ }
]);
diff --git a/tests/cases/fourslash/navigationBarGetterAndSetter.ts b/tests/cases/fourslash/navigationBarGetterAndSetter.ts
index 3ae2e0f60ac..ccf9e7c472e 100644
--- a/tests/cases/fourslash/navigationBarGetterAndSetter.ts
+++ b/tests/cases/fourslash/navigationBarGetterAndSetter.ts
@@ -8,6 +8,33 @@
//// }
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "X",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "x",
+ "kind": "getter"
+ },
+ {
+ "text": "x",
+ "kind": "setter",
+ "childItems": [
+ {
+ "text": "f",
+ "kind": "function"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarImports.ts b/tests/cases/fourslash/navigationBarImports.ts
index 43cb99c556a..44f0d46b401 100644
--- a/tests/cases/fourslash/navigationBarImports.ts
+++ b/tests/cases/fourslash/navigationBarImports.ts
@@ -4,6 +4,29 @@
////import c = require("m");
////import * as d from "m";
+verify.navigationTree({
+ "text": "\"navigationBarImports\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "alias"
+ },
+ {
+ "text": "b",
+ "kind": "alias"
+ },
+ {
+ "text": "c",
+ "kind": "alias"
+ },
+ {
+ "text": "d",
+ "kind": "alias"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "\"navigationBarImports\"",
diff --git a/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts b/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts
index ff1de04c07e..d2b8b24bcbf 100644
--- a/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts
+++ b/tests/cases/fourslash/navigationBarItemsBindingPatterns.ts
@@ -6,6 +6,57 @@
////const bar1, [c, d]
////var {e, x: [f, g]} = {a:1, x:[]};
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "let"
+ },
+ {
+ "text": "b",
+ "kind": "let"
+ },
+ {
+ "text": "bar",
+ "kind": "var"
+ },
+ {
+ "text": "bar1",
+ "kind": "const"
+ },
+ {
+ "text": "c",
+ "kind": "const"
+ },
+ {
+ "text": "d",
+ "kind": "const"
+ },
+ {
+ "text": "e",
+ "kind": "var"
+ },
+ {
+ "text": "f",
+ "kind": "var"
+ },
+ {
+ "text": "foo",
+ "kind": "var"
+ },
+ {
+ "text": "foo1",
+ "kind": "let"
+ },
+ {
+ "text": "g",
+ "kind": "var"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts b/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts
index 61e34d0f30e..f1250d530d3 100644
--- a/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts
+++ b/tests/cases/fourslash/navigationBarItemsBindingPatternsInConstructor.ts
@@ -11,6 +11,41 @@
//// }
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "A",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "constructor",
+ "kind": "constructor"
+ },
+ {
+ "text": "x",
+ "kind": "property"
+ }
+ ]
+ },
+ {
+ "text": "B",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "constructor",
+ "kind": "constructor"
+ },
+ {
+ "text": "x",
+ "kind": "property"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts b/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts
index 2e37f69b456..c300a1207d5 100644
--- a/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts
+++ b/tests/cases/fourslash/navigationBarItemsEmptyConstructors.ts
@@ -5,6 +5,23 @@
//// }
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "Test",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "constructor",
+ "kind": "constructor"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsExports.ts b/tests/cases/fourslash/navigationBarItemsExports.ts
index 3ec9b0a7138..1f29ae5af5b 100644
--- a/tests/cases/fourslash/navigationBarItemsExports.ts
+++ b/tests/cases/fourslash/navigationBarItemsExports.ts
@@ -9,6 +9,26 @@
////
////export * from "a"; // no bindings here
+verify.navigationTree({
+ "text": "\"navigationBarItemsExports\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "alias"
+ },
+ {
+ "text": "B",
+ "kind": "alias"
+ },
+ {
+ "text": "e",
+ "kind": "alias",
+ "kindModifiers": "export"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "\"navigationBarItemsExports\"",
diff --git a/tests/cases/fourslash/navigationBarItemsFunctions.ts b/tests/cases/fourslash/navigationBarItemsFunctions.ts
index b85e898065c..f43cd3effaf 100644
--- a/tests/cases/fourslash/navigationBarItemsFunctions.ts
+++ b/tests/cases/fourslash/navigationBarItemsFunctions.ts
@@ -14,6 +14,53 @@
//// var v = 10;
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "baz",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "v",
+ "kind": "var"
+ }
+ ]
+ },
+ {
+ "text": "foo",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "bar",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "biz",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "z",
+ "kind": "var"
+ }
+ ]
+ },
+ {
+ "text": "y",
+ "kind": "var"
+ }
+ ]
+ },
+ {
+ "text": "x",
+ "kind": "var"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts b/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts
index b0238a1ef06..49ca40841d7 100644
--- a/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts
+++ b/tests/cases/fourslash/navigationBarItemsFunctionsBroken.ts
@@ -4,6 +4,23 @@
//// function;
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "f",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "function"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts b/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts
index 4f279446100..8ebfab8519b 100644
--- a/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts
+++ b/tests/cases/fourslash/navigationBarItemsFunctionsBroken2.ts
@@ -5,6 +5,27 @@
//// function;
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "function"
+ },
+ {
+ "text": "f",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "function"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsImports.ts b/tests/cases/fourslash/navigationBarItemsImports.ts
index ed398ec7f1d..b0ce515a56c 100644
--- a/tests/cases/fourslash/navigationBarItemsImports.ts
+++ b/tests/cases/fourslash/navigationBarItemsImports.ts
@@ -13,6 +13,44 @@
////
////import * as ns from "a";
+verify.navigationTree({
+ "text": "\"navigationBarItemsImports\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "alias"
+ },
+ {
+ "text": "B",
+ "kind": "alias"
+ },
+ {
+ "text": "c",
+ "kind": "alias"
+ },
+ {
+ "text": "D",
+ "kind": "alias"
+ },
+ {
+ "text": "d1",
+ "kind": "alias"
+ },
+ {
+ "text": "d2",
+ "kind": "alias"
+ },
+ {
+ "text": "e",
+ "kind": "alias"
+ },
+ {
+ "text": "ns",
+ "kind": "alias"
+ }
+ ]
+});
verify.navigationBar([
{
diff --git a/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts b/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts
index a49f32d960e..35dff3af14c 100644
--- a/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts
+++ b/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts
@@ -18,6 +18,77 @@
//// emptyMethod() { } // Non child functions method should not be duplicated
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "Class",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "constructor",
+ "kind": "constructor",
+ "childItems": [
+ {
+ "text": "LocalEnumInConstructor",
+ "kind": "enum",
+ "childItems": [
+ {
+ "text": "LocalEnumMemberInConstructor",
+ "kind": "const"
+ }
+ ]
+ },
+ {
+ "text": "LocalFunctionInConstructor",
+ "kind": "function"
+ },
+ {
+ "text": "LocalInterfaceInConstrcutor",
+ "kind": "interface"
+ }
+ ]
+ },
+ {
+ "text": "emptyMethod",
+ "kind": "method"
+ },
+ {
+ "text": "method",
+ "kind": "method",
+ "childItems": [
+ {
+ "text": "LocalEnumInMethod",
+ "kind": "enum",
+ "childItems": [
+ {
+ "text": "LocalEnumMemberInMethod",
+ "kind": "const"
+ }
+ ]
+ },
+ {
+ "text": "LocalFunctionInMethod",
+ "kind": "function",
+ "childItems": [
+ {
+ "text": "LocalFunctionInLocalFunctionInMethod",
+ "kind": "function"
+ }
+ ]
+ },
+ {
+ "text": "LocalInterfaceInMethod",
+ "kind": "interface"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsItems.ts b/tests/cases/fourslash/navigationBarItemsItems.ts
index e3d8f0e633c..69422dd0cc2 100644
--- a/tests/cases/fourslash/navigationBarItemsItems.ts
+++ b/tests/cases/fourslash/navigationBarItemsItems.ts
@@ -39,6 +39,114 @@
////var p: IPoint = new Shapes.Point(3, 4);
////var dist = p.getDist();
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "dist",
+ "kind": "var"
+ },
+ {
+ "text": "IPoint",
+ "kind": "interface",
+ "childItems": [
+ {
+ "text": "()",
+ "kind": "call"
+ },
+ {
+ "text": "new()",
+ "kind": "construct"
+ },
+ {
+ "text": "[]",
+ "kind": "index"
+ },
+ {
+ "text": "getDist",
+ "kind": "method"
+ },
+ {
+ "text": "prop",
+ "kind": "property"
+ }
+ ]
+ },
+ {
+ "text": "p",
+ "kind": "var"
+ },
+ {
+ "text": "Shapes",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "Point",
+ "kind": "class",
+ "kindModifiers": "export",
+ "childItems": [
+ {
+ "text": "constructor",
+ "kind": "constructor"
+ },
+ {
+ "text": "getDist",
+ "kind": "method"
+ },
+ {
+ "text": "getOrigin",
+ "kind": "method",
+ "kindModifiers": "private,static"
+ },
+ {
+ "text": "origin",
+ "kind": "property",
+ "kindModifiers": "static"
+ },
+ {
+ "text": "value",
+ "kind": "getter"
+ },
+ {
+ "text": "value",
+ "kind": "setter"
+ },
+ {
+ "text": "x",
+ "kind": "property",
+ "kindModifiers": "public"
+ },
+ {
+ "text": "y",
+ "kind": "property",
+ "kindModifiers": "public"
+ }
+ ]
+ },
+ {
+ "text": "Values",
+ "kind": "enum",
+ "childItems": [
+ {
+ "text": "value1",
+ "kind": "const"
+ },
+ {
+ "text": "value2",
+ "kind": "const"
+ },
+ {
+ "text": "value3",
+ "kind": "const"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsItems2.ts b/tests/cases/fourslash/navigationBarItemsItems2.ts
index 6ab0827e8f9..fa5a5b09fac 100644
--- a/tests/cases/fourslash/navigationBarItemsItems2.ts
+++ b/tests/cases/fourslash/navigationBarItemsItems2.ts
@@ -6,6 +6,22 @@ goTo.marker();
edit.insertLine("module A");
edit.insert("export class ");
+verify.navigationTree({
+ "text": "\"navigationBarItemsItems2\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "class",
+ "kindModifiers": "export"
+ },
+ {
+ "text": "A",
+ "kind": "module"
+ }
+ ]
+});
+
// should not crash
verify.navigationBar([
{
diff --git a/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts b/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts
index 04091185dd0..705dc2227b3 100644
--- a/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts
+++ b/tests/cases/fourslash/navigationBarItemsItemsExternalModules.ts
@@ -4,6 +4,25 @@
//// public s: string;
////}
+verify.navigationTree({
+ "text": "\"navigationBarItemsItemsExternalModules\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "Bar",
+ "kind": "class",
+ "kindModifiers": "export",
+ "childItems": [
+ {
+ "text": "s",
+ "kind": "property",
+ "kindModifiers": "public"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "\"navigationBarItemsItemsExternalModules\"",
diff --git a/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts b/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts
index 4939091d944..c271050bc52 100644
--- a/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts
+++ b/tests/cases/fourslash/navigationBarItemsItemsExternalModules2.ts
@@ -6,6 +6,30 @@
////}
////export var x: number;
+verify.navigationTree({
+ "text": "\"file\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "Bar",
+ "kind": "class",
+ "kindModifiers": "export",
+ "childItems": [
+ {
+ "text": "s",
+ "kind": "property",
+ "kindModifiers": "public"
+ }
+ ]
+ },
+ {
+ "text": "x",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "\"file\"",
diff --git a/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts b/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts
index 5ee760fabc6..91ac533d75c 100644
--- a/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts
+++ b/tests/cases/fourslash/navigationBarItemsItemsExternalModules3.ts
@@ -6,6 +6,30 @@
////}
////export var x: number;
+verify.navigationTree({
+ "text": "\"my fil\\\"e\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "Bar",
+ "kind": "class",
+ "kindModifiers": "export",
+ "childItems": [
+ {
+ "text": "s",
+ "kind": "property",
+ "kindModifiers": "public"
+ }
+ ]
+ },
+ {
+ "text": "x",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "\"my fil\\\"e\"",
diff --git a/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts b/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts
index 9b8a65d0430..1beeffddb21 100644
--- a/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts
+++ b/tests/cases/fourslash/navigationBarItemsItemsModuleVariables.ts
@@ -20,6 +20,23 @@
////}
goTo.marker("file1");
// nothing else should show up
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "Module1",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "x",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+ }
+ ]
+});
verify.navigationBar([
{
"text": "",
@@ -46,6 +63,23 @@ verify.navigationBar([
]);
goTo.marker("file2");
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "Module1.SubModule",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "y",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+ }
+ ]
+});
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsMissingName1.ts b/tests/cases/fourslash/navigationBarItemsMissingName1.ts
index 2a445a5e1ed..60123d92e71 100644
--- a/tests/cases/fourslash/navigationBarItemsMissingName1.ts
+++ b/tests/cases/fourslash/navigationBarItemsMissingName1.ts
@@ -3,6 +3,28 @@
//// foo() {}
////}
+verify.navigationTree({
+ "text": "\"navigationBarItemsMissingName1\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "function",
+ "kindModifiers": "export"
+ },
+ {
+ "text": "C",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "foo",
+ "kind": "method"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "\"navigationBarItemsMissingName1\"",
diff --git a/tests/cases/fourslash/navigationBarItemsMissingName2.ts b/tests/cases/fourslash/navigationBarItemsMissingName2.ts
index 9faeb6de902..ce92128c825 100644
--- a/tests/cases/fourslash/navigationBarItemsMissingName2.ts
+++ b/tests/cases/fourslash/navigationBarItemsMissingName2.ts
@@ -6,6 +6,23 @@
////}
// Anonymous classes are still included.
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "foo",
+ "kind": "method"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsModules.ts b/tests/cases/fourslash/navigationBarItemsModules.ts
index a41c75de550..fd5907e2bc7 100644
--- a/tests/cases/fourslash/navigationBarItemsModules.ts
+++ b/tests/cases/fourslash/navigationBarItemsModules.ts
@@ -27,6 +27,73 @@
//We have 8 module keywords, and 4 var keywords.
//The declarations of A.B.C.x do not get merged, so the 4 vars are independent.
//The two 'A' modules, however, do get merged, so in reality we have 7 modules.
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "'X2.Y2.Z2'",
+ "kind": "module",
+ "kindModifiers": "declare"
+ },
+ {
+ "text": "\"X.Y.Z\"",
+ "kind": "module",
+ "kindModifiers": "declare"
+ },
+ {
+ "text": "A",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "B",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "C",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "x",
+ "kind": "var",
+ "kindModifiers": "declare"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "text": "z",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+ },
+ {
+ "text": "A.B",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "y",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+ },
+ {
+ "text": "A.B.C",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "x",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts b/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts
index dcf8894bb61..793844ac970 100644
--- a/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts
+++ b/tests/cases/fourslash/navigationBarItemsMultilineStringIdentifiers.ts
@@ -24,6 +24,56 @@
//// }
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "\"Multiline\\\nMadness\"",
+ "kind": "module",
+ "kindModifiers": "declare"
+ },
+ {
+ "text": "\"Multiline\\r\\nMadness\"",
+ "kind": "module",
+ "kindModifiers": "declare"
+ },
+ {
+ "text": "\"MultilineMadness\"",
+ "kind": "module",
+ "kindModifiers": "declare"
+ },
+ {
+ "text": "Bar",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "'a1\\\\\\r\\nb'",
+ "kind": "property"
+ },
+ {
+ "text": "'a2\\\n \\\n b'",
+ "kind": "method"
+ }
+ ]
+ },
+ {
+ "text": "Foo",
+ "kind": "interface",
+ "childItems": [
+ {
+ "text": "\"a1\\\\\\r\\nb\"",
+ "kind": "property"
+ },
+ {
+ "text": "\"a2\\\n \\\n b\"",
+ "kind": "method"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts b/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts
index b741084dab5..6e8e0ea350c 100644
--- a/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts
+++ b/tests/cases/fourslash/navigationBarItemsPropertiesDefinedInConstructors.ts
@@ -6,6 +6,43 @@
//// }
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "List",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "constructor",
+ "kind": "constructor",
+ "childItems": [
+ {
+ "text": "local",
+ "kind": "var"
+ }
+ ]
+ },
+ {
+ "text": "a",
+ "kind": "property",
+ "kindModifiers": "public"
+ },
+ {
+ "text": "b",
+ "kind": "property",
+ "kindModifiers": "private"
+ },
+ {
+ "text": "c",
+ "kind": "property"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsSymbols1.ts b/tests/cases/fourslash/navigationBarItemsSymbols1.ts
index ba57916028b..4326d7b4deb 100644
--- a/tests/cases/fourslash/navigationBarItemsSymbols1.ts
+++ b/tests/cases/fourslash/navigationBarItemsSymbols1.ts
@@ -6,6 +6,31 @@
//// get [Symbol.isConcatSpreadable]() { }
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "C",
+ "kind": "class",
+ "childItems": [
+ {
+ "text": "[Symbol.isConcatSpreadable]",
+ "kind": "getter"
+ },
+ {
+ "text": "[Symbol.isRegExp]",
+ "kind": "property"
+ },
+ {
+ "text": "[Symbol.iterator]",
+ "kind": "method"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsSymbols2.ts b/tests/cases/fourslash/navigationBarItemsSymbols2.ts
index 6812c88c150..64b076aaf0c 100644
--- a/tests/cases/fourslash/navigationBarItemsSymbols2.ts
+++ b/tests/cases/fourslash/navigationBarItemsSymbols2.ts
@@ -5,6 +5,27 @@
//// [Symbol.iterator](): string;
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "I",
+ "kind": "interface",
+ "childItems": [
+ {
+ "text": "[Symbol.isRegExp]",
+ "kind": "property"
+ },
+ {
+ "text": "[Symbol.iterator]",
+ "kind": "method"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsSymbols3.ts b/tests/cases/fourslash/navigationBarItemsSymbols3.ts
index 661005b86d9..be001c75e0b 100644
--- a/tests/cases/fourslash/navigationBarItemsSymbols3.ts
+++ b/tests/cases/fourslash/navigationBarItemsSymbols3.ts
@@ -5,6 +5,17 @@
//// [Symbol.isRegExp] = 0
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "E",
+ "kind": "enum"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarItemsTypeAlias.ts b/tests/cases/fourslash/navigationBarItemsTypeAlias.ts
index cba3fb8789c..387a9925d82 100644
--- a/tests/cases/fourslash/navigationBarItemsTypeAlias.ts
+++ b/tests/cases/fourslash/navigationBarItemsTypeAlias.ts
@@ -2,6 +2,17 @@
////type T = number | string;
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "T",
+ "kind": "type"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarJsDoc.ts b/tests/cases/fourslash/navigationBarJsDoc.ts
index 89049e6011a..8efce74d111 100644
--- a/tests/cases/fourslash/navigationBarJsDoc.ts
+++ b/tests/cases/fourslash/navigationBarJsDoc.ts
@@ -5,6 +5,25 @@
/////** @typedef {(string|number)} */
////const x = 0;
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "NumberLike",
+ "kind": "type"
+ },
+ {
+ "text": "x",
+ "kind": "const"
+ },
+ {
+ "text": "x",
+ "kind": "type"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts b/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts
index 8746f135e4d..561bdf4a056 100644
--- a/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts
+++ b/tests/cases/fourslash/navigationBarJsDocCommentWithNoTags.ts
@@ -3,6 +3,18 @@
/////** Test */
////export const Test = {}
+verify.navigationTree({
+ "text": "\"navigationBarJsDocCommentWithNoTags\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "Test",
+ "kind": "const",
+ "kindModifiers": "export"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "\"navigationBarJsDocCommentWithNoTags\"",
diff --git a/tests/cases/fourslash/navigationBarMerging.ts b/tests/cases/fourslash/navigationBarMerging.ts
index 2798d186c96..ebf02c94466 100644
--- a/tests/cases/fourslash/navigationBarMerging.ts
+++ b/tests/cases/fourslash/navigationBarMerging.ts
@@ -11,6 +11,37 @@
//// function bar() {}
////}
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "bar",
+ "kind": "function"
+ },
+ {
+ "text": "foo",
+ "kind": "function"
+ }
+ ]
+ },
+ {
+ "text": "b",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "foo",
+ "kind": "function"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
@@ -60,6 +91,22 @@ verify.navigationBar([
////function a() {}
goTo.file("file2.ts");
+
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "function"
+ },
+ {
+ "text": "a",
+ "kind": "module"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
@@ -101,6 +148,34 @@ verify.navigationBar([
////}
goTo.file("file3.ts");
+
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "A",
+ "kind": "interface",
+ "childItems": [
+ {
+ "text": "bar",
+ "kind": "property"
+ },
+ {
+ "text": "foo",
+ "kind": "property"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
@@ -147,6 +222,36 @@ verify.navigationBar([
////module A.B { export var y; }
goTo.file("file4.ts");
+
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "A",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "x",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+ },
+ {
+ "text": "A.B",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "y",
+ "kind": "var",
+ "kindModifiers": "export"
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts b/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts
index 732e2deb1dd..4c441728fdf 100644
--- a/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts
+++ b/tests/cases/fourslash/navigationBarNamespaceImportWithNoName.ts
@@ -1,4 +1,16 @@
////import *{} from 'foo';
+
+verify.navigationTree({
+ "text": "\"navigationBarNamespaceImportWithNoName\"",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "",
+ "kind": "alias"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "\"navigationBarNamespaceImportWithNoName\"",
diff --git a/tests/cases/fourslash/navigationBarVariables.ts b/tests/cases/fourslash/navigationBarVariables.ts
index 93093df1306..98d5e816e8e 100644
--- a/tests/cases/fourslash/navigationBarVariables.ts
+++ b/tests/cases/fourslash/navigationBarVariables.ts
@@ -4,6 +4,25 @@
////let y = 1;
////const z = 2;
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "x",
+ "kind": "var"
+ },
+ {
+ "text": "y",
+ "kind": "let"
+ },
+ {
+ "text": "z",
+ "kind": "const"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
@@ -31,6 +50,26 @@ verify.navigationBar([
////const [c] = 0;
goTo.file("file2.ts");
+
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "a",
+ "kind": "var"
+ },
+ {
+ "text": "b",
+ "kind": "let"
+ },
+ {
+ "text": "c",
+ "kind": "const"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts b/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts
index 978db18ab3b..212394159a8 100644
--- a/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts
+++ b/tests/cases/fourslash/server/jsdocTypedefTagNavigateTo.ts
@@ -10,6 +10,29 @@
//// /** @type {/*1*/NumberLike} */
//// var numberLike;
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "numberLike",
+ "kind": "var"
+ },
+ {
+ "text": "NumberLike",
+ "kind": "type"
+ },
+ {
+ "text": "NumberLike2",
+ "kind": "var"
+ },
+ {
+ "text": "NumberLike2",
+ "kind": "type"
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/server/navbar01.ts b/tests/cases/fourslash/server/navbar01.ts
index a5b22ee1fa9..4a4f59bcf78 100644
--- a/tests/cases/fourslash/server/navbar01.ts
+++ b/tests/cases/fourslash/server/navbar01.ts
@@ -38,6 +38,114 @@
////var p: IPoint = new Shapes.Point(3, 4);
////var dist = p.getDist();
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "dist",
+ "kind": "var"
+ },
+ {
+ "text": "IPoint",
+ "kind": "interface",
+ "childItems": [
+ {
+ "text": "()",
+ "kind": "call"
+ },
+ {
+ "text": "new()",
+ "kind": "construct"
+ },
+ {
+ "text": "[]",
+ "kind": "index"
+ },
+ {
+ "text": "getDist",
+ "kind": "method"
+ },
+ {
+ "text": "prop",
+ "kind": "property"
+ }
+ ]
+ },
+ {
+ "text": "p",
+ "kind": "var"
+ },
+ {
+ "text": "Shapes",
+ "kind": "module",
+ "childItems": [
+ {
+ "text": "Point",
+ "kind": "class",
+ "kindModifiers": "export",
+ "childItems": [
+ {
+ "text": "constructor",
+ "kind": "constructor"
+ },
+ {
+ "text": "getDist",
+ "kind": "method"
+ },
+ {
+ "text": "getOrigin",
+ "kind": "method",
+ "kindModifiers": "private,static"
+ },
+ {
+ "text": "origin",
+ "kind": "property",
+ "kindModifiers": "static"
+ },
+ {
+ "text": "value",
+ "kind": "getter"
+ },
+ {
+ "text": "value",
+ "kind": "setter"
+ },
+ {
+ "text": "x",
+ "kind": "property",
+ "kindModifiers": "public"
+ },
+ {
+ "text": "y",
+ "kind": "property",
+ "kindModifiers": "public"
+ }
+ ]
+ },
+ {
+ "text": "Values",
+ "kind": "enum",
+ "childItems": [
+ {
+ "text": "value1",
+ "kind": "const"
+ },
+ {
+ "text": "value2",
+ "kind": "const"
+ },
+ {
+ "text": "value3",
+ "kind": "const"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+});
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts b/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts
index fba24bdcf77..627d4dac178 100644
--- a/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts
+++ b/tests/cases/fourslash/shims-pp/getNavigationBarItems.ts
@@ -2,6 +2,17 @@
//// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0;
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "c",
+ "kind": "const"
+ }
+ ]
+})
+
verify.navigationBar([
{
"text": "",
diff --git a/tests/cases/fourslash/shims/getNavigationBarItems.ts b/tests/cases/fourslash/shims/getNavigationBarItems.ts
index fba24bdcf77..627d4dac178 100644
--- a/tests/cases/fourslash/shims/getNavigationBarItems.ts
+++ b/tests/cases/fourslash/shims/getNavigationBarItems.ts
@@ -2,6 +2,17 @@
//// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0;
+verify.navigationTree({
+ "text": "",
+ "kind": "script",
+ "childItems": [
+ {
+ "text": "c",
+ "kind": "const"
+ }
+ ]
+})
+
verify.navigationBar([
{
"text": "",