diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 596895d1aac..8b484f7e41c 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -358,6 +358,7 @@ "./vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts", "./vs/editor/standalone/common/monarch/monarchCommon.ts", "./vs/editor/standalone/common/monarch/monarchCompile.ts", + "./vs/editor/standalone/common/monarch/monarchLexer.ts", "./vs/editor/standalone/common/monarch/monarchTypes.ts", "./vs/editor/standalone/common/standaloneThemeService.ts", "./vs/editor/standalone/common/themes.ts", @@ -565,8 +566,10 @@ "./vs/workbench/parts/codeEditor/browser/menuPreventer.ts", "./vs/workbench/parts/codeEditor/browser/simpleEditorOptions.ts", "./vs/workbench/parts/codeEditor/electron-browser/accessibility.ts", + "./vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts", "./vs/workbench/parts/codeEditor/electron-browser/largeFileOptimizations.ts", "./vs/workbench/parts/codeEditor/electron-browser/selectionClipboard.ts", + "./vs/workbench/parts/codeEditor/electron-browser/textMate/inspectTMScopes.ts", "./vs/workbench/parts/codeEditor/electron-browser/toggleMinimap.ts", "./vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.ts", "./vs/workbench/parts/codeEditor/electron-browser/toggleRenderControlCharacter.ts", @@ -661,6 +664,7 @@ "./vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler.ts", "./vs/workbench/services/extensions/node/extensionDescriptionRegistry.ts", "./vs/workbench/services/extensions/node/extensionManagementServerService.ts", + "./vs/workbench/services/extensions/node/extensionPoints.ts", "./vs/workbench/services/extensions/node/lazyPromise.ts", "./vs/workbench/services/extensions/node/proxyIdentifier.ts", "./vs/workbench/services/extensions/node/rpcProtocol.ts", @@ -713,6 +717,7 @@ "./vs/workbench/services/search/test/node/textSearchManager.test.ts", "./vs/workbench/services/textMate/electron-browser/TMGrammars.ts", "./vs/workbench/services/textMate/electron-browser/TMHelper.ts", + "./vs/workbench/services/textMate/electron-browser/TMSyntax.ts", "./vs/workbench/services/textMate/electron-browser/textMateService.ts", "./vs/workbench/services/textfile/electron-browser/textResourcePropertiesService.ts", "./vs/workbench/services/themes/common/colorExtensionPoint.ts", diff --git a/src/typings/vscode-textmate.d.ts b/src/typings/vscode-textmate.d.ts index 816e6bfc237..224b9100482 100644 --- a/src/typings/vscode-textmate.d.ts +++ b/src/typings/vscode-textmate.d.ts @@ -30,7 +30,7 @@ declare module "vscode-textmate" { */ export interface RegistryOptions { theme?: IRawTheme; - loadGrammar(scopeName: string): Thenable; + loadGrammar(scopeName: string): Thenable | null; getInjections?(scopeName: string): string[]; getOnigLib?(): Thenable; } @@ -102,7 +102,7 @@ declare module "vscode-textmate" { /** * Tokenize `lineText` using previous line state `prevState`. */ - tokenizeLine(lineText: string, prevState: StackElement): ITokenizeLineResult; + tokenizeLine(lineText: string, prevState: StackElement | null): ITokenizeLineResult; /** * Tokenize `lineText` using previous line state `prevState`. * The result contains the tokens in binary format, resolved with the following information: @@ -113,7 +113,7 @@ declare module "vscode-textmate" { * - background color * e.g. for getting the languageId: `(metadata & MetadataConsts.LANGUAGEID_MASK) >>> MetadataConsts.LANGUAGEID_OFFSET` */ - tokenizeLine2(lineText: string, prevState: StackElement): ITokenizeLineResult2; + tokenizeLine2(lineText: string, prevState: StackElement | null): ITokenizeLineResult2; } export interface ITokenizeLineResult { readonly tokens: IToken[]; diff --git a/src/vs/base/common/htmlContent.ts b/src/vs/base/common/htmlContent.ts index b7e99fbf6c7..4060e867f81 100644 --- a/src/vs/base/common/htmlContent.ts +++ b/src/vs/base/common/htmlContent.ts @@ -43,7 +43,7 @@ export class MarkdownString implements IMarkdownString { } } -export function isEmptyMarkdownString(oneOrMany: IMarkdownString | IMarkdownString[]): boolean { +export function isEmptyMarkdownString(oneOrMany: IMarkdownString | IMarkdownString[] | null | undefined): boolean { if (isMarkdownString(oneOrMany)) { return !oneOrMany.value; } else if (Array.isArray(oneOrMany)) { diff --git a/src/vs/editor/common/modes/languageConfiguration.ts b/src/vs/editor/common/modes/languageConfiguration.ts index b73b42a29cc..61d5f3787c2 100644 --- a/src/vs/editor/common/modes/languageConfiguration.ts +++ b/src/vs/editor/common/modes/languageConfiguration.ts @@ -96,11 +96,11 @@ export interface IndentationRule { /** * If a line matches this pattern, then **only the next line** after it should be indented once. */ - indentNextLinePattern?: RegExp; + indentNextLinePattern?: RegExp | null; /** * If a line matches this pattern, then its indentation should not be changed and it should not be evaluated against the other rules. */ - unIndentedLinePattern?: RegExp; + unIndentedLinePattern?: RegExp | null; } diff --git a/src/vs/editor/common/modes/tokenizationRegistry.ts b/src/vs/editor/common/modes/tokenizationRegistry.ts index 9afe26388f0..7282be4a653 100644 --- a/src/vs/editor/common/modes/tokenizationRegistry.ts +++ b/src/vs/editor/common/modes/tokenizationRegistry.ts @@ -5,7 +5,7 @@ import { Color } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, toDisposable, Disposable } from 'vs/base/common/lifecycle'; import { ColorId, ITokenizationRegistry, ITokenizationSupport, ITokenizationSupportChangedEvent } from 'vs/editor/common/modes'; export class TokenizationRegistryImpl implements ITokenizationRegistry { @@ -43,10 +43,14 @@ export class TokenizationRegistryImpl implements ITokenizationRegistry { }); } - public registerPromise(language: string, supportPromise: Thenable): Thenable { + public registerPromise(language: string, supportPromise: Thenable): Thenable { const promise = this._promises[language] = supportPromise.then(support => { delete this._promises[language]; - return this.register(language, support); + if (support) { + return this.register(language, support); + } else { + return Disposable.None; + } }); return promise; } diff --git a/src/vs/editor/contrib/hover/hoverOperation.ts b/src/vs/editor/contrib/hover/hoverOperation.ts index 5add5dff3a0..59c0b9f4366 100644 --- a/src/vs/editor/contrib/hover/hoverOperation.ts +++ b/src/vs/editor/contrib/hover/hoverOperation.ts @@ -58,10 +58,10 @@ export class HoverOperation { private _asyncComputationPromiseDone: boolean; private _completeCallback: (r: Result) => void; - private _errorCallback?: (err: any) => void; + private _errorCallback: ((err: any) => void) | null | undefined; private _progressCallback: (progress: any) => void; - constructor(computer: IHoverComputer, success: (r: Result) => void, error: undefined | ((err: any) => void), progress: (progress: any) => void, hoverTime: number) { + constructor(computer: IHoverComputer, success: (r: Result) => void, error: ((err: any) => void) | null | undefined, progress: (progress: any) => void, hoverTime: number) { this._computer = computer; this._state = ComputeHoverOperationState.IDLE; this._hoverTime = hoverTime; diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index 5a9b0656d3a..b8dcfc1f751 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -40,7 +40,7 @@ class ModesContentComputer implements IHoverComputer { private _editor: ICodeEditor; private _result: HoverPart[]; - private _range: Range; + private _range: Range | null; constructor(editor: ICodeEditor) { this._editor = editor; @@ -57,10 +57,14 @@ class ModesContentComputer implements IHoverComputer { } computeAsync(token: CancellationToken): Promise { + if (!this._editor.hasModel() || !this._range) { + return Promise.resolve([]); + } + const model = this._editor.getModel(); if (!HoverProviderRegistry.has(model)) { - return Promise.resolve(null); + return Promise.resolve([]); } return getHover(model, new Position( @@ -70,6 +74,10 @@ class ModesContentComputer implements IHoverComputer { } computeSync(): HoverPart[] { + if (!this._editor.hasModel() || !this._range) { + return []; + } + const lineNumber = this._range.startLineNumber; if (lineNumber > this._editor.getModel().getLineCount()) { @@ -157,14 +165,14 @@ export class ModesContentHoverWidget extends ContentHoverWidget { static readonly ID = 'editor.contrib.modesContentHoverWidget'; private _messages: HoverPart[]; - private _lastRange: Range; + private _lastRange: Range | null; private _computer: ModesContentComputer; private _hoverOperation: HoverOperation; private _highlightDecorations: string[]; private _isChangingDecorations: boolean; private _markdownRenderer: MarkdownRenderer; private _shouldFocus: boolean; - private _colorPicker: ColorPickerWidget; + private _colorPicker: ColorPickerWidget | null; private renderDisposable: IDisposable = Disposable.None; @@ -175,6 +183,8 @@ export class ModesContentHoverWidget extends ContentHoverWidget { ) { super(ModesContentHoverWidget.ID, editor); + this._messages = []; + this._lastRange = null; this._computer = new ModesContentComputer(this._editor); this._highlightDecorations = []; this._isChangingDecorations = false; diff --git a/src/vs/editor/standalone/common/monarch/monarchLexer.ts b/src/vs/editor/standalone/common/monarch/monarchLexer.ts index 35c9e5b1c50..78f4ab9e01d 100644 --- a/src/vs/editor/standalone/common/monarch/monarchLexer.ts +++ b/src/vs/editor/standalone/common/monarch/monarchLexer.ts @@ -260,7 +260,7 @@ class MonarchClassicTokensCollector implements IMonarchTokensCollector { } this._lastTokenType = type; this._lastTokenLanguage = this._language; - this._tokens.push(new Token(startOffset, type, this._language)); + this._tokens.push(new Token(startOffset, type, this._language!)); } public nestedModeTokenize(embeddedModeLine: string, embeddedModeData: EmbeddedModeData, offsetDelta: number): modes.IState { @@ -306,7 +306,7 @@ class MonarchModernTokensCollector implements IMonarchTokensCollector { } public enterMode(startOffset: number, modeId: string): void { - this._currentLanguageId = this._modeService.getLanguageIdentifier(modeId).id; + this._currentLanguageId = this._modeService.getLanguageIdentifier(modeId)!.id; } public emit(startOffset: number, type: string): void { @@ -417,7 +417,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport { } public getInitialState(): modes.IState { - let rootState = MonarchStackElementFactory.create(null, this._lexer.start); + let rootState = MonarchStackElementFactory.create(null, this._lexer.start!); return MonarchLineStateFactory.create(rootState, null); } @@ -506,6 +506,13 @@ class MonarchTokenizer implements modes.ITokenizationSupport { return this._myTokenize(restOfTheLine, lineState, offsetDelta + popOffset, tokensCollector); } + private _safeRuleName(rule: monarchCommon.IRule | null): string { + if (rule) { + return rule.name; + } + return '(unknown)'; + } + private _myTokenize(line: string, lineState: MonarchLineState, offsetDelta: number, tokensCollector: IMonarchTokensCollector): MonarchLineState { tokensCollector.enterMode(offsetDelta, this._modeId); @@ -519,7 +526,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport { // these never need cloning or equality since they are only used within a line match interface GroupMatching { matches: string[]; - rule: monarchCommon.IRule; + rule: monarchCommon.IRule | null; groups: { action: monarchCommon.FuzzyAction; matched: string; }[]; } let groupMatching: GroupMatching | null = null; @@ -599,6 +606,11 @@ class MonarchTokenizer implements modes.ITokenizationSupport { action = this._lexer.defaultToken; } + if (!matched) { + // should never happen, needed for strict null checking + break; + } + // advance stream pos += matched.length; @@ -647,7 +659,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport { nextState = nextState.substr(1); // peel off starting '@' } if (!monarchCommon.findRules(this._lexer, nextState)) { - throw monarchCommon.createError(this._lexer, 'trying to switch to a state \'' + nextState + '\' that is undefined in rule: ' + rule.name); + throw monarchCommon.createError(this._lexer, 'trying to switch to a state \'' + nextState + '\' that is undefined in rule: ' + this._safeRuleName(rule)); } else { stack = stack.switchTo(nextState); } @@ -657,15 +669,15 @@ class MonarchTokenizer implements modes.ITokenizationSupport { if (action.next === '@push') { if (stack.depth >= this._lexer.maxStack) { throw monarchCommon.createError(this._lexer, 'maximum tokenizer stack size reached: [' + - stack.state + ',' + stack.parent.state + ',...]'); + stack.state + ',' + stack.parent!.state + ',...]'); } else { stack = stack.push(state); } } else if (action.next === '@pop') { if (stack.depth <= 1) { - throw monarchCommon.createError(this._lexer, 'trying to pop an empty stack in rule: ' + rule.name); + throw monarchCommon.createError(this._lexer, 'trying to pop an empty stack in rule: ' + this._safeRuleName(rule)); } else { - stack = stack.pop(); + stack = stack.pop()!; } } else if (action.next === '@popall') { stack = stack.popall(); @@ -676,7 +688,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport { } if (!monarchCommon.findRules(this._lexer, nextState)) { - throw monarchCommon.createError(this._lexer, 'trying to set a next state \'' + nextState + '\' that is undefined in rule: ' + rule.name); + throw monarchCommon.createError(this._lexer, 'trying to set a next state \'' + nextState + '\' that is undefined in rule: ' + this._safeRuleName(rule)); } else { stack = stack.push(nextState); } @@ -690,23 +702,23 @@ class MonarchTokenizer implements modes.ITokenizationSupport { // check result if (result === null) { - throw monarchCommon.createError(this._lexer, 'lexer rule has no well-defined action in rule: ' + rule.name); + throw monarchCommon.createError(this._lexer, 'lexer rule has no well-defined action in rule: ' + this._safeRuleName(rule)); } // is the result a group match? if (Array.isArray(result)) { if (groupMatching && groupMatching.groups.length > 0) { - throw monarchCommon.createError(this._lexer, 'groups cannot be nested: ' + rule.name); + throw monarchCommon.createError(this._lexer, 'groups cannot be nested: ' + this._safeRuleName(rule)); } if (matches.length !== result.length + 1) { - throw monarchCommon.createError(this._lexer, 'matched number of groups does not match the number of actions in rule: ' + rule.name); + throw monarchCommon.createError(this._lexer, 'matched number of groups does not match the number of actions in rule: ' + this._safeRuleName(rule)); } let totalLen = 0; for (let i = 1; i < matches.length; i++) { totalLen += matches[i].length; } if (totalLen !== matched.length) { - throw monarchCommon.createError(this._lexer, 'with groups, all characters should be matched in consecutive groups in rule: ' + rule.name); + throw monarchCommon.createError(this._lexer, 'with groups, all characters should be matched in consecutive groups in rule: ' + this._safeRuleName(rule)); } groupMatching = { @@ -740,7 +752,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport { if (stackLen0 !== stack.depth || state !== stack.state || (!groupMatching ? 0 : groupMatching.groups.length) !== groupLen0) { continue; } else { - throw monarchCommon.createError(this._lexer, 'no progress in tokenizer in rule: ' + rule.name); + throw monarchCommon.createError(this._lexer, 'no progress in tokenizer in rule: ' + this._safeRuleName(rule)); pos = lineLength; // must make progress or editor loops } } diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts index f2b86a26c86..b740bbcb96f 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint.ts @@ -41,7 +41,7 @@ interface ILanguageConfiguration { autoCloseBefore?: string; } -function isStringArr(something: string[]): boolean { +function isStringArr(something: string[] | null): something is string[] { if (!Array.isArray(something)) { return false; } @@ -54,7 +54,7 @@ function isStringArr(something: string[]): boolean { } -function isCharacterPair(something: CharacterPair): boolean { +function isCharacterPair(something: CharacterPair | null): boolean { return ( isStringArr(something) && something.length === 2 @@ -82,7 +82,7 @@ export class LanguageConfigurationFileHandler { }); }); textMateService.onDidEncounterLanguage((languageId) => { - this._loadConfigurationsForMode(this._modeService.getLanguageIdentifier(languageId)); + this._loadConfigurationsForMode(this._modeService.getLanguageIdentifier(languageId)!); }); } @@ -109,7 +109,7 @@ export class LanguageConfigurationFileHandler { }); } - private _extractValidCommentRule(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): CommentRule { + private _extractValidCommentRule(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): CommentRule | null { const source = configuration.comments; if (typeof source === 'undefined') { return null; @@ -139,7 +139,7 @@ export class LanguageConfigurationFileHandler { return result; } - private _extractValidBrackets(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): CharacterPair[] { + private _extractValidBrackets(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): CharacterPair[] | null { const source = configuration.brackets; if (typeof source === 'undefined') { return null; @@ -163,7 +163,7 @@ export class LanguageConfigurationFileHandler { return result; } - private _extractValidAutoClosingPairs(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): IAutoClosingPairConditional[] { + private _extractValidAutoClosingPairs(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): IAutoClosingPairConditional[] | null { const source = configuration.autoClosingPairs; if (typeof source === 'undefined') { return null; @@ -209,7 +209,7 @@ export class LanguageConfigurationFileHandler { return result; } - private _extractValidSurroundingPairs(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): IAutoClosingPair[] { + private _extractValidSurroundingPairs(languageIdentifier: LanguageIdentifier, configuration: ILanguageConfiguration): IAutoClosingPair[] | null { const source = configuration.surroundingPairs; if (typeof source === 'undefined') { return null; @@ -327,7 +327,7 @@ export class LanguageConfigurationFileHandler { return null; } - private _mapIndentationRules(indentationRules: IIndentationRules): IndentationRule { + private _mapIndentationRules(indentationRules: IIndentationRules): IndentationRule | null { try { let increaseIndentPattern = this._parseRegex(indentationRules.increaseIndentPattern); let decreaseIndentPattern = this._parseRegex(indentationRules.decreaseIndentPattern); diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/textMate/inspectTMScopes.ts b/src/vs/workbench/parts/codeEditor/electron-browser/textMate/inspectTMScopes.ts index 3d1cb79443f..8fa373d027d 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/textMate/inspectTMScopes.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/textMate/inspectTMScopes.ts @@ -116,7 +116,7 @@ class InspectTMScopes extends EditorAction { } interface ICompleteLineTokenization { - startState: StackElement; + startState: StackElement | null; tokens1: IToken[]; tokens2: Uint32Array; endState: StackElement; @@ -347,7 +347,7 @@ class InspectTMScopesWidget extends Disposable implements IContentWidget { }; } - private _getStateBeforeLine(grammar: IGrammar, lineNumber: number): StackElement { + private _getStateBeforeLine(grammar: IGrammar, lineNumber: number): StackElement | null { let state: StackElement | null = null; for (let i = 1; i < lineNumber; i++) { diff --git a/src/vs/workbench/services/extensions/node/extensionPoints.ts b/src/vs/workbench/services/extensions/node/extensionPoints.ts index e5813bafa0a..d80156e5e00 100644 --- a/src/vs/workbench/services/extensions/node/extensionPoints.ts +++ b/src/vs/workbench/services/extensions/node/extensionPoints.ts @@ -7,6 +7,7 @@ import * as nls from 'vs/nls'; import * as path from 'path'; import * as semver from 'semver'; import * as json from 'vs/base/common/json'; +import * as arrays from 'vs/base/common/arrays'; import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; import * as types from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; @@ -125,11 +126,11 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler { } interface LocalizedMessages { - values: MessageBag; - default: string; + values: MessageBag | undefined; + default: string | null; } - const reportErrors = (localized: string, errors: json.ParseError[]): void => { + const reportErrors = (localized: string | null, errors: json.ParseError[]): void => { errors.forEach((error) => { this._log.error(this._absoluteFolderPath, nls.localize('jsonsParseReportErrors', "Failed to parse {0}: {1}.", localized, getParseErrorMessage(error.error))); }); @@ -140,7 +141,7 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler { const translationId = `${extensionDescription.publisher}.${extensionDescription.name}`; let translationPath = this._nlsConfig.translations[translationId]; - let localizedMessages: Promise; + let localizedMessages: Promise; if (translationPath) { localizedMessages = pfs.readFile(translationPath, 'utf8').then((content) => { let errors: json.ParseError[] = []; @@ -156,7 +157,7 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler { return { values: undefined, default: `${basename}.nls.json` }; }); } else { - localizedMessages = pfs.fileExists(basename + '.nls' + extension).then(exists => { + localizedMessages = pfs.fileExists(basename + '.nls' + extension).then(exists => { if (!exists) { return undefined; } @@ -204,8 +205,8 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler { /** * Parses original message bundle, returns null if the original message bundle is null. */ - private static resolveOriginalMessageBundle(originalMessageBundle: string, errors: json.ParseError[]) { - return new Promise<{ [key: string]: string; }>((c, e) => { + private static resolveOriginalMessageBundle(originalMessageBundle: string | null, errors: json.ParseError[]) { + return new Promise<{ [key: string]: string; } | null>((c, e) => { if (originalMessageBundle) { pfs.readFile(originalMessageBundle).then(originalBundleContent => { c(json.parse(originalBundleContent.toString(), errors)); @@ -222,8 +223,8 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler { * Finds localized message bundle and the original (unlocalized) one. * If the localized file is not present, returns null for the original and marks original as localized. */ - private static findMessageBundles(nlsConfig: NlsConfiguration, basename: string): Promise<{ localized: string, original: string }> { - return new Promise<{ localized: string, original: string }>((c, e) => { + private static findMessageBundles(nlsConfig: NlsConfiguration, basename: string): Promise<{ localized: string; original: string | null; }> { + return new Promise<{ localized: string; original: string | null; }>((c, e) => { function loop(basename: string, locale: string): void { let toCheck = `${basename}.nls.${locale}.json`; pfs.fileExists(toCheck).then(exists => { @@ -251,7 +252,7 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler { * This routine makes the following assumptions: * The root element is an object literal */ - private static _replaceNLStrings(nlsConfig: NlsConfiguration, literal: T, messages: { [key: string]: string; }, originalMessages: { [key: string]: string }, log: ILog, messageScope: string): void { + private static _replaceNLStrings(nlsConfig: NlsConfiguration, literal: T, messages: { [key: string]: string; }, originalMessages: { [key: string]: string } | null, log: ILog, messageScope: string): void { function processEntry(obj: any, key: string | number, command?: boolean) { let value = obj[key]; if (types.isString(value)) { @@ -313,7 +314,7 @@ export interface IRelaxedExtensionDescription { } class ExtensionManifestValidator extends ExtensionManifestHandler { - validate(_extensionDescription: IExtensionDescription): IExtensionDescription { + validate(_extensionDescription: IExtensionDescription): IExtensionDescription | null { let extensionDescription = _extensionDescription; extensionDescription.isBuiltin = this._isBuiltin; extensionDescription.isUnderDevelopment = this._isUnderDevelopment; @@ -502,11 +503,11 @@ export class ExtensionScanner { /** * Read the extension defined in `absoluteFolderPath` */ - public static scanExtension(version: string, log: ILog, absoluteFolderPath: string, isBuiltin: boolean, isUnderDevelopment: boolean, nlsConfig: NlsConfiguration): Promise { + public static scanExtension(version: string, log: ILog, absoluteFolderPath: string, isBuiltin: boolean, isUnderDevelopment: boolean, nlsConfig: NlsConfiguration): Promise { absoluteFolderPath = path.normalize(absoluteFolderPath); let parser = new ExtensionManifestParser(version, log, absoluteFolderPath, isBuiltin, isUnderDevelopment); - return parser.parse().then((extensionDescription) => { + return parser.parse().then((extensionDescription) => { if (extensionDescription === null) { return null; } @@ -570,7 +571,8 @@ export class ExtensionScanner { } const nlsConfig = ExtensionScannerInput.createNLSConfig(input); - let extensionDescriptions = await Promise.all(refs.map(r => this.scanExtension(input.ourVersion, log, r.path, isBuiltin, isUnderDevelopment, nlsConfig))); + let _extensionDescriptions = await Promise.all(refs.map(r => this.scanExtension(input.ourVersion, log, r.path, isBuiltin, isUnderDevelopment, nlsConfig))); + let extensionDescriptions = arrays.coalesce(_extensionDescriptions); extensionDescriptions = extensionDescriptions.filter(item => item !== null && !obsolete[getLocalExtensionId(getGalleryExtensionId(item.publisher, item.name), item.version)]); if (!isBuiltin) { diff --git a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts index a0e060e0dde..977980e627a 100644 --- a/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts +++ b/src/vs/workbench/services/textMate/electron-browser/TMSyntax.ts @@ -57,7 +57,7 @@ export class TMScopeRegistry { return this._scopeNameToLanguageRegistration[scopeName] || null; } - public getGrammarLocation(scopeName: string): URI { + public getGrammarLocation(scopeName: string): URI | null { let data = this.getLanguageRegistration(scopeName); return data ? data.grammarLocation : null; } @@ -81,7 +81,7 @@ export class TMLanguageRegistration { readonly embeddedLanguages: IEmbeddedLanguagesMap; readonly tokenTypes: ITokenTypeMap; - constructor(scopeName: string, grammarLocation: URI, embeddedLanguages: IEmbeddedLanguagesMap, tokenTypes: TokenTypesContribution | undefined) { + constructor(scopeName: string, grammarLocation: URI, embeddedLanguages: IEmbeddedLanguagesMap | undefined, tokenTypes: TokenTypesContribution | undefined) { this.scopeName = scopeName; this.grammarLocation = grammarLocation; @@ -135,7 +135,7 @@ interface ICreateGrammarResult { export class TextMateService implements ITextMateService { public _serviceBrand: any; - private _grammarRegistry: Promise<[Registry, StackElement]>; + private _grammarRegistry: Promise<[Registry, StackElement]> | null; private _modeService: IModeService; private _themeService: IWorkbenchThemeService; private _fileService: IFileService; @@ -199,7 +199,7 @@ export class TextMateService implements ITextMateService { } } } - TokenizationRegistry.setColorMap([null, defaultForeground, defaultBackground]); + TokenizationRegistry.setColorMap([null!, defaultForeground, defaultBackground]); this._modeService.onDidCreateMode((mode) => { let modeId = mode.getId(); @@ -249,7 +249,7 @@ export class TextMateService implements ITextMateService { } private static _toColorMap(colorMap: string[]): Color[] { - let result: Color[] = [null]; + let result: Color[] = [null!]; for (let i = 1, len = colorMap.length; i < len; i++) { result[i] = Color.fromHex(colorMap[i]); } @@ -390,7 +390,7 @@ export class TextMateService implements ITextMateService { } } - let languageId = this._modeService.getLanguageIdentifier(modeId).id; + let languageId = this._modeService.getLanguageIdentifier(modeId)!.id; let containsEmbeddedLanguages = (Object.keys(embeddedLanguages).length > 0); return this._getOrCreateGrammarRegistry().then((_res) => { const [grammarRegistry, initialState] = _res;