mirror of
https://github.com/Microsoft/vscode
synced 2024-09-18 01:58:27 +00:00
strict null checks (#60565)
This commit is contained in:
parent
409e61c5ca
commit
5d645696cc
|
@ -75,6 +75,7 @@
|
|||
"./vs/base/common/normalization.ts",
|
||||
"./vs/base/common/numbers.ts",
|
||||
"./vs/base/common/objects.ts",
|
||||
"./vs/base/common/paging.ts",
|
||||
"./vs/base/common/parsers.ts",
|
||||
"./vs/base/common/paths.ts",
|
||||
"./vs/base/common/platform.ts",
|
||||
|
@ -332,12 +333,14 @@
|
|||
"./vs/platform/commands/common/commands.ts",
|
||||
"./vs/platform/configuration/common/configuration.ts",
|
||||
"./vs/platform/configuration/common/configurationRegistry.ts",
|
||||
"./vs/platform/contextkey/browser/contextKeyService.ts",
|
||||
"./vs/platform/contextkey/common/contextkey.ts",
|
||||
"./vs/platform/download/common/download.ts",
|
||||
"./vs/platform/editor/common/editor.ts",
|
||||
"./vs/platform/environment/common/environment.ts",
|
||||
"./vs/platform/extensions/common/extensionHost.ts",
|
||||
"./vs/platform/extensions/common/extensions.ts",
|
||||
"./vs/platform/extensions/node/extensionValidator.ts",
|
||||
"./vs/platform/files/common/files.ts",
|
||||
"./vs/platform/files/node/files.ts",
|
||||
"./vs/platform/instantiation/common/descriptors.ts",
|
||||
|
@ -346,11 +349,14 @@
|
|||
"./vs/platform/instantiation/common/instantiation.ts",
|
||||
"./vs/platform/instantiation/common/serviceCollection.ts",
|
||||
"./vs/platform/integrity/common/integrity.ts",
|
||||
"./vs/platform/integrity/node/integrityServiceImpl.ts",
|
||||
"./vs/platform/jsonschemas/common/jsonContributionRegistry.ts",
|
||||
"./vs/platform/keybinding/common/abstractKeybindingService.ts",
|
||||
"./vs/platform/keybinding/common/keybinding.ts",
|
||||
"./vs/platform/keybinding/common/keybindingResolver.ts",
|
||||
"./vs/platform/keybinding/common/keybindingsRegistry.ts",
|
||||
"./vs/platform/keybinding/common/resolvedKeybindingItem.ts",
|
||||
"./vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts",
|
||||
"./vs/platform/lifecycle/common/lifecycle.ts",
|
||||
"./vs/platform/localizations/common/localizations.ts",
|
||||
"./vs/platform/log/common/bufferLog.ts",
|
||||
|
@ -400,6 +406,9 @@
|
|||
"./vs/workbench/common/viewlet.ts",
|
||||
"./vs/workbench/parts/codeEditor/browser/menuPreventer.ts",
|
||||
"./vs/workbench/parts/codeEditor/browser/simpleEditorOptions.ts",
|
||||
"./vs/workbench/parts/codeEditor/electron-browser/largeFileOptimizations.ts",
|
||||
"./vs/workbench/parts/codeEditor/electron-browser/selectionClipboard.ts",
|
||||
"./vs/workbench/parts/codeEditor/electron-browser/toggleWordWrap.ts",
|
||||
"./vs/workbench/parts/comments/electron-browser/commentGlyphWidget.ts",
|
||||
"./vs/workbench/parts/execution/common/execution.ts",
|
||||
"./vs/workbench/parts/extensions/common/extensionQuery.ts",
|
||||
|
@ -426,6 +435,8 @@
|
|||
"./vs/workbench/services/configuration/common/jsonEditing.ts",
|
||||
"./vs/workbench/services/configurationResolver/common/configurationResolver.ts",
|
||||
"./vs/workbench/services/decorations/browser/decorations.ts",
|
||||
"./vs/workbench/services/extensions/common/extensions.ts",
|
||||
"./vs/workbench/services/extensions/common/extensionsRegistry.ts",
|
||||
"./vs/workbench/services/extensions/node/lazyPromise.ts",
|
||||
"./vs/workbench/services/extensions/node/proxyIdentifier.ts",
|
||||
"./vs/workbench/services/files/node/watcher/common.ts",
|
||||
|
@ -433,11 +444,17 @@
|
|||
"./vs/workbench/services/files/node/watcher/unix/watcher.ts",
|
||||
"./vs/workbench/services/hash/common/hashService.ts",
|
||||
"./vs/workbench/services/hash/node/hashService.ts",
|
||||
"./vs/workbench/services/keybinding/common/keybindingIO.ts",
|
||||
"./vs/workbench/services/keybinding/common/keyboardMapper.ts",
|
||||
"./vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper.ts",
|
||||
"./vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts",
|
||||
"./vs/workbench/services/keybinding/common/windowsKeyboardMapper.ts",
|
||||
"./vs/workbench/services/panel/common/panelService.ts",
|
||||
"./vs/workbench/services/scm/common/scm.ts",
|
||||
"./vs/workbench/services/scm/common/scmService.ts",
|
||||
"./vs/workbench/services/search/node/search.ts",
|
||||
"./vs/workbench/services/textMate/electron-browser/textMateService.ts",
|
||||
"./vs/workbench/services/textMate/electron-browser/TMHelper.ts",
|
||||
"./vs/workbench/services/themes/common/colorThemeSchema.ts",
|
||||
"./vs/workbench/services/themes/common/fileIconThemeSchema.ts",
|
||||
"./vs/workbench/services/themes/common/workbenchThemeService.ts",
|
||||
|
|
|
@ -529,10 +529,10 @@ export class ResolvedKeybindingPart {
|
|||
readonly altKey: boolean;
|
||||
readonly metaKey: boolean;
|
||||
|
||||
readonly keyLabel: string;
|
||||
readonly keyAriaLabel: string;
|
||||
readonly keyLabel: string | null;
|
||||
readonly keyAriaLabel: string | null;
|
||||
|
||||
constructor(ctrlKey: boolean, shiftKey: boolean, altKey: boolean, metaKey: boolean, kbLabel: string, kbAriaLabel: string) {
|
||||
constructor(ctrlKey: boolean, shiftKey: boolean, altKey: boolean, metaKey: boolean, kbLabel: string | null, kbAriaLabel: string | null) {
|
||||
this.ctrlKey = ctrlKey;
|
||||
this.shiftKey = shiftKey;
|
||||
this.altKey = altKey;
|
||||
|
@ -549,20 +549,20 @@ export abstract class ResolvedKeybinding {
|
|||
/**
|
||||
* This prints the binding in a format suitable for displaying in the UI.
|
||||
*/
|
||||
public abstract getLabel(): string;
|
||||
public abstract getLabel(): string | null;
|
||||
/**
|
||||
* This prints the binding in a format suitable for ARIA.
|
||||
*/
|
||||
public abstract getAriaLabel(): string;
|
||||
public abstract getAriaLabel(): string | null;
|
||||
/**
|
||||
* This prints the binding in a format suitable for electron's accelerators.
|
||||
* See https://github.com/electron/electron/blob/master/docs/api/accelerator.md
|
||||
*/
|
||||
public abstract getElectronAccelerator(): string;
|
||||
public abstract getElectronAccelerator(): string | null;
|
||||
/**
|
||||
* This prints the binding in a format suitable for user settings.
|
||||
*/
|
||||
public abstract getUserSettingsLabel(): string;
|
||||
public abstract getUserSettingsLabel(): string | null;
|
||||
/**
|
||||
* Is the user settings label reflecting the label?
|
||||
*/
|
||||
|
@ -576,10 +576,10 @@ export abstract class ResolvedKeybinding {
|
|||
/**
|
||||
* Returns the firstPart, chordPart that should be used for dispatching.
|
||||
*/
|
||||
public abstract getDispatchParts(): [string, string];
|
||||
public abstract getDispatchParts(): [string | null, string | null];
|
||||
/**
|
||||
* Returns the firstPart, chordPart of the keybinding.
|
||||
* For simple keybindings, the second element will be null.
|
||||
*/
|
||||
public abstract getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart];
|
||||
public abstract getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart | null];
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ export class ModifierLabelProvider {
|
|||
this.modifierLabels[OperatingSystem.Linux] = linux;
|
||||
}
|
||||
|
||||
public toLabel(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers, chordPartKey: string, OS: OperatingSystem): string | null {
|
||||
if (firstPartKey === null && chordPartKey === null) {
|
||||
public toLabel(firstPartMod: Modifiers | null, firstPartKey: string | null, chordPartMod: Modifiers | null, chordPartKey: string | null, OS: OperatingSystem): string | null {
|
||||
if (firstPartMod === null || firstPartKey === null) {
|
||||
return null;
|
||||
}
|
||||
return _asString(firstPartMod, firstPartKey, chordPartMod, chordPartKey, this.modifierLabels[OS]);
|
||||
|
@ -172,10 +172,10 @@ function _simpleAsString(modifiers: Modifiers, key: string, labels: ModifierLabe
|
|||
return result.join(labels.separator);
|
||||
}
|
||||
|
||||
function _asString(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers, chordPartKey: string, labels: ModifierLabels): string {
|
||||
function _asString(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers | null, chordPartKey: string | null, labels: ModifierLabels): string {
|
||||
let result = _simpleAsString(firstPartMod, firstPartKey, labels);
|
||||
|
||||
if (chordPartKey !== null) {
|
||||
if (chordPartMod !== null && chordPartKey !== null) {
|
||||
result += ' ';
|
||||
result += _simpleAsString(chordPartMod, chordPartKey, labels);
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ export interface IPager<T> {
|
|||
|
||||
interface IPage<T> {
|
||||
isResolved: boolean;
|
||||
promise: Thenable<void>;
|
||||
cts: CancellationTokenSource;
|
||||
promise: Thenable<void> | null;
|
||||
cts: CancellationTokenSource | null;
|
||||
promiseIndexes: Set<number>;
|
||||
elements: T[];
|
||||
}
|
||||
|
@ -52,7 +52,9 @@ export function singlePagePager<T>(elements: T[]): IPager<T> {
|
|||
firstPage: elements,
|
||||
total: elements.length,
|
||||
pageSize: elements.length,
|
||||
getPage: null
|
||||
getPage: (pageIndex: number, cancellationToken: CancellationToken): Thenable<T[]> => {
|
||||
return Promise.resolve(elements);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ export interface IOverlayWidgetPosition {
|
|||
/**
|
||||
* The position preference for the overlay widget.
|
||||
*/
|
||||
preference: OverlayWidgetPositionPreference;
|
||||
preference: OverlayWidgetPositionPreference | null;
|
||||
}
|
||||
/**
|
||||
* An overlay widgets renders on top of the text.
|
||||
|
|
|
@ -14,7 +14,7 @@ export const IModelService = createDecorator<IModelService>('modelService');
|
|||
export interface IModelService {
|
||||
_serviceBrand: any;
|
||||
|
||||
createModel(value: string | ITextBufferFactory, modeOrPromise: Promise<IMode> | IMode, resource: URI, isForSimpleWidget?: boolean): ITextModel;
|
||||
createModel(value: string | ITextBufferFactory, modeOrPromise: Promise<IMode> | IMode, resource: URI | undefined, isForSimpleWidget?: boolean): ITextModel;
|
||||
|
||||
updateModel(model: ITextModel, value: string | ITextBufferFactory): void;
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ const nlsSingleSelection = nls.localize("singleSelection", "Line {0}, Column {1}
|
|||
const nlsMultiSelectionRange = nls.localize("multiSelectionRange", "{0} selections ({1} characters selected)");
|
||||
const nlsMultiSelection = nls.localize("multiSelection", "{0} selections");
|
||||
|
||||
function getSelectionLabel(selections: Selection[], charactersSelected: number): string {
|
||||
function getSelectionLabel(selections: Selection[] | null, charactersSelected: number): string | null {
|
||||
if (!selections || selections.length === 0) {
|
||||
return nlsNoSelection;
|
||||
}
|
||||
|
@ -257,13 +257,13 @@ class AccessibilityHelpWidget extends Widget implements IOverlayWidget {
|
|||
}
|
||||
}
|
||||
|
||||
switch (opts.accessibilitySupport) {
|
||||
case platform.AccessibilitySupport.Unknown:
|
||||
const turnOnMessage = (
|
||||
platform.isMacintosh
|
||||
? nls.localize("changeConfigToOnMac", "To configure the editor to be optimized for usage with a Screen Reader press Command+E now.")
|
||||
: nls.localize("changeConfigToOnWinLinux", "To configure the editor to be optimized for usage with a Screen Reader press Control+E now.")
|
||||
);
|
||||
switch (opts.accessibilitySupport) {
|
||||
case platform.AccessibilitySupport.Unknown:
|
||||
text += '\n\n - ' + turnOnMessage;
|
||||
break;
|
||||
case platform.AccessibilitySupport.Enabled:
|
||||
|
|
|
@ -121,9 +121,9 @@ export class SimpleEditorModelResolverService implements ITextModelService {
|
|||
};
|
||||
}
|
||||
|
||||
private findModel(editor: ICodeEditor, resource: URI): ITextModel {
|
||||
private findModel(editor: ICodeEditor, resource: URI): ITextModel | null {
|
||||
let model = editor.getModel();
|
||||
if (model.uri.toString() !== resource.toString()) {
|
||||
if (model && model.uri.toString() !== resource.toString()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ export class StandaloneCommandService implements ICommandService {
|
|||
}
|
||||
|
||||
export class StandaloneKeybindingService extends AbstractKeybindingService {
|
||||
private _cachedResolver: KeybindingResolver;
|
||||
private _cachedResolver: KeybindingResolver | null;
|
||||
private _dynamicKeybindings: IKeybindingItem[];
|
||||
|
||||
constructor(
|
||||
|
@ -280,7 +280,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
|
|||
}));
|
||||
}
|
||||
|
||||
public addDynamicKeybinding(commandId: string, keybinding: number, handler: ICommandHandler, when: ContextKeyExpr): IDisposable {
|
||||
public addDynamicKeybinding(commandId: string, keybinding: number, handler: ICommandHandler, when: ContextKeyExpr | null): IDisposable {
|
||||
let toDispose: IDisposable[] = [];
|
||||
|
||||
this._dynamicKeybindings.push({
|
||||
|
@ -411,7 +411,7 @@ export class SimpleConfigurationService implements IConfigurationService {
|
|||
|
||||
public updateValue(key: string, value: any, arg3?: any, arg4?: any): Promise<void> {
|
||||
this.configuration().updateValue(key, value);
|
||||
return Promise.resolve(null);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public inspect<C>(key: string, options: IConfigurationOverrides = {}): {
|
||||
|
|
|
@ -122,13 +122,13 @@ export interface IDiffEditorConstructionOptions extends IDiffEditorOptions {
|
|||
}
|
||||
|
||||
export interface IStandaloneCodeEditor extends ICodeEditor {
|
||||
addCommand(keybinding: number, handler: ICommandHandler, context: string): string;
|
||||
addCommand(keybinding: number, handler: ICommandHandler, context: string): string | null;
|
||||
createContextKey<T>(key: string, defaultValue: T): IContextKey<T>;
|
||||
addAction(descriptor: IActionDescriptor): IDisposable;
|
||||
}
|
||||
|
||||
export interface IStandaloneDiffEditor extends IDiffEditor {
|
||||
addCommand(keybinding: number, handler: ICommandHandler, context: string): string;
|
||||
addCommand(keybinding: number, handler: ICommandHandler, context: string): string | null;
|
||||
createContextKey<T>(key: string, defaultValue: T): IContextKey<T>;
|
||||
addAction(descriptor: IActionDescriptor): IDisposable;
|
||||
|
||||
|
@ -182,7 +182,7 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon
|
|||
createAriaDomNode();
|
||||
}
|
||||
|
||||
public addCommand(keybinding: number, handler: ICommandHandler, context: string): string {
|
||||
public addCommand(keybinding: number, handler: ICommandHandler, context: string): string | null {
|
||||
if (!this._standaloneKeybindingService) {
|
||||
console.warn('Cannot add command because the editor is configured with an unrecognized KeybindingService');
|
||||
return null;
|
||||
|
@ -284,7 +284,7 @@ export class StandaloneEditor extends StandaloneCodeEditor implements IStandalon
|
|||
|
||||
constructor(
|
||||
domElement: HTMLElement,
|
||||
options: IEditorConstructionOptions,
|
||||
options: IEditorConstructionOptions | undefined,
|
||||
toDispose: IDisposable,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService,
|
||||
|
@ -301,7 +301,7 @@ export class StandaloneEditor extends StandaloneCodeEditor implements IStandalon
|
|||
if (typeof options.theme === 'string') {
|
||||
themeService.setTheme(options.theme);
|
||||
}
|
||||
let model: ITextModel = options.model;
|
||||
let _model: ITextModel | null | undefined = options.model;
|
||||
delete options.model;
|
||||
super(domElement, options, instantiationService, codeEditorService, commandService, contextKeyService, keybindingService, themeService, notificationService);
|
||||
|
||||
|
@ -309,10 +309,12 @@ export class StandaloneEditor extends StandaloneCodeEditor implements IStandalon
|
|||
this._configurationService = configurationService;
|
||||
this._register(toDispose);
|
||||
|
||||
if (typeof model === 'undefined') {
|
||||
let model: ITextModel | null;
|
||||
if (typeof _model === 'undefined') {
|
||||
model = (<any>self).monaco.editor.createModel(options.value || '', options.language || 'text/plain');
|
||||
this._ownsModel = true;
|
||||
} else {
|
||||
model = _model;
|
||||
this._ownsModel = false;
|
||||
}
|
||||
|
||||
|
@ -335,7 +337,7 @@ export class StandaloneEditor extends StandaloneCodeEditor implements IStandalon
|
|||
super.updateOptions(newOptions);
|
||||
}
|
||||
|
||||
_attachModel(model: ITextModel): void {
|
||||
_attachModel(model: ITextModel | null): void {
|
||||
super._attachModel(model);
|
||||
if (this._modelData) {
|
||||
this._contextViewService.setContainer(this._modelData.view.domNode.domNode);
|
||||
|
@ -407,7 +409,7 @@ export class StandaloneDiffEditor extends DiffEditorWidget implements IStandalon
|
|||
return <StandaloneCodeEditor>super.getModifiedEditor();
|
||||
}
|
||||
|
||||
public addCommand(keybinding: number, handler: ICommandHandler, context: string): string {
|
||||
public addCommand(keybinding: number, handler: ICommandHandler, context: string): string | null {
|
||||
return this.getModifiedEditor().addCommand(keybinding, handler, context);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ function withAllStandaloneServices<T extends editorCommon.IEditor>(domElement: H
|
|||
* The editor will read the size of `domElement`.
|
||||
*/
|
||||
export function create(domElement: HTMLElement, options?: IEditorConstructionOptions, override?: IEditorOverrideServices): IStandaloneCodeEditor {
|
||||
return withAllStandaloneServices(domElement, override, (services) => {
|
||||
return withAllStandaloneServices(domElement, override || {}, (services) => {
|
||||
return new StandaloneEditor(
|
||||
domElement,
|
||||
options,
|
||||
|
@ -188,7 +188,7 @@ export function getModelMarkers(filter: { owner?: string, resource?: URI, take?:
|
|||
/**
|
||||
* Get the model that has `uri` if it exists.
|
||||
*/
|
||||
export function getModel(uri: URI): ITextModel {
|
||||
export function getModel(uri: URI): ITextModel | null {
|
||||
return StaticServices.modelService.get().getModel(uri);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ export function getLanguages(): ILanguageExtensionPoint[] {
|
|||
|
||||
export function getEncodedLanguageId(languageId: string): number {
|
||||
let lid = StaticServices.modeService.get().getLanguageIdentifier(languageId);
|
||||
return lid && lid.id;
|
||||
return lid ? lid.id : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -347,7 +347,7 @@ export function registerHoverProvider(languageId: string, provider: modes.HoverP
|
|||
provideHover: (model: model.ITextModel, position: Position, token: CancellationToken): Thenable<modes.Hover> => {
|
||||
let word = model.getWordAtPosition(position);
|
||||
|
||||
return Promise.resolve<modes.Hover>(provider.provideHover(model, position, token)).then((value) => {
|
||||
return Promise.resolve<modes.Hover | null | undefined>(provider.provideHover(model, position, token)).then((value) => {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -130,11 +130,8 @@ export function log(lexer: ILexerMin, msg: string) {
|
|||
|
||||
// Throwing errors
|
||||
|
||||
/**
|
||||
* Throws error. May actually just log the error and continue.
|
||||
*/
|
||||
export function throwError(lexer: ILexerMin, msg: string) {
|
||||
throw new Error(`${lexer.languageId}: ${msg}`);
|
||||
export function createError(lexer: ILexerMin, msg: string): Error {
|
||||
return new Error(`${lexer.languageId}: ${msg}`);
|
||||
}
|
||||
|
||||
// Helper functions for rule finding and substitution
|
||||
|
|
|
@ -70,9 +70,9 @@ function compileRegExp(lexer: monarchCommon.ILexerMin, str: string): RegExp {
|
|||
sub = lexer[attr].source;
|
||||
} else {
|
||||
if (lexer[attr] === undefined) {
|
||||
monarchCommon.throwError(lexer, 'language definition does not contain attribute \'' + attr + '\', used at: ' + str);
|
||||
throw monarchCommon.createError(lexer, 'language definition does not contain attribute \'' + attr + '\', used at: ' + str);
|
||||
} else {
|
||||
monarchCommon.throwError(lexer, 'attribute reference \'' + attr + '\' must be a string, used at: ' + str);
|
||||
throw monarchCommon.createError(lexer, 'attribute reference \'' + attr + '\' must be a string, used at: ' + str);
|
||||
}
|
||||
}
|
||||
return (monarchCommon.empty(sub) ? '' : '(?:' + sub + ')');
|
||||
|
@ -148,10 +148,10 @@ function createGuard(lexer: monarchCommon.ILexerMin, ruleName: string, tkey: str
|
|||
else if (op === '@' || op === '!@') {
|
||||
let words = lexer[pat];
|
||||
if (!words) {
|
||||
monarchCommon.throwError(lexer, 'the @ match target \'' + pat + '\' is not defined, in rule: ' + ruleName);
|
||||
throw monarchCommon.createError(lexer, 'the @ match target \'' + pat + '\' is not defined, in rule: ' + ruleName);
|
||||
}
|
||||
if (!(isArrayOf(function (elem) { return (typeof (elem) === 'string'); }, words))) {
|
||||
monarchCommon.throwError(lexer, 'the @ match target \'' + pat + '\' must be an array of strings, in rule: ' + ruleName);
|
||||
throw monarchCommon.createError(lexer, 'the @ match target \'' + pat + '\' must be an array of strings, in rule: ' + ruleName);
|
||||
}
|
||||
let inWords = objects.createKeywordMatcher(words, lexer.ignoreCase);
|
||||
tester = function (s) { return (op === '@' ? inWords(s) : !inWords(s)); };
|
||||
|
@ -218,7 +218,7 @@ function compileAction(lexer: monarchCommon.ILexerMin, ruleName: string, action:
|
|||
}
|
||||
else if (action.token || action.token === '') {
|
||||
if (typeof (action.token) !== 'string') {
|
||||
monarchCommon.throwError(lexer, 'a \'token\' attribute must be of type string, in rule: ' + ruleName);
|
||||
throw monarchCommon.createError(lexer, 'a \'token\' attribute must be of type string, in rule: ' + ruleName);
|
||||
return { token: '' };
|
||||
}
|
||||
else {
|
||||
|
@ -233,12 +233,12 @@ function compileAction(lexer: monarchCommon.ILexerMin, ruleName: string, action:
|
|||
} else if (action.bracket === '@close') {
|
||||
newAction.bracket = monarchCommon.MonarchBracket.Close;
|
||||
} else {
|
||||
monarchCommon.throwError(lexer, 'a \'bracket\' attribute must be either \'@open\' or \'@close\', in rule: ' + ruleName);
|
||||
throw monarchCommon.createError(lexer, 'a \'bracket\' attribute must be either \'@open\' or \'@close\', in rule: ' + ruleName);
|
||||
}
|
||||
}
|
||||
if (action.next) {
|
||||
if (typeof (action.next) !== 'string') {
|
||||
monarchCommon.throwError(lexer, 'the next state must be a string value in rule: ' + ruleName);
|
||||
throw monarchCommon.createError(lexer, 'the next state must be a string value in rule: ' + ruleName);
|
||||
}
|
||||
else {
|
||||
let next: string = action.next;
|
||||
|
@ -248,7 +248,7 @@ function compileAction(lexer: monarchCommon.ILexerMin, ruleName: string, action:
|
|||
}
|
||||
if (next.indexOf('$') < 0) { // no dollar substitution, we can check if the state exists
|
||||
if (!monarchCommon.stateExists(lexer, monarchCommon.substituteMatches(lexer, next, '', [], ''))) {
|
||||
monarchCommon.throwError(lexer, 'the next state \'' + action.next + '\' is not defined in rule: ' + ruleName);
|
||||
throw monarchCommon.createError(lexer, 'the next state \'' + action.next + '\' is not defined in rule: ' + ruleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ function compileAction(lexer: monarchCommon.ILexerMin, ruleName: string, action:
|
|||
};
|
||||
}
|
||||
else {
|
||||
monarchCommon.throwError(lexer, 'an action must be a string, an object with a \'token\' or \'cases\' attribute, or an array of actions; in rule: ' + ruleName);
|
||||
throw monarchCommon.createError(lexer, 'an action must be a string, an object with a \'token\' or \'cases\' attribute, or an array of actions; in rule: ' + ruleName);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ class Rule implements monarchCommon.IRule {
|
|||
sregex = (<RegExp>re).source;
|
||||
}
|
||||
else {
|
||||
return monarchCommon.throwError(lexer, 'rules must start with a match string or regular expression: ' + this.name);
|
||||
throw monarchCommon.createError(lexer, 'rules must start with a match string or regular expression: ' + this.name);
|
||||
}
|
||||
|
||||
this.matchOnlyAtLineStart = (sregex.length > 0 && sregex[0] === '^');
|
||||
|
@ -407,13 +407,13 @@ export function compile(languageId: string, json: IMonarchLanguage): monarchComm
|
|||
let include = rule.include;
|
||||
if (include) {
|
||||
if (typeof (include) !== 'string') {
|
||||
monarchCommon.throwError(lexer, 'an \'include\' attribute must be a string at: ' + state);
|
||||
throw monarchCommon.createError(lexer, 'an \'include\' attribute must be a string at: ' + state);
|
||||
}
|
||||
if (include[0] === '@') {
|
||||
include = include.substr(1); // peel off starting @
|
||||
}
|
||||
if (!json.tokenizer[include]) {
|
||||
monarchCommon.throwError(lexer, 'include target \'' + include + '\' is not defined at: ' + state);
|
||||
throw monarchCommon.createError(lexer, 'include target \'' + include + '\' is not defined at: ' + state);
|
||||
}
|
||||
addRules(state + '.' + include, newrules, json.tokenizer[include]);
|
||||
}
|
||||
|
@ -434,7 +434,7 @@ export function compile(languageId: string, json: IMonarchLanguage): monarchComm
|
|||
newrule.setAction(lexerMin, rule1);
|
||||
}
|
||||
else {
|
||||
monarchCommon.throwError(lexer, 'a next state as the last element of a rule can only be given if the action is either an object or a string, at: ' + state);
|
||||
throw monarchCommon.createError(lexer, 'a next state as the last element of a rule can only be given if the action is either an object or a string, at: ' + state);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -443,7 +443,7 @@ export function compile(languageId: string, json: IMonarchLanguage): monarchComm
|
|||
}
|
||||
else {
|
||||
if (!rule.regex) {
|
||||
monarchCommon.throwError(lexer, 'a rule must either be an array, or an object with a \'regex\' or \'include\' field at: ' + state);
|
||||
throw monarchCommon.createError(lexer, 'a rule must either be an array, or an object with a \'regex\' or \'include\' field at: ' + state);
|
||||
}
|
||||
if (rule.name) {
|
||||
if (typeof rule.name === 'string') {
|
||||
|
@ -465,7 +465,7 @@ export function compile(languageId: string, json: IMonarchLanguage): monarchComm
|
|||
|
||||
// compile the tokenizer rules
|
||||
if (!json.tokenizer || typeof (json.tokenizer) !== 'object') {
|
||||
monarchCommon.throwError(lexer, 'a language definition must define the \'tokenizer\' attribute as an object');
|
||||
throw monarchCommon.createError(lexer, 'a language definition must define the \'tokenizer\' attribute as an object');
|
||||
}
|
||||
|
||||
lexer.tokenizer = <any>[];
|
||||
|
@ -485,7 +485,7 @@ export function compile(languageId: string, json: IMonarchLanguage): monarchComm
|
|||
// Set simple brackets
|
||||
if (json.brackets) {
|
||||
if (!(Array.isArray(<any>json.brackets))) {
|
||||
monarchCommon.throwError(lexer, 'the \'brackets\' attribute must be defined as an array');
|
||||
throw monarchCommon.createError(lexer, 'the \'brackets\' attribute must be defined as an array');
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -503,7 +503,7 @@ export function compile(languageId: string, json: IMonarchLanguage): monarchComm
|
|||
desc = { token: desc[2], open: desc[0], close: desc[1] };
|
||||
}
|
||||
if (desc.open === desc.close) {
|
||||
monarchCommon.throwError(lexer, 'open and close brackets in a \'brackets\' attribute must be different: ' + desc.open +
|
||||
throw monarchCommon.createError(lexer, 'open and close brackets in a \'brackets\' attribute must be different: ' + desc.open +
|
||||
'\n hint: use the \'bracket\' attribute if matching on equal brackets is required.');
|
||||
}
|
||||
if (typeof desc.open === 'string' && typeof desc.token === 'string' && typeof desc.close === 'string') {
|
||||
|
@ -514,7 +514,7 @@ export function compile(languageId: string, json: IMonarchLanguage): monarchComm
|
|||
});
|
||||
}
|
||||
else {
|
||||
monarchCommon.throwError(lexer, 'every element in the \'brackets\' array must be a \'{open,close,token}\' object or array');
|
||||
throw monarchCommon.createError(lexer, 'every element in the \'brackets\' array must be a \'{open,close,token}\' object or array');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ const CACHE_STACK_DEPTH = 5;
|
|||
class MonarchStackElementFactory {
|
||||
|
||||
private static readonly _INSTANCE = new MonarchStackElementFactory(CACHE_STACK_DEPTH);
|
||||
public static create(parent: MonarchStackElement, state: string): MonarchStackElement {
|
||||
public static create(parent: MonarchStackElement | null, state: string): MonarchStackElement {
|
||||
return this._INSTANCE.create(parent, state);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ class MonarchStackElementFactory {
|
|||
this._entries = Object.create(null);
|
||||
}
|
||||
|
||||
public create(parent: MonarchStackElement, state: string): MonarchStackElement {
|
||||
public create(parent: MonarchStackElement | null, state: string): MonarchStackElement {
|
||||
if (parent !== null && parent.depth >= this._maxCacheDepth) {
|
||||
// no caching above a certain depth
|
||||
return new MonarchStackElement(parent, state);
|
||||
|
@ -60,17 +60,17 @@ class MonarchStackElementFactory {
|
|||
|
||||
class MonarchStackElement {
|
||||
|
||||
public readonly parent: MonarchStackElement;
|
||||
public readonly parent: MonarchStackElement | null;
|
||||
public readonly state: string;
|
||||
public readonly depth: number;
|
||||
|
||||
constructor(parent: MonarchStackElement, state: string) {
|
||||
constructor(parent: MonarchStackElement | null, state: string) {
|
||||
this.parent = parent;
|
||||
this.state = state;
|
||||
this.depth = (this.parent ? this.parent.depth : 0) + 1;
|
||||
}
|
||||
|
||||
public static getStackElementId(element: MonarchStackElement): string {
|
||||
public static getStackElementId(element: MonarchStackElement | null): string {
|
||||
let result = '';
|
||||
while (element !== null) {
|
||||
if (result.length > 0) {
|
||||
|
@ -82,7 +82,7 @@ class MonarchStackElement {
|
|||
return result;
|
||||
}
|
||||
|
||||
private static _equals(a: MonarchStackElement, b: MonarchStackElement): boolean {
|
||||
private static _equals(a: MonarchStackElement | null, b: MonarchStackElement | null): boolean {
|
||||
while (a !== null && b !== null) {
|
||||
if (a === b) {
|
||||
return true;
|
||||
|
@ -107,7 +107,7 @@ class MonarchStackElement {
|
|||
return MonarchStackElementFactory.create(this, state);
|
||||
}
|
||||
|
||||
public pop(): MonarchStackElement {
|
||||
public pop(): MonarchStackElement | null {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ class EmbeddedModeData {
|
|||
class MonarchLineStateFactory {
|
||||
|
||||
private static readonly _INSTANCE = new MonarchLineStateFactory(CACHE_STACK_DEPTH);
|
||||
public static create(stack: MonarchStackElement, embeddedModeData: EmbeddedModeData): MonarchLineState {
|
||||
public static create(stack: MonarchStackElement, embeddedModeData: EmbeddedModeData | null): MonarchLineState {
|
||||
return this._INSTANCE.create(stack, embeddedModeData);
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ class MonarchLineStateFactory {
|
|||
this._entries = Object.create(null);
|
||||
}
|
||||
|
||||
public create(stack: MonarchStackElement, embeddedModeData: EmbeddedModeData): MonarchLineState {
|
||||
public create(stack: MonarchStackElement, embeddedModeData: EmbeddedModeData | null): MonarchLineState {
|
||||
if (embeddedModeData !== null) {
|
||||
// no caching when embedding
|
||||
return new MonarchLineState(stack, embeddedModeData);
|
||||
|
@ -192,11 +192,11 @@ class MonarchLineStateFactory {
|
|||
class MonarchLineState implements modes.IState {
|
||||
|
||||
public readonly stack: MonarchStackElement;
|
||||
public readonly embeddedModeData: EmbeddedModeData;
|
||||
public readonly embeddedModeData: EmbeddedModeData | null;
|
||||
|
||||
constructor(
|
||||
stack: MonarchStackElement,
|
||||
embeddedModeData: EmbeddedModeData
|
||||
embeddedModeData: EmbeddedModeData | null
|
||||
) {
|
||||
this.stack = stack;
|
||||
this.embeddedModeData = embeddedModeData;
|
||||
|
@ -239,9 +239,9 @@ interface IMonarchTokensCollector {
|
|||
class MonarchClassicTokensCollector implements IMonarchTokensCollector {
|
||||
|
||||
private _tokens: Token[];
|
||||
private _language: string;
|
||||
private _lastTokenType: string;
|
||||
private _lastTokenLanguage: string;
|
||||
private _language: string | null;
|
||||
private _lastTokenType: string | null;
|
||||
private _lastTokenLanguage: string | null;
|
||||
|
||||
constructor() {
|
||||
this._tokens = [];
|
||||
|
@ -291,7 +291,7 @@ class MonarchModernTokensCollector implements IMonarchTokensCollector {
|
|||
|
||||
private _modeService: IModeService;
|
||||
private _theme: TokenTheme;
|
||||
private _prependTokens: Uint32Array;
|
||||
private _prependTokens: Uint32Array | null;
|
||||
private _tokens: number[];
|
||||
private _currentLanguageId: modes.LanguageId;
|
||||
private _lastTokenMetadata: number;
|
||||
|
@ -319,7 +319,7 @@ class MonarchModernTokensCollector implements IMonarchTokensCollector {
|
|||
this._tokens.push(metadata);
|
||||
}
|
||||
|
||||
private static _merge(a: Uint32Array, b: number[], c: Uint32Array): Uint32Array {
|
||||
private static _merge(a: Uint32Array | null, b: number[], c: Uint32Array | null): Uint32Array {
|
||||
let aLen = (a !== null ? a.length : 0);
|
||||
let bLen = b.length;
|
||||
let cLen = (c !== null ? c.length : 0);
|
||||
|
@ -328,10 +328,10 @@ class MonarchModernTokensCollector implements IMonarchTokensCollector {
|
|||
return new Uint32Array(0);
|
||||
}
|
||||
if (aLen === 0 && bLen === 0) {
|
||||
return c;
|
||||
return c!;
|
||||
}
|
||||
if (bLen === 0 && cLen === 0) {
|
||||
return a;
|
||||
return a!;
|
||||
}
|
||||
|
||||
let result = new Uint32Array(aLen + bLen + cLen);
|
||||
|
@ -442,11 +442,11 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
}
|
||||
|
||||
private _findLeavingNestedModeOffset(line: string, state: MonarchLineState): number {
|
||||
let rules = this._lexer.tokenizer[state.stack.state];
|
||||
let rules: monarchCommon.IRule[] | null = this._lexer.tokenizer[state.stack.state];
|
||||
if (!rules) {
|
||||
rules = monarchCommon.findRules(this._lexer, state.stack.state); // do parent matching
|
||||
if (!rules) {
|
||||
monarchCommon.throwError(this._lexer, 'tokenizer state is not defined: ' + state.stack.state);
|
||||
throw monarchCommon.createError(this._lexer, 'tokenizer state is not defined: ' + state.stack.state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,7 +480,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
}
|
||||
|
||||
if (!hasEmbeddedPopRule) {
|
||||
monarchCommon.throwError(this._lexer, 'no rule containing nextEmbedded: "@pop" in tokenizer embedded state: ' + state.stack.state);
|
||||
throw monarchCommon.createError(this._lexer, 'no rule containing nextEmbedded: "@pop" in tokenizer embedded state: ' + state.stack.state);
|
||||
}
|
||||
|
||||
return popOffset;
|
||||
|
@ -492,14 +492,14 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
|
||||
if (popOffset === -1) {
|
||||
// tokenization will not leave nested mode
|
||||
let nestedEndState = tokensCollector.nestedModeTokenize(line, lineState.embeddedModeData, offsetDelta);
|
||||
return MonarchLineStateFactory.create(lineState.stack, new EmbeddedModeData(lineState.embeddedModeData.modeId, nestedEndState));
|
||||
let nestedEndState = tokensCollector.nestedModeTokenize(line, lineState.embeddedModeData!, offsetDelta);
|
||||
return MonarchLineStateFactory.create(lineState.stack, new EmbeddedModeData(lineState.embeddedModeData!.modeId, nestedEndState));
|
||||
}
|
||||
|
||||
let nestedModeLine = line.substring(0, popOffset);
|
||||
if (nestedModeLine.length > 0) {
|
||||
// tokenize with the nested mode
|
||||
tokensCollector.nestedModeTokenize(nestedModeLine, lineState.embeddedModeData, offsetDelta);
|
||||
tokensCollector.nestedModeTokenize(nestedModeLine, lineState.embeddedModeData!, offsetDelta);
|
||||
}
|
||||
|
||||
let restOfTheLine = line.substring(popOffset);
|
||||
|
@ -517,37 +517,37 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
|
||||
// regular expression group matching
|
||||
// these never need cloning or equality since they are only used within a line match
|
||||
let groupActions: monarchCommon.FuzzyAction[] = null;
|
||||
let groupMatches: string[] | null = null;
|
||||
let groupMatched: string[] | null = null;
|
||||
let groupRule: monarchCommon.IRule = null;
|
||||
interface GroupMatching {
|
||||
matches: string[];
|
||||
rule: monarchCommon.IRule;
|
||||
groups: { action: monarchCommon.FuzzyAction; matched: string; }[];
|
||||
}
|
||||
let groupMatching: GroupMatching | null = null;
|
||||
|
||||
while (pos < lineLength) {
|
||||
const pos0 = pos;
|
||||
const stackLen0 = stack.depth;
|
||||
const groupLen0 = groupActions ? groupActions.length : 0;
|
||||
const groupLen0 = groupMatching ? groupMatching.groups.length : 0;
|
||||
const state = stack.state;
|
||||
|
||||
let matches: string[] | null = null;
|
||||
let matched: string | null = null;
|
||||
let action: monarchCommon.FuzzyAction | monarchCommon.FuzzyAction[] = null;
|
||||
let rule: monarchCommon.IRule = null;
|
||||
let action: monarchCommon.FuzzyAction | monarchCommon.FuzzyAction[] | null = null;
|
||||
let rule: monarchCommon.IRule | null = null;
|
||||
|
||||
let enteringEmbeddedMode: string | null = null;
|
||||
|
||||
// check if we need to process group matches first
|
||||
if (groupActions) {
|
||||
matches = groupMatches;
|
||||
matched = groupMatched.shift();
|
||||
action = groupActions.shift();
|
||||
rule = groupRule;
|
||||
if (groupMatching) {
|
||||
matches = groupMatching.matches;
|
||||
const groupEntry = groupMatching.groups.shift()!;
|
||||
matched = groupEntry.matched;
|
||||
action = groupEntry.action;
|
||||
rule = groupMatching.rule;
|
||||
|
||||
// cleanup if necessary
|
||||
if (groupActions.length === 0) {
|
||||
groupActions = null;
|
||||
groupMatches = null;
|
||||
groupMatched = null;
|
||||
groupRule = null;
|
||||
if (groupMatching.groups.length === 0) {
|
||||
groupMatching = null;
|
||||
}
|
||||
} else {
|
||||
// otherwise we match on the token stream
|
||||
|
@ -558,11 +558,11 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
}
|
||||
|
||||
// get the rules for this state
|
||||
let rules = this._lexer.tokenizer[state];
|
||||
let rules: monarchCommon.IRule[] | null = this._lexer.tokenizer[state];
|
||||
if (!rules) {
|
||||
rules = monarchCommon.findRules(this._lexer, state); // do parent matching
|
||||
if (!rules) {
|
||||
monarchCommon.throwError(this._lexer, 'tokenizer state is not defined: ' + state);
|
||||
throw monarchCommon.createError(this._lexer, 'tokenizer state is not defined: ' + state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,7 +607,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
action = action.test(matched, matches, state, pos === lineLength);
|
||||
}
|
||||
|
||||
let result: monarchCommon.FuzzyAction | monarchCommon.FuzzyAction[] = null;
|
||||
let result: monarchCommon.FuzzyAction | monarchCommon.FuzzyAction[] | null = null;
|
||||
// set the result: either a string or an array of actions
|
||||
if (typeof action === 'string' || Array.isArray(action)) {
|
||||
result = action;
|
||||
|
@ -626,11 +626,11 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
if (action.nextEmbedded) {
|
||||
if (action.nextEmbedded === '@pop') {
|
||||
if (!embeddedModeData) {
|
||||
monarchCommon.throwError(this._lexer, 'cannot pop embedded mode if not inside one');
|
||||
throw monarchCommon.createError(this._lexer, 'cannot pop embedded mode if not inside one');
|
||||
}
|
||||
embeddedModeData = null;
|
||||
} else if (embeddedModeData) {
|
||||
monarchCommon.throwError(this._lexer, 'cannot enter embedded mode from within an embedded mode');
|
||||
throw monarchCommon.createError(this._lexer, 'cannot enter embedded mode from within an embedded mode');
|
||||
} else {
|
||||
enteringEmbeddedMode = monarchCommon.substituteMatches(this._lexer, action.nextEmbedded, matched, matches, state);
|
||||
}
|
||||
|
@ -647,23 +647,23 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
nextState = nextState.substr(1); // peel off starting '@'
|
||||
}
|
||||
if (!monarchCommon.findRules(this._lexer, nextState)) {
|
||||
monarchCommon.throwError(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: ' + rule.name);
|
||||
} else {
|
||||
stack = stack.switchTo(nextState);
|
||||
}
|
||||
} else if (action.transform && typeof action.transform === 'function') {
|
||||
monarchCommon.throwError(this._lexer, 'action.transform not supported');
|
||||
throw monarchCommon.createError(this._lexer, 'action.transform not supported');
|
||||
} else if (action.next) {
|
||||
if (action.next === '@push') {
|
||||
if (stack.depth >= this._lexer.maxStack) {
|
||||
monarchCommon.throwError(this._lexer, 'maximum tokenizer stack size reached: [' +
|
||||
throw monarchCommon.createError(this._lexer, 'maximum tokenizer stack size reached: [' +
|
||||
stack.state + ',' + stack.parent.state + ',...]');
|
||||
} else {
|
||||
stack = stack.push(state);
|
||||
}
|
||||
} else if (action.next === '@pop') {
|
||||
if (stack.depth <= 1) {
|
||||
monarchCommon.throwError(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: ' + rule.name);
|
||||
} else {
|
||||
stack = stack.pop();
|
||||
}
|
||||
|
@ -676,7 +676,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
}
|
||||
|
||||
if (!monarchCommon.findRules(this._lexer, nextState)) {
|
||||
monarchCommon.throwError(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: ' + rule.name);
|
||||
} else {
|
||||
stack = stack.push(nextState);
|
||||
}
|
||||
|
@ -690,28 +690,37 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
|
||||
// check result
|
||||
if (result === null) {
|
||||
monarchCommon.throwError(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: ' + rule.name);
|
||||
}
|
||||
|
||||
// is the result a group match?
|
||||
if (Array.isArray(result)) {
|
||||
if (groupActions && groupActions.length > 0) {
|
||||
monarchCommon.throwError(this._lexer, 'groups cannot be nested: ' + rule.name);
|
||||
if (groupMatching && groupMatching.groups.length > 0) {
|
||||
throw monarchCommon.createError(this._lexer, 'groups cannot be nested: ' + rule.name);
|
||||
}
|
||||
if (matches.length !== result.length + 1) {
|
||||
monarchCommon.throwError(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: ' + rule.name);
|
||||
}
|
||||
let totalLen = 0;
|
||||
for (let i = 1; i < matches.length; i++) {
|
||||
totalLen += matches[i].length;
|
||||
}
|
||||
if (totalLen !== matched.length) {
|
||||
monarchCommon.throwError(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: ' + rule.name);
|
||||
}
|
||||
groupMatches = matches;
|
||||
groupMatched = matches.slice(1);
|
||||
groupActions = result.slice(0);
|
||||
groupRule = rule;
|
||||
|
||||
groupMatching = {
|
||||
rule: rule,
|
||||
matches: matches,
|
||||
groups: []
|
||||
};
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
groupMatching.groups[i] = {
|
||||
action: result[i],
|
||||
matched: matches[i + 1]
|
||||
};
|
||||
}
|
||||
|
||||
pos -= matched.length;
|
||||
// call recursively to initiate first result match
|
||||
continue;
|
||||
|
@ -728,10 +737,10 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
|
||||
// check progress
|
||||
if (matched.length === 0) {
|
||||
if (stackLen0 !== stack.depth || state !== stack.state || (!groupActions ? 0 : groupActions.length) !== groupLen0) {
|
||||
if (stackLen0 !== stack.depth || state !== stack.state || (!groupMatching ? 0 : groupMatching.groups.length) !== groupLen0) {
|
||||
continue;
|
||||
} else {
|
||||
monarchCommon.throwError(this._lexer, 'no progress in tokenizer in rule: ' + rule.name);
|
||||
throw monarchCommon.createError(this._lexer, 'no progress in tokenizer in rule: ' + rule.name);
|
||||
pos = lineLength; // must make progress or editor loops
|
||||
}
|
||||
}
|
||||
|
@ -743,7 +752,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport {
|
|||
let rest = result.substr('@brackets'.length);
|
||||
let bracket = findBracket(this._lexer, matched);
|
||||
if (!bracket) {
|
||||
monarchCommon.throwError(this._lexer, '@brackets token returned but no bracket defined as: ' + matched);
|
||||
throw monarchCommon.createError(this._lexer, '@brackets token returned but no bracket defined as: ' + matched);
|
||||
bracket = { token: '', bracketType: monarchCommon.MonarchBracket.None };
|
||||
}
|
||||
tokenType = monarchCommon.sanitize(bracket.token + rest);
|
||||
|
|
8
src/vs/monaco.d.ts
vendored
8
src/vs/monaco.d.ts
vendored
|
@ -879,7 +879,7 @@ declare namespace monaco.editor {
|
|||
/**
|
||||
* Get the model that has `uri` if it exists.
|
||||
*/
|
||||
export function getModel(uri: Uri): ITextModel;
|
||||
export function getModel(uri: Uri): ITextModel | null;
|
||||
|
||||
/**
|
||||
* Get all the created models.
|
||||
|
@ -1092,13 +1092,13 @@ declare namespace monaco.editor {
|
|||
}
|
||||
|
||||
export interface IStandaloneCodeEditor extends ICodeEditor {
|
||||
addCommand(keybinding: number, handler: ICommandHandler, context: string): string;
|
||||
addCommand(keybinding: number, handler: ICommandHandler, context: string): string | null;
|
||||
createContextKey<T>(key: string, defaultValue: T): IContextKey<T>;
|
||||
addAction(descriptor: IActionDescriptor): IDisposable;
|
||||
}
|
||||
|
||||
export interface IStandaloneDiffEditor extends IDiffEditor {
|
||||
addCommand(keybinding: number, handler: ICommandHandler, context: string): string;
|
||||
addCommand(keybinding: number, handler: ICommandHandler, context: string): string | null;
|
||||
createContextKey<T>(key: string, defaultValue: T): IContextKey<T>;
|
||||
addAction(descriptor: IActionDescriptor): IDisposable;
|
||||
getOriginalEditor(): IStandaloneCodeEditor;
|
||||
|
@ -3623,7 +3623,7 @@ declare namespace monaco.editor {
|
|||
/**
|
||||
* The position preference for the overlay widget.
|
||||
*/
|
||||
preference: OverlayWidgetPositionPreference;
|
||||
preference: OverlayWidgetPositionPreference | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,11 +15,11 @@ const KEYBINDING_CONTEXT_ATTR = 'data-keybinding-context';
|
|||
|
||||
export class Context implements IContext {
|
||||
|
||||
protected _parent: Context;
|
||||
protected _parent: Context | null;
|
||||
protected _value: { [key: string]: any; };
|
||||
protected _id: number;
|
||||
|
||||
constructor(id: number, parent: Context) {
|
||||
constructor(id: number, parent: Context | null) {
|
||||
this._id = id;
|
||||
this._parent = parent;
|
||||
this._value = Object.create(null);
|
||||
|
@ -311,7 +311,7 @@ export class ContextKeyService extends AbstractContextKeyService implements ICon
|
|||
class ScopedContextKeyService extends AbstractContextKeyService {
|
||||
|
||||
private _parent: AbstractContextKeyService;
|
||||
private _domNode: IContextKeyServiceTarget;
|
||||
private _domNode: IContextKeyServiceTarget | undefined;
|
||||
|
||||
constructor(parent: AbstractContextKeyService, emitter: Emitter<string | string[]>, domNode?: IContextKeyServiceTarget) {
|
||||
super(parent.createChildContext());
|
||||
|
@ -349,10 +349,14 @@ class ScopedContextKeyService extends AbstractContextKeyService {
|
|||
}
|
||||
}
|
||||
|
||||
function findContextAttr(domNode: IContextKeyServiceTarget): number {
|
||||
function findContextAttr(domNode: IContextKeyServiceTarget | null): number {
|
||||
while (domNode) {
|
||||
if (domNode.hasAttribute(KEYBINDING_CONTEXT_ATTR)) {
|
||||
return parseInt(domNode.getAttribute(KEYBINDING_CONTEXT_ATTR), 10);
|
||||
const attr = domNode.getAttribute(KEYBINDING_CONTEXT_ATTR);
|
||||
if (attr) {
|
||||
return parseInt(attr, 10);
|
||||
}
|
||||
return NaN;
|
||||
}
|
||||
domNode = domNode.parentElement;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ export abstract class ContextKeyExpr {
|
|||
return new ContextKeyAndExpr(expr);
|
||||
}
|
||||
|
||||
public static deserialize(serialized: string): ContextKeyExpr | null {
|
||||
public static deserialize(serialized: string | null | undefined): ContextKeyExpr | null {
|
||||
if (!serialized) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ export interface IParsedVersion {
|
|||
minorMustEqual: boolean;
|
||||
patchBase: number;
|
||||
patchMustEqual: boolean;
|
||||
preRelease: string;
|
||||
preRelease: string | null;
|
||||
}
|
||||
|
||||
export interface INormalizedVersion {
|
||||
|
@ -35,7 +35,7 @@ export function isValidVersionStr(version: string): boolean {
|
|||
return (version === '*' || VERSION_REGEXP.test(version));
|
||||
}
|
||||
|
||||
export function parseVersion(version: string): IParsedVersion {
|
||||
export function parseVersion(version: string): IParsedVersion | null {
|
||||
if (!isValidVersionStr(version)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -57,6 +57,9 @@ export function parseVersion(version: string): IParsedVersion {
|
|||
}
|
||||
|
||||
let m = version.match(VERSION_REGEXP);
|
||||
if (!m) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
hasCaret: m[1] === '^',
|
||||
hasGreaterEquals: m[1] === '>=',
|
||||
|
@ -70,7 +73,7 @@ export function parseVersion(version: string): IParsedVersion {
|
|||
};
|
||||
}
|
||||
|
||||
export function normalizeVersion(version: IParsedVersion): INormalizedVersion {
|
||||
export function normalizeVersion(version: IParsedVersion | null): INormalizedVersion | null {
|
||||
if (!version) {
|
||||
return null;
|
||||
}
|
||||
|
@ -103,14 +106,14 @@ export function normalizeVersion(version: IParsedVersion): INormalizedVersion {
|
|||
}
|
||||
|
||||
export function isValidVersion(_version: string | INormalizedVersion, _desiredVersion: string | INormalizedVersion): boolean {
|
||||
let version: INormalizedVersion;
|
||||
let version: INormalizedVersion | null;
|
||||
if (typeof _version === 'string') {
|
||||
version = normalizeVersion(parseVersion(_version));
|
||||
} else {
|
||||
version = _version;
|
||||
}
|
||||
|
||||
let desiredVersion: INormalizedVersion;
|
||||
let desiredVersion: INormalizedVersion | null;
|
||||
if (typeof _desiredVersion === 'string') {
|
||||
desiredVersion = normalizeVersion(parseVersion(_desiredVersion));
|
||||
} else {
|
||||
|
|
|
@ -16,21 +16,21 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
|||
|
||||
interface IStorageData {
|
||||
dontShowPrompt: boolean;
|
||||
commit: string;
|
||||
commit: string | undefined;
|
||||
}
|
||||
|
||||
class IntegrityStorage {
|
||||
private static readonly KEY = 'integrityService';
|
||||
|
||||
private storageService: IStorageService;
|
||||
private value: IStorageData;
|
||||
private value: IStorageData | null;
|
||||
|
||||
constructor(storageService: IStorageService) {
|
||||
this.storageService = storageService;
|
||||
this.value = this._read();
|
||||
}
|
||||
|
||||
private _read(): IStorageData {
|
||||
private _read(): IStorageData | null {
|
||||
let jsonValue = this.storageService.get(IntegrityStorage.KEY, StorageScope.GLOBAL);
|
||||
if (!jsonValue) {
|
||||
return null;
|
||||
|
@ -42,11 +42,11 @@ class IntegrityStorage {
|
|||
}
|
||||
}
|
||||
|
||||
get(): IStorageData {
|
||||
get(): IStorageData | null {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
set(data: IStorageData): void {
|
||||
set(data: IStorageData | null): void {
|
||||
this.value = data;
|
||||
this.storageService.store(IntegrityStorage.KEY, JSON.stringify(this.value), StorageScope.GLOBAL);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
import { ResolvedKeybinding, Keybinding, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
|
@ -19,19 +20,19 @@ import { IntervalTimer } from 'vs/base/common/async';
|
|||
|
||||
interface CurrentChord {
|
||||
keypress: string;
|
||||
label: string;
|
||||
label: string | null;
|
||||
}
|
||||
|
||||
export abstract class AbstractKeybindingService extends Disposable implements IKeybindingService {
|
||||
public _serviceBrand: any;
|
||||
|
||||
private _currentChord: CurrentChord;
|
||||
private _currentChord: CurrentChord | null;
|
||||
private _currentChordChecker: IntervalTimer;
|
||||
private _currentChordStatusMessage: IDisposable;
|
||||
private _currentChordStatusMessage: IDisposable | null;
|
||||
protected _onDidUpdateKeybindings: Emitter<IKeybindingEvent>;
|
||||
|
||||
private _contextKeyService: IContextKeyService;
|
||||
private _statusService: IStatusbarService;
|
||||
private _statusService: IStatusbarService | undefined;
|
||||
private _notificationService: INotificationService;
|
||||
protected _commandService: ICommandService;
|
||||
protected _telemetryService: ITelemetryService;
|
||||
|
@ -87,10 +88,12 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
|
|||
}
|
||||
|
||||
public lookupKeybindings(commandId: string): ResolvedKeybinding[] {
|
||||
return this._getResolver().lookupKeybindings(commandId).map(item => item.resolvedKeybinding);
|
||||
return arrays.coalesce(
|
||||
this._getResolver().lookupKeybindings(commandId).map(item => item.resolvedKeybinding)
|
||||
);
|
||||
}
|
||||
|
||||
public lookupKeybinding(commandId: string): ResolvedKeybinding {
|
||||
public lookupKeybinding(commandId: string): ResolvedKeybinding | null {
|
||||
let result = this._getResolver().lookupPrimaryKeybinding(commandId);
|
||||
if (!result) {
|
||||
return null;
|
||||
|
@ -98,7 +101,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
|
|||
return result.resolvedKeybinding;
|
||||
}
|
||||
|
||||
public softDispatch(e: IKeyboardEvent, target: IContextKeyServiceTarget): IResolveResult {
|
||||
public softDispatch(e: IKeyboardEvent, target: IContextKeyServiceTarget): IResolveResult | null {
|
||||
const keybinding = this.resolveKeyboardEvent(e);
|
||||
if (keybinding.isChord()) {
|
||||
console.warn('Unexpected keyboard event mapped to a chord');
|
||||
|
@ -115,7 +118,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
|
|||
return this._getResolver().resolve(contextValue, currentChord, firstPart);
|
||||
}
|
||||
|
||||
private _enterChordMode(firstPart: string, keypressLabel: string): void {
|
||||
private _enterChordMode(firstPart: string, keypressLabel: string | null): void {
|
||||
this._currentChord = {
|
||||
keypress: firstPart,
|
||||
label: keypressLabel
|
||||
|
@ -155,7 +158,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
|
|||
const keybinding = this.resolveKeyboardEvent(e);
|
||||
if (keybinding.isChord()) {
|
||||
console.warn('Unexpected keyboard event mapped to a chord');
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
const [firstPart,] = keybinding.getDispatchParts();
|
||||
if (firstPart === null) {
|
||||
|
|
|
@ -55,7 +55,7 @@ export interface IKeybindingService {
|
|||
/**
|
||||
* Resolve and dispatch `keyboardEvent`, but do not invoke the command or change inner state.
|
||||
*/
|
||||
softDispatch(keyboardEvent: IKeyboardEvent, target: IContextKeyServiceTarget): IResolveResult;
|
||||
softDispatch(keyboardEvent: IKeyboardEvent, target: IContextKeyServiceTarget): IResolveResult | null;
|
||||
|
||||
/**
|
||||
* Look up keybindings for a command.
|
||||
|
@ -67,7 +67,7 @@ export interface IKeybindingService {
|
|||
* Look up the preferred (last defined) keybinding for a command.
|
||||
* @returns The preferred keybinding or null if the command is not bound.
|
||||
*/
|
||||
lookupKeybinding(commandId: string): ResolvedKeybinding;
|
||||
lookupKeybinding(commandId: string): ResolvedKeybinding | null;
|
||||
|
||||
getDefaultKeybindingsContent(): string;
|
||||
|
||||
|
|
|
@ -29,8 +29,10 @@ export class KeybindingResolver {
|
|||
this._defaultBoundCommands = new Map<string, boolean>();
|
||||
for (let i = 0, len = defaultKeybindings.length; i < len; i++) {
|
||||
const command = defaultKeybindings[i].command;
|
||||
if (command) {
|
||||
this._defaultBoundCommands.set(command, true);
|
||||
}
|
||||
}
|
||||
|
||||
this._map = new Map<string, ResolvedKeybindingItem[]>();
|
||||
this._lookupMap = new Map<string, ResolvedKeybindingItem[]>();
|
||||
|
@ -47,7 +49,7 @@ export class KeybindingResolver {
|
|||
}
|
||||
}
|
||||
|
||||
private static _isTargetedForRemoval(defaultKb: ResolvedKeybindingItem, keypressFirstPart: string | null, keypressChordPart: string | null, command: string, when: ContextKeyExpr): boolean {
|
||||
private static _isTargetedForRemoval(defaultKb: ResolvedKeybindingItem, keypressFirstPart: string | null, keypressChordPart: string | null, command: string, when: ContextKeyExpr | null): boolean {
|
||||
if (defaultKb.command !== command) {
|
||||
return false;
|
||||
}
|
||||
|
@ -147,6 +149,9 @@ export class KeybindingResolver {
|
|||
}
|
||||
|
||||
private _removeFromLookupMap(item: ResolvedKeybindingItem): void {
|
||||
if (!item.command) {
|
||||
return;
|
||||
}
|
||||
let arr = this._lookupMap.get(item.command);
|
||||
if (typeof arr === 'undefined') {
|
||||
return;
|
||||
|
@ -163,7 +168,7 @@ export class KeybindingResolver {
|
|||
* Returns true if it is provable `a` implies `b`.
|
||||
* **Precondition**: Assumes `a` and `b` are normalized!
|
||||
*/
|
||||
public static whenIsEntirelyIncluded(a: ContextKeyExpr, b: ContextKeyExpr): boolean {
|
||||
public static whenIsEntirelyIncluded(a: ContextKeyExpr | null, b: ContextKeyExpr | null): boolean {
|
||||
if (!b) {
|
||||
return true;
|
||||
}
|
||||
|
@ -229,7 +234,7 @@ export class KeybindingResolver {
|
|||
return items[items.length - 1];
|
||||
}
|
||||
|
||||
public resolve(context: IContext, currentChord: string, keypress: string): IResolveResult | null {
|
||||
public resolve(context: IContext, currentChord: string | null, keypress: string): IResolveResult | null {
|
||||
let lookupMap: ResolvedKeybindingItem[] | null = null;
|
||||
|
||||
if (currentChord !== null) {
|
||||
|
@ -294,7 +299,7 @@ export class KeybindingResolver {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static contextMatchesRules(context: IContext, rules: ContextKeyExpr): boolean {
|
||||
public static contextMatchesRules(context: IContext, rules: ContextKeyExpr | null): boolean {
|
||||
if (!rules) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -42,13 +42,13 @@ export interface IKeybindingRule extends IKeybindings {
|
|||
}
|
||||
|
||||
export interface IKeybindingRule2 {
|
||||
primary: Keybinding;
|
||||
win?: { primary: Keybinding; };
|
||||
linux?: { primary: Keybinding; };
|
||||
mac?: { primary: Keybinding; };
|
||||
primary: Keybinding | null;
|
||||
win?: { primary: Keybinding | null; } | null;
|
||||
linux?: { primary: Keybinding | null; } | null;
|
||||
mac?: { primary: Keybinding | null; } | null;
|
||||
id: string;
|
||||
weight: number;
|
||||
when: ContextKeyExpr;
|
||||
when: ContextKeyExpr | null;
|
||||
}
|
||||
|
||||
export const enum KeybindingRuleSource {
|
||||
|
@ -110,7 +110,7 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
|
|||
/**
|
||||
* Take current platform into account and reduce to primary & secondary.
|
||||
*/
|
||||
private static bindToCurrentPlatform2(kb: IKeybindingRule2): { primary?: Keybinding; } {
|
||||
private static bindToCurrentPlatform2(kb: IKeybindingRule2): { primary?: Keybinding | null; } {
|
||||
if (OS === OperatingSystem.Windows) {
|
||||
if (kb && kb.win) {
|
||||
return kb.win;
|
||||
|
|
|
@ -10,16 +10,16 @@ import { CharCode } from 'vs/base/common/charCode';
|
|||
export class ResolvedKeybindingItem {
|
||||
_resolvedKeybindingItemBrand: void;
|
||||
|
||||
public readonly resolvedKeybinding: ResolvedKeybinding;
|
||||
public readonly resolvedKeybinding: ResolvedKeybinding | null;
|
||||
public readonly keypressFirstPart: string | null;
|
||||
public readonly keypressChordPart: string | null;
|
||||
public readonly bubble: boolean;
|
||||
public readonly command: string;
|
||||
public readonly command: string | null;
|
||||
public readonly commandArgs: any;
|
||||
public readonly when: ContextKeyExpr;
|
||||
public readonly when: ContextKeyExpr | null;
|
||||
public readonly isDefault: boolean;
|
||||
|
||||
constructor(resolvedKeybinding: ResolvedKeybinding, command: string, commandArgs: any, when: ContextKeyExpr, isDefault: boolean) {
|
||||
constructor(resolvedKeybinding: ResolvedKeybinding | null, command: string | null, commandArgs: any, when: ContextKeyExpr | null, isDefault: boolean) {
|
||||
this.resolvedKeybinding = resolvedKeybinding;
|
||||
if (resolvedKeybinding) {
|
||||
let [keypressFirstPart, keypressChordPart] = resolvedKeybinding.getDispatchParts();
|
||||
|
@ -30,7 +30,7 @@ export class ResolvedKeybindingItem {
|
|||
this.keypressChordPart = null;
|
||||
}
|
||||
this.bubble = (command ? command.charCodeAt(0) === CharCode.Caret : false);
|
||||
this.command = this.bubble ? command.substr(1) : command;
|
||||
this.command = this.bubble ? command!.substr(1) : command;
|
||||
this.commandArgs = commandArgs;
|
||||
this.when = when;
|
||||
this.isDefault = isDefault;
|
||||
|
|
|
@ -14,12 +14,12 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
|
||||
private readonly _os: OperatingSystem;
|
||||
private readonly _firstPart: SimpleKeybinding;
|
||||
private readonly _chordPart: SimpleKeybinding;
|
||||
private readonly _chordPart: SimpleKeybinding | null;
|
||||
|
||||
constructor(actual: Keybinding, OS: OperatingSystem) {
|
||||
super();
|
||||
this._os = OS;
|
||||
if (actual === null) {
|
||||
if (!actual) {
|
||||
throw new Error(`Invalid USLayoutResolvedKeybinding`);
|
||||
} else if (actual.type === KeybindingType.Chord) {
|
||||
this._firstPart = actual.firstPart;
|
||||
|
@ -46,7 +46,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
return KeyCodeUtils.toString(keyCode);
|
||||
}
|
||||
|
||||
private _getUILabelForKeybinding(keybinding: SimpleKeybinding): string {
|
||||
private _getUILabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -56,13 +56,13 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
return this._keyCodeToUILabel(keybinding.keyCode);
|
||||
}
|
||||
|
||||
public getLabel(): string {
|
||||
public getLabel(): string | null {
|
||||
let firstPart = this._getUILabelForKeybinding(this._firstPart);
|
||||
let chordPart = this._getUILabelForKeybinding(this._chordPart);
|
||||
return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os);
|
||||
}
|
||||
|
||||
private _getAriaLabelForKeybinding(keybinding: SimpleKeybinding): string {
|
||||
private _getAriaLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -72,13 +72,13 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
return KeyCodeUtils.toString(keybinding.keyCode);
|
||||
}
|
||||
|
||||
public getAriaLabel(): string {
|
||||
public getAriaLabel(): string | null {
|
||||
let firstPart = this._getAriaLabelForKeybinding(this._firstPart);
|
||||
let chordPart = this._getAriaLabelForKeybinding(this._chordPart);
|
||||
return AriaLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os);
|
||||
}
|
||||
|
||||
private _keyCodeToElectronAccelerator(keyCode: KeyCode): string {
|
||||
private _keyCodeToElectronAccelerator(keyCode: KeyCode): string | null {
|
||||
if (keyCode >= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) {
|
||||
// Electron cannot handle numpad keys
|
||||
return null;
|
||||
|
@ -98,7 +98,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
return KeyCodeUtils.toString(keyCode);
|
||||
}
|
||||
|
||||
private _getElectronAcceleratorLabelForKeybinding(keybinding: SimpleKeybinding): string {
|
||||
private _getElectronAcceleratorLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
return this._keyCodeToElectronAccelerator(keybinding.keyCode);
|
||||
}
|
||||
|
||||
public getElectronAccelerator(): string {
|
||||
public getElectronAccelerator(): string | null {
|
||||
if (this._chordPart !== null) {
|
||||
// Electron cannot handle chords
|
||||
return null;
|
||||
|
@ -118,7 +118,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
return ElectronAcceleratorLabelProvider.toLabel(this._firstPart, firstPart, null, null, this._os);
|
||||
}
|
||||
|
||||
private _getUserSettingsLabelForKeybinding(keybinding: SimpleKeybinding): string {
|
||||
private _getUserSettingsLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
return KeyCodeUtils.toUserSettingsUS(keybinding.keyCode);
|
||||
}
|
||||
|
||||
public getUserSettingsLabel(): string {
|
||||
public getUserSettingsLabel(): string | null {
|
||||
let firstPart = this._getUserSettingsLabelForKeybinding(this._firstPart);
|
||||
let chordPart = this._getUserSettingsLabelForKeybinding(this._chordPart);
|
||||
let result = UserSettingsLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os);
|
||||
|
@ -143,18 +143,14 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
return (this._chordPart ? true : false);
|
||||
}
|
||||
|
||||
public getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart] {
|
||||
public getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart | null] {
|
||||
return [
|
||||
this._toResolvedKeybindingPart(this._firstPart),
|
||||
this._toResolvedKeybindingPart(this._chordPart)
|
||||
this._chordPart ? this._toResolvedKeybindingPart(this._chordPart) : null
|
||||
];
|
||||
}
|
||||
|
||||
private _toResolvedKeybindingPart(keybinding: SimpleKeybinding): ResolvedKeybindingPart {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ResolvedKeybindingPart(
|
||||
keybinding.ctrlKey,
|
||||
keybinding.shiftKey,
|
||||
|
@ -165,13 +161,13 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
|
|||
);
|
||||
}
|
||||
|
||||
public getDispatchParts(): [string, string] {
|
||||
public getDispatchParts(): [string | null, string | null] {
|
||||
let firstPart = this._firstPart ? USLayoutResolvedKeybinding.getDispatchStr(this._firstPart) : null;
|
||||
let chordPart = this._chordPart ? USLayoutResolvedKeybinding.getDispatchStr(this._chordPart) : null;
|
||||
return [firstPart, chordPart];
|
||||
}
|
||||
|
||||
public static getDispatchStr(keybinding: SimpleKeybinding): string {
|
||||
public static getDispatchStr(keybinding: SimpleKeybinding): string | null {
|
||||
if (keybinding.isModifierKey()) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC
|
|||
) {
|
||||
super();
|
||||
|
||||
this._isDisabled = this._storageService.getBoolean('editor.neverPromptForLargeFiles', StorageScope.GLOBAL, false);
|
||||
this._isDisabled = Boolean(this._storageService.getBoolean('editor.neverPromptForLargeFiles', StorageScope.GLOBAL, false));
|
||||
|
||||
this._register(this._editor.onDidChangeModel((e) => {
|
||||
const model = this._editor.getModel();
|
||||
|
|
|
@ -36,18 +36,18 @@ export class SelectionClipboard extends Disposable implements IEditorContributio
|
|||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
if (!editor.getModel()) {
|
||||
if (!editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
if (e.event.middleButton) {
|
||||
e.event.preventDefault();
|
||||
editor.focus();
|
||||
|
||||
if (e.target.position) {
|
||||
if (e.target && e.target.position) {
|
||||
editor.setPosition(e.target.position);
|
||||
}
|
||||
|
||||
if (e.target.type === MouseTargetType.SCROLLBAR) {
|
||||
if (e.target && e.target.type === MouseTargetType.SCROLLBAR) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -63,11 +63,10 @@ export class SelectionClipboard extends Disposable implements IEditorContributio
|
|||
}));
|
||||
|
||||
let setSelectionToClipboard = this._register(new RunOnceScheduler(() => {
|
||||
let model = editor.getModel();
|
||||
if (!model) {
|
||||
if (!editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let model = editor.getModel();
|
||||
let selections = editor.getSelections();
|
||||
selections = selections.slice(0);
|
||||
selections.sort(Range.compareRangesUsingStarts);
|
||||
|
|
|
@ -33,15 +33,15 @@ interface IWordWrapTransientState {
|
|||
}
|
||||
|
||||
interface IWordWrapState {
|
||||
readonly configuredWordWrap: 'on' | 'off' | 'wordWrapColumn' | 'bounded';
|
||||
readonly configuredWordWrap: 'on' | 'off' | 'wordWrapColumn' | 'bounded' | undefined;
|
||||
readonly configuredWordWrapMinified: boolean;
|
||||
readonly transientState: IWordWrapTransientState;
|
||||
readonly transientState: IWordWrapTransientState | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store (in memory) the word wrap state for a particular model.
|
||||
*/
|
||||
function writeTransientState(model: ITextModel, state: IWordWrapTransientState, codeEditorService: ICodeEditorService): void {
|
||||
function writeTransientState(model: ITextModel, state: IWordWrapTransientState | null, codeEditorService: ICodeEditorService): void {
|
||||
codeEditorService.setTransientModelProperty(model, transientWordWrapState, state);
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,9 @@ class ToggleWordWrapAction extends EditorAction {
|
|||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
if (!editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
const editorConfiguration = editor.getConfiguration();
|
||||
if (editorConfiguration.wrappingInfo.inDiffEditor) {
|
||||
// Cannot change wrapping settings inside the diff editor
|
||||
|
|
|
@ -71,8 +71,8 @@ export interface IExtensionPoint<T> {
|
|||
export class ExtensionPoint<T> implements IExtensionPoint<T> {
|
||||
|
||||
public readonly name: string;
|
||||
private _handler: IExtensionPointHandler<T>;
|
||||
private _users: IExtensionPointUser<T>[];
|
||||
private _handler: IExtensionPointHandler<T> | null;
|
||||
private _users: IExtensionPointUser<T>[] | null;
|
||||
private _done: boolean;
|
||||
|
||||
constructor(name: string) {
|
||||
|
|
|
@ -12,16 +12,19 @@ import { ScanCodeBinding } from 'vs/base/common/scanCode';
|
|||
import { KeybindingParser } from 'vs/base/common/keybindingParser';
|
||||
|
||||
export interface IUserKeybindingItem {
|
||||
firstPart: SimpleKeybinding | ScanCodeBinding;
|
||||
chordPart: SimpleKeybinding | ScanCodeBinding;
|
||||
command: string;
|
||||
firstPart: SimpleKeybinding | ScanCodeBinding | null;
|
||||
chordPart: SimpleKeybinding | ScanCodeBinding | null;
|
||||
command: string | null;
|
||||
commandArgs?: any;
|
||||
when: ContextKeyExpr;
|
||||
when: ContextKeyExpr | null;
|
||||
}
|
||||
|
||||
export class KeybindingIO {
|
||||
|
||||
public static writeKeybindingItem(out: OutputBuilder, item: ResolvedKeybindingItem, OS: OperatingSystem): void {
|
||||
if (!item.resolvedKeybinding) {
|
||||
return;
|
||||
}
|
||||
let quotedSerializedKeybinding = JSON.stringify(item.resolvedKeybinding.getUserSettingsLabel());
|
||||
out.write(`{ "key": ${rightPaddedString(quotedSerializedKeybinding + ',', 25)} "command": `);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ export interface IKeyboardMapper {
|
|||
dumpDebugInfo(): string;
|
||||
resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding[];
|
||||
resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding;
|
||||
resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding, chordPart: SimpleKeybinding | ScanCodeBinding): ResolvedKeybinding[];
|
||||
resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding | null, chordPart: SimpleKeybinding | ScanCodeBinding | null): ResolvedKeybinding[];
|
||||
}
|
||||
|
||||
export class CachedKeyboardMapper implements IKeyboardMapper {
|
||||
|
|
|
@ -103,7 +103,7 @@ export class MacLinuxFallbackKeyboardMapper implements IKeyboardMapper {
|
|||
return KeyCode.Unknown;
|
||||
}
|
||||
|
||||
private _resolveSimpleUserBinding(binding: SimpleKeybinding | ScanCodeBinding): SimpleKeybinding {
|
||||
private _resolveSimpleUserBinding(binding: SimpleKeybinding | ScanCodeBinding | null): SimpleKeybinding | null {
|
||||
if (!binding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ export class MacLinuxFallbackKeyboardMapper implements IKeyboardMapper {
|
|||
return new SimpleKeybinding(binding.ctrlKey, binding.shiftKey, binding.altKey, binding.metaKey, keyCode);
|
||||
}
|
||||
|
||||
public resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding, chordPart: SimpleKeybinding | ScanCodeBinding): ResolvedKeybinding[] {
|
||||
public resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding | null, chordPart: SimpleKeybinding | ScanCodeBinding | null): ResolvedKeybinding[] {
|
||||
const _firstPart = this._resolveSimpleUserBinding(firstPart);
|
||||
const _chordPart = this._resolveSimpleUserBinding(chordPart);
|
||||
if (_firstPart && _chordPart) {
|
||||
|
|
|
@ -37,7 +37,7 @@ export interface IMacLinuxKeyboardMapping {
|
|||
[scanCode: string]: IMacLinuxKeyMapping;
|
||||
}
|
||||
|
||||
export function macLinuxKeyboardMappingEquals(a: IMacLinuxKeyboardMapping, b: IMacLinuxKeyboardMapping): boolean {
|
||||
export function macLinuxKeyboardMappingEquals(a: IMacLinuxKeyboardMapping | null, b: IMacLinuxKeyboardMapping | null): boolean {
|
||||
if (!a && !b) {
|
||||
return true;
|
||||
}
|
||||
|
@ -61,16 +61,16 @@ export function macLinuxKeyboardMappingEquals(a: IMacLinuxKeyboardMapping, b: IM
|
|||
* - '/' => { keyCode: KeyCode.US_SLASH, shiftKey: false }
|
||||
* - '?' => { keyCode: KeyCode.US_SLASH, shiftKey: true }
|
||||
*/
|
||||
const CHAR_CODE_TO_KEY_CODE: { keyCode: KeyCode; shiftKey: boolean }[] = [];
|
||||
const CHAR_CODE_TO_KEY_CODE: ({ keyCode: KeyCode; shiftKey: boolean } | null)[] = [];
|
||||
|
||||
export class NativeResolvedKeybinding extends ResolvedKeybinding {
|
||||
|
||||
private readonly _mapper: MacLinuxKeyboardMapper;
|
||||
private readonly _OS: OperatingSystem;
|
||||
private readonly _firstPart: ScanCodeBinding;
|
||||
private readonly _chordPart: ScanCodeBinding;
|
||||
private readonly _chordPart: ScanCodeBinding | null;
|
||||
|
||||
constructor(mapper: MacLinuxKeyboardMapper, OS: OperatingSystem, firstPart: ScanCodeBinding, chordPart: ScanCodeBinding) {
|
||||
constructor(mapper: MacLinuxKeyboardMapper, OS: OperatingSystem, firstPart: ScanCodeBinding, chordPart: ScanCodeBinding | null) {
|
||||
super();
|
||||
if (!firstPart) {
|
||||
throw new Error(`Invalid USLayoutResolvedKeybinding`);
|
||||
|
@ -81,19 +81,19 @@ export class NativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
this._chordPart = chordPart;
|
||||
}
|
||||
|
||||
public getLabel(): string {
|
||||
public getLabel(): string | null {
|
||||
let firstPart = this._mapper.getUILabelForScanCodeBinding(this._firstPart);
|
||||
let chordPart = this._mapper.getUILabelForScanCodeBinding(this._chordPart);
|
||||
return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._OS);
|
||||
}
|
||||
|
||||
public getAriaLabel(): string {
|
||||
public getAriaLabel(): string | null {
|
||||
let firstPart = this._mapper.getAriaLabelForScanCodeBinding(this._firstPart);
|
||||
let chordPart = this._mapper.getAriaLabelForScanCodeBinding(this._chordPart);
|
||||
return AriaLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._OS);
|
||||
}
|
||||
|
||||
public getElectronAccelerator(): string {
|
||||
public getElectronAccelerator(): string | null {
|
||||
if (this._chordPart !== null) {
|
||||
// Electron cannot handle chords
|
||||
return null;
|
||||
|
@ -103,13 +103,13 @@ export class NativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return ElectronAcceleratorLabelProvider.toLabel(this._firstPart, firstPart, null, null, this._OS);
|
||||
}
|
||||
|
||||
public getUserSettingsLabel(): string {
|
||||
public getUserSettingsLabel(): string | null {
|
||||
let firstPart = this._mapper.getUserSettingsLabelForScanCodeBinding(this._firstPart);
|
||||
let chordPart = this._mapper.getUserSettingsLabelForScanCodeBinding(this._chordPart);
|
||||
return UserSettingsLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._OS);
|
||||
}
|
||||
|
||||
private _isWYSIWYG(binding: ScanCodeBinding): boolean {
|
||||
private _isWYSIWYG(binding: ScanCodeBinding | null): boolean {
|
||||
if (!binding) {
|
||||
return true;
|
||||
}
|
||||
|
@ -136,18 +136,14 @@ export class NativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return (this._chordPart ? true : false);
|
||||
}
|
||||
|
||||
public getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart] {
|
||||
public getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart | null] {
|
||||
return [
|
||||
this._toResolvedKeybindingPart(this._firstPart),
|
||||
this._toResolvedKeybindingPart(this._chordPart)
|
||||
this._chordPart ? this._toResolvedKeybindingPart(this._chordPart) : null
|
||||
];
|
||||
}
|
||||
|
||||
private _toResolvedKeybindingPart(binding: ScanCodeBinding): ResolvedKeybindingPart {
|
||||
if (!binding) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ResolvedKeybindingPart(
|
||||
binding.ctrlKey,
|
||||
binding.shiftKey,
|
||||
|
@ -158,7 +154,7 @@ export class NativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
);
|
||||
}
|
||||
|
||||
public getDispatchParts(): [string, string] {
|
||||
public getDispatchParts(): [string | null, string | null] {
|
||||
let firstPart = this._firstPart ? this._mapper.getDispatchStrForScanCodeBinding(this._firstPart) : null;
|
||||
let chordPart = this._chordPart ? this._mapper.getDispatchStrForScanCodeBinding(this._chordPart) : null;
|
||||
return [firstPart, chordPart];
|
||||
|
@ -449,11 +445,11 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
/**
|
||||
* UI label for a ScanCode.
|
||||
*/
|
||||
private readonly _scanCodeToLabel: string[] = [];
|
||||
private readonly _scanCodeToLabel: (string | null)[] = [];
|
||||
/**
|
||||
* Dispatching string for a ScanCode.
|
||||
*/
|
||||
private readonly _scanCodeToDispatch: string[] = [];
|
||||
private readonly _scanCodeToDispatch: (string | null)[] = [];
|
||||
|
||||
constructor(isUSStandard: boolean, rawMappings: IMacLinuxKeyboardMapping, OS: OperatingSystem) {
|
||||
this._isUSStandard = isUSStandard;
|
||||
|
@ -838,7 +834,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return result.join('\n');
|
||||
}
|
||||
|
||||
private _leftPad(str: string, cnt: number): string {
|
||||
private _leftPad(str: string | null, cnt: number): string {
|
||||
if (str === null) {
|
||||
str = 'null';
|
||||
}
|
||||
|
@ -866,7 +862,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return result;
|
||||
}
|
||||
|
||||
public getUILabelForScanCodeBinding(binding: ScanCodeBinding): string {
|
||||
public getUILabelForScanCodeBinding(binding: ScanCodeBinding | null): string | null {
|
||||
if (!binding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -888,7 +884,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return this._scanCodeToLabel[binding.scanCode];
|
||||
}
|
||||
|
||||
public getAriaLabelForScanCodeBinding(binding: ScanCodeBinding): string {
|
||||
public getAriaLabelForScanCodeBinding(binding: ScanCodeBinding | null): string | null {
|
||||
if (!binding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -898,7 +894,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return this._scanCodeToLabel[binding.scanCode];
|
||||
}
|
||||
|
||||
public getDispatchStrForScanCodeBinding(keypress: ScanCodeBinding): string {
|
||||
public getDispatchStrForScanCodeBinding(keypress: ScanCodeBinding): string | null {
|
||||
const codeDispatch = this._scanCodeToDispatch[keypress.scanCode];
|
||||
if (!codeDispatch) {
|
||||
return null;
|
||||
|
@ -922,7 +918,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return result;
|
||||
}
|
||||
|
||||
public getUserSettingsLabelForScanCodeBinding(binding: ScanCodeBinding): string {
|
||||
public getUserSettingsLabelForScanCodeBinding(binding: ScanCodeBinding | null): string | null {
|
||||
if (!binding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -951,7 +947,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return this._scanCodeToDispatch[binding.scanCode];
|
||||
}
|
||||
|
||||
private _getElectronLabelForKeyCode(keyCode: KeyCode): string {
|
||||
private _getElectronLabelForKeyCode(keyCode: KeyCode): string | null {
|
||||
if (keyCode >= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) {
|
||||
// Electron cannot handle numpad keys
|
||||
return null;
|
||||
|
@ -972,7 +968,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return KeyCodeUtils.toString(keyCode);
|
||||
}
|
||||
|
||||
public getElectronAcceleratorLabelForScanCodeBinding(binding: ScanCodeBinding): string {
|
||||
public getElectronAcceleratorLabelForScanCodeBinding(binding: ScanCodeBinding | null): string | null {
|
||||
if (!binding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1101,7 +1097,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return new NativeResolvedKeybinding(this, this._OS, keypress, null);
|
||||
}
|
||||
|
||||
private _resolveSimpleUserBinding(binding: SimpleKeybinding | ScanCodeBinding): ScanCodeBinding[] {
|
||||
private _resolveSimpleUserBinding(binding: SimpleKeybinding | ScanCodeBinding | null): ScanCodeBinding[] {
|
||||
if (!binding) {
|
||||
return [];
|
||||
}
|
||||
|
@ -1111,7 +1107,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return this.simpleKeybindingToScanCodeBinding(binding);
|
||||
}
|
||||
|
||||
public resolveUserBinding(_firstPart: SimpleKeybinding | ScanCodeBinding, _chordPart: SimpleKeybinding | ScanCodeBinding): ResolvedKeybinding[] {
|
||||
public resolveUserBinding(_firstPart: SimpleKeybinding | ScanCodeBinding | null, _chordPart: SimpleKeybinding | ScanCodeBinding | null): ResolvedKeybinding[] {
|
||||
const firstParts = this._resolveSimpleUserBinding(_firstPart);
|
||||
const chordParts = this._resolveSimpleUserBinding(_chordPart);
|
||||
|
||||
|
@ -1131,7 +1127,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
|
|||
return result;
|
||||
}
|
||||
|
||||
private static _charCodeToKb(charCode: number): { keyCode: KeyCode; shiftKey: boolean } {
|
||||
private static _charCodeToKb(charCode: number): { keyCode: KeyCode; shiftKey: boolean } | null {
|
||||
if (charCode < CHAR_CODE_TO_KEY_CODE.length) {
|
||||
return CHAR_CODE_TO_KEY_CODE[charCode];
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ export interface IWindowsKeyboardMapping {
|
|||
[scanCode: string]: IWindowsKeyMapping;
|
||||
}
|
||||
|
||||
export function windowsKeyboardMappingEquals(a: IWindowsKeyboardMapping, b: IWindowsKeyboardMapping): boolean {
|
||||
export function windowsKeyboardMappingEquals(a: IWindowsKeyboardMapping | null, b: IWindowsKeyboardMapping | null): boolean {
|
||||
if (!a && !b) {
|
||||
return true;
|
||||
}
|
||||
|
@ -80,9 +80,9 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
|
||||
private readonly _mapper: WindowsKeyboardMapper;
|
||||
private readonly _firstPart: SimpleKeybinding;
|
||||
private readonly _chordPart: SimpleKeybinding;
|
||||
private readonly _chordPart: SimpleKeybinding | null;
|
||||
|
||||
constructor(mapper: WindowsKeyboardMapper, firstPart: SimpleKeybinding, chordPart: SimpleKeybinding) {
|
||||
constructor(mapper: WindowsKeyboardMapper, firstPart: SimpleKeybinding, chordPart: SimpleKeybinding | null) {
|
||||
super();
|
||||
if (!firstPart) {
|
||||
throw new Error(`Invalid WindowsNativeResolvedKeybinding firstPart`);
|
||||
|
@ -92,7 +92,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
this._chordPart = chordPart;
|
||||
}
|
||||
|
||||
private _getUILabelForKeybinding(keybinding: SimpleKeybinding): string {
|
||||
private _getUILabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -102,13 +102,13 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return this._mapper.getUILabelForKeyCode(keybinding.keyCode);
|
||||
}
|
||||
|
||||
public getLabel(): string {
|
||||
public getLabel(): string | null {
|
||||
let firstPart = this._getUILabelForKeybinding(this._firstPart);
|
||||
let chordPart = this._getUILabelForKeybinding(this._chordPart);
|
||||
return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, OperatingSystem.Windows);
|
||||
}
|
||||
|
||||
private _getUSLabelForKeybinding(keybinding: SimpleKeybinding): string {
|
||||
private _getUSLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -118,13 +118,13 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return KeyCodeUtils.toString(keybinding.keyCode);
|
||||
}
|
||||
|
||||
public getUSLabel(): string {
|
||||
public getUSLabel(): string | null {
|
||||
let firstPart = this._getUSLabelForKeybinding(this._firstPart);
|
||||
let chordPart = this._getUSLabelForKeybinding(this._chordPart);
|
||||
return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, OperatingSystem.Windows);
|
||||
}
|
||||
|
||||
private _getAriaLabelForKeybinding(keybinding: SimpleKeybinding): string {
|
||||
private _getAriaLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -134,13 +134,13 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return this._mapper.getAriaLabelForKeyCode(keybinding.keyCode);
|
||||
}
|
||||
|
||||
public getAriaLabel(): string {
|
||||
public getAriaLabel(): string | null {
|
||||
let firstPart = this._getAriaLabelForKeybinding(this._firstPart);
|
||||
let chordPart = this._getAriaLabelForKeybinding(this._chordPart);
|
||||
return AriaLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, OperatingSystem.Windows);
|
||||
}
|
||||
|
||||
private _keyCodeToElectronAccelerator(keyCode: KeyCode): string {
|
||||
private _keyCodeToElectronAccelerator(keyCode: KeyCode): string | null {
|
||||
if (keyCode >= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) {
|
||||
// Electron cannot handle numpad keys
|
||||
return null;
|
||||
|
@ -161,7 +161,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return KeyCodeUtils.toString(keyCode);
|
||||
}
|
||||
|
||||
private _getElectronAcceleratorLabelForKeybinding(keybinding: SimpleKeybinding): string {
|
||||
private _getElectronAcceleratorLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return this._keyCodeToElectronAccelerator(keybinding.keyCode);
|
||||
}
|
||||
|
||||
public getElectronAccelerator(): string {
|
||||
public getElectronAccelerator(): string | null {
|
||||
if (this._chordPart !== null) {
|
||||
// Electron cannot handle chords
|
||||
return null;
|
||||
|
@ -181,7 +181,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return ElectronAcceleratorLabelProvider.toLabel(this._firstPart, firstPart, null, null, OperatingSystem.Windows);
|
||||
}
|
||||
|
||||
private _getUserSettingsLabelForKeybinding(keybinding: SimpleKeybinding): string {
|
||||
private _getUserSettingsLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return this._mapper.getUserSettingsLabelForKeyCode(keybinding.keyCode);
|
||||
}
|
||||
|
||||
public getUserSettingsLabel(): string {
|
||||
public getUserSettingsLabel(): string | null {
|
||||
let firstPart = this._getUserSettingsLabelForKeybinding(this._firstPart);
|
||||
let chordPart = this._getUserSettingsLabelForKeybinding(this._chordPart);
|
||||
let result = UserSettingsLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, OperatingSystem.Windows);
|
||||
|
@ -226,18 +226,14 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return (this._chordPart ? true : false);
|
||||
}
|
||||
|
||||
public getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart] {
|
||||
public getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart | null] {
|
||||
return [
|
||||
this._toResolvedKeybindingPart(this._firstPart),
|
||||
this._toResolvedKeybindingPart(this._chordPart)
|
||||
this._chordPart ? this._toResolvedKeybindingPart(this._chordPart) : null
|
||||
];
|
||||
}
|
||||
|
||||
private _toResolvedKeybindingPart(keybinding: SimpleKeybinding): ResolvedKeybindingPart {
|
||||
if (!keybinding) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ResolvedKeybindingPart(
|
||||
keybinding.ctrlKey,
|
||||
keybinding.shiftKey,
|
||||
|
@ -248,13 +244,13 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
);
|
||||
}
|
||||
|
||||
public getDispatchParts(): [string, string] {
|
||||
public getDispatchParts(): [string | null, string | null] {
|
||||
let firstPart = this._firstPart ? this._getDispatchStr(this._firstPart) : null;
|
||||
let chordPart = this._chordPart ? this._getDispatchStr(this._chordPart) : null;
|
||||
return [firstPart, chordPart];
|
||||
}
|
||||
|
||||
private _getDispatchStr(keybinding: SimpleKeybinding): string {
|
||||
private _getDispatchStr(keybinding: SimpleKeybinding): string | null {
|
||||
if (keybinding.isModifierKey()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -277,7 +273,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
|
|||
return result;
|
||||
}
|
||||
|
||||
private static getProducedCharCode(kb: ScanCodeBinding, mapping: IScanCodeMapping): string {
|
||||
private static getProducedCharCode(kb: ScanCodeBinding, mapping: IScanCodeMapping): string | null {
|
||||
if (!mapping) {
|
||||
return null;
|
||||
}
|
||||
|
@ -307,7 +303,7 @@ export class WindowsKeyboardMapper implements IKeyboardMapper {
|
|||
public readonly isUSStandard: boolean;
|
||||
private readonly _codeInfo: IScanCodeMapping[];
|
||||
private readonly _scanCodeToKeyCode: KeyCode[];
|
||||
private readonly _keyCodeToLabel: string[] = [];
|
||||
private readonly _keyCodeToLabel: (string | null)[] = [];
|
||||
private readonly _keyCodeExists: boolean[];
|
||||
|
||||
constructor(isUSStandard: boolean, rawMappings: IWindowsKeyboardMapping) {
|
||||
|
@ -492,7 +488,7 @@ export class WindowsKeyboardMapper implements IKeyboardMapper {
|
|||
return result.join('\n');
|
||||
}
|
||||
|
||||
private _leftPad(str: string, cnt: number): string {
|
||||
private _leftPad(str: string | null, cnt: number): string {
|
||||
if (str === null) {
|
||||
str = 'null';
|
||||
}
|
||||
|
@ -542,7 +538,7 @@ export class WindowsKeyboardMapper implements IKeyboardMapper {
|
|||
return new WindowsNativeResolvedKeybinding(this, keybinding, null);
|
||||
}
|
||||
|
||||
private _resolveSimpleUserBinding(binding: SimpleKeybinding | ScanCodeBinding): SimpleKeybinding {
|
||||
private _resolveSimpleUserBinding(binding: SimpleKeybinding | ScanCodeBinding | null): SimpleKeybinding | null {
|
||||
if (!binding) {
|
||||
return null;
|
||||
}
|
||||
|
@ -559,7 +555,7 @@ export class WindowsKeyboardMapper implements IKeyboardMapper {
|
|||
return new SimpleKeybinding(binding.ctrlKey, binding.shiftKey, binding.altKey, binding.metaKey, keyCode);
|
||||
}
|
||||
|
||||
public resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding, chordPart: SimpleKeybinding | ScanCodeBinding): ResolvedKeybinding[] {
|
||||
public resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding | null, chordPart: SimpleKeybinding | ScanCodeBinding | null): ResolvedKeybinding[] {
|
||||
const _firstPart = this._resolveSimpleUserBinding(firstPart);
|
||||
const _chordPart = this._resolveSimpleUserBinding(chordPart);
|
||||
if (_firstPart && _chordPart) {
|
||||
|
|
|
@ -41,9 +41,9 @@ import { KeybindingParser } from 'vs/base/common/keybindingParser';
|
|||
export class KeyboardMapperFactory {
|
||||
public static readonly INSTANCE = new KeyboardMapperFactory();
|
||||
|
||||
private _layoutInfo: nativeKeymap.IKeyboardLayoutInfo;
|
||||
private _rawMapping: nativeKeymap.IKeyboardMapping;
|
||||
private _keyboardMapper: IKeyboardMapper;
|
||||
private _layoutInfo: nativeKeymap.IKeyboardLayoutInfo | null;
|
||||
private _rawMapping: nativeKeymap.IKeyboardMapping | null;
|
||||
private _keyboardMapper: IKeyboardMapper | null;
|
||||
private _initialized: boolean;
|
||||
|
||||
private readonly _onDidChangeKeyboardMapper: Emitter<void> = new Emitter<void>();
|
||||
|
@ -70,10 +70,10 @@ export class KeyboardMapperFactory {
|
|||
// Forcefully set to use keyCode
|
||||
return new MacLinuxFallbackKeyboardMapper(OS);
|
||||
}
|
||||
return this._keyboardMapper;
|
||||
return this._keyboardMapper!;
|
||||
}
|
||||
|
||||
public getCurrentKeyboardLayout(): nativeKeymap.IKeyboardLayoutInfo {
|
||||
public getCurrentKeyboardLayout(): nativeKeymap.IKeyboardLayoutInfo | null {
|
||||
if (!this._initialized) {
|
||||
this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap());
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ export class KeyboardMapperFactory {
|
|||
return false;
|
||||
}
|
||||
|
||||
public getRawKeyboardMapping(): nativeKeymap.IKeyboardMapping {
|
||||
public getRawKeyboardMapping(): nativeKeymap.IKeyboardMapping | null {
|
||||
if (!this._initialized) {
|
||||
this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap());
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ export class KeyboardMapperFactory {
|
|||
return new MacLinuxKeyboardMapper(isUSStandard, <IMacLinuxKeyboardMapping>rawMapping, OS);
|
||||
}
|
||||
|
||||
private static _equals(a: nativeKeymap.IKeyboardMapping, b: nativeKeymap.IKeyboardMapping): boolean {
|
||||
private static _equals(a: nativeKeymap.IKeyboardMapping | null, b: nativeKeymap.IKeyboardMapping | null): boolean {
|
||||
if (OS === OperatingSystem.Windows) {
|
||||
return windowsKeyboardMappingEquals(<IWindowsKeyboardMapping>a, <IWindowsKeyboardMapping>b);
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ function getDispatchConfig(configurationService: IConfigurationService): Dispatc
|
|||
export class WorkbenchKeybindingService extends AbstractKeybindingService {
|
||||
|
||||
private _keyboardMapper: IKeyboardMapper;
|
||||
private _cachedResolver: KeybindingResolver;
|
||||
private _cachedResolver: KeybindingResolver | null;
|
||||
private _firstTimeComputingResolver: boolean;
|
||||
private userKeybindings: ConfigWatcher<IUserFriendlyKeybinding[]>;
|
||||
|
||||
|
@ -479,7 +479,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
|
|||
return commandAdded;
|
||||
}
|
||||
|
||||
private _asCommandRule(isBuiltin: boolean, idx: number, binding: ContributedKeyBinding): IKeybindingRule2 {
|
||||
private _asCommandRule(isBuiltin: boolean, idx: number, binding: ContributedKeyBinding): IKeybindingRule2 | undefined {
|
||||
|
||||
let { command, when, key, mac, linux, win } = binding;
|
||||
|
||||
|
@ -490,14 +490,14 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
|
|||
weight = KeybindingWeight.ExternalExtension + idx;
|
||||
}
|
||||
|
||||
let desc = {
|
||||
let desc: IKeybindingRule2 = {
|
||||
id: command,
|
||||
when: ContextKeyExpr.deserialize(when),
|
||||
weight: weight,
|
||||
primary: KeybindingParser.parseKeybinding(key, OS),
|
||||
mac: mac && { primary: KeybindingParser.parseKeybinding(mac, OS) },
|
||||
linux: linux && { primary: KeybindingParser.parseKeybinding(linux, OS) },
|
||||
win: win && { primary: KeybindingParser.parseKeybinding(win, OS) }
|
||||
mac: mac ? { primary: KeybindingParser.parseKeybinding(mac, OS) } : null,
|
||||
linux: linux ? { primary: KeybindingParser.parseKeybinding(linux, OS) } : null,
|
||||
win: win ? { primary: KeybindingParser.parseKeybinding(win, OS) } : null
|
||||
};
|
||||
|
||||
if (!desc.primary && !desc.mac && !desc.linux && !desc.win) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as path from 'path';
|
||||
import { IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper';
|
||||
import { Keybinding, ResolvedKeybinding, SimpleKeybinding } from 'vs/base/common/keyCodes';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
@ -62,13 +63,14 @@ export function readRawMapping<T>(file: string): TPromise<T> {
|
|||
}
|
||||
|
||||
export function assertMapping(writeFileIfDifferent: boolean, mapper: IKeyboardMapper, file: string): TPromise<void> {
|
||||
const filePath = getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/${file}`);
|
||||
const filePath = path.normalize(getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/${file}`));
|
||||
|
||||
return readFile(filePath).then((buff) => {
|
||||
let expected = buff.toString();
|
||||
const actual = mapper.dumpDebugInfo();
|
||||
if (actual !== expected && writeFileIfDifferent) {
|
||||
writeFile(filePath, actual);
|
||||
const destPath = filePath.replace(/vscode\/out\/vs/, 'vscode/src/vs');
|
||||
writeFile(destPath, actual);
|
||||
}
|
||||
|
||||
assert.deepEqual(actual.split(/\r\n|\n/), expected.split(/\r\n|\n/));
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { IColorTheme, ITokenColorizationSetting } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
|
||||
export function findMatchingThemeRule(theme: IColorTheme, scopes: string[], onlyColorRules: boolean = true): ThemeRule {
|
||||
export function findMatchingThemeRule(theme: IColorTheme, scopes: string[], onlyColorRules: boolean = true): ThemeRule | null {
|
||||
for (let i = scopes.length - 1; i >= 0; i--) {
|
||||
let parentScopes = scopes.slice(0, i);
|
||||
let scope = scopes[i];
|
||||
|
@ -17,7 +17,7 @@ export function findMatchingThemeRule(theme: IColorTheme, scopes: string[], only
|
|||
return null;
|
||||
}
|
||||
|
||||
function findMatchingThemeRule2(theme: IColorTheme, scope: string, parentScopes: string[], onlyColorRules: boolean): ThemeRule {
|
||||
function findMatchingThemeRule2(theme: IColorTheme, scope: string, parentScopes: string[], onlyColorRules: boolean): ThemeRule | null {
|
||||
let result: ThemeRule | null = null;
|
||||
|
||||
// Loop backwards, to ensure the last most specific rule wins
|
||||
|
@ -69,7 +69,7 @@ export class ThemeRule {
|
|||
return ThemeRule._matches(this.scope, this.parentScopes, scope, parentScopes);
|
||||
}
|
||||
|
||||
private static _cmp(a: ThemeRule, b: ThemeRule): number {
|
||||
private static _cmp(a: ThemeRule | null, b: ThemeRule | null): number {
|
||||
if (a === null && b === null) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ export class ThemeRule {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public isMoreSpecific(other: ThemeRule): boolean {
|
||||
public isMoreSpecific(other: ThemeRule | null): boolean {
|
||||
return (ThemeRule._cmp(this, other) > 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue