mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
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:
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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,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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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}`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user