Enable '--strictNullChecks' (#22088)

* Enable '--strictNullChecks'

* Fix API baselines

* Make sys.getEnvironmentVariable non-nullable

* make properties optional instead of using `| undefined` in thier type

* reportDiagnostics should be required

* Declare firstAccessor as non-nullable

* Make `some` a type guard

* Fix `getEnvironmentVariable` definition in tests

* Pretend transformFlags are always defined

* Fix one more use of sys.getEnvironmentVariable

* `requiredResponse` accepts undefined, remove assertions

* Mark optional properties as optional instead of using `| undefined`

* Mark optional properties as optional instead of using ` | undefined`

* Remove unnecessary null assertions

* Put the bang on the declaration instead of every use

* Make `createMapFromTemplate` require a parameter

* Mark `EmitResult.emittedFiles` and `EmitResult.sourceMaps` as optional

* Plumb through undefined in emitLsit and EmitExpressionList

* `ElementAccessExpression.argumentExpression` can not be `undefined`

* Add overloads for `writeTokenText`

* Make `shouldWriteSeparatingLineTerminator` argument non-nullable

* Make `synthesizedNodeStartsOnNewLine` argument required

* `PropertyAssignment.initializer` cannot be undefined

* Use one `!` at declaration site instead of on every use site

* Capture host in a constant and avoid null assertions

* Remove few more unused assertions

* Update baselines

* Use parameter defaults

* Update baselines

* Fix lint

* Make Symbol#valueDeclaration and Symbol#declarations non-optional to reduce assertions

* Make Node#symbol and Type#symbol non-optional to reduce assertions

* Make `flags` non-nullable to reduce assertions

* Convert some asserts to type guards

* Make `isNonLocalAlias` a type guard

* Add overload for `getSymbolOfNode` for `Declaration`

* Some more `getSymbolOfNode` changes

* Push undefined suppression into `typeToTypeNodeHelper`

* `NodeBuilderContext.tracker` is never `undefined`

* use `Debug.assertDefined`

* Remove unnecessary tag

* Mark `LiteralType.freshType` and `LiteralTupe.regularType` as required
This commit is contained in:
Andy
2018-05-22 14:46:57 -07:00
committed by GitHub
parent 3fe946df78
commit e53e56cf82
167 changed files with 4846 additions and 4735 deletions
@@ -19,7 +19,7 @@ function pipeExists(name: string): boolean {
}
function createCancellationToken(args: string[]): ServerCancellationToken {
let cancellationPipeName: string;
let cancellationPipeName: string | undefined;
for (let i = 0; i < args.length - 1; i++) {
if (args[i] === "--cancellationPipeName") {
cancellationPipeName = args[i + 1];
@@ -43,7 +43,7 @@ function createCancellationToken(args: string[]): ServerCancellationToken {
if (namePrefix.length === 0 || namePrefix.indexOf("*") >= 0) {
throw new Error("Invalid name for template cancellation pipe: it should have length greater than 2 characters and contain only one '*'.");
}
let perRequestPipeName: string;
let perRequestPipeName: string | undefined;
let currentRequestId: number;
return {
isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName),
@@ -61,7 +61,7 @@ function createCancellationToken(args: string[]): ServerCancellationToken {
}
else {
return {
isCancellationRequested: () => pipeExists(cancellationPipeName),
isCancellationRequested: () => pipeExists(cancellationPipeName!), // TODO: GH#18217
setRequest: (_requestId: number): void => void 0,
resetRequest: (_requestId: number): void => void 0
};
+52 -52
View File
@@ -50,7 +50,7 @@ namespace ts.server {
private getLineMap(fileName: string): number[] {
let lineMap = this.lineMaps.get(fileName);
if (!lineMap) {
lineMap = computeLineStarts(getSnapshotText(this.host.getScriptSnapshot(fileName)));
lineMap = computeLineStarts(getSnapshotText(this.host.getScriptSnapshot(fileName)!));
this.lineMaps.set(fileName, lineMap);
}
return lineMap;
@@ -89,10 +89,9 @@ namespace ts.server {
private processResponse<T extends protocol.Response>(request: protocol.Request): T {
let foundResponseMessage = false;
let lastMessage: string;
let response: T;
let response!: T;
while (!foundResponseMessage) {
lastMessage = this.messages.shift();
const lastMessage = this.messages.shift()!;
Debug.assert(!!lastMessage, "Did not receive any responses.");
const responseBody = extractMessage(lastMessage);
try {
@@ -133,7 +132,7 @@ namespace ts.server {
changeFile(fileName: string, start: number, end: number, insertString: string): void {
// clear the line map after an edit
this.lineMaps.set(fileName, undefined);
this.lineMaps.set(fileName, undefined!); // TODO: GH#18217
const args: protocol.ChangeRequestArgs = { ...this.createFileLocationRequestArgsWithEndLineAndOffset(fileName, start, end), insertString };
this.processRequest(CommandNames.Change, args);
@@ -149,14 +148,15 @@ namespace ts.server {
const request = this.processRequest<protocol.QuickInfoRequest>(CommandNames.Quickinfo, args);
const response = this.processResponse<protocol.QuickInfoResponse>(request);
const body = response.body!; // TODO: GH#18217
return {
kind: response.body.kind,
kindModifiers: response.body.kindModifiers,
textSpan: this.decodeSpan(response.body, fileName),
displayParts: [{ kind: "text", text: response.body.displayString }],
documentation: [{ kind: "text", text: response.body.documentation }],
tags: response.body.tags
kind: body.kind,
kindModifiers: body.kindModifiers,
textSpan: this.decodeSpan(body, fileName),
displayParts: [{ kind: "text", text: body.displayString }],
documentation: [{ kind: "text", text: body.documentation }],
tags: body.tags
};
}
@@ -167,8 +167,8 @@ namespace ts.server {
const response = this.processResponse<protocol.ProjectInfoResponse>(request);
return {
configFileName: response.body.configFileName,
fileNames: response.body.fileNames
configFileName: response.body!.configFileName, // TODO: GH#18217
fileNames: response.body!.fileNames
};
}
@@ -183,7 +183,7 @@ namespace ts.server {
isGlobalCompletion: false,
isMemberCompletion: false,
isNewIdentifierLocation: false,
entries: response.body.map<CompletionEntry>(entry => {
entries: response.body!.map<CompletionEntry>(entry => { // TODO: GH#18217
if (entry.replacementSpan !== undefined) {
const { name, kind, kindModifiers, sortText, replacementSpan, hasAction, source, isRecommended } = entry;
// TODO: GH#241
@@ -201,10 +201,9 @@ namespace ts.server {
const request = this.processRequest<protocol.CompletionDetailsRequest>(CommandNames.CompletionDetails, args);
const response = this.processResponse<protocol.CompletionDetailsResponse>(request);
Debug.assert(response.body.length === 1, "Unexpected length of completion details response body.");
const convertedCodeActions = map(response.body[0].codeActions, ({ description, changes }) => ({ description, changes: this.convertChanges(changes, fileName) }));
return { ...response.body[0], codeActions: convertedCodeActions };
Debug.assert(response.body!.length === 1, "Unexpected length of completion details response body.");
const convertedCodeActions = map(response.body![0].codeActions, ({ description, changes }) => ({ description, changes: this.convertChanges(changes, fileName) }));
return { ...response.body![0], codeActions: convertedCodeActions };
}
getCompletionEntrySymbol(_fileName: string, _position: number, _entryName: string): Symbol {
@@ -220,14 +219,14 @@ namespace ts.server {
const request = this.processRequest<protocol.NavtoRequest>(CommandNames.Navto, args);
const response = this.processResponse<protocol.NavtoResponse>(request);
return response.body.map(entry => ({
return response.body!.map(entry => ({ // TODO: GH#18217
name: entry.name,
containerName: entry.containerName || "",
containerKind: entry.containerKind || ScriptElementKind.unknown,
kind: entry.kind,
kindModifiers: entry.kindModifiers,
matchKind: entry.matchKind,
isCaseSensitive: entry.isCaseSensitive,
kindModifiers: entry.kindModifiers!, // TODO: GH#18217
matchKind: entry.matchKind!, // TODO: GH#18217
isCaseSensitive: entry.isCaseSensitive!, // TODO: GH#18217
fileName: entry.file,
textSpan: this.decodeSpan(entry),
}));
@@ -241,11 +240,11 @@ namespace ts.server {
const request = this.processRequest<protocol.FormatRequest>(CommandNames.Format, args);
const response = this.processResponse<protocol.FormatResponse>(request);
return response.body.map(entry => this.convertCodeEditsToTextChange(file, entry));
return response.body!.map(entry => this.convertCodeEditsToTextChange(file, entry)); // TODO: GH#18217
}
getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[] {
return this.getFormattingEditsForRange(fileName, 0, this.host.getScriptSnapshot(fileName).getLength(), options);
return this.getFormattingEditsForRange(fileName, 0, this.host.getScriptSnapshot(fileName)!.getLength(), options);
}
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, _options: FormatCodeOptions): TextChange[] {
@@ -255,7 +254,7 @@ namespace ts.server {
const request = this.processRequest<protocol.FormatOnKeyRequest>(CommandNames.Formatonkey, args);
const response = this.processResponse<protocol.FormatResponse>(request);
return response.body.map(entry => this.convertCodeEditsToTextChange(fileName, entry));
return response.body!.map(entry => this.convertCodeEditsToTextChange(fileName, entry)); // TODO: GH#18217
}
getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
@@ -264,7 +263,7 @@ namespace ts.server {
const request = this.processRequest<protocol.DefinitionRequest>(CommandNames.Definition, args);
const response = this.processResponse<protocol.DefinitionResponse>(request);
return response.body.map(entry => ({
return response.body!.map(entry => ({ // TODO: GH#18217
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName: entry.file,
@@ -281,7 +280,7 @@ namespace ts.server {
const response = this.processResponse<protocol.DefinitionInfoAndBoundSpanReponse>(request);
return {
definitions: response.body.definitions.map(entry => ({
definitions: response.body!.definitions.map(entry => ({ // TODO: GH#18217
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName: entry.file,
@@ -289,7 +288,7 @@ namespace ts.server {
kind: ScriptElementKind.unknown,
name: ""
})),
textSpan: this.decodeSpan(response.body.textSpan, request.arguments.file)
textSpan: this.decodeSpan(response.body!.textSpan, request.arguments.file)
};
}
@@ -299,7 +298,7 @@ namespace ts.server {
const request = this.processRequest<protocol.TypeDefinitionRequest>(CommandNames.TypeDefinition, args);
const response = this.processResponse<protocol.TypeDefinitionResponse>(request);
return response.body.map(entry => ({
return response.body!.map(entry => ({ // TODO: GH#18217
containerKind: ScriptElementKind.unknown,
containerName: "",
fileName: entry.file,
@@ -315,7 +314,7 @@ namespace ts.server {
const request = this.processRequest<protocol.ImplementationRequest>(CommandNames.Implementation, args);
const response = this.processResponse<protocol.ImplementationResponse>(request);
return response.body.map(entry => ({
return response.body!.map(entry => ({ // TODO: GH#18217
fileName: entry.file,
textSpan: this.decodeSpan(entry),
kind: ScriptElementKind.unknown,
@@ -334,7 +333,7 @@ namespace ts.server {
const request = this.processRequest<protocol.ReferencesRequest>(CommandNames.References, args);
const response = this.processResponse<protocol.ReferencesResponse>(request);
return response.body.refs.map(entry => ({
return response.body!.refs.map(entry => ({ // TODO: GH#18217
fileName: entry.file,
textSpan: this.decodeSpan(entry),
isWriteAccess: entry.isWriteAccess,
@@ -349,7 +348,7 @@ namespace ts.server {
getSyntacticDiagnostics(file: string): DiagnosticWithLocation[] {
return this.getDiagnostics(file, CommandNames.SyntacticDiagnosticsSync);
}
getSemanticDiagnostics(file: string): DiagnosticWithLocation[] {
getSemanticDiagnostics(file: string): Diagnostic[] {
return this.getDiagnostics(file, CommandNames.SemanticDiagnosticsSync);
}
getSuggestionDiagnostics(file: string): DiagnosticWithLocation[] {
@@ -364,7 +363,7 @@ namespace ts.server {
const category = firstDefined(Object.keys(DiagnosticCategory), id =>
isString(id) && entry.category === id.toLowerCase() ? (<any>DiagnosticCategory)[id] : undefined);
return {
file: undefined,
file: undefined!, // TODO: GH#18217
start: entry.start,
length: entry.length,
messageText: entry.message,
@@ -384,8 +383,9 @@ namespace ts.server {
const request = this.processRequest<protocol.RenameRequest>(CommandNames.Rename, args);
const response = this.processResponse<protocol.RenameResponse>(request);
const body = response.body!; // TODO: GH#18217
const locations: RenameLocation[] = [];
for (const entry of response.body.locs) {
for (const entry of body.locs) {
const fileName = entry.file;
for (const loc of entry.locs) {
locations.push({ textSpan: this.decodeSpan(loc, fileName), fileName });
@@ -393,17 +393,17 @@ namespace ts.server {
}
return this.lastRenameEntry = {
canRename: response.body.info.canRename,
displayName: response.body.info.displayName,
fullDisplayName: response.body.info.fullDisplayName,
kind: response.body.info.kind,
kindModifiers: response.body.info.kindModifiers,
localizedErrorMessage: response.body.info.localizedErrorMessage,
canRename: body.info.canRename,
displayName: body.info.displayName,
fullDisplayName: body.info.fullDisplayName,
kind: body.info.kind,
kindModifiers: body.info.kindModifiers,
localizedErrorMessage: body.info.localizedErrorMessage,
triggerSpan: createTextSpanFromBounds(position, position),
fileName,
position,
findInStrings,
findInComments,
findInStrings: !!findInStrings,
findInComments: !!findInComments,
locations,
};
}
@@ -420,7 +420,7 @@ namespace ts.server {
return this.lastRenameEntry.locations;
}
private decodeNavigationBarItems(items: protocol.NavigationBarItem[], fileName: string, lineMap: number[]): NavigationBarItem[] {
private decodeNavigationBarItems(items: protocol.NavigationBarItem[] | undefined, fileName: string, lineMap: number[]): NavigationBarItem[] {
if (!items) {
return [];
}
@@ -460,7 +460,7 @@ namespace ts.server {
const response = this.processResponse<protocol.NavTreeResponse>(request);
const lineMap = this.getLineMap(file);
return this.decodeNavigationTree(response.body, file, lineMap);
return this.decodeNavigationTree(response.body!, file, lineMap); // TODO: GH#18217
}
private decodeSpan(span: protocol.TextSpan & { file: string }): TextSpan;
@@ -488,7 +488,7 @@ namespace ts.server {
const response = this.processResponse<protocol.SignatureHelpResponse>(request);
if (!response.body) {
return undefined;
return undefined!; // TODO: GH#18217
}
const { items, applicableSpan: encodedApplicableSpan, selectedItemIndex, argumentIndex, argumentCount } = response.body;
@@ -504,7 +504,7 @@ namespace ts.server {
const request = this.processRequest<protocol.OccurrencesRequest>(CommandNames.Occurrences, args);
const response = this.processResponse<protocol.OccurrencesResponse>(request);
return response.body.map(entry => ({
return response.body!.map(entry => ({ // TODO: GH#18217
fileName: entry.file,
textSpan: this.decodeSpan(entry),
isWriteAccess: entry.isWriteAccess,
@@ -518,7 +518,7 @@ namespace ts.server {
const request = this.processRequest<protocol.DocumentHighlightsRequest>(CommandNames.DocumentHighlights, args);
const response = this.processResponse<protocol.DocumentHighlightsResponse>(request);
return response.body.map(item => ({
return response.body!.map(item => ({ // TODO: GH#18217
fileName: item.file,
highlightSpans: item.highlightSpans.map(span => ({
textSpan: this.decodeSpan(span, item.file),
@@ -531,7 +531,7 @@ namespace ts.server {
const request = this.processRequest<protocol.OutliningSpansRequest>(CommandNames.GetOutliningSpans, { file });
const response = this.processResponse<protocol.OutliningSpansResponse>(request);
return response.body.map<OutliningSpan>(item => ({
return response.body!.map<OutliningSpan>(item => ({
textSpan: this.decodeSpan(item.textSpan, file),
hintSpan: this.decodeSpan(item.hintSpan, file),
bannerText: item.bannerText,
@@ -562,7 +562,7 @@ namespace ts.server {
const request = this.processRequest<protocol.CodeFixRequest>(CommandNames.GetCodeFixes, args);
const response = this.processResponse<protocol.CodeFixResponse>(request);
return response.body.map<CodeFixAction>(({ fixName, description, changes, commands, fixId, fixAllDescription }) =>
return response.body!.map<CodeFixAction>(({ fixName, description, changes, commands, fixId, fixAllDescription }) => // TODO: GH#18217
({ fixName, description, changes: this.convertChanges(changes, file), commands: commands as CodeActionCommand[], fixId, fixAllDescription }));
}
@@ -598,7 +598,7 @@ namespace ts.server {
const request = this.processRequest<protocol.GetApplicableRefactorsRequest>(CommandNames.GetApplicableRefactors, args);
const response = this.processResponse<protocol.GetApplicableRefactorsResponse>(request);
return response.body;
return response.body!; // TODO: GH#18217
}
getEditsForRefactor(
@@ -624,7 +624,7 @@ namespace ts.server {
const renameFilename: string | undefined = response.body.renameFilename;
let renameLocation: number | undefined;
if (renameFilename !== undefined) {
renameLocation = this.lineOffsetToPosition(renameFilename, response.body.renameLocation);
renameLocation = this.lineOffsetToPosition(renameFilename, response.body.renameLocation!); // TODO: GH#18217
}
return {
@@ -672,7 +672,7 @@ namespace ts.server {
const request = this.processRequest<protocol.BraceRequest>(CommandNames.Brace, args);
const response = this.processResponse<protocol.BraceResponse>(request);
return response.body.map(entry => this.decodeSpan(entry, fileName));
return response.body!.map(entry => this.decodeSpan(entry, fileName)); // TODO: GH#18217
}
getIndentationAtPosition(_fileName: string, _position: number, _options: EditorOptions): number {
+66 -66
View File
@@ -71,7 +71,7 @@ namespace ts.server {
}
export interface ProjectInfoTypeAcquisitionData {
readonly enable: boolean;
readonly enable: boolean | undefined;
// Actual values of include/exclude entries are scrubbed.
readonly include: boolean;
readonly exclude: boolean;
@@ -225,13 +225,13 @@ namespace ts.server {
interface FilePropertyReader<T> {
getFileName(f: T): string;
getScriptKind(f: T, extraFileExtensions?: FileExtensionInfo[]): ScriptKind;
hasMixedContent(f: T, extraFileExtensions: FileExtensionInfo[]): boolean;
hasMixedContent(f: T, extraFileExtensions: FileExtensionInfo[] | undefined): boolean;
}
const fileNamePropertyReader: FilePropertyReader<string> = {
getFileName: x => x,
getScriptKind: (fileName, extraFileExtensions) => {
let result: ScriptKind;
let result: ScriptKind | undefined;
if (extraFileExtensions) {
const fileExtension = getAnyExtensionFromPath(fileName);
if (fileExtension) {
@@ -244,18 +244,18 @@ namespace ts.server {
});
}
}
return result;
return result!; // TODO: GH#18217
},
hasMixedContent: (fileName, extraFileExtensions) => some(extraFileExtensions, ext => ext.isMixedContent && fileExtensionIs(fileName, ext.extension)),
};
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
getFileName: x => x.fileName,
getScriptKind: x => tryConvertScriptKindName(x.scriptKind),
hasMixedContent: x => x.hasMixedContent,
getScriptKind: x => tryConvertScriptKindName(x.scriptKind!), // TODO: GH#18217
hasMixedContent: x => !!x.hasMixedContent,
};
function findProjectByName<T extends Project>(projectName: string, projects: T[]): T {
function findProjectByName<T extends Project>(projectName: string, projects: T[]): T | undefined {
for (const proj of projects) {
if (proj.getProjectName() === projectName) {
return proj;
@@ -374,7 +374,7 @@ namespace ts.server {
/**
* Open files: with value being project root path, and key being Path of the file that is open
*/
readonly openFiles = createMap<NormalizedPath>();
readonly openFiles = createMap<NormalizedPath | undefined>();
/**
* Map of open files that are opened without complete path but have projectRoot as current directory
*/
@@ -413,7 +413,7 @@ namespace ts.server {
public readonly useSingleInferredProject: boolean;
public readonly useInferredProjectPerProjectRoot: boolean;
public readonly typingsInstaller: ITypingsInstaller;
private readonly globalCacheLocationDirectoryPath: Path;
private readonly globalCacheLocationDirectoryPath: Path | undefined;
public readonly throttleWaitMilliseconds?: number;
private readonly eventHandler?: ProjectServiceEventHandler;
private readonly suppressDiagnosticEvents?: boolean;
@@ -453,8 +453,9 @@ namespace ts.server {
}
this.currentDirectory = toNormalizedPath(this.host.getCurrentDirectory());
this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation &&
ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation));
this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation
? ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation))
: undefined;
this.throttledOperations = new ThrottledOperations(this.host, this.logger);
if (this.typesMapLocation) {
@@ -498,15 +499,14 @@ namespace ts.server {
/*@internal*/
setDocument(key: DocumentRegistryBucketKey, path: Path, sourceFile: SourceFile) {
const info = this.getScriptInfoForPath(path);
Debug.assert(!!info);
const info = Debug.assertDefined(this.getScriptInfoForPath(path));
info.cacheSourceFile = { key, sourceFile };
}
/*@internal*/
getDocument(key: DocumentRegistryBucketKey, path: Path) {
getDocument(key: DocumentRegistryBucketKey, path: Path): SourceFile | undefined {
const info = this.getScriptInfoForPath(path);
return info && info.cacheSourceFile && info.cacheSourceFile.key === key && info.cacheSourceFile.sourceFile;
return info && info.cacheSourceFile && info.cacheSourceFile.key === key ? info.cacheSourceFile.sourceFile : undefined;
}
/* @internal */
@@ -533,7 +533,7 @@ namespace ts.server {
private loadTypesMap() {
try {
const fileContent = this.host.readFile(this.typesMapLocation);
const fileContent = this.host.readFile(this.typesMapLocation!); // TODO: GH#18217
if (fileContent === undefined) {
this.logger.info(`Provided types map file "${this.typesMapLocation}" doesn't exist`);
return;
@@ -623,7 +623,7 @@ namespace ts.server {
const event: ProjectsUpdatedInBackgroundEvent = {
eventName: ProjectsUpdatedInBackgroundEvent,
data: {
openFiles: arrayFrom(this.openFiles.keys(), path => this.getScriptInfoForPath(path as Path).fileName)
openFiles: arrayFrom(this.openFiles.keys(), path => this.getScriptInfoForPath(path as Path)!.fileName)
}
};
this.eventHandler(event);
@@ -673,7 +673,7 @@ namespace ts.server {
project.projectRootPath === canonicalProjectRootPath :
!project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) {
project.setCompilerOptions(compilerOptions);
project.compileOnSaveEnabled = compilerOptions.compileOnSave;
project.compileOnSaveEnabled = compilerOptions.compileOnSave!;
project.markAsDirty();
this.delayUpdateProjectGraph(project);
}
@@ -692,7 +692,7 @@ namespace ts.server {
return this.findExternalProjectByProjectName(projectName) || this.findConfiguredProjectByProjectName(toNormalizedPath(projectName));
}
getDefaultProjectForFile(fileName: NormalizedPath, ensureProject: boolean) {
getDefaultProjectForFile(fileName: NormalizedPath, ensureProject: boolean): Project | undefined {
let scriptInfo = this.getScriptInfoForNormalizedPath(fileName);
if (ensureProject && (!scriptInfo || scriptInfo.isOrphan())) {
this.ensureProjectStructuresUptoDate();
@@ -702,7 +702,7 @@ namespace ts.server {
}
return scriptInfo.getDefaultProject();
}
return scriptInfo && !scriptInfo.isOrphan() && scriptInfo.getDefaultProject();
return scriptInfo && !scriptInfo.isOrphan() ? scriptInfo.getDefaultProject() : undefined;
}
getScriptInfoEnsuringProjectsUptoDate(uncheckedFileName: string) {
@@ -810,7 +810,7 @@ namespace ts.server {
/** Gets the config file existence info for the configured project */
/*@internal*/
getConfigFileExistenceInfo(project: ConfiguredProject) {
return this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath);
return this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath)!;
}
private onConfigChangedForConfiguredProject(project: ConfiguredProject, eventKind: FileWatcherEventKind) {
@@ -846,7 +846,7 @@ namespace ts.server {
private onConfigFileChangeForOpenScriptInfo(configFileName: NormalizedPath, eventKind: FileWatcherEventKind) {
// This callback is called only if we dont have config file project for this config file
const canonicalConfigPath = normalizedPathToPath(configFileName, this.currentDirectory, this.toCanonicalFileName);
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigPath);
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigPath)!;
configFileExistenceInfo.exists = (eventKind !== FileWatcherEventKind.Deleted);
this.logConfigFileWatchUpdate(configFileName, canonicalConfigPath, configFileExistenceInfo, ConfigFileWatcherStatus.ReloadingFiles);
@@ -975,7 +975,7 @@ namespace ts.server {
if (ensureProjectsForOpenFiles) {
// collect orphaned files and assign them to inferred project just like we treat open of a file
this.openFiles.forEach((projectRootPath, path) => {
const info = this.getScriptInfoForPath(path as Path);
const info = this.getScriptInfoForPath(path as Path)!;
// collect all orphaned script infos from open files
if (info.isOrphan()) {
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
@@ -1001,7 +1001,7 @@ namespace ts.server {
this.filenameToScriptInfo.delete(info.path);
const realpath = info.getRealpathIfDifferent();
if (realpath) {
this.realpathToScriptInfos.remove(realpath, info);
this.realpathToScriptInfos!.remove(realpath, info); // TODO: GH#18217
}
}
@@ -1091,7 +1091,7 @@ namespace ts.server {
const inferredRoots: string[] = [];
const otherFiles: string[] = [];
configFileExistenceInfo.openFilesImpactedByConfigFile.forEach((isRootOfInferredProject, key) => {
const info = this.getScriptInfoForPath(key as Path);
const info = this.getScriptInfoForPath(key as Path)!;
(isRootOfInferredProject ? inferredRoots : otherFiles).push(info.fileName);
});
@@ -1235,7 +1235,7 @@ namespace ts.server {
const projectRootPath = this.openFiles.get(info.path);
let searchPath = asNormalizedPath(getDirectoryPath(info.fileName));
const isSearchPathInProjectRoot = () => containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames);
const isSearchPathInProjectRoot = () => containsPath(projectRootPath!, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames);
// If projectRootPath doesnt contain info.path, then do normal search for config file
const anySearchPathOk = !projectRootPath || !isSearchPathInProjectRoot();
@@ -1310,7 +1310,7 @@ namespace ts.server {
this.logger.info("Open files: ");
this.openFiles.forEach((projectRootPath, path) => {
const info = this.getScriptInfoForPath(path as Path);
const info = this.getScriptInfoForPath(path as Path)!;
this.logger.info(`\tFileName: ${info.fileName} ProjectRootPath: ${projectRootPath}`);
if (writeProjectFileNames) {
this.logger.info(`\t\tProjects: ${info.containingProjects.map(p => p.getProjectName())}`);
@@ -1337,7 +1337,7 @@ namespace ts.server {
private convertConfigFileContentToProjectOptions(configFilename: string, cachedDirectoryStructureHost: CachedDirectoryStructureHost) {
configFilename = normalizePath(configFilename);
const configFileContent = this.host.readFile(configFilename);
const configFileContent = this.host.readFile(configFilename)!; // TODO: GH#18217
const result = parseJsonText(configFilename, configFileContent);
if (!result.endOfFileToken) {
@@ -1366,7 +1366,7 @@ namespace ts.server {
configHasFilesProperty: parsedCommandLine.raw.files !== undefined,
configHasIncludeProperty: parsedCommandLine.raw.include !== undefined,
configHasExcludeProperty: parsedCommandLine.raw.exclude !== undefined,
wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories),
wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories!), // TODO: GH#18217
typeAcquisition: parsedCommandLine.typeAcquisition,
compileOnSave: parsedCommandLine.compileOnSave,
projectReferences: parsedCommandLine.projectReferences
@@ -1376,7 +1376,7 @@ namespace ts.server {
}
/** Get a filename if the language service exceeds the maximum allowed program size; otherwise returns undefined. */
private getFilenameForExceededTotalSizeLimitForNonTsFiles<T>(name: string, options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader<T>): string | undefined {
private getFilenameForExceededTotalSizeLimitForNonTsFiles<T>(name: string, options: CompilerOptions | undefined, fileNames: T[], propertyReader: FilePropertyReader<T>): string | undefined {
if (options && options.disableSizeLimit || !this.host.getFileSize) {
return;
}
@@ -1414,7 +1414,7 @@ namespace ts.server {
function getTop5LargestFiles({ propertyReader, hasTypeScriptFileExtension, host }: { propertyReader: FilePropertyReader<any>, hasTypeScriptFileExtension: (filename: string) => boolean, host: ServerHost }) {
return fileNames.map(f => propertyReader.getFileName(f))
.filter(name => hasTypeScriptFileExtension(name))
.map(name => ({ name, size: host.getFileSize(name) }))
.map(name => ({ name, size: host.getFileSize!(name) })) // TODO: GH#18217
.sort((a, b) => b.size - a.size)
.slice(0, 5);
}
@@ -1469,7 +1469,7 @@ namespace ts.server {
return "other";
}
const configFilePath = project instanceof ConfiguredProject && project.getConfigFilePath();
const configFilePath = project instanceof ConfiguredProject ? project.getConfigFilePath() : undefined!; // TODO: GH#18217
return getBaseConfigFileName(configFilePath) || "other";
}
@@ -1490,16 +1490,16 @@ namespace ts.server {
}
private createConfiguredProject(configFileName: NormalizedPath) {
const cachedDirectoryStructureHost = createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames);
const cachedDirectoryStructureHost = createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames)!; // TODO: GH#18217
const { projectOptions, configFileErrors, configFileSpecs } = this.convertConfigFileContentToProjectOptions(configFileName, cachedDirectoryStructureHost);
this.logger.info(`Opened configuration file ${configFileName}`);
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files!, fileNamePropertyReader); // TODO: GH#18217
const project = new ConfiguredProject(
configFileName,
this,
this.documentRegistry,
projectOptions.configHasFilesProperty,
projectOptions.compilerOptions,
projectOptions.compilerOptions!, // TODO: GH#18217
lastFileExceededProgramSize,
projectOptions.compileOnSave === undefined ? false : projectOptions.compileOnSave,
cachedDirectoryStructureHost,
@@ -1516,12 +1516,12 @@ namespace ts.server {
project
);
if (!lastFileExceededProgramSize) {
project.watchWildcards(projectOptions.wildcardDirectories);
project.watchWildcards(projectOptions.wildcardDirectories!); // TODO: GH#18217
}
project.setProjectErrors(configFileErrors);
const filesToAdd = projectOptions.files.concat(project.getExternalFiles());
this.addFilesToNonInferredProjectAndUpdateGraph(project, filesToAdd, fileNamePropertyReader, projectOptions.typeAcquisition);
const filesToAdd = projectOptions.files!.concat(project.getExternalFiles());
this.addFilesToNonInferredProjectAndUpdateGraph(project, filesToAdd, fileNamePropertyReader, projectOptions.typeAcquisition!); // TODO: GH#18217
this.configuredProjects.set(project.canonicalConfigFilePath, project);
this.setConfigFileExistenceByNewConfiguredProject(project);
this.sendProjectTelemetry(configFileName, project, projectOptions);
@@ -1541,7 +1541,7 @@ namespace ts.server {
// Use the project's fileExists so that it can use caching instead of reaching to disk for the query
if (!isDynamic && !project.fileExists(newRootFile)) {
path = normalizedPathToPath(normalizedPath, this.currentDirectory, this.toCanonicalFileName);
const existingValue = projectRootFilesMap.get(path);
const existingValue = projectRootFilesMap.get(path)!;
if (isScriptInfo(existingValue)) {
project.removeFile(existingValue, /*fileExists*/ false, /*detachFromProject*/ true);
}
@@ -1551,7 +1551,7 @@ namespace ts.server {
else {
const scriptKind = propertyReader.getScriptKind(f, this.hostConfiguration.extraFileExtensions);
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
scriptInfo = this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(normalizedPath, project.currentDirectory, scriptKind, hasMixedContent, project.directoryStructureHost);
scriptInfo = this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(normalizedPath, project.currentDirectory, scriptKind, hasMixedContent, project.directoryStructureHost)!; // TODO: GH#18217
path = scriptInfo.path;
// If this script info is not already a root add it
if (!project.isRoot(scriptInfo)) {
@@ -1586,7 +1586,7 @@ namespace ts.server {
project.markAsDirty();
}
private updateNonInferredProject<T>(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader<T>, newOptions: CompilerOptions, newTypeAcquisition: TypeAcquisition, compileOnSave: boolean) {
private updateNonInferredProject<T>(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader<T>, newOptions: CompilerOptions, newTypeAcquisition: TypeAcquisition, compileOnSave: boolean | undefined) {
project.setCompilerOptions(newOptions);
// VS only set the CompileOnSaveEnabled option in the request if the option was changed recently
// therefore if it is undefined, it should not be updated.
@@ -1601,7 +1601,7 @@ namespace ts.server {
*/
/*@internal*/
reloadFileNamesOfConfiguredProject(project: ConfiguredProject): boolean {
const configFileSpecs = project.configFileSpecs;
const configFileSpecs = project.configFileSpecs!; // TODO: GH#18217
const configFileName = project.getConfigFilePath();
const fileNamesResult = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), project.getCompilationSettings(), project.getCachedDirectoryStructureHost(), this.hostConfiguration.extraFileExtensions);
project.updateErrorOnNoInputFiles(fileNamesResult.fileNames.length !== 0);
@@ -1629,16 +1629,16 @@ namespace ts.server {
project.configFileSpecs = configFileSpecs;
project.setProjectErrors(configFileErrors);
project.updateReferences(projectOptions.projectReferences);
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files!, fileNamePropertyReader); // TODO: GH#18217
if (lastFileExceededProgramSize) {
project.disableLanguageService(lastFileExceededProgramSize);
project.stopWatchingWildCards();
}
else {
project.enableLanguageService();
project.watchWildcards(projectOptions.wildcardDirectories);
project.watchWildcards(projectOptions.wildcardDirectories!); // TODO: GH#18217
}
this.updateNonInferredProject(project, projectOptions.files, fileNamePropertyReader, projectOptions.compilerOptions, projectOptions.typeAcquisition, projectOptions.compileOnSave);
this.updateNonInferredProject(project, projectOptions.files!, fileNamePropertyReader, projectOptions.compilerOptions!, projectOptions.typeAcquisition!, projectOptions.compileOnSave!); // TODO: GH#18217
this.sendConfigFileDiagEvent(project, configFileName);
}
@@ -1671,7 +1671,7 @@ namespace ts.server {
// we don't have an explicit root path, so we should try to find an inferred project
// that more closely contains the file.
let bestMatch: InferredProject;
let bestMatch: InferredProject | undefined;
for (const project of this.inferredProjects) {
// ignore single inferred projects (handled elsewhere)
if (!project.projectRootPath) continue;
@@ -1679,7 +1679,7 @@ namespace ts.server {
if (!containsPath(project.projectRootPath, info.path, this.host.getCurrentDirectory(), !this.host.useCaseSensitiveFileNames)) continue;
// ignore inferred projects that are higher up in the project root.
// TODO(rbuckton): Should we add the file as a root to these as well?
if (bestMatch && bestMatch.projectRootPath.length > project.projectRootPath.length) continue;
if (bestMatch && bestMatch.projectRootPath!.length > project.projectRootPath.length) continue;
bestMatch = project;
}
@@ -1837,7 +1837,7 @@ namespace ts.server {
if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
return;
}
info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent, path);
info = new ScriptInfo(this.host, fileName, scriptKind!, !!hasMixedContent, path); // TODO: GH#18217
this.filenameToScriptInfo.set(info.path, info);
if (!openedByClient) {
this.watchClosedScriptInfo(info);
@@ -1851,7 +1851,7 @@ namespace ts.server {
// Opening closed script info
// either it was created just now, or was part of projects but was closed
this.stopWatchingScriptInfo(info);
info.open(fileContent);
info.open(fileContent!);
if (hasMixedContent) {
info.registerFileUpdate();
}
@@ -1878,7 +1878,7 @@ namespace ts.server {
if (args.file) {
const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file));
if (info) {
info.setOptions(convertFormatOptions(args.formatOptions), args.preferences);
info.setOptions(convertFormatOptions(args.formatOptions!), args.preferences);
this.logger.info(`Host configuration update for file ${args.file}`);
}
}
@@ -1952,7 +1952,7 @@ namespace ts.server {
return;
}
const info = this.getScriptInfoForPath(path as Path);
const info = this.getScriptInfoForPath(path as Path)!; // TODO: GH#18217
Debug.assert(info.isScriptOpen());
// This tries to search for a tsconfig.json for the given file. If we found it,
// we first detect if there is already a configured project created for it: if so,
@@ -2020,7 +2020,7 @@ namespace ts.server {
this.printProjects();
this.openFiles.forEach((projectRootPath, path) => {
const info = this.getScriptInfoForPath(path as Path);
const info = this.getScriptInfoForPath(path as Path)!;
// collect all orphaned script infos from open files
if (info.isOrphan()) {
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
@@ -2055,10 +2055,10 @@ namespace ts.server {
}
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
let configFileName: NormalizedPath;
let configFileErrors: ReadonlyArray<Diagnostic>;
let configFileName: NormalizedPath | undefined;
let configFileErrors: ReadonlyArray<Diagnostic> | undefined;
const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent);
const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent)!; // TODO: GH#18217
this.openFiles.set(info.path, projectRootPath);
let project: ConfiguredProject | ExternalProject | undefined = this.findExternalProjectContainingOpenScriptInfo(info);
if (!project && !this.syntaxOnly) { // Checking syntaxOnly is an optimization
@@ -2100,7 +2100,6 @@ namespace ts.server {
}
Debug.assert(!info.isOrphan());
// Remove the configured projects that have zero references from open files.
// This was postponed from closeOpenFile to after opening next file,
// so that we can reuse the project if we need to right away
@@ -2141,7 +2140,7 @@ namespace ts.server {
return;
}
const info: OpenFileInfo = { checkJs: !!scriptInfo.getDefaultProject().getSourceFile(scriptInfo.path).checkJsDirective };
const info: OpenFileInfo = { checkJs: !!scriptInfo.getDefaultProject().getSourceFile(scriptInfo.path)!.checkJsDirective };
this.eventHandler({ eventName: OpenFileInfoTelemetryEvent, data: { info } });
}
@@ -2159,7 +2158,7 @@ namespace ts.server {
private collectChanges(lastKnownProjectVersions: protocol.ProjectVersionInfo[], currentProjects: Project[], result: ProjectFilesWithTSDiagnostics[]): void {
for (const proj of currentProjects) {
const knownProject = forEach(lastKnownProjectVersions, p => p.projectName === proj.getProjectName() && p);
const knownProject = find(lastKnownProjectVersions, p => p.projectName === proj.getProjectName());
result.push(proj.getChangesSinceVersion(knownProject && knownProject.version));
}
}
@@ -2174,19 +2173,19 @@ namespace ts.server {
}
/* @internal */
applyChangesInOpenFiles(openFiles: protocol.ExternalFile[], changedFiles: protocol.ChangedOpenFile[], closedFiles: string[]): void {
applyChangesInOpenFiles(openFiles: protocol.ExternalFile[] | undefined, changedFiles: protocol.ChangedOpenFile[] | undefined, closedFiles: string[] | undefined): void {
if (openFiles) {
for (const file of openFiles) {
const scriptInfo = this.getScriptInfo(file.fileName);
Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind!), file.hasMixedContent); // TODO: GH#18217
}
}
if (changedFiles) {
for (const file of changedFiles) {
const scriptInfo = this.getScriptInfo(file.fileName);
const scriptInfo = this.getScriptInfo(file.fileName)!;
Debug.assert(!!scriptInfo);
this.applyChangesToFile(scriptInfo, file.changes);
}
@@ -2267,7 +2266,8 @@ namespace ts.server {
}
applySafeList(proj: protocol.ExternalProject): NormalizedPath[] {
const { rootFiles, typeAcquisition } = proj;
const { rootFiles } = proj;
const typeAcquisition = proj.typeAcquisition!;
Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now");
// If type acquisition has been explicitly disabled, do not exclude anything from the project
if (typeAcquisition.enable === false) {
@@ -2390,7 +2390,7 @@ namespace ts.server {
const excludedFiles = this.applySafeList(proj);
let tsConfigFiles: NormalizedPath[];
let tsConfigFiles: NormalizedPath[] | undefined;
const rootFiles: protocol.ExternalFile[] = [];
for (const file of proj.rootFiles) {
const normalized = toNormalizedPath(file.fileName);
@@ -2410,7 +2410,7 @@ namespace ts.server {
}
const externalProject = this.findExternalProjectByProjectName(proj.projectFileName);
let exisingConfigFiles: string[];
let exisingConfigFiles: string[] | undefined;
if (externalProject) {
externalProject.excludedFiles = excludedFiles;
if (!tsConfigFiles) {
@@ -2438,7 +2438,7 @@ namespace ts.server {
}
else {
// project previously had some config files - compare them with new set of files and close all configured projects that correspond to unused files
const oldConfigFiles = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName);
const oldConfigFiles = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName)!;
let iNew = 0;
let iOld = 0;
while (iNew < tsConfigFiles.length && iOld < oldConfigFiles.length) {
@@ -2487,7 +2487,7 @@ namespace ts.server {
}
hasDeferredExtension() {
for (const extension of this.hostConfiguration.extraFileExtensions) {
for (const extension of this.hostConfiguration.extraFileExtensions!) { // TODO: GH#18217
if (extension.scriptKind === ScriptKind.Deferred) {
return true;
}
+42 -42
View File
@@ -103,7 +103,7 @@ namespace ts.server {
cachedUnresolvedImportsPerFile = createMap<ReadonlyArray<string>>();
/*@internal*/
lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
lastCachedUnresolvedImportsList: SortedReadonlyArray<string> | undefined;
/*@internal*/
private hasAddedorRemovedFiles = false;
@@ -127,7 +127,7 @@ namespace ts.server {
/**
* Set of files names that were updated since the last call to getChangesSinceVersion.
*/
private updatedFileNames: Map<true>;
private updatedFileNames: Map<true> | undefined;
/**
* Set of files that was returned from the last call to getChangesSinceVersion.
*/
@@ -173,7 +173,7 @@ namespace ts.server {
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} | undefined {
const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
const result = host.require(resolvedPath, moduleName);
const result = host.require!(resolvedPath, moduleName); // TODO: GH#18217
if (result.error) {
const err = result.error.stack || result.error.message || JSON.stringify(result.error);
log(`Failed to load module '${moduleName}': ${err}`);
@@ -226,11 +226,11 @@ namespace ts.server {
this.trace = s => this.writeLog(s);
}
else if (host.trace) {
this.trace = s => host.trace(s);
this.trace = s => host.trace!(s);
}
if (host.realpath) {
this.realpath = path => host.realpath(path);
this.realpath = path => host.realpath!(path);
}
// Use the current directory as resolution root only if the project created using current directory string
@@ -307,15 +307,15 @@ namespace ts.server {
getScriptKind(fileName: string) {
const info = this.getOrCreateScriptInfoAndAttachToProject(fileName);
return info && info.scriptKind;
return (info && info.scriptKind)!; // TODO: GH#18217
}
getScriptVersion(filename: string) {
const info = this.getOrCreateScriptInfoAndAttachToProject(filename);
return info && info.getLatestVersion();
return (info && info.getLatestVersion())!; // TODO: GH#18217
}
getScriptSnapshot(filename: string): IScriptSnapshot {
getScriptSnapshot(filename: string): IScriptSnapshot | undefined {
const scriptInfo = this.getOrCreateScriptInfoAndAttachToProject(filename);
if (scriptInfo) {
return scriptInfo.getSnapshot();
@@ -340,7 +340,7 @@ namespace ts.server {
}
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[] {
return this.directoryStructureHost.readDirectory(path, extensions, exclude, include, depth);
return this.directoryStructureHost.readDirectory!(path, extensions, exclude, include, depth);
}
readFile(fileName: string): string | undefined {
@@ -358,7 +358,7 @@ namespace ts.server {
return this.resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames);
}
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations {
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined {
return this.resolutionCache.getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile);
}
@@ -367,16 +367,16 @@ namespace ts.server {
}
directoryExists(path: string): boolean {
return this.directoryStructureHost.directoryExists(path);
return this.directoryStructureHost.directoryExists!(path); // TODO: GH#18217
}
getDirectories(path: string): string[] {
return this.directoryStructureHost.getDirectories(path);
return this.directoryStructureHost.getDirectories!(path); // TODO: GH#18217
}
/*@internal*/
getCachedDirectoryStructureHost(): CachedDirectoryStructureHost {
return undefined;
return undefined!; // TODO: GH#18217
}
/*@internal*/
@@ -471,8 +471,8 @@ namespace ts.server {
}
this.updateGraph();
this.builderState = BuilderState.create(this.program, this.projectService.toCanonicalFileName, this.builderState);
return mapDefined(BuilderState.getFilesAffectedBy(this.builderState, this.program, scriptInfo.path, this.cancellationToken, data => this.projectService.host.createHash(data)),
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined);
return mapDefined(BuilderState.getFilesAffectedBy(this.builderState, this.program, scriptInfo.path, this.cancellationToken, data => this.projectService.host.createHash!(data)), // TODO: GH#18217
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)!) ? sourceFile.fileName : undefined);
}
/**
@@ -567,25 +567,25 @@ namespace ts.server {
}
this.projectService.pendingEnsureProjectForOpenFiles = true;
this.rootFiles = undefined;
this.rootFilesMap = undefined;
this.externalFiles = undefined;
this.program = undefined;
this.builderState = undefined;
this.rootFiles = undefined!;
this.rootFilesMap = undefined!;
this.externalFiles = undefined!;
this.program = undefined!;
this.builderState = undefined!;
this.resolutionCache.clear();
this.resolutionCache = undefined;
this.cachedUnresolvedImportsPerFile = undefined;
this.directoryStructureHost = undefined;
this.resolutionCache = undefined!;
this.cachedUnresolvedImportsPerFile = undefined!;
this.directoryStructureHost = undefined!;
// Clean up file watchers waiting for missing files
if (this.missingFilesMap) {
clearMap(this.missingFilesMap, closeFileWatcher);
this.missingFilesMap = undefined;
this.missingFilesMap = undefined!;
}
// signal language service to release source files acquired from document registry
this.languageService.dispose();
this.languageService = undefined;
this.languageService = undefined!;
}
private detachScriptInfoIfNotRoot(uncheckedFilename: string) {
@@ -623,17 +623,15 @@ namespace ts.server {
return this.rootFiles;
}
getScriptInfos() {
getScriptInfos(): ScriptInfo[] {
if (!this.languageServiceEnabled) {
// if language service is not enabled - return just root files
return this.rootFiles;
}
return map(this.program.getSourceFiles(), sourceFile => {
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.path);
if (!scriptInfo) {
Debug.fail(`scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' is missing.`);
}
return scriptInfo;
Debug.assert(!!scriptInfo, "getScriptInfo", () => `scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' is missing.`);
return scriptInfo!;
});
}
@@ -701,11 +699,12 @@ namespace ts.server {
return this.isRoot(info) || (this.program && this.program.getSourceFileByPath(info.path) !== undefined);
}
containsFile(filename: NormalizedPath, requireOpen?: boolean) {
containsFile(filename: NormalizedPath, requireOpen?: boolean): boolean {
const info = this.projectService.getScriptInfoForPath(this.toPath(filename));
if (info && (info.isScriptOpen() || !requireOpen)) {
return this.containsScriptInfo(info);
}
return false;
}
isRoot(info: ScriptInfo) {
@@ -879,7 +878,7 @@ namespace ts.server {
const start = timestamp();
this.hasInvalidatedResolution = this.resolutionCache.createHasInvalidatedResolution();
this.resolutionCache.startCachingPerDirectoryResolution();
this.program = this.languageService.getProgram();
this.program = this.languageService.getProgram()!; // TODO: GH#18217
this.dirty = false;
this.resolutionCache.finishCachingPerDirectoryResolution();
@@ -888,7 +887,7 @@ namespace ts.server {
// bump up the version if
// - oldProgram is not set - this is a first time updateGraph is called
// - newProgram is different from the old program and structure of the old program was not reused.
const hasNewProgram = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & StructureIsReused.Completely)));
const hasNewProgram = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused! & StructureIsReused.Completely)));
this.hasChangedAutomaticTypeDirectiveNames = false;
if (hasNewProgram) {
if (oldProgram) {
@@ -922,7 +921,7 @@ namespace ts.server {
// by the LSHost for files in the program when the program is retrieved above but
// the program doesn't contain external files so this must be done explicitly.
inserted => {
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.currentDirectory, this.directoryStructureHost);
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.currentDirectory, this.directoryStructureHost)!;
scriptInfo.attachToProject(this);
},
removed => this.detachScriptInfoFromProject(removed)
@@ -1212,7 +1211,8 @@ namespace ts.server {
ProjectKind.Inferred,
projectService,
documentRegistry,
/*files*/ undefined,
// TODO: GH#18217
/*files*/ undefined!,
/*lastFileExceededProgramSize*/ undefined,
compilerOptions,
/*compileOnSaveEnabled*/ false,
@@ -1279,7 +1279,7 @@ namespace ts.server {
export class ConfiguredProject extends Project {
private typeAcquisition: TypeAcquisition;
/* @internal */
configFileWatcher: FileWatcher;
configFileWatcher: FileWatcher | undefined;
private directoriesWatchedForWildcards: Map<WildcardDirectoryWatcher> | undefined;
readonly canonicalConfigFilePath: NormalizedPath;
@@ -1287,12 +1287,12 @@ namespace ts.server {
pendingReload: ConfigFileProgramReloadLevel;
/*@internal*/
configFileSpecs: ConfigFileSpecs;
configFileSpecs: ConfigFileSpecs | undefined;
/** Ref count to the project when opened from external project */
private externalProjectRefCount = 0;
private projectErrors: Diagnostic[];
private projectErrors: Diagnostic[] | undefined;
/*@internal*/
constructor(configFileName: NormalizedPath,
@@ -1473,7 +1473,7 @@ namespace ts.server {
// The project is referenced only if open files impacted by this project are present in this project
return forEachEntry(
configFileExistenceInfo.openFilesImpactedByConfigFile,
(_value, infoPath) => this.containsScriptInfo(this.projectService.getScriptInfoForPath(infoPath as Path))
(_value, infoPath) => this.containsScriptInfo(this.projectService.getScriptInfoForPath(infoPath as Path)!)
) || false;
}
@@ -1484,10 +1484,10 @@ namespace ts.server {
/*@internal*/
updateErrorOnNoInputFiles(hasFileNames: boolean) {
if (hasFileNames) {
filterMutate(this.projectErrors, error => !isErrorNoInputFiles(error));
filterMutate(this.projectErrors!, error => !isErrorNoInputFiles(error)); // TODO: GH#18217
}
else if (!this.configFileSpecs.filesSpecs && !some(this.projectErrors, isErrorNoInputFiles)) {
this.projectErrors.push(getErrorForNoInputFiles(this.configFileSpecs, this.getConfigFilePath()));
else if (!this.configFileSpecs!.filesSpecs && !some(this.projectErrors, isErrorNoInputFiles)) { // TODO: GH#18217
this.projectErrors!.push(getErrorForNoInputFiles(this.configFileSpecs!, this.getConfigFilePath()));
}
}
}
+5 -5
View File
@@ -1201,7 +1201,7 @@ namespace ts.server.protocol {
/**
* Filename of the last file analyzed before disabling the language service. undefined, if the language service is enabled.
*/
lastFileExceededProgramSize: string | undefined;
lastFileExceededProgramSize?: string;
}
/**
@@ -1809,7 +1809,7 @@ namespace ts.server.protocol {
export interface CompletionEntryIdentifier {
name: string;
source: string;
source?: string;
}
/**
@@ -1853,7 +1853,7 @@ namespace ts.server.protocol {
/**
* Optional modifiers for the kind (such as 'public').
*/
kindModifiers: string;
kindModifiers?: string;
/**
* A string that is used for comparing completion items so that they can be ordered. This
* is often the same as the name but may be different in certain circumstances.
@@ -1912,12 +1912,12 @@ namespace ts.server.protocol {
/**
* Documentation strings for the symbol.
*/
documentation: SymbolDisplayPart[];
documentation?: SymbolDisplayPart[];
/**
* JSDoc tags for the symbol.
*/
tags: JSDocTagInfo[];
tags?: JSDocTagInfo[];
/**
* The associated code actions for this entry
+14 -14
View File
@@ -14,11 +14,11 @@ namespace ts.server {
* The script version cache is generated on demand and text is still retained.
* Only on edits to the script version cache, the text will be set to undefined
*/
private text: string;
private text: string | undefined;
/**
* Line map for the text when there is no script version cache present
*/
private lineMap: number[];
private lineMap: number[] | undefined;
private textVersion = 0;
/**
@@ -115,7 +115,7 @@ namespace ts.server {
public getSnapshot(): IScriptSnapshot {
return this.useScriptVersionCacheIfValidOrOpen()
? this.svc.getSnapshot()
? this.svc!.getSnapshot()
: ScriptSnapshot.fromString(this.getOrLoadText());
}
@@ -129,10 +129,10 @@ namespace ts.server {
if (!this.useScriptVersionCacheIfValidOrOpen()) {
const lineMap = this.getLineMap();
const start = lineMap[line]; // -1 since line is 1-based
const end = line + 1 < lineMap.length ? lineMap[line + 1] : this.text.length;
const end = line + 1 < lineMap.length ? lineMap[line + 1] : this.text!.length;
return createTextSpanFromBounds(start, end);
}
return this.svc.lineToTextSpan(line);
return this.svc!.lineToTextSpan(line);
}
/**
@@ -145,7 +145,7 @@ namespace ts.server {
}
// TODO: assert this offset is actually on the line
return this.svc.lineOffsetToPosition(line, offset);
return this.svc!.lineOffsetToPosition(line, offset);
}
positionToLineOffset(position: number): protocol.Location {
@@ -153,7 +153,7 @@ namespace ts.server {
const { line, character } = computeLineAndCharacterOfPosition(this.getLineMap(), position);
return { line: line + 1, offset: character + 1 };
}
return this.svc.positionToLineOffset(position);
return this.svc!.positionToLineOffset(position);
}
private getFileText(tempFileName?: string) {
@@ -188,7 +188,7 @@ namespace ts.server {
Debug.assert(!this.svc || this.pendingReloadFromDisk, "ScriptVersionCache should not be set when reloading from disk");
this.reloadWithFileText();
}
return this.text;
return this.text!;
}
private getLineMap() {
@@ -217,7 +217,7 @@ namespace ts.server {
private preferences: UserPreferences | undefined;
/* @internal */
fileWatcher: FileWatcher;
fileWatcher: FileWatcher | undefined;
private textStorage: TextStorage;
/*@internal*/
@@ -294,7 +294,7 @@ namespace ts.server {
this.realpath = project.toPath(realpath);
// If it is different from this.path, add to the map
if (this.realpath !== this.path) {
project.projectService.realpathToScriptInfos.add(this.realpath, this);
project.projectService.realpathToScriptInfos!.add(this.realpath, this); // TODO: GH#18217
}
}
}
@@ -306,8 +306,8 @@ namespace ts.server {
return this.realpath && this.realpath !== this.path ? this.realpath : undefined;
}
getFormatCodeSettings(): FormatCodeSettings { return this.formatSettings; }
getPreferences(): UserPreferences { return this.preferences; }
getFormatCodeSettings(): FormatCodeSettings | undefined { return this.formatSettings; }
getPreferences(): UserPreferences | undefined { return this.preferences; }
attachToProject(project: Project): boolean {
const isNew = !this.isAttached(project);
@@ -345,7 +345,7 @@ namespace ts.server {
case 2:
if (this.containingProjects[0] === project) {
project.onFileAddedOrRemoved();
this.containingProjects[0] = this.containingProjects.pop();
this.containingProjects[0] = this.containingProjects.pop()!;
}
else if (this.containingProjects[1] === project) {
project.onFileAddedOrRemoved();
@@ -406,7 +406,7 @@ namespace ts.server {
}
}
setOptions(formatSettings: FormatCodeSettings, preferences: UserPreferences): void {
setOptions(formatSettings: FormatCodeSettings, preferences: UserPreferences | undefined): void {
if (formatSettings) {
if (!this.formatSettings) {
this.formatSettings = getDefaultFormatCodeSettings(this.host);
+12 -11
View File
@@ -55,7 +55,7 @@ namespace ts.server {
this.stack = [this.lineIndex.root];
}
insertLines(insertedText: string, suppressTrailingText: boolean) {
insertLines(insertedText: string | undefined, suppressTrailingText: boolean) {
if (suppressTrailingText) {
this.trailingText = "";
}
@@ -72,8 +72,8 @@ namespace ts.server {
lines.pop();
}
}
let branchParent: LineNode;
let lastZeroCount: LineCollection;
let branchParent: LineNode | undefined;
let lastZeroCount: LineCollection | undefined;
for (let k = this.endBranch.length - 1; k >= 0; k--) {
(<LineNode>this.endBranch[k]).updateCounts();
@@ -88,7 +88,7 @@ namespace ts.server {
}
}
if (lastZeroCount) {
branchParent.remove(lastZeroCount);
branchParent!.remove(lastZeroCount);
}
// path at least length two (root and leaf)
@@ -159,7 +159,7 @@ namespace ts.server {
this.lineCollectionAtBranch = lineCollection;
}
let child: LineCollection;
let child: LineCollection | undefined;
function fresh(node: LineCollection): LineCollection {
if (node.isLeaf()) {
return new LineLeaf("");
@@ -332,7 +332,7 @@ namespace ts.server {
if (oldVersion >= this.minVersion) {
const textChangeRanges: TextChangeRange[] = [];
for (let i = oldVersion + 1; i <= newVersion; i++) {
const snap = this.versions[this.versionToIndex(i)];
const snap = this.versions[this.versionToIndex(i)!]; // TODO: GH#18217
for (const textChange of snap.changesSincePreviousVersion) {
textChangeRanges.push(textChange.getTextChangeRange());
}
@@ -370,7 +370,7 @@ namespace ts.server {
return this.index.getLength();
}
getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange {
getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange | undefined {
if (oldSnapshot instanceof LineIndexSnapshot && this.cache === oldSnapshot.cache) {
if (this.version <= oldSnapshot.version) {
return unchangedTextChangeRange;
@@ -397,7 +397,7 @@ namespace ts.server {
return { line: oneBasedLine, offset: zeroBasedColumn + 1 };
}
private positionToColumnAndLineText(position: number): { zeroBasedColumn: number, lineText: string } {
private positionToColumnAndLineText(position: number): { zeroBasedColumn: number, lineText: string | undefined } {
return this.root.charOffsetToLineInfo(1, position);
}
@@ -471,9 +471,10 @@ namespace ts.server {
this.load(LineIndex.linesFromText(newText).lines);
return this;
}
return undefined!; // TODO: GH#18217
}
else {
let checkText: string;
let checkText: string | undefined;
if (this.checkEdits) {
const source = this.getText(0, this.root.charCount());
checkText = source.slice(0, pos) + newText + source.slice(pos + deleteLength);
@@ -499,7 +500,7 @@ namespace ts.server {
const { zeroBasedColumn, lineText } = this.positionToColumnAndLineText(e);
if (zeroBasedColumn === 0) {
// move range end just past line that will merge with previous line
deleteLength += lineText.length;
deleteLength += lineText!.length; // TODO: GH#18217
// store text by appending to end of insertedText
newText = newText ? newText + lineText : lineText;
}
@@ -700,7 +701,7 @@ namespace ts.server {
}
private splitAfter(childIndex: number) {
let splitNode: LineNode;
let splitNode: LineNode | undefined;
const clen = this.children.length;
childIndex++;
const endLength = childIndex;
+20 -19
View File
@@ -1,3 +1,5 @@
// tslint:disable no-unnecessary-type-assertion (TODO: tslint can't find node types)
namespace ts.server {
const childProcess: {
fork(modulePath: string, args: string[], options?: { execArgv: string[], env?: MapLike<string> }): NodeChildProcess;
@@ -38,8 +40,7 @@ namespace ts.server {
return combinePaths(combinePaths(cacheLocation, "typescript"), versionMajorMinor);
}
default:
Debug.fail(`unsupported platform '${process.platform}'`);
return;
return Debug.fail(`unsupported platform '${process.platform}'`);
}
}
@@ -200,7 +201,7 @@ namespace ts.server {
if (this.fd >= 0) {
const buf = new Buffer(s);
// tslint:disable-next-line no-null-keyword
fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null);
fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null!); // TODO: GH#18217
}
if (this.traceToConsole) {
console.warn(s);
@@ -230,7 +231,7 @@ namespace ts.server {
// buffer, but we have yet to find a way to retrieve that value.
private static readonly maxActiveRequestCount = 10;
private static readonly requestDelayMillis = 100;
private packageInstalledPromise: { resolve(value: ApplyCodeActionCommandResult): void, reject(reason: any): void };
private packageInstalledPromise: { resolve(value: ApplyCodeActionCommandResult): void, reject(reason: any): void } | undefined;
constructor(
private readonly telemetryEnabled: boolean,
@@ -364,10 +365,10 @@ namespace ts.server {
case ActionPackageInstalled: {
const { success, message } = response;
if (success) {
this.packageInstalledPromise.resolve({ successMessage: message });
this.packageInstalledPromise!.resolve({ successMessage: message });
}
else {
this.packageInstalledPromise.reject(message);
this.packageInstalledPromise!.reject(message);
}
this.packageInstalledPromise = undefined;
@@ -435,7 +436,7 @@ namespace ts.server {
}
while (this.requestQueue.length > 0) {
const queuedRequest = this.requestQueue.shift();
const queuedRequest = this.requestQueue.shift()!;
if (this.requestMap.get(queuedRequest.operationId) === queuedRequest) {
this.requestMap.delete(queuedRequest.operationId);
this.scheduleRequest(queuedRequest);
@@ -468,7 +469,7 @@ namespace ts.server {
}
class IOSession extends Session {
private eventPort: number;
private eventPort: number | undefined;
private eventSocket: NodeSocket | undefined;
private socketEventQueue: { body: any, eventName: string }[] | undefined;
private constructed: boolean | undefined;
@@ -529,7 +530,7 @@ namespace ts.server {
}
event<T extends object>(body: T, eventName: string): void {
Debug.assert(this.constructed, "Should only call `IOSession.prototype.event` on an initialized IOSession");
Debug.assert(!!this.constructed, "Should only call `IOSession.prototype.event` on an initialized IOSession");
if (this.canUseEvents && this.eventPort) {
if (!this.eventSocket) {
@@ -550,7 +551,7 @@ namespace ts.server {
}
private writeToEventSocket(body: object, eventName: string): void {
this.eventSocket.write(formatMessage(toEvent(eventName, body), this.logger, this.byteLength, this.host.newLine), "utf8");
this.eventSocket!.write(formatMessage(toEvent(eventName, body), this.logger, this.byteLength, this.host.newLine), "utf8");
}
exit() {
@@ -578,7 +579,7 @@ namespace ts.server {
logToFile?: boolean;
}
function parseLoggingEnvironmentString(logEnvStr: string): LogOptions {
function parseLoggingEnvironmentString(logEnvStr: string | undefined): LogOptions {
if (!logEnvStr) {
return {};
}
@@ -625,7 +626,7 @@ namespace ts.server {
}
}
function getLogLevel(level: string) {
function getLogLevel(level: string | undefined) {
if (level) {
const l = level.toLowerCase();
for (const name in LogLevel) {
@@ -650,7 +651,7 @@ namespace ts.server {
: undefined;
const logVerbosity = cmdLineVerbosity || envLogOptions.detailLevel;
return new Logger(logFileName, envLogOptions.traceToConsole, logVerbosity);
return new Logger(logFileName!, envLogOptions.traceToConsole!, logVerbosity!); // TODO: GH#18217
}
// This places log file in the directory containing editorServices.js
// TODO: check that this location is writable
@@ -765,11 +766,11 @@ namespace ts.server {
function setCanWriteFlagAndWriteMessageIfNecessary() {
canWrite = true;
if (pending.length) {
writeMessage(pending.shift());
writeMessage(pending.shift()!);
}
}
function extractWatchDirectoryCacheKey(path: string, currentDriveKey: string) {
function extractWatchDirectoryCacheKey(path: string, currentDriveKey: string | undefined) {
path = normalizeSlashes(path);
if (isUNCPath(path)) {
// UNC path: extract server name
@@ -804,7 +805,7 @@ namespace ts.server {
const sys = <ServerHost>ts.sys;
const nodeVersion = getNodeMajorVersion();
// use watchGuard process on Windows when node version is 4 or later
const useWatchGuard = process.platform === "win32" && nodeVersion >= 4;
const useWatchGuard = process.platform === "win32" && nodeVersion! >= 4;
const originalWatchDirectory: ServerHost["watchDirectory"] = sys.watchDirectory.bind(sys);
const noopWatcher: FileWatcher = { close: noop };
// This is the function that catches the exceptions when watching directory, and yet lets project service continue to function
@@ -905,8 +906,8 @@ namespace ts.server {
let eventPort: number | undefined;
{
const str = findArgument("--eventPort");
const v = str && parseInt(str);
if (!isNaN(v)) {
const v = str === undefined ? undefined : parseInt(str);
if (v !== undefined && !isNaN(v)) {
eventPort = v;
}
}
@@ -918,7 +919,7 @@ namespace ts.server {
setStackTraceLimit();
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation);
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation)!; // TODO: GH#18217
const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(sys.getExecutingFilePath(), "../typesMap.json");
const npmLocation = findArgument(Arguments.NpmLocation);
+105 -105
View File
@@ -68,10 +68,10 @@ namespace ts.server {
}
function formatDiag(fileName: NormalizedPath, project: Project, diag: Diagnostic): protocol.Diagnostic {
const scriptInfo = project.getScriptInfoForNormalizedPath(fileName);
const scriptInfo = project.getScriptInfoForNormalizedPath(fileName)!; // TODO: GH#18217
return {
start: scriptInfo.positionToLineOffset(diag.start),
end: scriptInfo.positionToLineOffset(diag.start + diag.length),
start: scriptInfo.positionToLineOffset(diag.start!),
end: scriptInfo.positionToLineOffset(diag.start! + diag.length!), // TODO: GH#18217
text: flattenDiagnosticMessageText(diag.messageText, "\n"),
code: diag.code,
category: diagnosticCategoryName(diag),
@@ -87,8 +87,8 @@ namespace ts.server {
function formatConfigFileDiag(diag: Diagnostic, includeFileName: true): protocol.DiagnosticWithFileName;
function formatConfigFileDiag(diag: Diagnostic, includeFileName: false): protocol.Diagnostic;
function formatConfigFileDiag(diag: Diagnostic, includeFileName: boolean): protocol.Diagnostic | protocol.DiagnosticWithFileName {
const start = diag.file && convertToLocation(getLineAndCharacterOfPosition(diag.file, diag.start));
const end = diag.file && convertToLocation(getLineAndCharacterOfPosition(diag.file, diag.start + diag.length));
const start = (diag.file && convertToLocation(getLineAndCharacterOfPosition(diag.file, diag.start!)))!; // TODO: GH#18217
const end = (diag.file && convertToLocation(getLineAndCharacterOfPosition(diag.file, diag.start! + diag.length!)))!; // TODO: GH#18217
const text = flattenDiagnosticMessageText(diag.messageText, "\n");
const { code, source } = diag;
const category = diagnosticCategoryName(diag);
@@ -177,7 +177,7 @@ namespace ts.server {
}
public immediate(action: () => void) {
const requestId = this.requestId;
const requestId = this.requestId!;
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id");
this.setImmediateId(this.operationHost.getServerHost().setImmediate(() => {
this.immediateId = undefined;
@@ -186,7 +186,7 @@ namespace ts.server {
}
public delay(ms: number, action: () => void) {
const requestId = this.requestId;
const requestId = this.requestId!;
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id");
this.setTimerHandle(this.operationHost.getServerHost().setTimeout(() => {
this.timerHandle = undefined;
@@ -223,7 +223,7 @@ namespace ts.server {
this.timerHandle = timerHandle;
}
private setImmediateId(immediateId: number) {
private setImmediateId(immediateId: number | undefined) {
if (this.immediateId !== undefined) {
this.operationHost.getServerHost().clearImmediate(this.immediateId);
}
@@ -319,7 +319,7 @@ namespace ts.server {
protected canUseEvents: boolean;
private suppressDiagnosticEvents?: boolean;
private eventHandler: ProjectServiceEventHandler;
private eventHandler: ProjectServiceEventHandler | undefined;
private readonly noGetErrOnBackgroundUpdate?: boolean;
constructor(opts: SessionOptions) {
@@ -426,7 +426,7 @@ namespace ts.server {
if (err.message) {
msg += ":\n" + indent(err.message);
if ((<StackTraceError>err).stack) {
msg += "\n" + indent((<StackTraceError>err).stack);
msg += "\n" + indent((<StackTraceError>err).stack!);
}
}
this.logger.msg(msg, Msg.Err);
@@ -449,7 +449,7 @@ namespace ts.server {
// For backwards-compatibility only.
/** @deprecated */
public output(info: any, cmdName: string, reqSeq?: number, errorMsg?: string): void {
this.doOutput(info, cmdName, reqSeq, /*success*/ !errorMsg, errorMsg);
this.doOutput(info, cmdName, reqSeq!, /*success*/ !errorMsg, errorMsg); // TODO: GH#18217
}
private doOutput(info: {} | undefined, cmdName: string, reqSeq: number, success: boolean, message?: string): void {
@@ -573,16 +573,16 @@ namespace ts.server {
return project.getLanguageService().getEncodedSemanticClassifications(file, args);
}
private getProject(projectFileName: string) {
return projectFileName && this.projectService.findProject(projectFileName);
private getProject(projectFileName: string | undefined): Project | undefined {
return projectFileName === undefined ? undefined : this.projectService.findProject(projectFileName);
}
private getConfigFileAndProject(args: protocol.FileRequestArgs) {
private getConfigFileAndProject(args: protocol.FileRequestArgs): { configFile: NormalizedPath | undefined, project: Project | undefined } {
const project = this.getProject(args.projectFileName);
const file = toNormalizedPath(args.file);
return {
configFile: project && project.hasConfigFile(file) && file,
configFile: project && project.hasConfigFile(file) ? file : undefined,
project
};
}
@@ -592,7 +592,7 @@ namespace ts.server {
const optionsErrors = project.getLanguageService().getCompilerOptionsDiagnostics();
const diagnosticsForConfigFile = filter(
concatenate(projectErrors, optionsErrors),
diagnostic => diagnostic.file && diagnostic.file.fileName === configFile
diagnostic => !!diagnostic.file && diagnostic.file.fileName === configFile
);
return includeLinePosition ?
this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnosticsForConfigFile) :
@@ -605,17 +605,17 @@ namespace ts.server {
private convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics: ReadonlyArray<Diagnostic>): protocol.DiagnosticWithLinePosition[] {
return diagnostics.map<protocol.DiagnosticWithLinePosition>(d => ({
message: flattenDiagnosticMessageText(d.messageText, this.host.newLine),
start: d.start,
length: d.length,
start: d.start!, // TODO: GH#18217
length: d.length!, // TODO: GH#18217
category: diagnosticCategoryName(d),
code: d.code,
startLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start)),
endLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start + d.length))
startLocation: (d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start!)))!, // TODO: GH#18217
endLocation: (d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start! + d.length!)))! // TODO: GH#18217
}));
}
private getCompilerOptionsDiagnostics(args: protocol.CompilerOptionsDiagnosticsRequestArgs) {
const project = this.getProject(args.projectFileName);
const project = this.getProject(args.projectFileName)!;
// Get diagnostics that dont have associated file with them
// The diagnostics which have file would be in config file and
// would be reported as part of configFileDiagnostics
@@ -628,7 +628,7 @@ namespace ts.server {
);
}
private convertToDiagnosticsWithLinePosition(diagnostics: ReadonlyArray<Diagnostic>, scriptInfo: ScriptInfo): protocol.DiagnosticWithLinePosition[] {
private convertToDiagnosticsWithLinePosition(diagnostics: ReadonlyArray<Diagnostic>, scriptInfo: ScriptInfo | undefined): protocol.DiagnosticWithLinePosition[] {
return diagnostics.map(d => <protocol.DiagnosticWithLinePosition>{
message: flattenDiagnosticMessageText(d.messageText, this.host.newLine),
start: d.start,
@@ -636,8 +636,8 @@ namespace ts.server {
category: diagnosticCategoryName(d),
code: d.code,
source: d.source,
startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start),
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length),
startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start!), // TODO: GH#18217
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start! + d.length!),
reportsUnnecessary: d.reportsUnnecessary
});
}
@@ -675,14 +675,14 @@ namespace ts.server {
private getDefinitionAndBoundSpan(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.DefinitionInfoAndBoundSpan | DefinitionInfoAndBoundSpan {
const { file, project } = this.getFileAndProject(args);
const position = this.getPositionInFile(args, file);
const scriptInfo = project.getScriptInfo(file);
const scriptInfo = project.getScriptInfo(file)!;
const definitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position);
if (!definitionAndBoundSpan || !definitionAndBoundSpan.definitions) {
return {
definitions: emptyArray,
textSpan: undefined
textSpan: undefined! // TODO: GH#18217
};
}
@@ -726,8 +726,8 @@ namespace ts.server {
private toFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan {
const ls = project.getLanguageService();
const start = ls.toLineColumnOffset(fileName, textSpan.start);
const end = ls.toLineColumnOffset(fileName, textSpanEnd(textSpan));
const start = ls.toLineColumnOffset!(fileName, textSpan.start); // TODO: GH#18217
const end = ls.toLineColumnOffset!(fileName, textSpanEnd(textSpan));
return {
file: fileName,
@@ -775,7 +775,7 @@ namespace ts.server {
return occurrences.map(occurrence => {
const { fileName, isWriteAccess, textSpan, isInString } = occurrence;
const scriptInfo = project.getScriptInfo(fileName);
const scriptInfo = project.getScriptInfo(fileName)!;
const result: protocol.OccurrencesResponseItem = {
start: scriptInfo.positionToLineOffset(textSpan.start),
end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)),
@@ -797,15 +797,15 @@ namespace ts.server {
return emptyArray;
}
return this.getDiagnosticsWorker(args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition);
return this.getDiagnosticsWorker(args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), !!args.includeLinePosition);
}
private getSemanticDiagnosticsSync(args: protocol.SemanticDiagnosticsSyncRequestArgs): ReadonlyArray<protocol.Diagnostic> | ReadonlyArray<protocol.DiagnosticWithLinePosition> {
const { configFile, project } = this.getConfigFileAndProject(args);
if (configFile) {
return this.getConfigFileDiagnostics(configFile, project, args.includeLinePosition);
return this.getConfigFileDiagnostics(configFile, project!, !!args.includeLinePosition); // TODO: GH#18217
}
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition);
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), !!args.includeLinePosition);
}
private getSuggestionDiagnosticsSync(args: protocol.SuggestionDiagnosticsSyncRequestArgs): ReadonlyArray<protocol.Diagnostic> | ReadonlyArray<protocol.DiagnosticWithLinePosition> {
@@ -815,7 +815,7 @@ namespace ts.server {
return emptyArray;
}
// isSemantic because we don't want to info diagnostics in declaration files for JS-only users
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSuggestionDiagnostics(file), args.includeLinePosition);
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSuggestionDiagnostics(file), !!args.includeLinePosition);
}
private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.DocumentHighlightsItem> | ReadonlyArray<DocumentHighlights> {
@@ -837,7 +837,7 @@ namespace ts.server {
function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights): protocol.DocumentHighlightsItem {
const { fileName, highlightSpans } = documentHighlights;
const scriptInfo = project.getScriptInfo(fileName);
const scriptInfo = project.getScriptInfo(fileName)!;
return {
file: fileName,
highlightSpans: highlightSpans.map(convertHighlightSpan)
@@ -860,7 +860,7 @@ namespace ts.server {
return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList, /*excludeConfigFiles*/ false);
}
private getProjectInfoWorker(uncheckedFileName: string, projectFileName: string, needFileNameList: boolean, excludeConfigFiles: boolean) {
private getProjectInfoWorker(uncheckedFileName: string, projectFileName: string | undefined, needFileNameList: boolean, excludeConfigFiles: boolean) {
const { project } = this.getFileAndProjectWorker(uncheckedFileName, projectFileName);
project.updateGraph();
const projectInfo = {
@@ -878,7 +878,7 @@ namespace ts.server {
}
private getProjects(args: protocol.FileRequestArgs): Projects {
let projects: ReadonlyArray<Project>;
let projects: ReadonlyArray<Project> | undefined;
let symLinkedProjects: MultiMap<Project> | undefined;
if (args.projectFileName) {
const project = this.getProject(args.projectFileName);
@@ -887,7 +887,7 @@ namespace ts.server {
}
}
else {
const scriptInfo = this.projectService.getScriptInfo(args.file);
const scriptInfo = this.projectService.getScriptInfo(args.file)!;
projects = scriptInfo.containingProjects;
symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo);
}
@@ -896,7 +896,7 @@ namespace ts.server {
if ((!projects || !projects.length) && !symLinkedProjects) {
return Errors.ThrowNoProject();
}
return symLinkedProjects ? { projects, symLinkedProjects } : projects;
return symLinkedProjects ? { projects: projects!, symLinkedProjects } : projects!; // TODO: GH#18217
}
private getDefaultProject(args: protocol.FileRequestArgs) {
@@ -906,11 +906,11 @@ namespace ts.server {
return project;
}
}
const info = this.projectService.getScriptInfo(args.file);
const info = this.projectService.getScriptInfo(args.file)!;
return info.getDefaultProject();
}
private getRenameLocations(args: protocol.RenameRequestArgs, simplifiedResult: boolean): protocol.RenameResponseBody | ReadonlyArray<RenameLocation> {
private getRenameLocations(args: protocol.RenameRequestArgs, simplifiedResult: boolean): protocol.RenameResponseBody | ReadonlyArray<RenameLocation> | undefined {
const file = toNormalizedPath(args.file);
const position = this.getPositionInFile(args, file);
const projects = this.getProjects(args);
@@ -932,16 +932,16 @@ namespace ts.server {
const fileSpans = combineProjectOutput(
file,
path => this.projectService.getScriptInfoForPath(path).fileName,
path => this.projectService.getScriptInfoForPath(path)!.fileName,
projects,
(project, file) => {
const renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments);
const renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings!, args.findInComments!);
if (!renameLocations) {
return emptyArray;
}
return renameLocations.map(location => {
const locationScriptInfo = project.getScriptInfo(location.fileName);
const locationScriptInfo = project.getScriptInfo(location.fileName)!;
return {
file: location.fileName,
start: locationScriptInfo.positionToLineOffset(location.textSpan.start),
@@ -955,7 +955,7 @@ namespace ts.server {
const locs: protocol.SpanGroup[] = [];
for (const cur of fileSpans) {
let curFileAccum: protocol.SpanGroup;
let curFileAccum: protocol.SpanGroup | undefined;
if (locs.length > 0) {
curFileAccum = locs[locs.length - 1];
if (curFileAccum.file !== cur.file) {
@@ -974,9 +974,9 @@ namespace ts.server {
else {
return combineProjectOutput(
file,
path => this.projectService.getScriptInfoForPath(path).fileName,
path => this.projectService.getScriptInfoForPath(path)!.fileName,
projects,
(p, file) => p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments),
(p, file) => p.getLanguageService().findRenameLocations(file, position, args.findInStrings!, args.findInComments!),
/*comparer*/ undefined,
renameLocationIsEqualTo
);
@@ -1021,7 +1021,7 @@ namespace ts.server {
const projects = this.getProjects(args);
const defaultProject = this.getDefaultProject(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const position = this.getPosition(args, scriptInfo);
if (simplifiedResult) {
const nameInfo = defaultProject.getLanguageService().getQuickInfoAtPosition(file, position);
@@ -1034,7 +1034,7 @@ namespace ts.server {
const nameText = scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan));
const refs = combineProjectOutput<NormalizedPath, protocol.ReferencesResponseItem>(
file,
path => this.projectService.getScriptInfoForPath(path).fileName,
path => this.projectService.getScriptInfoForPath(path)!.fileName,
projects,
(project, file) => {
const references = project.getLanguageService().getReferencesAtPosition(file, position);
@@ -1043,7 +1043,7 @@ namespace ts.server {
}
return references.map(ref => {
const refScriptInfo = project.getScriptInfo(ref.fileName);
const refScriptInfo = project.getScriptInfo(ref.fileName)!;
const start = refScriptInfo.positionToLineOffset(ref.textSpan.start);
const refLineSpan = refScriptInfo.lineToTextSpan(start.line - 1);
const lineText = refScriptInfo.getSnapshot().getText(refLineSpan.start, textSpanEnd(refLineSpan)).replace(/\r|\n/g, "");
@@ -1071,7 +1071,7 @@ namespace ts.server {
else {
return combineProjectOutput(
file,
path => this.projectService.getScriptInfoForPath(path).fileName,
path => this.projectService.getScriptInfoForPath(path)!.fileName,
projects,
(project, file) => project.getLanguageService().findReferences(file, position),
/*comparer*/ undefined,
@@ -1102,11 +1102,11 @@ namespace ts.server {
}
private getPositionInFile(args: protocol.FileLocationRequestArgs, file: NormalizedPath): number {
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
return this.getPosition(args, scriptInfo);
}
private getFileAndProject(args: protocol.FileRequestArgs) {
private getFileAndProject(args: protocol.FileRequestArgs): { file: NormalizedPath, project: Project } {
return this.getFileAndProjectWorker(args.file, args.projectFileName);
}
@@ -1124,9 +1124,9 @@ namespace ts.server {
};
}
private getFileAndProjectWorker(uncheckedFileName: string, projectFileName: string) {
private getFileAndProjectWorker(uncheckedFileName: string, projectFileName: string | undefined): { file: NormalizedPath, project: Project } {
const file = toNormalizedPath(uncheckedFileName);
const project: Project = this.getProject(projectFileName) || this.projectService.getDefaultProjectForFile(file, /*ensureProject*/ true);
const project = this.getProject(projectFileName) || this.projectService.getDefaultProjectForFile(file, /*ensureProject*/ true)!; // TODO: GH#18217
return { file, project };
}
@@ -1134,7 +1134,7 @@ namespace ts.server {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const spans = languageService.getOutliningSpans(file);
if (simplifiedResult) {
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
return spans.map(s => ({
textSpan: this.toLocationTextSpan(s.textSpan, scriptInfo),
hintSpan: this.toLocationTextSpan(s.hintSpan, scriptInfo),
@@ -1192,9 +1192,9 @@ namespace ts.server {
return languageService.isValidBraceCompletionAtPosition(file, position, args.openingBrace.charCodeAt(0));
}
private getQuickInfoWorker(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.QuickInfoResponseBody | QuickInfo {
private getQuickInfoWorker(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.QuickInfoResponseBody | QuickInfo | undefined {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const quickInfo = project.getLanguageService().getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo));
if (!quickInfo) {
return undefined;
@@ -1219,9 +1219,9 @@ namespace ts.server {
}
}
private getFormattingEditsForRange(args: protocol.FormatRequestArgs): protocol.CodeEdit[] {
private getFormattingEditsForRange(args: protocol.FormatRequestArgs): protocol.CodeEdit[] | undefined {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const startPosition = scriptInfo.lineOffsetToPosition(args.line, args.offset);
const endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
@@ -1238,7 +1238,7 @@ namespace ts.server {
private getFormattingEditsForRangeFull(args: protocol.FormatRequestArgs) {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file);
return languageService.getFormattingEditsForRange(file, args.position, args.endPosition, options);
return languageService.getFormattingEditsForRange(file, args.position!, args.endPosition!, options); // TODO: GH#18217
}
private getFormattingEditsForDocumentFull(args: protocol.FormatRequestArgs) {
@@ -1250,12 +1250,12 @@ namespace ts.server {
private getFormattingEditsAfterKeystrokeFull(args: protocol.FormatOnKeyRequestArgs) {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file);
return languageService.getFormattingEditsAfterKeystroke(file, args.position, args.key, options);
return languageService.getFormattingEditsAfterKeystroke(file, args.position!, args.key, options); // TODO: GH#18217
}
private getFormattingEditsAfterKeystroke(args: protocol.FormatOnKeyRequestArgs): protocol.CodeEdit[] {
private getFormattingEditsAfterKeystroke(args: protocol.FormatOnKeyRequestArgs): protocol.CodeEdit[] | undefined {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const position = scriptInfo.lineOffsetToPosition(args.line, args.offset);
const formatOptions = this.getFormatOptions(file);
const edits = languageService.getFormattingEditsAfterKeystroke(file, position, args.key,
@@ -1277,7 +1277,7 @@ namespace ts.server {
hasIndent++;
}
else if (lineText.charAt(i) === "\t") {
hasIndent += formatOptions.tabSize;
hasIndent += formatOptions.tabSize!; // TODO: GH#18217
}
else {
break;
@@ -1310,7 +1310,7 @@ namespace ts.server {
private getCompletions(args: protocol.CompletionsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CompletionEntry> | CompletionInfo | undefined {
const prefix = args.prefix || "";
const { file, project } = this.getFileAndProject(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const position = this.getPosition(args, scriptInfo);
const completions = project.getLanguageService().getCompletionsAtPosition(file, position, {
@@ -1321,7 +1321,7 @@ namespace ts.server {
});
if (simplifiedResult) {
return mapDefined<CompletionEntry, protocol.CompletionEntry>(completions && completions.entries, entry => {
if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) {
if (completions!.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) {
const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, isRecommended } = entry;
const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined;
// Use `hasAction || undefined` to avoid serializing `false`.
@@ -1336,7 +1336,7 @@ namespace ts.server {
private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CompletionEntryDetails> | ReadonlyArray<CompletionEntryDetails> {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const position = this.getPosition(args, scriptInfo);
const formattingOptions = project.projectService.getFormatCodeOptions(file);
@@ -1356,14 +1356,14 @@ namespace ts.server {
}
// if specified a project, we only return affected file list in this project
const projects = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects;
const projects = args.projectFileName ? [this.projectService.findProject(args.projectFileName)!] : info.containingProjects;
const symLinkedProjects = !args.projectFileName && this.projectService.getSymlinkedProjects(info);
return combineProjectOutput(
info,
path => this.projectService.getScriptInfoForPath(path),
path => this.projectService.getScriptInfoForPath(path)!,
symLinkedProjects ? { projects, symLinkedProjects } : projects,
(project, info) => {
let result: protocol.CompileOnSaveAffectedFileListSingleProject;
let result: protocol.CompileOnSaveAffectedFileListSingleProject | undefined;
if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.isOrphan() && !project.getCompilationSettings().noEmit) {
result = {
projectFileName: project.getProjectName(),
@@ -1384,13 +1384,13 @@ namespace ts.server {
if (!project.languageServiceEnabled) {
return false;
}
const scriptInfo = project.getScriptInfo(file);
const scriptInfo = project.getScriptInfo(file)!;
return project.emitFile(scriptInfo, (path, data, writeByteOrderMark) => this.host.writeFile(path, data, writeByteOrderMark));
}
private getSignatureHelpItems(args: protocol.SignatureHelpRequestArgs, simplifiedResult: boolean): protocol.SignatureHelpItems | SignatureHelpItems {
private getSignatureHelpItems(args: protocol.SignatureHelpRequestArgs, simplifiedResult: boolean): protocol.SignatureHelpItems | SignatureHelpItems | undefined {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const position = this.getPosition(args, scriptInfo);
const helpItems = project.getLanguageService().getSignatureHelpItems(file, position);
if (!helpItems) {
@@ -1435,7 +1435,7 @@ namespace ts.server {
}
private change(args: protocol.ChangeRequestArgs) {
const scriptInfo = this.projectService.getScriptInfo(args.file);
const scriptInfo = this.projectService.getScriptInfo(args.file)!;
Debug.assert(!!scriptInfo);
const start = scriptInfo.lineOffsetToPosition(args.line, args.offset);
const end = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
@@ -1443,14 +1443,14 @@ namespace ts.server {
this.changeSeq++;
this.projectService.applyChangesToFile(scriptInfo, [{
span: { start, length: end - start },
newText: args.insertString
newText: args.insertString! // TODO: GH#18217
}]);
}
}
private reload(args: protocol.ReloadRequestArgs, reqSeq: number) {
const file = toNormalizedPath(args.file);
const tempFileName = args.tmpfile && toNormalizedPath(args.tmpfile);
const tempFileName = args.tmpfile === undefined ? undefined : toNormalizedPath(args.tmpfile);
const info = this.projectService.getScriptInfoForNormalizedPath(file);
if (info) {
this.changeSeq++;
@@ -1487,13 +1487,13 @@ namespace ts.server {
}));
}
private getNavigationBarItems(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationBarItem[] | NavigationBarItem[] {
private getNavigationBarItems(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationBarItem[] | NavigationBarItem[] | undefined {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const items = languageService.getNavigationBarItems(file);
return !items
? undefined
: simplifiedResult
? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file))
? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file)!)
: items;
}
@@ -1514,13 +1514,13 @@ namespace ts.server {
};
}
private getNavigationTree(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationTree | NavigationTree {
private getNavigationTree(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationTree | NavigationTree | undefined {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const tree = languageService.getNavigationTree(file);
return !tree
? undefined
: simplifiedResult
? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file))
? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file)!)
: tree;
}
@@ -1544,7 +1544,7 @@ namespace ts.server {
}
return navItems.map((navItem) => {
const scriptInfo = project.getScriptInfo(navItem.fileName);
const scriptInfo = project.getScriptInfo(navItem.fileName)!;
const bakedItem: protocol.NavtoItem = {
name: navItem.name,
kind: navItem.kind,
@@ -1624,8 +1624,8 @@ namespace ts.server {
}
private extractPositionAndRange(args: protocol.FileLocationOrRangeRequestArgs, scriptInfo: ScriptInfo): { position: number, textRange: TextRange } {
let position: number;
let textRange: TextRange;
let position: number | undefined;
let textRange: TextRange | undefined;
if (this.isLocation(args)) {
position = getPosition(args);
}
@@ -1633,7 +1633,7 @@ namespace ts.server {
const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);
textRange = { pos: startPosition, end: endPosition };
}
return { position, textRange };
return { position: position!, textRange: textRange! }; // TODO: GH#18217
function getPosition(loc: protocol.FileLocationRequestArgs) {
return loc.position !== undefined ? loc.position : scriptInfo.lineOffsetToPosition(loc.line, loc.offset);
@@ -1642,14 +1642,14 @@ namespace ts.server {
private getApplicableRefactors(args: protocol.GetApplicableRefactorsRequestArgs): protocol.ApplicableRefactorInfo[] {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const scriptInfo = project.getScriptInfoForNormalizedPath(file)!;
const { position, textRange } = this.extractPositionAndRange(args, scriptInfo);
return project.getLanguageService().getApplicableRefactors(file, position || textRange, this.getPreferences(file));
}
private getEditsForRefactor(args: protocol.GetEditsForRefactorRequestArgs, simplifiedResult: boolean): RefactorEditInfo | protocol.RefactorEditInfo {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const scriptInfo = project.getScriptInfoForNormalizedPath(file)!;
const { position, textRange } = this.extractPositionAndRange(args, scriptInfo);
const result = project.getLanguageService().getEditsForRefactor(
@@ -1671,7 +1671,7 @@ namespace ts.server {
const { renameFilename, renameLocation, edits } = result;
let mappedRenameLocation: protocol.Location | undefined;
if (renameFilename !== undefined && renameLocation !== undefined) {
const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename));
const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename))!;
mappedRenameLocation = getLocationInNewDocument(getSnapshotText(renameScriptInfo.getSnapshot()), renameFilename, renameLocation, edits);
}
return { renameLocation: mappedRenameLocation, renameFilename, edits: this.mapTextChangesToCodeEdits(project, edits) };
@@ -1699,16 +1699,16 @@ namespace ts.server {
return simplifiedResult ? this.mapTextChangesToCodeEdits(project, changes) : changes;
}
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CodeFixAction> | ReadonlyArray<CodeFixAction> {
if (args.errorCodes.length === 0) {
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CodeFixAction> | ReadonlyArray<CodeFixAction> | undefined {
if (args.errorCodes!.length === 0) { // TODO: GH#18217
return undefined;
}
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
const scriptInfo = project.getScriptInfoForNormalizedPath(file)!;
const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);
const codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes, this.getFormatOptions(file), this.getPreferences(file));
const codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes!, this.getFormatOptions(file), this.getPreferences(file));
return simplifiedResult ? codeActions.map(codeAction => this.mapCodeFixAction(project, codeAction)) : codeActions;
}
@@ -1736,7 +1736,7 @@ namespace ts.server {
}
private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) {
let startPosition: number, endPosition: number;
let startPosition: number | undefined, endPosition: number | undefined;
if (args.startPosition !== undefined) {
startPosition = args.startPosition;
}
@@ -1766,7 +1766,7 @@ namespace ts.server {
}
private mapTextChangesToCodeEdits(project: Project, textChanges: ReadonlyArray<FileTextChanges>): protocol.FileCodeEdits[] {
return textChanges.map(change => this.mapTextChangesToCodeEditsUsingScriptinfo(change, project.getScriptInfoForNormalizedPath(toNormalizedPath(change.fileName))));
return textChanges.map(change => this.mapTextChangesToCodeEditsUsingScriptinfo(change, project.getScriptInfoForNormalizedPath(toNormalizedPath(change.fileName))!));
}
private mapTextChangesToCodeEditsUsingScriptinfo(textChanges: FileTextChanges, scriptInfo: ScriptInfo | undefined): protocol.FileCodeEdits {
@@ -1797,9 +1797,9 @@ namespace ts.server {
return { fileName: textChanges.fileName, textChanges: [{ start: { line: 0, offset: 0 }, end: { line: 0, offset: 0 }, newText: change.newText }] };
}
private getBraceMatching(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.TextSpan[] | TextSpan[] {
private getBraceMatching(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.TextSpan[] | TextSpan[] | undefined {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const position = this.getPosition(args, scriptInfo);
const spans = languageService.getBraceMatchingAtPosition(file, position);
@@ -1821,7 +1821,7 @@ namespace ts.server {
}
// No need to analyze lib.d.ts
const fileNamesInProject = fileNames.filter(value => !stringContains(value, "lib.d.ts"));
const fileNamesInProject = fileNames!.filter(value => !stringContains(value, "lib.d.ts")); // TODO: GH#18217
if (fileNamesInProject.length === 0) {
return;
}
@@ -1832,13 +1832,13 @@ namespace ts.server {
const lowPriorityFiles: NormalizedPath[] = [];
const veryLowPriorityFiles: NormalizedPath[] = [];
const normalizedFileName = toNormalizedPath(fileName);
const project = this.projectService.getDefaultProjectForFile(normalizedFileName, /*ensureProject*/ true);
const project = this.projectService.getDefaultProjectForFile(normalizedFileName, /*ensureProject*/ true)!;
for (const fileNameInProject of fileNamesInProject) {
if (this.getCanonicalFileName(fileNameInProject) === this.getCanonicalFileName(fileName)) {
highPriorityFiles.push(fileNameInProject);
}
else {
const info = this.projectService.getScriptInfo(fileNameInProject);
const info = this.projectService.getScriptInfo(fileNameInProject)!; // TODO: GH#18217
if (!info.isScriptOpen()) {
if (fileExtensionIs(fileNameInProject, Extension.Dts)) {
veryLowPriorityFiles.push(fileNameInProject);
@@ -1871,7 +1871,7 @@ namespace ts.server {
return { responseRequired: false };
}
private requiredResponse(response: {}): HandlerResponse {
private requiredResponse(response: {} | undefined): HandlerResponse {
return { response, responseRequired: true };
}
@@ -1915,7 +1915,7 @@ namespace ts.server {
},
[CommandNames.ApplyChangedToOpenFiles]: (request: protocol.ApplyChangedToOpenFilesRequest) => {
this.changeSeq++;
this.projectService.applyChangesInOpenFiles(request.arguments.openFiles, request.arguments.changedFiles, request.arguments.closedFiles);
this.projectService.applyChangesInOpenFiles(request.arguments.openFiles, request.arguments.changedFiles!, request.arguments.closedFiles!); // TODO: GH#18217
// TODO: report errors
return this.requiredResponse(/*response*/ true);
},
@@ -1963,7 +1963,7 @@ namespace ts.server {
this.openClientFile(
toNormalizedPath(request.arguments.file),
request.arguments.fileContent,
convertScriptKindName(request.arguments.scriptKindName),
convertScriptKindName(request.arguments.scriptKindName!), // TODO: GH#18217
request.arguments.projectRootPath ? toNormalizedPath(request.arguments.projectRootPath) : undefined);
return this.notRequired();
},
@@ -2189,7 +2189,7 @@ namespace ts.server {
private resetCurrentRequest(requestId: number): void {
Debug.assert(this.currentRequestId === requestId);
this.currentRequestId = undefined;
this.currentRequestId = undefined!; // TODO: GH#18217
this.cancellationToken.resetRequest(requestId);
}
@@ -2217,7 +2217,7 @@ namespace ts.server {
public onMessage(message: string) {
this.gcTimer.scheduleCollect();
let start: number[];
let start: number[] | undefined;
if (this.logger.hasLevel(LogLevel.requestTime)) {
start = this.hrtime();
if (this.logger.hasLevel(LogLevel.verbose)) {
@@ -2225,7 +2225,7 @@ namespace ts.server {
}
}
let request: protocol.Request;
let request: protocol.Request | undefined;
try {
request = <protocol.Request>JSON.parse(message);
const { response, responseRequired } = this.executeCommand(request);
@@ -2250,7 +2250,7 @@ namespace ts.server {
catch (err) {
if (err instanceof OperationCanceledException) {
// Handle cancellation exceptions
this.doOutput({ canceled: true }, request.command, request.seq, /*success*/ true);
this.doOutput({ canceled: true }, request!.command, request!.seq, /*success*/ true);
return;
}
this.logError(err, message);
+8 -8
View File
@@ -8,7 +8,7 @@ namespace ts.server {
export interface ITypingsInstaller {
isKnownTypesPackageName(name: string): boolean;
installPackage(options: InstallPackageOptionsWithProject): Promise<ApplyCodeActionCommandResult>;
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>): void;
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string> | undefined): void;
attach(projectService: ProjectService): void;
onProjectClosed(p: Project): void;
readonly globalTypingsCacheLocation: string | undefined;
@@ -21,19 +21,19 @@ namespace ts.server {
enqueueInstallTypingsRequest: noop,
attach: noop,
onProjectClosed: noop,
globalTypingsCacheLocation: undefined
globalTypingsCacheLocation: undefined! // TODO: GH#18217
};
interface TypingsCacheEntry {
readonly typeAcquisition: TypeAcquisition;
readonly compilerOptions: CompilerOptions;
readonly typings: SortedReadonlyArray<string>;
readonly unresolvedImports: SortedReadonlyArray<string>;
readonly unresolvedImports: SortedReadonlyArray<string> | undefined;
/* mainly useful for debugging */
poisoned: boolean;
}
function setIsEqualTo(arr1: string[], arr2: string[]): boolean {
function setIsEqualTo(arr1: string[] | undefined, arr2: string[] | undefined): boolean {
if (arr1 === arr2) {
return true;
}
@@ -43,13 +43,13 @@ namespace ts.server {
const set: Map<boolean> = createMap<boolean>();
let unique = 0;
for (const v of arr1) {
for (const v of arr1!) {
if (set.get(v) !== true) {
set.set(v, true);
unique++;
}
}
for (const v of arr2) {
for (const v of arr2!) {
const isSet = set.get(v);
if (isSet === undefined) {
return false;
@@ -73,7 +73,7 @@ namespace ts.server {
return opt1.allowJs !== opt2.allowJs;
}
function unresolvedImportsChanged(imports1: SortedReadonlyArray<string>, imports2: SortedReadonlyArray<string>): boolean {
function unresolvedImportsChanged(imports1: SortedReadonlyArray<string> | undefined, imports2: SortedReadonlyArray<string> | undefined): boolean {
if (imports1 === imports2) {
return false;
}
@@ -95,7 +95,7 @@ namespace ts.server {
return this.installer.installPackage(options);
}
enqueueInstallTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean) {
enqueueInstallTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string> | undefined, forceRefresh: boolean) {
const typeAcquisition = project.getTypeAcquisition();
if (!typeAcquisition || !typeAcquisition.enable) {
@@ -1,4 +1,4 @@
/// <reference types="node" />
// tslint:disable no-unnecessary-type-assertion (TODO: tslint can't find node types)
namespace ts.server.typingsInstaller {
const fs: {
@@ -22,7 +22,7 @@ namespace ts.server.typingsInstaller {
}
writeLine = (text: string) => {
try {
fs.appendFileSync(this.logFile, `[${nowString()}] ${text}${sys.newLine}`);
fs.appendFileSync(this.logFile!, `[${nowString()}] ${text}${sys.newLine}`); // TODO: GH#18217
}
catch (e) {
this.logEnabled = false;
@@ -53,7 +53,7 @@ namespace ts.server.typingsInstaller {
return createMap<MapLike<string>>();
}
try {
const content = <TypesRegistryFile>JSON.parse(host.readFile(typesRegistryFilePath));
const content = <TypesRegistryFile>JSON.parse(host.readFile(typesRegistryFilePath)!);
return createMapFromTemplate(content.entries);
}
catch (e) {
@@ -176,7 +176,7 @@ namespace ts.server.typingsInstaller {
if (this.log.isEnabled()) {
this.log.writeLine(`Sending response:\n ${JSON.stringify(response)}`);
}
process.send(response);
process.send!(response); // TODO: GH#18217
if (this.log.isEnabled()) {
this.log.writeLine(`Response has been sent.`);
}
@@ -240,7 +240,7 @@ namespace ts.server.typingsInstaller {
}
process.exit(0);
});
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, /*throttleLimit*/5, log);
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation!, typingSafeListLocation!, typesMapLocation!, npmLocation, /*throttleLimit*/5, log); // TODO: GH#18217
installer.listen();
function indent(newline: string, str: string): string {
+11 -11
View File
@@ -17,7 +17,7 @@ namespace ts.server.typingsInstaller {
writeLine: noop
};
function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost, log: Log): string {
function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost, log: Log): string | undefined {
try {
const result = resolveModuleName(packageName, combinePaths(cachePath, "index.d.ts"), { moduleResolution: ModuleResolutionKind.NodeJs }, installTypingHost);
return result.resolvedModule && result.resolvedModule.resolvedFileName;
@@ -154,7 +154,7 @@ namespace ts.server.typingsInstaller {
this.log.isEnabled() ? (s => this.log.writeLine(s)) : undefined,
req.fileNames,
req.projectRootPath,
this.safeList,
this.safeList!,
this.packageNameToTypingLocation,
req.typeAcquisition,
req.unresolvedImports,
@@ -209,8 +209,8 @@ namespace ts.server.typingsInstaller {
this.log.writeLine(`Trying to find '${packageJson}'...`);
}
if (this.installTypingHost.fileExists(packageJson) && this.installTypingHost.fileExists(packageLockJson)) {
const npmConfig = <NpmConfig>JSON.parse(this.installTypingHost.readFile(packageJson));
const npmLock = <NpmLock>JSON.parse(this.installTypingHost.readFile(packageLockJson));
const npmConfig = <NpmConfig>JSON.parse(this.installTypingHost.readFile(packageJson)!); // TODO: GH#18217
const npmLock = <NpmLock>JSON.parse(this.installTypingHost.readFile(packageLockJson)!); // TODO: GH#18217
if (this.log.isEnabled()) {
this.log.writeLine(`Loaded content of '${packageJson}': ${JSON.stringify(npmConfig)}`);
this.log.writeLine(`Loaded content of '${packageLockJson}'`);
@@ -246,7 +246,7 @@ namespace ts.server.typingsInstaller {
}
const info = getProperty(npmLock.dependencies, key);
const version = info && info.version;
const semver = Semver.parse(version);
const semver = Semver.parse(version!); // TODO: GH#18217
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: semver };
this.packageNameToTypingLocation.set(packageName, newTyping);
}
@@ -275,7 +275,7 @@ namespace ts.server.typingsInstaller {
if (this.log.isEnabled()) this.log.writeLine(`Entry for package '${typing}' does not exist in local types registry - skipping...`);
return false;
}
if (this.packageNameToTypingLocation.get(typing) && JsTyping.isTypingUpToDate(this.packageNameToTypingLocation.get(typing), this.typesRegistry.get(typing))) {
if (this.packageNameToTypingLocation.get(typing) && JsTyping.isTypingUpToDate(this.packageNameToTypingLocation.get(typing)!, this.typesRegistry.get(typing)!)) {
if (this.log.isEnabled()) this.log.writeLine(`'${typing}' already has an up-to-date typing - skipping...`);
return false;
}
@@ -349,7 +349,7 @@ namespace ts.server.typingsInstaller {
}
// packageName is guaranteed to exist in typesRegistry by filterTypings
const distTags = this.typesRegistry.get(packageName);
const distTags = this.typesRegistry.get(packageName)!;
const newVersion = Semver.parse(distTags[`ts${versionMajorMinor}`] || distTags[latestDistTag]);
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: newVersion };
this.packageNameToTypingLocation.set(packageName, newTyping);
@@ -392,7 +392,7 @@ namespace ts.server.typingsInstaller {
return;
}
let watchers = this.projectWatchers.get(projectName);
let watchers = this.projectWatchers.get(projectName)!;
const toRemove = createMap<FileWatcher>();
if (!watchers) {
watchers = createMap();
@@ -418,7 +418,7 @@ namespace ts.server.typingsInstaller {
if (isLoggingEnabled) {
this.log.writeLine(`FileWatcher:: Added:: WatchInfo: ${file}`);
}
const watcher = this.installTypingHost.watchFile(file, (f, eventKind) => {
const watcher = this.installTypingHost.watchFile!(file, (f, eventKind) => { // TODO: GH#18217
if (isLoggingEnabled) {
this.log.writeLine(`FileWatcher:: Triggered with ${f} eventKind: ${FileWatcherEventKind[eventKind]}:: WatchInfo: ${file}:: handler is already invoked '${watchers.isInvoked}'`);
}
@@ -439,7 +439,7 @@ namespace ts.server.typingsInstaller {
if (isLoggingEnabled) {
this.log.writeLine(`DirectoryWatcher:: Added:: WatchInfo: ${dir} recursive`);
}
const watcher = this.installTypingHost.watchDirectory(dir, f => {
const watcher = this.installTypingHost.watchDirectory!(dir, f => { // TODO: GH#18217
if (isLoggingEnabled) {
this.log.writeLine(`DirectoryWatcher:: Triggered with ${f} :: WatchInfo: ${dir} recursive :: handler is already invoked '${watchers.isInvoked}'`);
}
@@ -512,7 +512,7 @@ namespace ts.server.typingsInstaller {
private executeWithThrottling() {
while (this.inFlightRequestCount < this.throttleLimit && this.pendingRunRequests.length) {
this.inFlightRequestCount++;
const request = this.pendingRunRequests.pop();
const request = this.pendingRunRequests.pop()!;
this.installWorker(request.requestId, request.packageNames, request.cwd, ok => {
this.inFlightRequestCount--;
request.onRequestCompleted(ok);
+7 -7
View File
@@ -17,7 +17,7 @@ namespace ts.server {
startGroup(): void;
endGroup(): void;
msg(s: string, type?: Msg): void;
getLogFileName(): string;
getLogFileName(): string | undefined;
}
// TODO: Use a const enum (https://github.com/Microsoft/TypeScript/issues/16804)
@@ -96,7 +96,7 @@ namespace ts.server {
}
export interface NormalizedPathMap<T> {
get(path: NormalizedPath): T;
get(path: NormalizedPath): T | undefined;
set(path: NormalizedPath, value: T): void;
contains(path: NormalizedPath): boolean;
remove(path: NormalizedPath): void;
@@ -150,7 +150,7 @@ namespace ts.server {
}
export function createSortedArray<T>(): SortedArray<T> {
return [] as SortedArray<T>;
return [] as any as SortedArray<T>; // TODO: GH#19873
}
}
@@ -160,7 +160,7 @@ namespace ts.server {
private readonly pendingTimeouts: Map<any> = createMap<any>();
private readonly logger?: Logger | undefined;
constructor(private readonly host: ServerHost, logger: Logger) {
this.logger = logger.hasLevel(LogLevel.verbose) && logger;
this.logger = logger.hasLevel(LogLevel.verbose) ? logger : undefined;
}
/**
@@ -208,11 +208,11 @@ namespace ts.server {
self.timerId = undefined;
const log = self.logger.hasLevel(LogLevel.requestTime);
const before = log && self.host.getMemoryUsage();
const before = log && self.host.getMemoryUsage!(); // TODO: GH#18217
self.host.gc();
self.host.gc!(); // TODO: GH#18217
if (log) {
const after = self.host.getMemoryUsage();
const after = self.host.getMemoryUsage!(); // TODO: GH#18217
self.logger.perftrc(`GC::before ${before}, after ${after}`);
}
}