提交 da546f5d 编写于 作者: M Matt Bierner

Add null checks in filters and context keys

上级 0c403f82
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
"./vs/base/common/errors.ts", "./vs/base/common/errors.ts",
"./vs/base/common/errorsWithActions.ts", "./vs/base/common/errorsWithActions.ts",
"./vs/base/common/event.ts", "./vs/base/common/event.ts",
"./vs/base/common/filters.ts",
"./vs/base/common/functional.ts", "./vs/base/common/functional.ts",
"./vs/base/common/glob.ts", "./vs/base/common/glob.ts",
"./vs/base/common/hash.ts", "./vs/base/common/hash.ts",
...@@ -105,6 +106,7 @@ ...@@ -105,6 +106,7 @@
"./vs/editor/common/model.ts", "./vs/editor/common/model.ts",
"./vs/editor/common/model/editStack.ts", "./vs/editor/common/model/editStack.ts",
"./vs/editor/common/model/intervalTree.ts", "./vs/editor/common/model/intervalTree.ts",
"./vs/editor/common/editorContextKeys.ts",
"./vs/editor/common/model/mirrorTextModel.ts", "./vs/editor/common/model/mirrorTextModel.ts",
"./vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts", "./vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts",
"./vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts", "./vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts",
...@@ -170,6 +172,7 @@ ...@@ -170,6 +172,7 @@
"./vs/platform/quickOpen/common/quickOpen.ts", "./vs/platform/quickOpen/common/quickOpen.ts",
"./vs/platform/quickinput/common/quickInput.ts", "./vs/platform/quickinput/common/quickInput.ts",
"./vs/platform/registry/common/platform.ts", "./vs/platform/registry/common/platform.ts",
"./vs/platform/search/common/search.ts",
"./vs/platform/state/common/state.ts", "./vs/platform/state/common/state.ts",
"./vs/platform/statusbar/common/statusbar.ts", "./vs/platform/statusbar/common/statusbar.ts",
"./vs/platform/telemetry/common/telemetry.ts", "./vs/platform/telemetry/common/telemetry.ts",
...@@ -211,8 +214,7 @@ ...@@ -211,8 +214,7 @@
"./vs/workbench/services/panel/common/panelService.ts", "./vs/workbench/services/panel/common/panelService.ts",
"./vs/workbench/services/search/node/search.ts", "./vs/workbench/services/search/node/search.ts",
"./vs/workbench/services/title/common/titleService.ts", "./vs/workbench/services/title/common/titleService.ts",
"./vs/workbench/test/electron-browser/api/mock.ts", "./vs/workbench/test/electron-browser/api/mock.ts"
"vs/platform/search/common/search.ts"
], ],
"exclude": [ "exclude": [
"./typings/require-monaco.d.ts" "./typings/require-monaco.d.ts"
......
...@@ -9,7 +9,7 @@ import * as strings from 'vs/base/common/strings'; ...@@ -9,7 +9,7 @@ import * as strings from 'vs/base/common/strings';
export interface IFilter { export interface IFilter {
// Returns null if word doesn't match. // Returns null if word doesn't match.
(word: string, wordToMatchAgainst: string): IMatch[]; (word: string, wordToMatchAgainst: string): IMatch[] | null;
} }
export interface IMatch { export interface IMatch {
...@@ -26,7 +26,7 @@ export interface IMatch { ...@@ -26,7 +26,7 @@ export interface IMatch {
* filter. * filter.
*/ */
export function or(...filter: IFilter[]): IFilter { export function or(...filter: IFilter[]): IFilter {
return function (word: string, wordToMatchAgainst: string): IMatch[] { return function (word: string, wordToMatchAgainst: string): IMatch[] | null {
for (let i = 0, len = filter.length; i < len; i++) { for (let i = 0, len = filter.length; i < len; i++) {
let match = filter[i](word, wordToMatchAgainst); let match = filter[i](word, wordToMatchAgainst);
if (match) { if (match) {
...@@ -42,7 +42,7 @@ export function or(...filter: IFilter[]): IFilter { ...@@ -42,7 +42,7 @@ export function or(...filter: IFilter[]): IFilter {
export const matchesStrictPrefix: IFilter = _matchesPrefix.bind(undefined, false); export const matchesStrictPrefix: IFilter = _matchesPrefix.bind(undefined, false);
export const matchesPrefix: IFilter = _matchesPrefix.bind(undefined, true); export const matchesPrefix: IFilter = _matchesPrefix.bind(undefined, true);
function _matchesPrefix(ignoreCase: boolean, word: string, wordToMatchAgainst: string): IMatch[] { function _matchesPrefix(ignoreCase: boolean, word: string, wordToMatchAgainst: string): IMatch[] | null {
if (!wordToMatchAgainst || wordToMatchAgainst.length < word.length) { if (!wordToMatchAgainst || wordToMatchAgainst.length < word.length) {
return null; return null;
} }
...@@ -63,7 +63,7 @@ function _matchesPrefix(ignoreCase: boolean, word: string, wordToMatchAgainst: s ...@@ -63,7 +63,7 @@ function _matchesPrefix(ignoreCase: boolean, word: string, wordToMatchAgainst: s
// Contiguous Substring // Contiguous Substring
export function matchesContiguousSubString(word: string, wordToMatchAgainst: string): IMatch[] { export function matchesContiguousSubString(word: string, wordToMatchAgainst: string): IMatch[] | null {
let index = wordToMatchAgainst.toLowerCase().indexOf(word.toLowerCase()); let index = wordToMatchAgainst.toLowerCase().indexOf(word.toLowerCase());
if (index === -1) { if (index === -1) {
return null; return null;
...@@ -74,18 +74,18 @@ export function matchesContiguousSubString(word: string, wordToMatchAgainst: str ...@@ -74,18 +74,18 @@ export function matchesContiguousSubString(word: string, wordToMatchAgainst: str
// Substring // Substring
export function matchesSubString(word: string, wordToMatchAgainst: string): IMatch[] { export function matchesSubString(word: string, wordToMatchAgainst: string): IMatch[] | null {
return _matchesSubString(word.toLowerCase(), wordToMatchAgainst.toLowerCase(), 0, 0); return _matchesSubString(word.toLowerCase(), wordToMatchAgainst.toLowerCase(), 0, 0);
} }
function _matchesSubString(word: string, wordToMatchAgainst: string, i: number, j: number): IMatch[] { function _matchesSubString(word: string, wordToMatchAgainst: string, i: number, j: number): IMatch[] | null {
if (i === word.length) { if (i === word.length) {
return []; return [];
} else if (j === wordToMatchAgainst.length) { } else if (j === wordToMatchAgainst.length) {
return null; return null;
} else { } else {
if (word[i] === wordToMatchAgainst[j]) { if (word[i] === wordToMatchAgainst[j]) {
let result: IMatch[] = null; let result: IMatch[] | null = null;
if (result = _matchesSubString(word, wordToMatchAgainst, i + 1, j + 1)) { if (result = _matchesSubString(word, wordToMatchAgainst, i + 1, j + 1)) {
return join({ start: j, end: j + 1 }, result); return join({ start: j, end: j + 1 }, result);
} }
...@@ -144,7 +144,7 @@ function nextAnchor(camelCaseWord: string, start: number): number { ...@@ -144,7 +144,7 @@ function nextAnchor(camelCaseWord: string, start: number): number {
return camelCaseWord.length; return camelCaseWord.length;
} }
function _matchesCamelCase(word: string, camelCaseWord: string, i: number, j: number): IMatch[] { function _matchesCamelCase(word: string, camelCaseWord: string, i: number, j: number): IMatch[] | null {
if (i === word.length) { if (i === word.length) {
return []; return [];
} else if (j === camelCaseWord.length) { } else if (j === camelCaseWord.length) {
...@@ -152,7 +152,7 @@ function _matchesCamelCase(word: string, camelCaseWord: string, i: number, j: nu ...@@ -152,7 +152,7 @@ function _matchesCamelCase(word: string, camelCaseWord: string, i: number, j: nu
} else if (word[i] !== camelCaseWord[j].toLowerCase()) { } else if (word[i] !== camelCaseWord[j].toLowerCase()) {
return null; return null;
} else { } else {
let result: IMatch[] = null; let result: IMatch[] | null = null;
let nextUpperIndex = j + 1; let nextUpperIndex = j + 1;
result = _matchesCamelCase(word, camelCaseWord, i + 1, j + 1); result = _matchesCamelCase(word, camelCaseWord, i + 1, j + 1);
while (!result && (nextUpperIndex = nextAnchor(camelCaseWord, nextUpperIndex)) < camelCaseWord.length) { while (!result && (nextUpperIndex = nextAnchor(camelCaseWord, nextUpperIndex)) < camelCaseWord.length) {
...@@ -222,7 +222,7 @@ function isCamelCasePattern(word: string): boolean { ...@@ -222,7 +222,7 @@ function isCamelCasePattern(word: string): boolean {
} }
} }
export function matchesCamelCase(word: string, camelCaseWord: string): IMatch[] { export function matchesCamelCase(word: string, camelCaseWord: string): IMatch[] | null {
if (!camelCaseWord) { if (!camelCaseWord) {
return null; return null;
} }
...@@ -251,7 +251,7 @@ export function matchesCamelCase(word: string, camelCaseWord: string): IMatch[] ...@@ -251,7 +251,7 @@ export function matchesCamelCase(word: string, camelCaseWord: string): IMatch[]
camelCaseWord = camelCaseWord.toLowerCase(); camelCaseWord = camelCaseWord.toLowerCase();
} }
let result: IMatch[] = null; let result: IMatch[] | null = null;
let i = 0; let i = 0;
word = word.toLowerCase(); word = word.toLowerCase();
...@@ -267,12 +267,12 @@ export function matchesCamelCase(word: string, camelCaseWord: string): IMatch[] ...@@ -267,12 +267,12 @@ export function matchesCamelCase(word: string, camelCaseWord: string): IMatch[]
// Otherwise also matches sub string of the word with beginnings of the words in the target. E.g. "gp" or "g p" will match "Git: Pull" // Otherwise also matches sub string of the word with beginnings of the words in the target. E.g. "gp" or "g p" will match "Git: Pull"
// Useful in cases where the target is words (e.g. command labels) // Useful in cases where the target is words (e.g. command labels)
export function matchesWords(word: string, target: string, contiguous: boolean = false): IMatch[] { export function matchesWords(word: string, target: string, contiguous: boolean = false): IMatch[] | null {
if (!target || target.length === 0) { if (!target || target.length === 0) {
return null; return null;
} }
let result: IMatch[] = null; let result: IMatch[] | null = null;
let i = 0; let i = 0;
word = word.toLowerCase(); word = word.toLowerCase();
...@@ -284,7 +284,7 @@ export function matchesWords(word: string, target: string, contiguous: boolean = ...@@ -284,7 +284,7 @@ export function matchesWords(word: string, target: string, contiguous: boolean =
return result; return result;
} }
function _matchesWords(word: string, target: string, i: number, j: number, contiguous: boolean): IMatch[] { function _matchesWords(word: string, target: string, i: number, j: number, contiguous: boolean): IMatch[] | null {
if (i === word.length) { if (i === word.length) {
return []; return [];
} else if (j === target.length) { } else if (j === target.length) {
...@@ -292,7 +292,7 @@ function _matchesWords(word: string, target: string, i: number, j: number, conti ...@@ -292,7 +292,7 @@ function _matchesWords(word: string, target: string, i: number, j: number, conti
} else if (word[i] !== target[j]) { } else if (word[i] !== target[j]) {
return null; return null;
} else { } else {
let result: IMatch[] = null; let result: IMatch[] | null = null;
let nextWordIndex = j + 1; let nextWordIndex = j + 1;
result = _matchesWords(word, target, i + 1, j + 1, contiguous); result = _matchesWords(word, target, i + 1, j + 1, contiguous);
if (!contiguous) { if (!contiguous) {
...@@ -321,7 +321,7 @@ export const fuzzyContiguousFilter = or(matchesPrefix, matchesCamelCase, matches ...@@ -321,7 +321,7 @@ export const fuzzyContiguousFilter = or(matchesPrefix, matchesCamelCase, matches
const fuzzySeparateFilter = or(matchesPrefix, matchesCamelCase, matchesSubString); const fuzzySeparateFilter = or(matchesPrefix, matchesCamelCase, matchesSubString);
const fuzzyRegExpCache = new LRUCache<string, RegExp>(10000); // bounded to 10000 elements const fuzzyRegExpCache = new LRUCache<string, RegExp>(10000); // bounded to 10000 elements
export function matchesFuzzy(word: string, wordToMatchAgainst: string, enableSeparateSubstringMatching = false): IMatch[] { export function matchesFuzzy(word: string, wordToMatchAgainst: string, enableSeparateSubstringMatching = false): IMatch[] | null {
if (typeof word !== 'string' || typeof wordToMatchAgainst !== 'string') { if (typeof word !== 'string' || typeof wordToMatchAgainst !== 'string') {
return null; // return early for invalid input return null; // return early for invalid input
} }
...@@ -334,7 +334,7 @@ export function matchesFuzzy(word: string, wordToMatchAgainst: string, enableSep ...@@ -334,7 +334,7 @@ export function matchesFuzzy(word: string, wordToMatchAgainst: string, enableSep
} }
// RegExp Filter // RegExp Filter
let match: RegExpExecArray = regexp.exec(wordToMatchAgainst); let match = regexp.exec(wordToMatchAgainst);
if (match) { if (match) {
return [{ start: match.index, end: match.index + match[0].length }]; return [{ start: match.index, end: match.index + match[0].length }];
} }
...@@ -372,7 +372,7 @@ export function createMatches(offsetOrScore: number[] | FuzzyScore): IMatch[] { ...@@ -372,7 +372,7 @@ export function createMatches(offsetOrScore: number[] | FuzzyScore): IMatch[] {
} else { } else {
offsets = offsetOrScore as number[]; offsets = offsetOrScore as number[];
} }
let last: IMatch; let last: IMatch | undefined;
for (const pos of offsets) { for (const pos of offsets) {
if (last && last.end === pos) { if (last && last.end === pos) {
last.end += 1; last.end += 1;
...@@ -466,7 +466,7 @@ export interface FuzzyScorer { ...@@ -466,7 +466,7 @@ export interface FuzzyScorer {
(pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, firstMatchCanBeWeak: boolean): FuzzyScore; (pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, firstMatchCanBeWeak: boolean): FuzzyScore;
} }
export function fuzzyScore(pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, firstMatchCanBeWeak: boolean): FuzzyScore { export function fuzzyScore(pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, firstMatchCanBeWeak: boolean): FuzzyScore | undefined {
const patternLen = pattern.length > 100 ? 100 : pattern.length; const patternLen = pattern.length > 100 ? 100 : pattern.length;
const wordLen = word.length > 100 ? 100 : word.length; const wordLen = word.length > 100 ? 100 : word.length;
...@@ -711,16 +711,16 @@ class LazyArray { ...@@ -711,16 +711,16 @@ class LazyArray {
//#region --- graceful --- //#region --- graceful ---
export function fuzzyScoreGracefulAggressive(pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, firstMatchCanBeWeak: boolean): FuzzyScore { export function fuzzyScoreGracefulAggressive(pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, firstMatchCanBeWeak: boolean): FuzzyScore | undefined {
return fuzzyScoreWithPermutations(pattern, lowPattern, patternPos, word, lowWord, wordPos, true, firstMatchCanBeWeak); return fuzzyScoreWithPermutations(pattern, lowPattern, patternPos, word, lowWord, wordPos, true, firstMatchCanBeWeak);
} }
export function fuzzyScoreGraceful(pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, firstMatchCanBeWeak: boolean): FuzzyScore { export function fuzzyScoreGraceful(pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, firstMatchCanBeWeak: boolean): FuzzyScore | undefined {
return fuzzyScoreWithPermutations(pattern, lowPattern, patternPos, word, lowWord, wordPos, false, firstMatchCanBeWeak); return fuzzyScoreWithPermutations(pattern, lowPattern, patternPos, word, lowWord, wordPos, false, firstMatchCanBeWeak);
} }
function fuzzyScoreWithPermutations(pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, aggressive: boolean, firstMatchCanBeWeak: boolean): FuzzyScore { function fuzzyScoreWithPermutations(pattern: string, lowPattern: string, patternPos: number, word: string, lowWord: string, wordPos: number, aggressive: boolean, firstMatchCanBeWeak: boolean): FuzzyScore | undefined {
let top: [number, number[]] = fuzzyScore(pattern, lowPattern, patternPos, word, lowWord, wordPos, firstMatchCanBeWeak); let top = fuzzyScore(pattern, lowPattern, patternPos, word, lowWord, wordPos, firstMatchCanBeWeak);
if (top && !aggressive) { if (top && !aggressive) {
// when using the original pattern yield a result we` // when using the original pattern yield a result we`
...@@ -752,7 +752,7 @@ function fuzzyScoreWithPermutations(pattern: string, lowPattern: string, pattern ...@@ -752,7 +752,7 @@ function fuzzyScoreWithPermutations(pattern: string, lowPattern: string, pattern
return top; return top;
} }
function nextTypoPermutation(pattern: string, patternPos: number): string { function nextTypoPermutation(pattern: string, patternPos: number): string | undefined {
if (patternPos + 1 >= pattern.length) { if (patternPos + 1 >= pattern.length) {
return undefined; return undefined;
......
...@@ -28,24 +28,24 @@ export namespace EditorContextKeys { ...@@ -28,24 +28,24 @@ export namespace EditorContextKeys {
export const hasSingleSelection: ContextKeyExpr = hasMultipleSelections.toNegated(); export const hasSingleSelection: ContextKeyExpr = hasMultipleSelections.toNegated();
export const tabMovesFocus = new RawContextKey<boolean>('editorTabMovesFocus', false); export const tabMovesFocus = new RawContextKey<boolean>('editorTabMovesFocus', false);
export const tabDoesNotMoveFocus: ContextKeyExpr = tabMovesFocus.toNegated(); export const tabDoesNotMoveFocus: ContextKeyExpr = tabMovesFocus.toNegated();
export const isInEmbeddedEditor = new RawContextKey<boolean>('isInEmbeddedEditor', undefined); export const isInEmbeddedEditor = new RawContextKey<boolean>('isInEmbeddedEditor', false);
export const canUndo = new RawContextKey<boolean>('canUndo', false); export const canUndo = new RawContextKey<boolean>('canUndo', false);
export const canRedo = new RawContextKey<boolean>('canRedo', false); export const canRedo = new RawContextKey<boolean>('canRedo', false);
// -- mode context keys // -- mode context keys
export const languageId = new RawContextKey<string>('editorLangId', undefined); export const languageId = new RawContextKey<string>('editorLangId', '');
export const hasCompletionItemProvider = new RawContextKey<boolean>('editorHasCompletionItemProvider', undefined); export const hasCompletionItemProvider = new RawContextKey<boolean>('editorHasCompletionItemProvider', false);
export const hasCodeActionsProvider = new RawContextKey<boolean>('editorHasCodeActionsProvider', undefined); export const hasCodeActionsProvider = new RawContextKey<boolean>('editorHasCodeActionsProvider', false);
export const hasCodeLensProvider = new RawContextKey<boolean>('editorHasCodeLensProvider', undefined); export const hasCodeLensProvider = new RawContextKey<boolean>('editorHasCodeLensProvider', false);
export const hasDefinitionProvider = new RawContextKey<boolean>('editorHasDefinitionProvider', undefined); export const hasDefinitionProvider = new RawContextKey<boolean>('editorHasDefinitionProvider', false);
export const hasImplementationProvider = new RawContextKey<boolean>('editorHasImplementationProvider', undefined); export const hasImplementationProvider = new RawContextKey<boolean>('editorHasImplementationProvider', false);
export const hasTypeDefinitionProvider = new RawContextKey<boolean>('editorHasTypeDefinitionProvider', undefined); export const hasTypeDefinitionProvider = new RawContextKey<boolean>('editorHasTypeDefinitionProvider', false);
export const hasHoverProvider = new RawContextKey<boolean>('editorHasHoverProvider', undefined); export const hasHoverProvider = new RawContextKey<boolean>('editorHasHoverProvider', false);
export const hasDocumentHighlightProvider = new RawContextKey<boolean>('editorHasDocumentHighlightProvider', undefined); export const hasDocumentHighlightProvider = new RawContextKey<boolean>('editorHasDocumentHighlightProvider', false);
export const hasDocumentSymbolProvider = new RawContextKey<boolean>('editorHasDocumentSymbolProvider', undefined); export const hasDocumentSymbolProvider = new RawContextKey<boolean>('editorHasDocumentSymbolProvider', false);
export const hasReferenceProvider = new RawContextKey<boolean>('editorHasReferenceProvider', undefined); export const hasReferenceProvider = new RawContextKey<boolean>('editorHasReferenceProvider', false);
export const hasRenameProvider = new RawContextKey<boolean>('editorHasRenameProvider', undefined); export const hasRenameProvider = new RawContextKey<boolean>('editorHasRenameProvider', false);
export const hasDocumentFormattingProvider = new RawContextKey<boolean>('editorHasDocumentFormattingProvider', undefined); export const hasDocumentFormattingProvider = new RawContextKey<boolean>('editorHasDocumentFormattingProvider', false);
export const hasDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasDocumentSelectionFormattingProvider', undefined); export const hasDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasDocumentSelectionFormattingProvider', false);
export const hasSignatureHelpProvider = new RawContextKey<boolean>('editorHasSignatureHelpProvider', undefined); export const hasSignatureHelpProvider = new RawContextKey<boolean>('editorHasSignatureHelpProvider', false);
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册