mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79 (#14050)
* Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79 * Fix breaks * Extension management fixes * Fix breaks in windows bundling * Fix/skip failing tests * Update distro * Add clear to nuget.config * Add hygiene task * Bump distro * Fix hygiene issue * Add build to hygiene exclusion * Update distro * Update hygiene * Hygiene exclusions * Update tsconfig * Bump distro for server breaks * Update build config * Update darwin path * Add done calls to notebook tests * Skip failing tests * Disable smoke tests
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
|
||||
@@ -36,7 +37,7 @@ export interface IAction extends IDisposable {
|
||||
export interface IActionRunner extends IDisposable {
|
||||
run(action: IAction, context?: any): Promise<any>;
|
||||
readonly onDidRun: Event<IRunEvent>;
|
||||
readonly onDidBeforeRun: Event<IRunEvent>;
|
||||
readonly onBeforeRun: Event<IRunEvent>;
|
||||
}
|
||||
|
||||
export interface IActionViewItem extends IDisposable {
|
||||
@@ -196,8 +197,8 @@ export interface IRunEvent {
|
||||
|
||||
export class ActionRunner extends Disposable implements IActionRunner {
|
||||
|
||||
private _onDidBeforeRun = this._register(new Emitter<IRunEvent>());
|
||||
readonly onDidBeforeRun: Event<IRunEvent> = this._onDidBeforeRun.event;
|
||||
private _onBeforeRun = this._register(new Emitter<IRunEvent>());
|
||||
readonly onBeforeRun: Event<IRunEvent> = this._onBeforeRun.event;
|
||||
|
||||
private _onDidRun = this._register(new Emitter<IRunEvent>());
|
||||
readonly onDidRun: Event<IRunEvent> = this._onDidRun.event;
|
||||
@@ -207,7 +208,7 @@ export class ActionRunner extends Disposable implements IActionRunner {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
this._onDidBeforeRun.fire({ action: action });
|
||||
this._onBeforeRun.fire({ action: action });
|
||||
|
||||
try {
|
||||
const result = await this.runAction(action, context);
|
||||
@@ -253,15 +254,31 @@ export class Separator extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export type SubmenuActions = IAction[] | (() => IAction[]);
|
||||
export class ActionWithMenuAction extends Action {
|
||||
|
||||
get actions(): IAction[] {
|
||||
return this._actions;
|
||||
}
|
||||
|
||||
constructor(id: string, private _actions: IAction[], label?: string, cssClass?: string, enabled?: boolean, actionCallback?: (event?: any) => Promise<any>) {
|
||||
super(id, label, cssClass, enabled, actionCallback);
|
||||
}
|
||||
}
|
||||
|
||||
export class SubmenuAction extends Action {
|
||||
|
||||
get actions(): IAction[] {
|
||||
return Array.isArray(this._actions) ? this._actions : this._actions();
|
||||
return this._actions;
|
||||
}
|
||||
|
||||
constructor(id: string, label: string, private _actions: SubmenuActions, cssClass?: string) {
|
||||
super(id, label, cssClass, true);
|
||||
constructor(id: string, label: string, private _actions: IAction[], cssClass?: string) {
|
||||
super(id, label, cssClass, !!_actions?.length);
|
||||
}
|
||||
}
|
||||
|
||||
export class EmptySubmenuAction extends Action {
|
||||
static readonly ID = 'vs.actions.empty';
|
||||
constructor() {
|
||||
super(EmptySubmenuAction.ID, nls.localize('submenu.empty', '(empty)'), undefined, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,149 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { mergeSort } from 'vs/base/common/arrays';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
/**
|
||||
* @deprecated use `FileAccess.asFileUri(relativePath, requireFn).fsPath`
|
||||
*/
|
||||
export function getPathFromAmdModule(requirefn: typeof require, relativePath: string): string {
|
||||
return getUriFromAmdModule(requirefn, relativePath).fsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use `FileAccess.asFileUri()` for node.js contexts or `FileAccess.asBrowserUri` for browser contexts.
|
||||
*/
|
||||
export function getUriFromAmdModule(requirefn: typeof require, relativePath: string): URI {
|
||||
return URI.parse(requirefn.toUrl(relativePath));
|
||||
}
|
||||
|
||||
export abstract class LoaderStats {
|
||||
abstract get amdLoad(): [string, number][];
|
||||
abstract get amdInvoke(): [string, number][];
|
||||
abstract get nodeRequire(): [string, number][];
|
||||
abstract get nodeEval(): [string, number][];
|
||||
abstract get nodeRequireTotal(): number;
|
||||
|
||||
|
||||
static get(): LoaderStats {
|
||||
|
||||
|
||||
const amdLoadScript = new Map<string, number>();
|
||||
const amdInvokeFactory = new Map<string, number>();
|
||||
const nodeRequire = new Map<string, number>();
|
||||
const nodeEval = new Map<string, number>();
|
||||
|
||||
function mark(map: Map<string, number>, stat: LoaderEvent) {
|
||||
if (map.has(stat.detail)) {
|
||||
// console.warn('BAD events, DOUBLE start', stat);
|
||||
// map.delete(stat.detail);
|
||||
return;
|
||||
}
|
||||
map.set(stat.detail, -stat.timestamp);
|
||||
}
|
||||
|
||||
function diff(map: Map<string, number>, stat: LoaderEvent) {
|
||||
let duration = map.get(stat.detail);
|
||||
if (!duration) {
|
||||
// console.warn('BAD events, end WITHOUT start', stat);
|
||||
// map.delete(stat.detail);
|
||||
return;
|
||||
}
|
||||
if (duration >= 0) {
|
||||
// console.warn('BAD events, DOUBLE end', stat);
|
||||
// map.delete(stat.detail);
|
||||
return;
|
||||
}
|
||||
map.set(stat.detail, duration + stat.timestamp);
|
||||
}
|
||||
|
||||
const stats = mergeSort(require.getStats().slice(0), (a, b) => a.timestamp - b.timestamp);
|
||||
|
||||
for (const stat of stats) {
|
||||
switch (stat.type) {
|
||||
case LoaderEventType.BeginLoadingScript:
|
||||
mark(amdLoadScript, stat);
|
||||
break;
|
||||
case LoaderEventType.EndLoadingScriptOK:
|
||||
case LoaderEventType.EndLoadingScriptError:
|
||||
diff(amdLoadScript, stat);
|
||||
break;
|
||||
|
||||
case LoaderEventType.BeginInvokeFactory:
|
||||
mark(amdInvokeFactory, stat);
|
||||
break;
|
||||
case LoaderEventType.EndInvokeFactory:
|
||||
diff(amdInvokeFactory, stat);
|
||||
break;
|
||||
|
||||
case LoaderEventType.NodeBeginNativeRequire:
|
||||
mark(nodeRequire, stat);
|
||||
break;
|
||||
case LoaderEventType.NodeEndNativeRequire:
|
||||
diff(nodeRequire, stat);
|
||||
break;
|
||||
|
||||
case LoaderEventType.NodeBeginEvaluatingScript:
|
||||
mark(nodeEval, stat);
|
||||
break;
|
||||
case LoaderEventType.NodeEndEvaluatingScript:
|
||||
diff(nodeEval, stat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let nodeRequireTotal = 0;
|
||||
nodeRequire.forEach(value => nodeRequireTotal += value);
|
||||
|
||||
function to2dArray(map: Map<string, number>): [string, number][] {
|
||||
let res: [string, number][] = [];
|
||||
map.forEach((value, index) => res.push([index, value]));
|
||||
return res;
|
||||
}
|
||||
|
||||
return {
|
||||
amdLoad: to2dArray(amdLoadScript),
|
||||
amdInvoke: to2dArray(amdInvokeFactory),
|
||||
nodeRequire: to2dArray(nodeRequire),
|
||||
nodeEval: to2dArray(nodeEval),
|
||||
nodeRequireTotal
|
||||
};
|
||||
}
|
||||
|
||||
static toMarkdownTable(header: string[], rows: Array<Array<{ toString(): string } | undefined>>): string {
|
||||
let result = '';
|
||||
|
||||
let lengths: number[] = [];
|
||||
header.forEach((cell, ci) => {
|
||||
lengths[ci] = cell.length;
|
||||
});
|
||||
rows.forEach(row => {
|
||||
row.forEach((cell, ci) => {
|
||||
if (typeof cell === 'undefined') {
|
||||
cell = row[ci] = '-';
|
||||
}
|
||||
const len = cell.toString().length;
|
||||
lengths[ci] = Math.max(len, lengths[ci]);
|
||||
});
|
||||
});
|
||||
|
||||
// header
|
||||
header.forEach((cell, ci) => { result += `| ${cell + ' '.repeat(lengths[ci] - cell.toString().length)} `; });
|
||||
result += '|\n';
|
||||
header.forEach((_cell, ci) => { result += `| ${'-'.repeat(lengths[ci])} `; });
|
||||
result += '|\n';
|
||||
|
||||
// cells
|
||||
rows.forEach(row => {
|
||||
row.forEach((cell, ci) => {
|
||||
if (typeof cell !== 'undefined') {
|
||||
result += `| ${cell + ' '.repeat(lengths[ci] - cell.toString().length)} `;
|
||||
}
|
||||
});
|
||||
result += '|\n';
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,40 @@ export function findFirstInSorted<T>(array: ReadonlyArray<T>, p: (x: T) => boole
|
||||
|
||||
type Compare<T> = (a: T, b: T) => number;
|
||||
|
||||
|
||||
export function quickSelect<T>(nth: number, data: T[], compare: Compare<T>): T {
|
||||
|
||||
nth = nth | 0;
|
||||
|
||||
if (nth >= data.length) {
|
||||
throw new TypeError('invalid index');
|
||||
}
|
||||
|
||||
let pivotValue = data[Math.floor(data.length * Math.random())];
|
||||
let lower: T[] = [];
|
||||
let higher: T[] = [];
|
||||
let pivots: T[] = [];
|
||||
|
||||
for (let value of data) {
|
||||
const val = compare(value, pivotValue);
|
||||
if (val < 0) {
|
||||
lower.push(value);
|
||||
} else if (val > 0) {
|
||||
higher.push(value);
|
||||
} else {
|
||||
pivots.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (nth < lower.length) {
|
||||
return quickSelect(nth, lower, compare);
|
||||
} else if (nth < lower.length + pivots.length) {
|
||||
return pivots[0];
|
||||
} else {
|
||||
return quickSelect(nth - (lower.length + pivots.length), higher, compare);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like `Array#sort` but always stable. Usually runs a little slower `than Array#sort`
|
||||
* so only use this when actually needing stable sort.
|
||||
@@ -555,6 +589,8 @@ export function mapArrayOrNot<T, U>(items: T | T[], fn: (_: T) => U): U | U[] {
|
||||
fn(items);
|
||||
}
|
||||
|
||||
export function asArray<T>(x: T | T[]): T[];
|
||||
export function asArray<T>(x: T | readonly T[]): readonly T[];
|
||||
export function asArray<T>(x: T | T[]): T[] {
|
||||
return Array.isArray(x) ? x : [x];
|
||||
}
|
||||
@@ -562,3 +598,17 @@ export function asArray<T>(x: T | T[]): T[] {
|
||||
export function getRandomElement<T>(arr: T[]): T | undefined {
|
||||
return arr[Math.floor(Math.random() * arr.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first mapped value of the array which is not undefined.
|
||||
*/
|
||||
export function mapFind<T, R>(array: Iterable<T>, mapFn: (value: T) => R | undefined): R | undefined {
|
||||
for (const value of array) {
|
||||
const mapped = mapFn(value);
|
||||
if (mapped !== undefined) {
|
||||
return mapped;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,21 @@ export function raceCancellation<T>(promise: Promise<T>, token: CancellationToke
|
||||
return Promise.race([promise, new Promise<T | undefined>(resolve => token.onCancellationRequested(() => resolve(defaultValue)))]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as soon as one of the promises is resolved and cancels remaining promises
|
||||
*/
|
||||
export async function raceCancellablePromises<T>(cancellablePromises: CancelablePromise<T>[]): Promise<T> {
|
||||
let resolvedPromiseIndex = -1;
|
||||
const promises = cancellablePromises.map((promise, index) => promise.then(result => { resolvedPromiseIndex = index; return result; }));
|
||||
const result = await Promise.race(promises);
|
||||
cancellablePromises.forEach((cancellablePromise, index) => {
|
||||
if (index !== resolvedPromiseIndex) {
|
||||
cancellablePromise.cancel();
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export function raceTimeout<T>(promise: Promise<T>, timeout: number, onTimeout?: () => void): Promise<T | undefined> {
|
||||
let promiseResolve: ((value: T | undefined) => void) | undefined = undefined;
|
||||
|
||||
@@ -149,13 +164,13 @@ export class Throttler {
|
||||
|
||||
this.activePromise = promiseFactory();
|
||||
|
||||
return new Promise((c, e) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.activePromise!.then((result: any) => {
|
||||
this.activePromise = null;
|
||||
c(result);
|
||||
resolve(result);
|
||||
}, (err: any) => {
|
||||
this.activePromise = null;
|
||||
e(err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -430,6 +445,45 @@ export function first<T>(promiseFactories: ITask<Promise<T>>[], shouldStop: (t:
|
||||
return loop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of the first promise that matches the "shouldStop",
|
||||
* running all promises in parallel. Supports cancelable promises.
|
||||
*/
|
||||
export function firstParallel<T>(promiseList: Promise<T>[], shouldStop?: (t: T) => boolean, defaultValue?: T | null): Promise<T | null>;
|
||||
export function firstParallel<T, R extends T>(promiseList: Promise<T>[], shouldStop: (t: T) => t is R, defaultValue?: R | null): Promise<R | null>;
|
||||
export function firstParallel<T>(promiseList: Promise<T>[], shouldStop: (t: T) => boolean = t => !!t, defaultValue: T | null = null) {
|
||||
if (promiseList.length === 0) {
|
||||
return Promise.resolve(defaultValue);
|
||||
}
|
||||
|
||||
let todo = promiseList.length;
|
||||
const finish = () => {
|
||||
todo = -1;
|
||||
for (const promise of promiseList) {
|
||||
(promise as Partial<CancelablePromise<T>>).cancel?.();
|
||||
}
|
||||
};
|
||||
|
||||
return new Promise<T | null>((resolve, reject) => {
|
||||
for (const promise of promiseList) {
|
||||
promise.then(result => {
|
||||
if (--todo >= 0 && shouldStop(result)) {
|
||||
finish();
|
||||
resolve(result);
|
||||
} else if (todo === 0) {
|
||||
resolve(defaultValue);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
if (--todo >= 0) {
|
||||
finish();
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
interface ILimitedTaskFactory<T> {
|
||||
factory: ITask<Promise<T>>;
|
||||
c: (value: T | Promise<T>) => void;
|
||||
@@ -924,3 +978,38 @@ export class TaskSequentializer {
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region
|
||||
|
||||
/**
|
||||
* The `IntervalCounter` allows to count the number
|
||||
* of calls to `increment()` over a duration of
|
||||
* `interval`. This utility can be used to conditionally
|
||||
* throttle a frequent task when a certain threshold
|
||||
* is reached.
|
||||
*/
|
||||
export class IntervalCounter {
|
||||
|
||||
private lastIncrementTime = 0;
|
||||
|
||||
private value = 0;
|
||||
|
||||
constructor(private readonly interval: number) { }
|
||||
|
||||
increment(): number {
|
||||
const now = Date.now();
|
||||
|
||||
// We are outside of the range of `interval` and as such
|
||||
// start counting from 0 and remember the time
|
||||
if (now - this.lastIncrementTime > this.interval) {
|
||||
this.lastIncrementTime = now;
|
||||
this.value = 0;
|
||||
}
|
||||
|
||||
this.value++;
|
||||
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import { codiconStartMarker } from 'vs/base/common/codicon';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
export interface IIconRegistry {
|
||||
readonly all: IterableIterator<Codicon>;
|
||||
@@ -18,9 +19,12 @@ class Registry implements IIconRegistry {
|
||||
private readonly _onDidRegister = new Emitter<Codicon>();
|
||||
|
||||
public add(icon: Codicon) {
|
||||
if (!this._icons.has(icon.id)) {
|
||||
const existing = this._icons.get(icon.id);
|
||||
if (!existing) {
|
||||
this._icons.set(icon.id, icon);
|
||||
this._onDidRegister.fire(icon);
|
||||
} else if (icon.description) {
|
||||
existing.description = icon.description;
|
||||
} else {
|
||||
console.error(`Duplicate registration of codicon ${icon.id}`);
|
||||
}
|
||||
@@ -43,11 +47,11 @@ const _registry = new Registry();
|
||||
|
||||
export const iconRegistry: IIconRegistry = _registry;
|
||||
|
||||
export function registerIcon(id: string, def: Codicon, description?: string) {
|
||||
return new Codicon(id, def);
|
||||
export function registerCodicon(id: string, def: Codicon, description?: string): Codicon {
|
||||
return new Codicon(id, def, description);
|
||||
}
|
||||
|
||||
export class Codicon {
|
||||
export class Codicon implements CSSIcon {
|
||||
constructor(public readonly id: string, public readonly definition: Codicon | IconDefinition, public description?: string) {
|
||||
_registry.add(this);
|
||||
}
|
||||
@@ -57,6 +61,12 @@ export class Codicon {
|
||||
public get cssSelector() { return '.codicon.codicon-' + this.id; }
|
||||
}
|
||||
|
||||
export interface CSSIcon {
|
||||
readonly classNames: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface IconDefinition {
|
||||
character: string;
|
||||
}
|
||||
@@ -481,8 +491,19 @@ export namespace Codicon {
|
||||
export const exportIcon = new Codicon('export', { character: '\\ebac' });
|
||||
export const graphLeft = new Codicon('graph-left', { character: '\\ebad' });
|
||||
export const magnet = new Codicon('magnet', { character: '\\ebae' });
|
||||
export const notebook = new Codicon('notebook', { character: '\\ebaf' });
|
||||
export const redo = new Codicon('redo', { character: '\\ebb0' });
|
||||
export const checkAll = new Codicon('check-all', { character: '\\ebb1' });
|
||||
export const pinnedDirty = new Codicon('pinned-dirty', { character: '\\ebb2' });
|
||||
export const passFilled = new Codicon('pass-filled', { character: '\\ebb3' });
|
||||
export const circleLargeFilled = new Codicon('circle-large-filled', { character: '\\ebb4' });
|
||||
export const circleLargeOutline = new Codicon('circle-large-outline', { character: '\\ebb5' });
|
||||
|
||||
export const dropDownButton = new Codicon('drop-down-button', Codicon.chevronDown.definition, localize('dropDownButton', 'Icon for drop down buttons.'));
|
||||
}
|
||||
|
||||
// common icons
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -78,7 +78,37 @@ export function fromMap<T>(original: Map<string, T>): IStringDictionary<T> {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function diffSets<T>(before: Set<T>, after: Set<T>): { removed: T[], added: T[] } {
|
||||
const removed: T[] = [];
|
||||
const added: T[] = [];
|
||||
for (let element of before) {
|
||||
if (!after.has(element)) {
|
||||
removed.push(element);
|
||||
}
|
||||
}
|
||||
for (let element of after) {
|
||||
if (!before.has(element)) {
|
||||
added.push(element);
|
||||
}
|
||||
}
|
||||
return { removed, added };
|
||||
}
|
||||
|
||||
export function diffMaps<K, V>(before: Map<K, V>, after: Map<K, V>): { removed: V[], added: V[] } {
|
||||
const removed: V[] = [];
|
||||
const added: V[] = [];
|
||||
for (let [index, value] of before) {
|
||||
if (!after.has(index)) {
|
||||
removed.push(value);
|
||||
}
|
||||
}
|
||||
for (let [index, value] of after) {
|
||||
if (!before.has(index)) {
|
||||
added.push(value);
|
||||
}
|
||||
}
|
||||
return { removed, added };
|
||||
}
|
||||
export class SetMap<K, V> {
|
||||
|
||||
private map = new Map<K, Set<V>>();
|
||||
|
||||
@@ -240,7 +240,7 @@ export class HSVA {
|
||||
} else if (h < 300) {
|
||||
r = x;
|
||||
b = c;
|
||||
} else if (h < 360) {
|
||||
} else if (h <= 360) {
|
||||
r = c;
|
||||
b = x;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { pad } from './strings';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
const minute = 60;
|
||||
@@ -121,11 +120,11 @@ export function fromNow(date: number | Date, appendAgoLabel?: boolean): string {
|
||||
|
||||
export function toLocalISOString(date: Date): string {
|
||||
return date.getFullYear() +
|
||||
'-' + pad(date.getMonth() + 1, 2) +
|
||||
'-' + pad(date.getDate(), 2) +
|
||||
'T' + pad(date.getHours(), 2) +
|
||||
':' + pad(date.getMinutes(), 2) +
|
||||
':' + pad(date.getSeconds(), 2) +
|
||||
'-' + String(date.getMonth() + 1).padStart(2, '0') +
|
||||
'-' + String(date.getDate()).padStart(2, '0') +
|
||||
'T' + String(date.getHours()).padStart(2, '0') +
|
||||
':' + String(date.getMinutes()).padStart(2, '0') +
|
||||
':' + String(date.getSeconds()).padStart(2, '0') +
|
||||
'.' + (date.getMilliseconds() / 1000).toFixed(3).slice(2, 5) +
|
||||
'Z';
|
||||
}
|
||||
|
||||
@@ -880,9 +880,81 @@ export class LcsDiff {
|
||||
change.modifiedStart -= bestDelta;
|
||||
}
|
||||
|
||||
// There could be multiple longest common substrings.
|
||||
// Give preference to the ones containing longer lines
|
||||
if (this._hasStrings) {
|
||||
for (let i = 1, len = changes.length; i < len; i++) {
|
||||
const aChange = changes[i - 1];
|
||||
const bChange = changes[i];
|
||||
const matchedLength = bChange.originalStart - aChange.originalStart - aChange.originalLength;
|
||||
const aOriginalStart = aChange.originalStart;
|
||||
const bOriginalEnd = bChange.originalStart + bChange.originalLength;
|
||||
const abOriginalLength = bOriginalEnd - aOriginalStart;
|
||||
const aModifiedStart = aChange.modifiedStart;
|
||||
const bModifiedEnd = bChange.modifiedStart + bChange.modifiedLength;
|
||||
const abModifiedLength = bModifiedEnd - aModifiedStart;
|
||||
// Avoid wasting a lot of time with these searches
|
||||
if (matchedLength < 5 && abOriginalLength < 20 && abModifiedLength < 20) {
|
||||
const t = this._findBetterContiguousSequence(
|
||||
aOriginalStart, abOriginalLength,
|
||||
aModifiedStart, abModifiedLength,
|
||||
matchedLength
|
||||
);
|
||||
if (t) {
|
||||
const [originalMatchStart, modifiedMatchStart] = t;
|
||||
if (originalMatchStart !== aChange.originalStart + aChange.originalLength || modifiedMatchStart !== aChange.modifiedStart + aChange.modifiedLength) {
|
||||
// switch to another sequence that has a better score
|
||||
aChange.originalLength = originalMatchStart - aChange.originalStart;
|
||||
aChange.modifiedLength = modifiedMatchStart - aChange.modifiedStart;
|
||||
bChange.originalStart = originalMatchStart + matchedLength;
|
||||
bChange.modifiedStart = modifiedMatchStart + matchedLength;
|
||||
bChange.originalLength = bOriginalEnd - bChange.originalStart;
|
||||
bChange.modifiedLength = bModifiedEnd - bChange.modifiedStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
private _findBetterContiguousSequence(originalStart: number, originalLength: number, modifiedStart: number, modifiedLength: number, desiredLength: number): [number, number] | null {
|
||||
if (originalLength < desiredLength || modifiedLength < desiredLength) {
|
||||
return null;
|
||||
}
|
||||
const originalMax = originalStart + originalLength - desiredLength + 1;
|
||||
const modifiedMax = modifiedStart + modifiedLength - desiredLength + 1;
|
||||
let bestScore = 0;
|
||||
let bestOriginalStart = 0;
|
||||
let bestModifiedStart = 0;
|
||||
for (let i = originalStart; i < originalMax; i++) {
|
||||
for (let j = modifiedStart; j < modifiedMax; j++) {
|
||||
const score = this._contiguousSequenceScore(i, j, desiredLength);
|
||||
if (score > 0 && score > bestScore) {
|
||||
bestScore = score;
|
||||
bestOriginalStart = i;
|
||||
bestModifiedStart = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestScore > 0) {
|
||||
return [bestOriginalStart, bestModifiedStart];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private _contiguousSequenceScore(originalStart: number, modifiedStart: number, length: number): number {
|
||||
let score = 0;
|
||||
for (let l = 0; l < length; l++) {
|
||||
if (!this.ElementsAreEqual(originalStart + l, modifiedStart + l)) {
|
||||
return 0;
|
||||
}
|
||||
score += this._originalStringElements[originalStart + l].length;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
private _OriginalIsBoundary(index: number): boolean {
|
||||
if (index <= 0 || index >= this._originalElementsOrHash.length - 1) {
|
||||
return true;
|
||||
|
||||
@@ -629,7 +629,7 @@ export class PauseableEmitter<T> extends Emitter<T> {
|
||||
if (this._mergeFn) {
|
||||
// use the merge function to create a single composite
|
||||
// event. make a copy in case firing pauses this emitter
|
||||
const events = this._eventQueue.toArray();
|
||||
const events = Array.from(this._eventQueue);
|
||||
this._eventQueue.clear();
|
||||
super.fire(this._mergeFn(events));
|
||||
|
||||
|
||||
@@ -191,42 +191,42 @@ export function isEqual(pathA: string, pathB: string, ignoreCase?: boolean): boo
|
||||
return equalsIgnoreCase(pathA, pathB);
|
||||
}
|
||||
|
||||
export function isEqualOrParent(path: string, candidate: string, ignoreCase?: boolean, separator = sep): boolean {
|
||||
if (path === candidate) {
|
||||
export function isEqualOrParent(base: string, parentCandidate: string, ignoreCase?: boolean, separator = sep): boolean {
|
||||
if (base === parentCandidate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!path || !candidate) {
|
||||
if (!base || !parentCandidate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (candidate.length > path.length) {
|
||||
if (parentCandidate.length > base.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ignoreCase) {
|
||||
const beginsWith = startsWithIgnoreCase(path, candidate);
|
||||
const beginsWith = startsWithIgnoreCase(base, parentCandidate);
|
||||
if (!beginsWith) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (candidate.length === path.length) {
|
||||
if (parentCandidate.length === base.length) {
|
||||
return true; // same path, different casing
|
||||
}
|
||||
|
||||
let sepOffset = candidate.length;
|
||||
if (candidate.charAt(candidate.length - 1) === separator) {
|
||||
let sepOffset = parentCandidate.length;
|
||||
if (parentCandidate.charAt(parentCandidate.length - 1) === separator) {
|
||||
sepOffset--; // adjust the expected sep offset in case our candidate already ends in separator character
|
||||
}
|
||||
|
||||
return path.charAt(sepOffset) === separator;
|
||||
return base.charAt(sepOffset) === separator;
|
||||
}
|
||||
|
||||
if (candidate.charAt(candidate.length - 1) !== separator) {
|
||||
candidate += separator;
|
||||
if (parentCandidate.charAt(parentCandidate.length - 1) !== separator) {
|
||||
parentCandidate += separator;
|
||||
}
|
||||
|
||||
return path.indexOf(candidate) === 0;
|
||||
return base.indexOf(parentCandidate) === 0;
|
||||
}
|
||||
|
||||
export function isWindowsDriveLetter(char0: number): boolean {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import * as extpath from 'vs/base/common/extpath';
|
||||
import * as paths from 'vs/base/common/path';
|
||||
@@ -382,7 +381,7 @@ function trivia3(pattern: string, options: IGlobOptions): ParsedStringPattern {
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const withBasenames = arrays.first(parsedPatterns, pattern => !!(<ParsedStringPattern>pattern).allBasenames);
|
||||
const withBasenames = parsedPatterns.find(pattern => !!(<ParsedStringPattern>pattern).allBasenames);
|
||||
if (withBasenames) {
|
||||
parsedPattern.allBasenames = (<ParsedStringPattern>withBasenames).allBasenames;
|
||||
}
|
||||
@@ -552,7 +551,7 @@ function parsedExpression(expression: IExpression, options: IGlobOptions): Parse
|
||||
return null;
|
||||
};
|
||||
|
||||
const withBasenames = arrays.first(parsedPatterns, pattern => !!(<ParsedStringPattern>pattern).allBasenames);
|
||||
const withBasenames = parsedPatterns.find(pattern => !!(<ParsedStringPattern>pattern).allBasenames);
|
||||
if (withBasenames) {
|
||||
resultExpression.allBasenames = (<ParsedStringPattern>withBasenames).allBasenames;
|
||||
}
|
||||
@@ -588,7 +587,7 @@ function parsedExpression(expression: IExpression, options: IGlobOptions): Parse
|
||||
return null;
|
||||
};
|
||||
|
||||
const withBasenames = arrays.first(parsedPatterns, pattern => !!(<ParsedStringPattern>pattern).allBasenames);
|
||||
const withBasenames = parsedPatterns.find(pattern => !!(<ParsedStringPattern>pattern).allBasenames);
|
||||
if (withBasenames) {
|
||||
resultExpression.allBasenames = (<ParsedStringPattern>withBasenames).allBasenames;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ export function hash(obj: any): number {
|
||||
return doHash(obj, 0);
|
||||
}
|
||||
|
||||
|
||||
export function doHash(obj: any, hashVal: number): number {
|
||||
switch (typeof obj) {
|
||||
case 'object':
|
||||
@@ -107,8 +106,14 @@ function leftPad(value: string, length: number, char: string = '0'): string {
|
||||
return value;
|
||||
}
|
||||
|
||||
function toHexString(value: number, bitsize: number = 32): string {
|
||||
return leftPad((value >>> 0).toString(16), bitsize / 4);
|
||||
export function toHexString(buffer: ArrayBuffer): string;
|
||||
export function toHexString(value: number, bitsize?: number): string;
|
||||
export function toHexString(bufferOrValue: ArrayBuffer | number, bitsize: number = 32): string {
|
||||
if (bufferOrValue instanceof ArrayBuffer) {
|
||||
return Array.from(new Uint8Array(bufferOrValue)).map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
|
||||
return leftPad((bufferOrValue >>> 0).toString(16), bitsize / 4);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -97,3 +97,106 @@ export class HistoryNavigator<T> implements INavigator<T> {
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
|
||||
interface HistoryNode<T> {
|
||||
value: T;
|
||||
previous: HistoryNode<T> | undefined;
|
||||
next: HistoryNode<T> | undefined;
|
||||
}
|
||||
|
||||
export class HistoryNavigator2<T> {
|
||||
|
||||
private head: HistoryNode<T>;
|
||||
private tail: HistoryNode<T>;
|
||||
private cursor: HistoryNode<T>;
|
||||
private size: number;
|
||||
|
||||
constructor(history: readonly T[], private capacity: number = 10) {
|
||||
if (history.length < 1) {
|
||||
throw new Error('not supported');
|
||||
}
|
||||
|
||||
this.size = 1;
|
||||
this.head = this.tail = this.cursor = {
|
||||
value: history[0],
|
||||
previous: undefined,
|
||||
next: undefined
|
||||
};
|
||||
|
||||
for (let i = 1; i < history.length; i++) {
|
||||
this.add(history[i]);
|
||||
}
|
||||
}
|
||||
|
||||
add(value: T): void {
|
||||
const node: HistoryNode<T> = {
|
||||
value,
|
||||
previous: this.tail,
|
||||
next: undefined
|
||||
};
|
||||
|
||||
this.tail.next = node;
|
||||
this.tail = node;
|
||||
this.cursor = this.tail;
|
||||
this.size++;
|
||||
|
||||
while (this.size > this.capacity) {
|
||||
this.head = this.head.next!;
|
||||
this.head.previous = undefined;
|
||||
this.size--;
|
||||
}
|
||||
}
|
||||
|
||||
replaceLast(value: T): void {
|
||||
this.tail.value = value;
|
||||
}
|
||||
|
||||
isAtEnd(): boolean {
|
||||
return this.cursor === this.tail;
|
||||
}
|
||||
|
||||
current(): T {
|
||||
return this.cursor.value;
|
||||
}
|
||||
|
||||
previous(): T {
|
||||
if (this.cursor.previous) {
|
||||
this.cursor = this.cursor.previous;
|
||||
}
|
||||
|
||||
return this.cursor.value;
|
||||
}
|
||||
|
||||
next(): T {
|
||||
if (this.cursor.next) {
|
||||
this.cursor = this.cursor.next;
|
||||
}
|
||||
|
||||
return this.cursor.value;
|
||||
}
|
||||
|
||||
has(t: T): boolean {
|
||||
let temp: HistoryNode<T> | undefined = this.head;
|
||||
while (temp) {
|
||||
if (temp.value === t) {
|
||||
return true;
|
||||
}
|
||||
temp = temp.next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
resetCursor(): T {
|
||||
this.cursor = this.tail;
|
||||
return this.cursor.value;
|
||||
}
|
||||
|
||||
*[Symbol.iterator](): Iterator<T> {
|
||||
let node: HistoryNode<T> | undefined = this.head;
|
||||
|
||||
while (node) {
|
||||
yield node.value;
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,53 +15,58 @@ export interface IMarkdownString {
|
||||
uris?: { [href: string]: UriComponents };
|
||||
}
|
||||
|
||||
export const enum MarkdownStringTextNewlineStyle {
|
||||
Paragraph = 0,
|
||||
Break = 1,
|
||||
}
|
||||
|
||||
export class MarkdownString implements IMarkdownString {
|
||||
private readonly _isTrusted: boolean;
|
||||
private readonly _supportThemeIcons: boolean;
|
||||
|
||||
public value: string;
|
||||
public isTrusted?: boolean;
|
||||
public supportThemeIcons?: boolean;
|
||||
|
||||
constructor(
|
||||
private _value: string = '',
|
||||
value: string = '',
|
||||
isTrustedOrOptions: boolean | { isTrusted?: boolean, supportThemeIcons?: boolean } = false,
|
||||
) {
|
||||
if (typeof this._value !== 'string') {
|
||||
this.value = value;
|
||||
if (typeof this.value !== 'string') {
|
||||
throw illegalArgument('value');
|
||||
}
|
||||
|
||||
if (typeof isTrustedOrOptions === 'boolean') {
|
||||
this._isTrusted = isTrustedOrOptions;
|
||||
this._supportThemeIcons = false;
|
||||
this.isTrusted = isTrustedOrOptions;
|
||||
this.supportThemeIcons = false;
|
||||
}
|
||||
else {
|
||||
this._isTrusted = isTrustedOrOptions.isTrusted ?? false;
|
||||
this._supportThemeIcons = isTrustedOrOptions.supportThemeIcons ?? false;
|
||||
this.isTrusted = isTrustedOrOptions.isTrusted ?? undefined;
|
||||
this.supportThemeIcons = isTrustedOrOptions.supportThemeIcons ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
get value() { return this._value; }
|
||||
get isTrusted() { return this._isTrusted; }
|
||||
get supportThemeIcons() { return this._supportThemeIcons; }
|
||||
|
||||
appendText(value: string): MarkdownString {
|
||||
appendText(value: string, newlineStyle: MarkdownStringTextNewlineStyle = MarkdownStringTextNewlineStyle.Paragraph): MarkdownString {
|
||||
// escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
|
||||
this._value += (this._supportThemeIcons ? escapeCodicons(value) : value)
|
||||
this.value += (this.supportThemeIcons ? escapeCodicons(value) : value)
|
||||
.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
|
||||
.replace(/\n/g, '\n\n');
|
||||
.replace(/([ \t]+)/g, (_match, g1) => ' '.repeat(g1.length))
|
||||
.replace(/^>/gm, '\\>')
|
||||
.replace(/\n/g, newlineStyle === MarkdownStringTextNewlineStyle.Break ? '\\\n' : '\n\n');
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
appendMarkdown(value: string): MarkdownString {
|
||||
this._value += value;
|
||||
|
||||
this.value += value;
|
||||
return this;
|
||||
}
|
||||
|
||||
appendCodeblock(langId: string, code: string): MarkdownString {
|
||||
this._value += '\n```';
|
||||
this._value += langId;
|
||||
this._value += '\n';
|
||||
this._value += code;
|
||||
this._value += '\n```\n';
|
||||
this.value += '\n```';
|
||||
this.value += langId;
|
||||
this.value += '\n';
|
||||
this.value += code;
|
||||
this.value += '\n```\n';
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
14
src/vs/base/common/insane/insane.d.ts
vendored
14
src/vs/base/common/insane/insane.d.ts
vendored
@@ -3,13 +3,15 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export interface InsaneOptions {
|
||||
readonly allowedSchemes?: readonly string[],
|
||||
readonly allowedTags?: readonly string[],
|
||||
readonly allowedAttributes?: { readonly [key: string]: string[] },
|
||||
readonly filter?: (token: { tag: string, attrs: { readonly [key: string]: string } }) => boolean,
|
||||
}
|
||||
|
||||
export function insane(
|
||||
html: string,
|
||||
options?: {
|
||||
readonly allowedSchemes?: readonly string[],
|
||||
readonly allowedTags?: readonly string[],
|
||||
readonly allowedAttributes?: { readonly [key: string]: string[] },
|
||||
readonly filter?: (token: { tag: string, attrs: { readonly [key: string]: string } }) => boolean,
|
||||
},
|
||||
options?: InsaneOptions,
|
||||
strict?: boolean,
|
||||
): string;
|
||||
|
||||
@@ -126,7 +126,7 @@ export interface Location {
|
||||
/**
|
||||
* Matches the locations path against a pattern consisting of strings (for properties) and numbers (for array indices).
|
||||
* '*' will match a single segment, of any property name or index.
|
||||
* '**' will match a sequece of segments or no segment, of any property name or index.
|
||||
* '**' will match a sequence of segments or no segment, of any property name or index.
|
||||
*/
|
||||
matches: (patterns: JSONPath) => boolean;
|
||||
/**
|
||||
|
||||
@@ -95,6 +95,10 @@ function hasDriveLetter(path: string): boolean {
|
||||
return !!(isWindows && path && path[1] === ':');
|
||||
}
|
||||
|
||||
export function extractDriveLetter(path: string): string | undefined {
|
||||
return hasDriveLetter(path) ? path[0] : undefined;
|
||||
}
|
||||
|
||||
export function normalizeDriveLetter(path: string): string {
|
||||
if (hasDriveLetter(path)) {
|
||||
return path.charAt(0).toUpperCase() + path.slice(1);
|
||||
|
||||
@@ -131,12 +131,4 @@ export class LinkedList<E> {
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
|
||||
toArray(): E[] {
|
||||
const result: E[] = [];
|
||||
for (let node = this._first; node !== Node.Undefined; node = node.next) {
|
||||
result.push(node.element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { compareSubstringIgnoreCase, compare, compareSubstring } from 'vs/base/common/strings';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { isLinux } from 'vs/base/common/platform';
|
||||
import { compareSubstringIgnoreCase, compare, compareSubstring, compareIgnoreCase } from 'vs/base/common/strings';
|
||||
|
||||
export function getOrSet<K, V>(map: Map<K, V>, key: K, value: V): V {
|
||||
let result = map.get(key);
|
||||
@@ -77,6 +75,57 @@ export class StringIterator implements IKeyIterator<string> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ConfigKeysIterator implements IKeyIterator<string> {
|
||||
|
||||
private _value!: string;
|
||||
private _from!: number;
|
||||
private _to!: number;
|
||||
|
||||
constructor(
|
||||
private readonly _caseSensitive: boolean = true
|
||||
) { }
|
||||
|
||||
reset(key: string): this {
|
||||
this._value = key;
|
||||
this._from = 0;
|
||||
this._to = 0;
|
||||
return this.next();
|
||||
}
|
||||
|
||||
hasNext(): boolean {
|
||||
return this._to < this._value.length;
|
||||
}
|
||||
|
||||
next(): this {
|
||||
// this._data = key.split(/[\\/]/).filter(s => !!s);
|
||||
this._from = this._to;
|
||||
let justSeps = true;
|
||||
for (; this._to < this._value.length; this._to++) {
|
||||
const ch = this._value.charCodeAt(this._to);
|
||||
if (ch === CharCode.Period) {
|
||||
if (justSeps) {
|
||||
this._from++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
justSeps = false;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
cmp(a: string): number {
|
||||
return this._caseSensitive
|
||||
? compareSubstring(a, this._value, 0, a.length, this._from, this._to)
|
||||
: compareSubstringIgnoreCase(a, this._value, 0, a.length, this._from, this._to);
|
||||
}
|
||||
|
||||
value(): string {
|
||||
return this._value.substring(this._from, this._to);
|
||||
}
|
||||
}
|
||||
|
||||
export class PathIterator implements IKeyIterator<string> {
|
||||
|
||||
private _value!: string;
|
||||
@@ -140,6 +189,8 @@ export class UriIterator implements IKeyIterator<URI> {
|
||||
private _states: UriIteratorState[] = [];
|
||||
private _stateIdx: number = 0;
|
||||
|
||||
constructor(private readonly _ignorePathCasing: (uri: URI) => boolean) { }
|
||||
|
||||
reset(key: URI): this {
|
||||
this._value = key;
|
||||
this._states = [];
|
||||
@@ -150,10 +201,7 @@ export class UriIterator implements IKeyIterator<URI> {
|
||||
this._states.push(UriIteratorState.Authority);
|
||||
}
|
||||
if (this._value.path) {
|
||||
//todo@jrieken the case-sensitive logic is copied form `resources.ts#hasToIgnoreCase`
|
||||
// which cannot be used because it depends on this
|
||||
const caseSensitive = key.scheme === Schemas.file && isLinux;
|
||||
this._pathIterator = new PathIterator(false, caseSensitive);
|
||||
this._pathIterator = new PathIterator(false, !this._ignorePathCasing(key));
|
||||
this._pathIterator.reset(key.path);
|
||||
if (this._pathIterator.value()) {
|
||||
this._states.push(UriIteratorState.Path);
|
||||
@@ -185,9 +233,9 @@ export class UriIterator implements IKeyIterator<URI> {
|
||||
|
||||
cmp(a: string): number {
|
||||
if (this._states[this._stateIdx] === UriIteratorState.Scheme) {
|
||||
return compare(a, this._value.scheme);
|
||||
return compareIgnoreCase(a, this._value.scheme);
|
||||
} else if (this._states[this._stateIdx] === UriIteratorState.Authority) {
|
||||
return compareSubstringIgnoreCase(a, this._value.authority);
|
||||
return compareIgnoreCase(a, this._value.authority);
|
||||
} else if (this._states[this._stateIdx] === UriIteratorState.Path) {
|
||||
return this._pathIterator.cmp(a);
|
||||
} else if (this._states[this._stateIdx] === UriIteratorState.Query) {
|
||||
@@ -229,8 +277,8 @@ class TernarySearchTreeNode<K, V> {
|
||||
|
||||
export class TernarySearchTree<K, V> {
|
||||
|
||||
static forUris<E>(): TernarySearchTree<URI, E> {
|
||||
return new TernarySearchTree<URI, E>(new UriIterator());
|
||||
static forUris<E>(ignorePathCasing: (key: URI) => boolean = () => false): TernarySearchTree<URI, E> {
|
||||
return new TernarySearchTree<URI, E>(new UriIterator(ignorePathCasing));
|
||||
}
|
||||
|
||||
static forPaths<E>(): TernarySearchTree<string, E> {
|
||||
@@ -241,6 +289,10 @@ export class TernarySearchTree<K, V> {
|
||||
return new TernarySearchTree<string, E>(new StringIterator());
|
||||
}
|
||||
|
||||
static forConfigKeys<E>(): TernarySearchTree<string, E> {
|
||||
return new TernarySearchTree<string, E>(new ConfigKeysIterator());
|
||||
}
|
||||
|
||||
private _iter: IKeyIterator<K>;
|
||||
private _root: TernarySearchTreeNode<K, V> | undefined;
|
||||
|
||||
@@ -299,6 +351,10 @@ export class TernarySearchTree<K, V> {
|
||||
}
|
||||
|
||||
get(key: K): V | undefined {
|
||||
return this._getNode(key)?.value;
|
||||
}
|
||||
|
||||
private _getNode(key: K) {
|
||||
const iter = this._iter.reset(key);
|
||||
let node = this._root;
|
||||
while (node) {
|
||||
@@ -317,11 +373,22 @@ export class TernarySearchTree<K, V> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return node ? node.value : undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
has(key: K): boolean {
|
||||
return !!this._getNode(key);
|
||||
}
|
||||
|
||||
delete(key: K): void {
|
||||
return this._delete(key, false);
|
||||
}
|
||||
|
||||
deleteSuperstr(key: K): void {
|
||||
return this._delete(key, true);
|
||||
}
|
||||
|
||||
private _delete(key: K, superStr: boolean): void {
|
||||
const iter = this._iter.reset(key);
|
||||
const stack: [-1 | 0 | 1, TernarySearchTreeNode<K, V>][] = [];
|
||||
let node = this._root;
|
||||
@@ -343,8 +410,15 @@ export class TernarySearchTree<K, V> {
|
||||
stack.push([0, node]);
|
||||
node = node.mid;
|
||||
} else {
|
||||
// remove element
|
||||
node.value = undefined;
|
||||
if (superStr) {
|
||||
// remove children
|
||||
node.left = undefined;
|
||||
node.mid = undefined;
|
||||
node.right = undefined;
|
||||
} else {
|
||||
// remove element
|
||||
node.value = undefined;
|
||||
}
|
||||
|
||||
// clean up empty nodes
|
||||
while (stack.length > 0 && node.isEmpty()) {
|
||||
@@ -385,7 +459,7 @@ export class TernarySearchTree<K, V> {
|
||||
return node && node.value || candidate;
|
||||
}
|
||||
|
||||
findSuperstr(key: K): Iterator<V> | undefined {
|
||||
findSuperstr(key: K): IterableIterator<[K, V]> | undefined {
|
||||
const iter = this._iter.reset(key);
|
||||
let node = this._root;
|
||||
while (node) {
|
||||
@@ -405,57 +479,38 @@ export class TernarySearchTree<K, V> {
|
||||
if (!node.mid) {
|
||||
return undefined;
|
||||
} else {
|
||||
return this._nodeIterator(node.mid);
|
||||
return this._entries(node.mid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _nodeIterator(node: TernarySearchTreeNode<K, V>): Iterator<V> {
|
||||
let res: { done: false; value: V; };
|
||||
let idx: number;
|
||||
let data: V[];
|
||||
const next = (): IteratorResult<V> => {
|
||||
if (!data) {
|
||||
// lazy till first invocation
|
||||
data = [];
|
||||
idx = 0;
|
||||
this._forEach(node, value => data.push(value));
|
||||
}
|
||||
if (idx >= data.length) {
|
||||
return { done: true, value: undefined };
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
res = { done: false, value: data[idx++] };
|
||||
} else {
|
||||
res.value = data[idx++];
|
||||
}
|
||||
return res;
|
||||
};
|
||||
return { next };
|
||||
forEach(callback: (value: V, index: K) => any): void {
|
||||
for (const [key, value] of this) {
|
||||
callback(value, key);
|
||||
}
|
||||
}
|
||||
|
||||
forEach(callback: (value: V, index: K) => any) {
|
||||
this._forEach(this._root, callback);
|
||||
*[Symbol.iterator](): IterableIterator<[K, V]> {
|
||||
yield* this._entries(this._root);
|
||||
}
|
||||
|
||||
private _forEach(node: TernarySearchTreeNode<K, V> | undefined, callback: (value: V, index: K) => any) {
|
||||
private *_entries(node: TernarySearchTreeNode<K, V> | undefined): IterableIterator<[K, V]> {
|
||||
if (node) {
|
||||
// left
|
||||
this._forEach(node.left, callback);
|
||||
yield* this._entries(node.left);
|
||||
|
||||
// node
|
||||
if (node.value) {
|
||||
// callback(node.value, this._iter.join(parts));
|
||||
callback(node.value, node.key);
|
||||
yield [node.key, node.value];
|
||||
}
|
||||
// mid
|
||||
this._forEach(node.mid, callback);
|
||||
yield* this._entries(node.mid);
|
||||
|
||||
// right
|
||||
this._forEach(node.right, callback);
|
||||
yield* this._entries(node.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
"git": {
|
||||
"name": "marked",
|
||||
"repositoryUrl": "https://github.com/markedjs/marked",
|
||||
"commitHash": "529a8d4e185a8aa561e4d8d2891f8556b5717cd4"
|
||||
"commitHash": "8cfa29ccd2a2759e8e60fe0d8d6df8c022beda4e"
|
||||
}
|
||||
},
|
||||
"license": "MIT",
|
||||
"version": "0.6.2"
|
||||
"version": "1.1.0"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = global || self, global.marked = factory());
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.marked = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
|
||||
function _defineProperties(target, props) {
|
||||
@@ -368,11 +368,28 @@
|
||||
|
||||
function checkSanitizeDeprecation(opt) {
|
||||
if (opt && opt.sanitize && !opt.silent) {
|
||||
// VS CODE CHANGE
|
||||
// Disable logging about sanitize options. We already use insane after running the sanitizer
|
||||
|
||||
// console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
|
||||
console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
|
||||
}
|
||||
} // copied from https://stackoverflow.com/a/5450113/806777
|
||||
|
||||
|
||||
function repeatString(pattern, count) {
|
||||
if (count < 1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var result = '';
|
||||
|
||||
while (count > 1) {
|
||||
if (count & 1) {
|
||||
result += pattern;
|
||||
}
|
||||
|
||||
count >>= 1;
|
||||
pattern += pattern;
|
||||
}
|
||||
|
||||
return result + pattern;
|
||||
}
|
||||
|
||||
var helpers = {
|
||||
@@ -386,7 +403,8 @@
|
||||
splitCells: splitCells,
|
||||
rtrim: rtrim,
|
||||
findClosingBracket: findClosingBracket,
|
||||
checkSanitizeDeprecation: checkSanitizeDeprecation
|
||||
checkSanitizeDeprecation: checkSanitizeDeprecation,
|
||||
repeatString: repeatString
|
||||
};
|
||||
|
||||
var defaults$1 = defaults.defaults;
|
||||
@@ -620,7 +638,7 @@
|
||||
// so it is seen as the next token.
|
||||
|
||||
space = item.length;
|
||||
item = item.replace(/^ *([*+-]|\d+[.)]) */, ''); // Outdent whatever the
|
||||
item = item.replace(/^ *([*+-]|\d+[.)]) ?/, ''); // Outdent whatever the
|
||||
// list item contains. Hacky.
|
||||
|
||||
if (~item.indexOf('\n ')) {
|
||||
@@ -1138,11 +1156,11 @@
|
||||
|
||||
block.gfm = merge$1({}, block.normal, {
|
||||
nptable: '^ *([^|\\n ].*\\|.*)\\n' // Header
|
||||
+ ' *([-:]+ *\\|[-| :]*)' // Align
|
||||
+ ' {0,3}([-:]+ *\\|[-| :]*)' // Align
|
||||
+ '(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)',
|
||||
// Cells
|
||||
table: '^ *\\|(.+)\\n' // Header
|
||||
+ ' *\\|?( *[-:]+[-| :]*)' // Align
|
||||
+ ' {0,3}\\|?( *[-:]+[-| :]*)' // Align
|
||||
+ '(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
|
||||
|
||||
});
|
||||
@@ -1187,24 +1205,24 @@
|
||||
start: /^(?:(\*\*(?=[*punctuation]))|\*\*)(?![\s])|__/,
|
||||
// (1) returns if starts w/ punctuation
|
||||
middle: /^\*\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*\*$|^__(?![\s])((?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?)__$/,
|
||||
endAst: /[^punctuation\s]\*\*(?!\*)|[punctuation]\*\*(?!\*)(?:(?=[punctuation\s]|$))/,
|
||||
endAst: /[^punctuation\s]\*\*(?!\*)|[punctuation]\*\*(?!\*)(?:(?=[punctuation_\s]|$))/,
|
||||
// last char can't be punct, or final * must also be followed by punct (or endline)
|
||||
endUnd: /[^\s]__(?!_)(?:(?=[punctuation\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
|
||||
endUnd: /[^\s]__(?!_)(?:(?=[punctuation*\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
|
||||
|
||||
},
|
||||
em: {
|
||||
start: /^(?:(\*(?=[punctuation]))|\*)(?![*\s])|_/,
|
||||
// (1) returns if starts w/ punctuation
|
||||
middle: /^\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*$|^_(?![_\s])(?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?_$/,
|
||||
endAst: /[^punctuation\s]\*(?!\*)|[punctuation]\*(?!\*)(?:(?=[punctuation\s]|$))/,
|
||||
endAst: /[^punctuation\s]\*(?!\*)|[punctuation]\*(?!\*)(?:(?=[punctuation_\s]|$))/,
|
||||
// last char can't be punct, or final * must also be followed by punct (or endline)
|
||||
endUnd: /[^\s]_(?!_)(?:(?=[punctuation\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
|
||||
endUnd: /[^\s]_(?!_)(?:(?=[punctuation*\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
|
||||
|
||||
},
|
||||
code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
|
||||
br: /^( {2,}|\\)\n(?!\s*$)/,
|
||||
del: noopTest$1,
|
||||
text: /^(`+|[^`])(?:[\s\S]*?(?:(?=[\\<!\[`*]|\b_|$)|[^ ](?= {2,}\n))|(?= {2,}\n))/,
|
||||
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*]|\b_|$)|[^ ](?= {2,}\n)))/,
|
||||
punctuation: /^([\s*punctuation])/
|
||||
}; // list of punctuation marks from common mark spec
|
||||
// without * and _ to workaround cases with double emphasis
|
||||
@@ -1220,7 +1238,7 @@
|
||||
inline.em.endAst = edit$1(inline.em.endAst, 'g').replace(/punctuation/g, inline._punctuation).getRegex();
|
||||
inline.em.endUnd = edit$1(inline.em.endUnd, 'g').replace(/punctuation/g, inline._punctuation).getRegex();
|
||||
inline.strong.start = edit$1(inline.strong.start).replace(/punctuation/g, inline._punctuation).getRegex();
|
||||
inline.strong.middle = edit$1(inline.strong.middle).replace(/punctuation/g, inline._punctuation).replace(/blockSkip/g, inline._blockSkip).getRegex();
|
||||
inline.strong.middle = edit$1(inline.strong.middle).replace(/punctuation/g, inline._punctuation).replace(/overlapSkip/g, inline._overlapSkip).getRegex();
|
||||
inline.strong.endAst = edit$1(inline.strong.endAst, 'g').replace(/punctuation/g, inline._punctuation).getRegex();
|
||||
inline.strong.endUnd = edit$1(inline.strong.endUnd, 'g').replace(/punctuation/g, inline._punctuation).getRegex();
|
||||
inline.blockSkip = edit$1(inline._blockSkip, 'g').getRegex();
|
||||
@@ -1272,7 +1290,7 @@
|
||||
url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
|
||||
_backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
|
||||
del: /^~+(?=\S)([\s\S]*?\S)~+/,
|
||||
text: /^(`+|[^`])(?:[\s\S]*?(?:(?=[\\<!\[`*~]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?= {2,}\n|[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/
|
||||
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/
|
||||
});
|
||||
inline.gfm.url = edit$1(inline.gfm.url, 'i').replace('email', inline.gfm._extended_email).getRegex();
|
||||
/**
|
||||
@@ -1291,6 +1309,7 @@
|
||||
var defaults$2 = defaults.defaults;
|
||||
var block$1 = rules.block,
|
||||
inline$1 = rules.inline;
|
||||
var repeatString$1 = helpers.repeatString;
|
||||
/**
|
||||
* smartypants text replacement
|
||||
*/
|
||||
@@ -1373,6 +1392,15 @@
|
||||
var lexer = new Lexer(options);
|
||||
return lexer.lex(src);
|
||||
}
|
||||
/**
|
||||
* Static Lex Inline Method
|
||||
*/
|
||||
;
|
||||
|
||||
Lexer.lexInline = function lexInline(src, options) {
|
||||
var lexer = new Lexer(options);
|
||||
return lexer.inlineTokens(src);
|
||||
}
|
||||
/**
|
||||
* Preprocessing
|
||||
*/
|
||||
@@ -1652,7 +1680,7 @@
|
||||
if (links.length > 0) {
|
||||
while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
|
||||
if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
|
||||
maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
|
||||
maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString$1('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1660,7 +1688,7 @@
|
||||
|
||||
|
||||
while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
|
||||
maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
|
||||
maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString$1('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
|
||||
}
|
||||
|
||||
while (src) {
|
||||
@@ -2073,6 +2101,15 @@
|
||||
var parser = new Parser(options);
|
||||
return parser.parse(tokens);
|
||||
}
|
||||
/**
|
||||
* Static Parse Inline Method
|
||||
*/
|
||||
;
|
||||
|
||||
Parser.parseInline = function parseInline(tokens, options) {
|
||||
var parser = new Parser(options);
|
||||
return parser.parseInline(tokens);
|
||||
}
|
||||
/**
|
||||
* Parse Loop
|
||||
*/
|
||||
@@ -2606,6 +2643,42 @@
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Parse Inline
|
||||
*/
|
||||
|
||||
|
||||
marked.parseInline = function (src, opt) {
|
||||
// throw error in case of non string input
|
||||
if (typeof src === 'undefined' || src === null) {
|
||||
throw new Error('marked.parseInline(): input parameter is undefined or null');
|
||||
}
|
||||
|
||||
if (typeof src !== 'string') {
|
||||
throw new Error('marked.parseInline(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected');
|
||||
}
|
||||
|
||||
opt = merge$2({}, marked.defaults, opt || {});
|
||||
checkSanitizeDeprecation$1(opt);
|
||||
|
||||
try {
|
||||
var tokens = Lexer_1.lexInline(src, opt);
|
||||
|
||||
if (opt.walkTokens) {
|
||||
marked.walkTokens(tokens, opt.walkTokens);
|
||||
}
|
||||
|
||||
return Parser_1.parseInline(tokens, opt);
|
||||
} catch (e) {
|
||||
e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
||||
|
||||
if (opt.silent) {
|
||||
return '<p>An error occurred:</p><pre>' + escape$2(e.message + '', true) + '</pre>';
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@@ -161,7 +161,7 @@ function guessMimeTypeByPath(path: string, filename: string, associations: IText
|
||||
let extensionMatch: ITextMimeAssociationItem | null = null;
|
||||
|
||||
// We want to prioritize associations based on the order they are registered so that the last registered
|
||||
// association wins over all other. This is for https://github.com/Microsoft/vscode/issues/20074
|
||||
// association wins over all other. This is for https://github.com/microsoft/vscode/issues/20074
|
||||
for (let i = associations.length - 1; i >= 0; i--) {
|
||||
const association = associations[i];
|
||||
|
||||
@@ -217,7 +217,7 @@ function guessMimeTypeByFirstline(firstLine: string): string | null {
|
||||
if (firstLine.length > 0) {
|
||||
|
||||
// We want to prioritize associations based on the order they are registered so that the last registered
|
||||
// association wins over all other. This is for https://github.com/Microsoft/vscode/issues/20074
|
||||
// association wins over all other. This is for https://github.com/microsoft/vscode/issues/20074
|
||||
for (let i = registeredAssociations.length - 1; i >= 0; i--) {
|
||||
const association = registeredAssociations[i];
|
||||
if (!association.firstline) {
|
||||
|
||||
@@ -78,6 +78,12 @@ export namespace Schemas {
|
||||
* Scheme used for extension pages
|
||||
*/
|
||||
export const extension = 'extension';
|
||||
|
||||
/**
|
||||
* Scheme used as a replacement of `file` scheme to load
|
||||
* files with our custom protocol handler (desktop only).
|
||||
*/
|
||||
export const vscodeFileResource = 'vscode-file';
|
||||
}
|
||||
|
||||
class RemoteAuthoritiesImpl {
|
||||
@@ -129,3 +135,91 @@ class RemoteAuthoritiesImpl {
|
||||
}
|
||||
|
||||
export const RemoteAuthorities = new RemoteAuthoritiesImpl();
|
||||
|
||||
class FileAccessImpl {
|
||||
|
||||
private readonly FALLBACK_AUTHORITY = 'vscode-app';
|
||||
|
||||
/**
|
||||
* Returns a URI to use in contexts where the browser is responsible
|
||||
* for loading (e.g. fetch()) or when used within the DOM.
|
||||
*
|
||||
* **Note:** use `dom.ts#asCSSUrl` whenever the URL is to be used in CSS context.
|
||||
*/
|
||||
asBrowserUri(uri: URI): URI;
|
||||
asBrowserUri(moduleId: string, moduleIdToUrl: { toUrl(moduleId: string): string }): URI;
|
||||
asBrowserUri(uriOrModule: URI | string, moduleIdToUrl?: { toUrl(moduleId: string): string }): URI {
|
||||
const uri = this.toUri(uriOrModule, moduleIdToUrl);
|
||||
|
||||
// Handle remote URIs via `RemoteAuthorities`
|
||||
if (uri.scheme === Schemas.vscodeRemote) {
|
||||
return RemoteAuthorities.rewrite(uri);
|
||||
}
|
||||
|
||||
// Only convert the URI if we are in a native context and it has `file:` scheme
|
||||
if (platform.isElectronSandboxed && platform.isNative && uri.scheme === Schemas.file) {
|
||||
return this.toCodeFileUri(uri);
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO@bpasero remove me eventually when vscode-file is adopted everywhere
|
||||
*/
|
||||
_asCodeFileUri(uri: URI): URI;
|
||||
_asCodeFileUri(moduleId: string, moduleIdToUrl: { toUrl(moduleId: string): string }): URI;
|
||||
_asCodeFileUri(uriOrModule: URI | string, moduleIdToUrl?: { toUrl(moduleId: string): string }): URI {
|
||||
const uri = this.toUri(uriOrModule, moduleIdToUrl);
|
||||
|
||||
return this.toCodeFileUri(uri);
|
||||
}
|
||||
|
||||
private toCodeFileUri(uri: URI): URI {
|
||||
return uri.with({
|
||||
scheme: Schemas.vscodeFileResource,
|
||||
// We need to provide an authority here so that it can serve
|
||||
// as origin for network and loading matters in chromium.
|
||||
// If the URI is not coming with an authority already, we
|
||||
// add our own
|
||||
authority: uri.authority || this.FALLBACK_AUTHORITY,
|
||||
query: null,
|
||||
fragment: null
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `file` URI to use in contexts where node.js
|
||||
* is responsible for loading.
|
||||
*/
|
||||
asFileUri(uri: URI): URI;
|
||||
asFileUri(moduleId: string, moduleIdToUrl: { toUrl(moduleId: string): string }): URI;
|
||||
asFileUri(uriOrModule: URI | string, moduleIdToUrl?: { toUrl(moduleId: string): string }): URI {
|
||||
const uri = this.toUri(uriOrModule, moduleIdToUrl);
|
||||
|
||||
// Only convert the URI if it is `vscode-file:` scheme
|
||||
if (uri.scheme === Schemas.vscodeFileResource) {
|
||||
return uri.with({
|
||||
scheme: Schemas.file,
|
||||
// Only preserve the `authority` if it is different from
|
||||
// our fallback authority. This ensures we properly preserve
|
||||
// Windows UNC paths that come with their own authority.
|
||||
authority: uri.authority !== this.FALLBACK_AUTHORITY ? uri.authority : null,
|
||||
query: null,
|
||||
fragment: null
|
||||
});
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
private toUri(uriOrModule: URI | string, moduleIdToUrl?: { toUrl(moduleId: string): string }): URI {
|
||||
if (URI.isUri(uriOrModule)) {
|
||||
return uriOrModule;
|
||||
}
|
||||
|
||||
return URI.parse(moduleIdToUrl!.toUrl(uriOrModule));
|
||||
}
|
||||
}
|
||||
|
||||
export const FileAccess = new FileAccessImpl();
|
||||
|
||||
@@ -10,7 +10,7 @@ export function deepClone<T>(obj: T): T {
|
||||
return obj;
|
||||
}
|
||||
if (obj instanceof RegExp) {
|
||||
// See https://github.com/Microsoft/TypeScript/issues/10990
|
||||
// See https://github.com/microsoft/TypeScript/issues/10990
|
||||
return obj as any;
|
||||
}
|
||||
const result: any = Array.isArray(obj) ? [] : {};
|
||||
@@ -232,3 +232,9 @@ export function distinct(base: obj, target: obj): obj {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getCaseInsensitive(target: obj, key: string): any {
|
||||
const lowercaseKey = key.toLowerCase();
|
||||
const equivalentKey = Object.keys(target).find(k => k.toLowerCase() === lowercaseKey);
|
||||
return equivalentKey ? target[equivalentKey] : target[key];
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ function _factory(sharedObj) {
|
||||
sharedObj.MonacoPerformanceMarks = sharedObj.MonacoPerformanceMarks || [];
|
||||
|
||||
const _dataLen = 2;
|
||||
const _timeStamp = typeof console.timeStamp === 'function' ? console.timeStamp.bind(console) : () => { };
|
||||
const _nativeMark = typeof performance === 'object' && typeof performance.mark === 'function' ? performance.mark.bind(performance) : () => { };
|
||||
|
||||
function importEntries(entries) {
|
||||
sharedObj.MonacoPerformanceMarks.splice(0, 0, ...entries);
|
||||
@@ -55,7 +55,7 @@ function _factory(sharedObj) {
|
||||
|
||||
function mark(name) {
|
||||
sharedObj.MonacoPerformanceMarks.push(name, Date.now());
|
||||
_timeStamp(name);
|
||||
_nativeMark(name);
|
||||
}
|
||||
|
||||
const exports = {
|
||||
|
||||
@@ -26,15 +26,16 @@ export interface IProcessEnvironment {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
interface INodeProcess {
|
||||
platform: string;
|
||||
export interface INodeProcess {
|
||||
platform: 'win32' | 'linux' | 'darwin';
|
||||
env: IProcessEnvironment;
|
||||
getuid(): number;
|
||||
nextTick: Function;
|
||||
versions?: {
|
||||
electron?: string;
|
||||
};
|
||||
sandboxed?: boolean; // Electron
|
||||
type?: string;
|
||||
cwd(): string;
|
||||
}
|
||||
declare const process: INodeProcess;
|
||||
declare const global: any;
|
||||
@@ -47,9 +48,21 @@ interface INavigator {
|
||||
declare const navigator: INavigator;
|
||||
declare const self: any;
|
||||
|
||||
const isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer');
|
||||
const _globals = (typeof self === 'object' ? self : typeof global === 'object' ? global : {} as any);
|
||||
|
||||
// OS detection
|
||||
let nodeProcess: INodeProcess | undefined = undefined;
|
||||
if (typeof process !== 'undefined') {
|
||||
// Native environment (non-sandboxed)
|
||||
nodeProcess = process;
|
||||
} else if (typeof _globals.vscode !== 'undefined') {
|
||||
// Native environment (sandboxed)
|
||||
nodeProcess = _globals.vscode.process;
|
||||
}
|
||||
|
||||
const isElectronRenderer = typeof nodeProcess?.versions?.electron === 'string' && nodeProcess.type === 'renderer';
|
||||
export const isElectronSandboxed = isElectronRenderer && nodeProcess?.sandboxed;
|
||||
|
||||
// Web environment
|
||||
if (typeof navigator === 'object' && !isElectronRenderer) {
|
||||
_userAgent = navigator.userAgent;
|
||||
_isWindows = _userAgent.indexOf('Windows') >= 0;
|
||||
@@ -59,13 +72,16 @@ if (typeof navigator === 'object' && !isElectronRenderer) {
|
||||
_isWeb = true;
|
||||
_locale = navigator.language;
|
||||
_language = _locale;
|
||||
} else if (typeof process === 'object') {
|
||||
_isWindows = (process.platform === 'win32');
|
||||
_isMacintosh = (process.platform === 'darwin');
|
||||
_isLinux = (process.platform === 'linux');
|
||||
}
|
||||
|
||||
// Native environment
|
||||
else if (typeof nodeProcess === 'object') {
|
||||
_isWindows = (nodeProcess.platform === 'win32');
|
||||
_isMacintosh = (nodeProcess.platform === 'darwin');
|
||||
_isLinux = (nodeProcess.platform === 'linux');
|
||||
_locale = LANGUAGE_DEFAULT;
|
||||
_language = LANGUAGE_DEFAULT;
|
||||
const rawNlsConfig = process.env['VSCODE_NLS_CONFIG'];
|
||||
const rawNlsConfig = nodeProcess.env['VSCODE_NLS_CONFIG'];
|
||||
if (rawNlsConfig) {
|
||||
try {
|
||||
const nlsConfig: NLSConfig = JSON.parse(rawNlsConfig);
|
||||
@@ -80,6 +96,11 @@ if (typeof navigator === 'object' && !isElectronRenderer) {
|
||||
_isNative = true;
|
||||
}
|
||||
|
||||
// Unknown environment
|
||||
else {
|
||||
console.error('Unable to resolve platform.');
|
||||
}
|
||||
|
||||
export const enum Platform {
|
||||
Web,
|
||||
Mac,
|
||||
@@ -113,10 +134,6 @@ export const isIOS = _isIOS;
|
||||
export const platform = _platform;
|
||||
export const userAgent = _userAgent;
|
||||
|
||||
export function isRootUser(): boolean {
|
||||
return _isNative && !_isWindows && (process.getuid() === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* The language used for the user interface. The format of
|
||||
* the string is all lower case (e.g. zh-tw for Traditional
|
||||
@@ -157,7 +174,6 @@ export const locale = _locale;
|
||||
*/
|
||||
export const translationsConfigFile = _translationsConfigFile;
|
||||
|
||||
const _globals = (typeof self === 'object' ? self : typeof global === 'object' ? global : {} as any);
|
||||
export const globals: any = _globals;
|
||||
|
||||
interface ISetImmediate {
|
||||
@@ -196,8 +212,8 @@ export const setImmediate: ISetImmediate = (function defineSetImmediate() {
|
||||
globals.postMessage({ vscodeSetImmediateId: myId }, '*');
|
||||
};
|
||||
}
|
||||
if (typeof process !== 'undefined' && typeof process.nextTick === 'function') {
|
||||
return process.nextTick.bind(process);
|
||||
if (nodeProcess) {
|
||||
return nodeProcess.nextTick.bind(nodeProcess);
|
||||
}
|
||||
const _promise = Promise.resolve();
|
||||
return (callback: (...args: any[]) => void) => _promise.then(callback);
|
||||
|
||||
@@ -3,23 +3,44 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { isWindows, isMacintosh, setImmediate, IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { isWindows, isMacintosh, setImmediate, globals, INodeProcess } from 'vs/base/common/platform';
|
||||
|
||||
interface IProcess {
|
||||
platform: string;
|
||||
env: IProcessEnvironment;
|
||||
declare const process: INodeProcess;
|
||||
|
||||
cwd(): string;
|
||||
nextTick(callback: (...args: any[]) => void): void;
|
||||
let safeProcess: INodeProcess;
|
||||
|
||||
// Native node.js environment
|
||||
if (typeof process !== 'undefined') {
|
||||
safeProcess = process;
|
||||
}
|
||||
|
||||
declare const process: IProcess;
|
||||
const safeProcess: IProcess = (typeof process === 'undefined') ? {
|
||||
cwd(): string { return '/'; },
|
||||
env: Object.create(null),
|
||||
get platform(): string { return isWindows ? 'win32' : isMacintosh ? 'darwin' : 'linux'; },
|
||||
nextTick(callback: (...args: any[]) => void): void { return setImmediate(callback); }
|
||||
} : process;
|
||||
// Native sandbox environment
|
||||
else if (typeof globals.vscode !== 'undefined') {
|
||||
safeProcess = {
|
||||
|
||||
// Supported
|
||||
get platform(): 'win32' | 'linux' | 'darwin' { return globals.vscode.process.platform; },
|
||||
get env() { return globals.vscode.process.env; },
|
||||
nextTick(callback: (...args: any[]) => void): void { return setImmediate(callback); },
|
||||
|
||||
// Unsupported
|
||||
cwd(): string { return globals.vscode.process.env['VSCODE_CWD'] || globals.vscode.process.execPath.substr(0, globals.vscode.process.execPath.lastIndexOf(globals.vscode.process.platform === 'win32' ? '\\' : '/')); }
|
||||
};
|
||||
}
|
||||
|
||||
// Web environment
|
||||
else {
|
||||
safeProcess = {
|
||||
|
||||
// Supported
|
||||
get platform(): 'win32' | 'linux' | 'darwin' { return isWindows ? 'win32' : isMacintosh ? 'darwin' : 'linux'; },
|
||||
nextTick(callback: (...args: any[]) => void): void { return setImmediate(callback); },
|
||||
|
||||
// Unsupported
|
||||
get env() { return Object.create(null); },
|
||||
cwd(): string { return '/'; }
|
||||
};
|
||||
}
|
||||
|
||||
export const cwd = safeProcess.cwd;
|
||||
export const env = safeProcess.env;
|
||||
|
||||
@@ -110,7 +110,8 @@ export function sanitizeProcessEnvironment(env: IProcessEnvironment, ...preserve
|
||||
/^ELECTRON_.+$/,
|
||||
/^GOOGLE_API_KEY$/,
|
||||
/^VSCODE_.+$/,
|
||||
/^SNAP(|_.*)$/
|
||||
/^SNAP(|_.*)$/,
|
||||
/^GDK_PIXBUF_.+$/,
|
||||
];
|
||||
const envKeys = Object.keys(env);
|
||||
envKeys
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import * as paths from 'vs/base/common/path';
|
||||
import { relativePath, joinPath } from 'vs/base/common/resources';
|
||||
import { IExtUri, extUri as defaultExtUri } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { PathIterator } from 'vs/base/common/map';
|
||||
|
||||
@@ -95,12 +95,12 @@ export class ResourceTree<T extends NonNullable<any>, C> {
|
||||
return obj instanceof Node;
|
||||
}
|
||||
|
||||
constructor(context: C, rootURI: URI = URI.file('/')) {
|
||||
constructor(context: C, rootURI: URI = URI.file('/'), private extUri: IExtUri = defaultExtUri) {
|
||||
this.root = new Node(rootURI, '', context);
|
||||
}
|
||||
|
||||
add(uri: URI, element: T): void {
|
||||
const key = relativePath(this.root.uri, uri) || uri.fsPath;
|
||||
const key = this.extUri.relativePath(this.root.uri, uri) || uri.path;
|
||||
const iterator = new PathIterator(false).reset(key);
|
||||
let node = this.root;
|
||||
let path = '';
|
||||
@@ -113,7 +113,7 @@ export class ResourceTree<T extends NonNullable<any>, C> {
|
||||
|
||||
if (!child) {
|
||||
child = new Node(
|
||||
joinPath(this.root.uri, path),
|
||||
this.extUri.joinPath(this.root.uri, path),
|
||||
path,
|
||||
this.root.context,
|
||||
iterator.hasNext() ? undefined : element,
|
||||
@@ -136,7 +136,7 @@ export class ResourceTree<T extends NonNullable<any>, C> {
|
||||
}
|
||||
|
||||
delete(uri: URI): T | undefined {
|
||||
const key = relativePath(this.root.uri, uri) || uri.fsPath;
|
||||
const key = this.extUri.relativePath(this.root.uri, uri) || uri.path;
|
||||
const iterator = new PathIterator(false).reset(key);
|
||||
return this._delete(this.root, iterator);
|
||||
}
|
||||
@@ -168,7 +168,7 @@ export class ResourceTree<T extends NonNullable<any>, C> {
|
||||
}
|
||||
|
||||
getNode(uri: URI): IResourceNode<T, C> | undefined {
|
||||
const key = relativePath(this.root.uri, uri) || uri.fsPath;
|
||||
const key = this.extUri.relativePath(this.root.uri, uri) || uri.path;
|
||||
const iterator = new PathIterator(false).reset(key);
|
||||
let node = this.root;
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ import { equalsIgnoreCase, compare as strCompare } from 'vs/base/common/strings'
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { isWindows, isLinux } from 'vs/base/common/platform';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { ParsedExpression, IExpression, parse } from 'vs/base/common/glob';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
|
||||
export function originalFSPath(uri: URI): string {
|
||||
return uriToFsPath(uri, true);
|
||||
@@ -58,6 +56,11 @@ export interface IExtUri {
|
||||
*/
|
||||
getComparisonKey(uri: URI, ignoreFragment?: boolean): string;
|
||||
|
||||
/**
|
||||
* Whether the casing of the path-component of the uri should be ignored.
|
||||
*/
|
||||
ignorePathCasing(uri: URI): boolean;
|
||||
|
||||
// --- path math
|
||||
|
||||
basenameOrAuthority(resource: URI): string;
|
||||
@@ -161,6 +164,10 @@ export class ExtUri implements IExtUri {
|
||||
}).toString();
|
||||
}
|
||||
|
||||
ignorePathCasing(uri: URI): boolean {
|
||||
return this._ignorePathCasing(uri);
|
||||
}
|
||||
|
||||
isEqualOrParent(base: URI, parentCandidate: URI, ignoreFragment: boolean = false): boolean {
|
||||
if (base.scheme === parentCandidate.scheme) {
|
||||
if (base.scheme === Schemas.file) {
|
||||
@@ -427,33 +434,6 @@ export namespace DataUri {
|
||||
}
|
||||
}
|
||||
|
||||
export class ResourceGlobMatcher {
|
||||
|
||||
private readonly globalExpression: ParsedExpression;
|
||||
private readonly expressionsByRoot: TernarySearchTree<URI, { root: URI, expression: ParsedExpression }> = TernarySearchTree.forUris<{ root: URI, expression: ParsedExpression }>();
|
||||
|
||||
constructor(
|
||||
globalExpression: IExpression,
|
||||
rootExpressions: { root: URI, expression: IExpression }[]
|
||||
) {
|
||||
this.globalExpression = parse(globalExpression);
|
||||
for (const expression of rootExpressions) {
|
||||
this.expressionsByRoot.set(expression.root, { root: expression.root, expression: parse(expression.expression) });
|
||||
}
|
||||
}
|
||||
|
||||
matches(resource: URI): boolean {
|
||||
const rootExpression = this.expressionsByRoot.findSubstr(resource);
|
||||
if (rootExpression) {
|
||||
const path = relativePath(rootExpression.root, resource);
|
||||
if (path && !!rootExpression.expression(path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return !!this.globalExpression(resource.path);
|
||||
}
|
||||
}
|
||||
|
||||
export function toLocalResource(resource: URI, authority: string | undefined, localScheme: string): URI {
|
||||
if (authority) {
|
||||
let path = resource.path;
|
||||
|
||||
17
src/vs/base/common/semver/cgmanifest.json
Normal file
17
src/vs/base/common/semver/cgmanifest.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"registrations": [
|
||||
{
|
||||
"component": {
|
||||
"type": "git",
|
||||
"git": {
|
||||
"name": "semver",
|
||||
"repositoryUrl": "https://github.com/npm/node-semver",
|
||||
"commitHash": "44cbc8482ac4f0f8d2de0abb7f8808056d2d55f9"
|
||||
}
|
||||
},
|
||||
"license": "The ISC License",
|
||||
"version": "5.5.0"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
312
src/vs/base/common/semver/semver.d.ts
vendored
Normal file
312
src/vs/base/common/semver/semver.d.ts
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export as namespace semver;
|
||||
|
||||
export = semver;
|
||||
|
||||
declare namespace semver {
|
||||
|
||||
// Type definitions for semver 6.2
|
||||
// Project: https://github.com/npm/node-semver
|
||||
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
|
||||
// BendingBender <https://github.com/BendingBender>
|
||||
// Lucian Buzzo <https://github.com/LucianBuzzo>
|
||||
// Klaus Meinhardt <https://github.com/ajafff>
|
||||
// ExE Boss <https://github.com/ExE-Boss>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/semver
|
||||
|
||||
export const SEMVER_SPEC_VERSION: "2.0.0";
|
||||
|
||||
export type ReleaseType = "major" | "premajor" | "minor" | "preminor" | "patch" | "prepatch" | "prerelease";
|
||||
|
||||
export interface Options {
|
||||
loose?: boolean;
|
||||
includePrerelease?: boolean;
|
||||
}
|
||||
|
||||
export interface CoerceOptions extends Options {
|
||||
/**
|
||||
* Used by `coerce()` to coerce from right to left.
|
||||
*
|
||||
* @default false
|
||||
*
|
||||
* @example
|
||||
* coerce('1.2.3.4', { rtl: true });
|
||||
* // => SemVer { version: '2.3.4', ... }
|
||||
*
|
||||
* @since 6.2.0
|
||||
*/
|
||||
rtl?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parsed version as a SemVer object, or null if it's not valid.
|
||||
*/
|
||||
export function parse(version: string | SemVer | null | undefined, optionsOrLoose?: boolean | Options): SemVer | null;
|
||||
|
||||
/**
|
||||
* Return the parsed version as a string, or null if it's not valid.
|
||||
*/
|
||||
export function valid(version: string | SemVer | null | undefined, optionsOrLoose?: boolean | Options): string | null;
|
||||
|
||||
/**
|
||||
* Coerces a string to SemVer if possible
|
||||
*/
|
||||
export function coerce(version: string | number | SemVer | null | undefined, options?: CoerceOptions): SemVer | null;
|
||||
|
||||
/**
|
||||
* Returns cleaned (removed leading/trailing whitespace, remove '=v' prefix) and parsed version, or null if version is invalid.
|
||||
*/
|
||||
export function clean(version: string, optionsOrLoose?: boolean | Options): string | null;
|
||||
|
||||
/**
|
||||
* Return the version incremented by the release type (major, minor, patch, or prerelease), or null if it's not valid.
|
||||
*/
|
||||
export function inc(version: string | SemVer, release: ReleaseType, optionsOrLoose?: boolean | Options, identifier?: string): string | null;
|
||||
export function inc(version: string | SemVer, release: ReleaseType, identifier?: string): string | null;
|
||||
|
||||
/**
|
||||
* Return the major version number.
|
||||
*/
|
||||
export function major(version: string | SemVer, optionsOrLoose?: boolean | Options): number;
|
||||
|
||||
/**
|
||||
* Return the minor version number.
|
||||
*/
|
||||
export function minor(version: string | SemVer, optionsOrLoose?: boolean | Options): number;
|
||||
|
||||
/**
|
||||
* Return the patch version number.
|
||||
*/
|
||||
export function patch(version: string | SemVer, optionsOrLoose?: boolean | Options): number;
|
||||
|
||||
/**
|
||||
* Returns an array of prerelease components, or null if none exist.
|
||||
*/
|
||||
export function prerelease(version: string | SemVer, optionsOrLoose?: boolean | Options): ReadonlyArray<string> | null;
|
||||
|
||||
// Comparison
|
||||
/**
|
||||
* v1 > v2
|
||||
*/
|
||||
export function gt(v1: string | SemVer, v2: string | SemVer, optionsOrLoose?: boolean | Options): boolean;
|
||||
/**
|
||||
* v1 >= v2
|
||||
*/
|
||||
export function gte(v1: string | SemVer, v2: string | SemVer, optionsOrLoose?: boolean | Options): boolean;
|
||||
/**
|
||||
* v1 < v2
|
||||
*/
|
||||
export function lt(v1: string | SemVer, v2: string | SemVer, optionsOrLoose?: boolean | Options): boolean;
|
||||
/**
|
||||
* v1 <= v2
|
||||
*/
|
||||
export function lte(v1: string | SemVer, v2: string | SemVer, optionsOrLoose?: boolean | Options): boolean;
|
||||
/**
|
||||
* v1 == v2 This is true if they're logically equivalent, even if they're not the exact same string. You already know how to compare strings.
|
||||
*/
|
||||
export function eq(v1: string | SemVer, v2: string | SemVer, optionsOrLoose?: boolean | Options): boolean;
|
||||
/**
|
||||
* v1 != v2 The opposite of eq.
|
||||
*/
|
||||
export function neq(v1: string | SemVer, v2: string | SemVer, optionsOrLoose?: boolean | Options): boolean;
|
||||
|
||||
/**
|
||||
* Pass in a comparison string, and it'll call the corresponding semver comparison function.
|
||||
* "===" and "!==" do simple string comparison, but are included for completeness.
|
||||
* Throws if an invalid comparison string is provided.
|
||||
*/
|
||||
export function cmp(v1: string | SemVer, operator: Operator, v2: string | SemVer, optionsOrLoose?: boolean | Options): boolean;
|
||||
export type Operator = '===' | '!==' | '' | '=' | '==' | '!=' | '>' | '>=' | '<' | '<=';
|
||||
|
||||
/**
|
||||
* Compares two versions excluding build identifiers (the bit after `+` in the semantic version string).
|
||||
*
|
||||
* Sorts in ascending order when passed to `Array.sort()`.
|
||||
*
|
||||
* @return
|
||||
* - `0` if `v1` == `v2`
|
||||
* - `1` if `v1` is greater
|
||||
* - `-1` if `v2` is greater.
|
||||
*/
|
||||
export function compare(v1: string | SemVer, v2: string | SemVer, optionsOrLoose?: boolean | Options): 1 | 0 | -1;
|
||||
/**
|
||||
* The reverse of compare.
|
||||
*
|
||||
* Sorts in descending order when passed to `Array.sort()`.
|
||||
*/
|
||||
export function rcompare(v1: string | SemVer, v2: string | SemVer, optionsOrLoose?: boolean | Options): 1 | 0 | -1;
|
||||
|
||||
/**
|
||||
* Compares two identifiers, must be numeric strings or truthy/falsy values.
|
||||
*
|
||||
* Sorts in ascending order when passed to `Array.sort()`.
|
||||
*/
|
||||
export function compareIdentifiers(a: string | null | undefined, b: string | null | undefined): 1 | 0 | -1;
|
||||
/**
|
||||
* The reverse of compareIdentifiers.
|
||||
*
|
||||
* Sorts in descending order when passed to `Array.sort()`.
|
||||
*/
|
||||
export function rcompareIdentifiers(a: string | null | undefined, b: string | null | undefined): 1 | 0 | -1;
|
||||
|
||||
/**
|
||||
* Compares two versions including build identifiers (the bit after `+` in the semantic version string).
|
||||
*
|
||||
* Sorts in ascending order when passed to `Array.sort()`.
|
||||
*
|
||||
* @return
|
||||
* - `0` if `v1` == `v2`
|
||||
* - `1` if `v1` is greater
|
||||
* - `-1` if `v2` is greater.
|
||||
*
|
||||
* @since 6.1.0
|
||||
*/
|
||||
export function compareBuild(a: string | SemVer, b: string | SemVer): 1 | 0 | -1;
|
||||
|
||||
/**
|
||||
* Sorts an array of semver entries in ascending order using `compareBuild()`.
|
||||
*/
|
||||
export function sort<T extends string | SemVer>(list: T[], optionsOrLoose?: boolean | Options): T[];
|
||||
/**
|
||||
* Sorts an array of semver entries in descending order using `compareBuild()`.
|
||||
*/
|
||||
export function rsort<T extends string | SemVer>(list: T[], optionsOrLoose?: boolean | Options): T[];
|
||||
|
||||
/**
|
||||
* Returns difference between two versions by the release type (major, premajor, minor, preminor, patch, prepatch, or prerelease), or null if the versions are the same.
|
||||
*/
|
||||
export function diff(v1: string | SemVer, v2: string | SemVer, optionsOrLoose?: boolean | Options): ReleaseType | null;
|
||||
|
||||
// Ranges
|
||||
/**
|
||||
* Return the valid range or null if it's not valid
|
||||
*/
|
||||
export function validRange(range: string | Range | null | undefined, optionsOrLoose?: boolean | Options): string;
|
||||
/**
|
||||
* Return true if the version satisfies the range.
|
||||
*/
|
||||
export function satisfies(version: string | SemVer, range: string | Range, optionsOrLoose?: boolean | Options): boolean;
|
||||
/**
|
||||
* Return the highest version in the list that satisfies the range, or null if none of them do.
|
||||
*/
|
||||
export function maxSatisfying<T extends string | SemVer>(versions: ReadonlyArray<T>, range: string | Range, optionsOrLoose?: boolean | Options): T | null;
|
||||
/**
|
||||
* Return the lowest version in the list that satisfies the range, or null if none of them do.
|
||||
*/
|
||||
export function minSatisfying<T extends string | SemVer>(versions: ReadonlyArray<T>, range: string | Range, optionsOrLoose?: boolean | Options): T | null;
|
||||
/**
|
||||
* Return the lowest version that can possibly match the given range.
|
||||
*/
|
||||
export function minVersion(range: string | Range, optionsOrLoose?: boolean | Options): SemVer | null;
|
||||
/**
|
||||
* Return true if version is greater than all the versions possible in the range.
|
||||
*/
|
||||
export function gtr(version: string | SemVer, range: string | Range, optionsOrLoose?: boolean | Options): boolean;
|
||||
/**
|
||||
* Return true if version is less than all the versions possible in the range.
|
||||
*/
|
||||
export function ltr(version: string | SemVer, range: string | Range, optionsOrLoose?: boolean | Options): boolean;
|
||||
/**
|
||||
* Return true if the version is outside the bounds of the range in either the high or low direction.
|
||||
* The hilo argument must be either the string '>' or '<'. (This is the function called by gtr and ltr.)
|
||||
*/
|
||||
export function outside(version: string | SemVer, range: string | Range, hilo: '>' | '<', optionsOrLoose?: boolean | Options): boolean;
|
||||
/**
|
||||
* Return true if any of the ranges comparators intersect
|
||||
*/
|
||||
export function intersects(range1: string | Range, range2: string | Range, optionsOrLoose?: boolean | Options): boolean;
|
||||
|
||||
export class SemVer {
|
||||
constructor(version: string | SemVer, optionsOrLoose?: boolean | Options);
|
||||
|
||||
raw: string;
|
||||
loose: boolean;
|
||||
options: Options;
|
||||
format(): string;
|
||||
inspect(): string;
|
||||
|
||||
major: number;
|
||||
minor: number;
|
||||
patch: number;
|
||||
version: string;
|
||||
build: ReadonlyArray<string>;
|
||||
prerelease: ReadonlyArray<string | number>;
|
||||
|
||||
/**
|
||||
* Compares two versions excluding build identifiers (the bit after `+` in the semantic version string).
|
||||
*
|
||||
* @return
|
||||
* - `0` if `this` == `other`
|
||||
* - `1` if `this` is greater
|
||||
* - `-1` if `other` is greater.
|
||||
*/
|
||||
compare(other: string | SemVer): 1 | 0 | -1;
|
||||
|
||||
/**
|
||||
* Compares the release portion of two versions.
|
||||
*
|
||||
* @return
|
||||
* - `0` if `this` == `other`
|
||||
* - `1` if `this` is greater
|
||||
* - `-1` if `other` is greater.
|
||||
*/
|
||||
compareMain(other: string | SemVer): 1 | 0 | -1;
|
||||
|
||||
/**
|
||||
* Compares the prerelease portion of two versions.
|
||||
*
|
||||
* @return
|
||||
* - `0` if `this` == `other`
|
||||
* - `1` if `this` is greater
|
||||
* - `-1` if `other` is greater.
|
||||
*/
|
||||
comparePre(other: string | SemVer): 1 | 0 | -1;
|
||||
|
||||
/**
|
||||
* Compares the build identifier of two versions.
|
||||
*
|
||||
* @return
|
||||
* - `0` if `this` == `other`
|
||||
* - `1` if `this` is greater
|
||||
* - `-1` if `other` is greater.
|
||||
*/
|
||||
compareBuild(other: string | SemVer): 1 | 0 | -1;
|
||||
|
||||
inc(release: ReleaseType, identifier?: string): SemVer;
|
||||
}
|
||||
|
||||
export class Comparator {
|
||||
constructor(comp: string | Comparator, optionsOrLoose?: boolean | Options);
|
||||
|
||||
semver: SemVer;
|
||||
operator: '' | '=' | '<' | '>' | '<=' | '>=';
|
||||
value: string;
|
||||
loose: boolean;
|
||||
options: Options;
|
||||
parse(comp: string): void;
|
||||
test(version: string | SemVer): boolean;
|
||||
intersects(comp: Comparator, optionsOrLoose?: boolean | Options): boolean;
|
||||
}
|
||||
|
||||
export class Range {
|
||||
constructor(range: string | Range, optionsOrLoose?: boolean | Options);
|
||||
|
||||
range: string;
|
||||
raw: string;
|
||||
loose: boolean;
|
||||
options: Options;
|
||||
includePrerelease: boolean;
|
||||
format(): string;
|
||||
inspect(): string;
|
||||
|
||||
set: ReadonlyArray<ReadonlyArray<Comparator>>;
|
||||
parseRange(range: string): ReadonlyArray<Comparator>;
|
||||
test(version: string | SemVer): boolean;
|
||||
intersects(range: Range, optionsOrLoose?: boolean | Options): boolean;
|
||||
}
|
||||
|
||||
}
|
||||
11
src/vs/base/common/semver/semver.js
Normal file
11
src/vs/base/common/semver/semver.js
Normal file
File diff suppressed because one or more lines are too long
@@ -13,20 +13,6 @@ export function isFalsyOrWhitespace(str: string | undefined): boolean {
|
||||
return str.trim().length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated ES6: use `String.padStart`
|
||||
*/
|
||||
export function pad(n: number, l: number, char: string = '0'): string {
|
||||
const str = '' + n;
|
||||
const r = [str];
|
||||
|
||||
for (let i = str.length; i < l; i++) {
|
||||
r.push(char);
|
||||
}
|
||||
|
||||
return r.reverse().join('');
|
||||
}
|
||||
|
||||
const _formatRegexp = /{(\d+)}/g;
|
||||
|
||||
/**
|
||||
@@ -69,6 +55,28 @@ export function escapeRegExpCharacters(value: string): string {
|
||||
return value.replace(/[\\\{\}\*\+\?\|\^\$\.\[\]\(\)]/g, '\\$&');
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts how often `character` occurs inside `value`.
|
||||
*/
|
||||
export function count(value: string, character: string): number {
|
||||
let result = 0;
|
||||
const ch = character.charCodeAt(0);
|
||||
for (let i = value.length - 1; i >= 0; i--) {
|
||||
if (value.charCodeAt(i) === ch) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function truncate(value: string, maxLength: number, suffix = '…'): string {
|
||||
if (value.length <= maxLength) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return `${value.substr(0, maxLength)}${suffix}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all occurrences of needle from the beginning and end of haystack.
|
||||
* @param haystack string to trim
|
||||
@@ -243,6 +251,10 @@ export function regExpFlags(regexp: RegExp): string {
|
||||
+ ((regexp as any /* standalone editor compilation */).unicode ? 'u' : '');
|
||||
}
|
||||
|
||||
export function splitLines(str: string): string[] {
|
||||
return str.split(/\r\n|\r|\n/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first index of the string that is not whitespace.
|
||||
* If string is empty or contains only whitespaces, returns -1
|
||||
@@ -855,6 +867,7 @@ export function stripUTF8BOM(str: string): string {
|
||||
return startsWithUTF8BOM(str) ? str.substr(1) : str;
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
/**
|
||||
* @deprecated ES6
|
||||
*/
|
||||
@@ -925,9 +938,15 @@ export function getNLines(str: string, n = 1): string {
|
||||
n--;
|
||||
} while (n > 0 && idx >= 0);
|
||||
|
||||
return idx >= 0 ?
|
||||
str.substr(0, idx) :
|
||||
str;
|
||||
if (idx === -1) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (str[idx - 1] === '\r') {
|
||||
idx--;
|
||||
}
|
||||
|
||||
return str.substr(0, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -345,7 +345,7 @@ export class URI implements UriComponents {
|
||||
*/
|
||||
static joinPath(uri: URI, ...pathFragment: string[]): URI {
|
||||
if (!uri.path) {
|
||||
throw new Error(`[UriError]: cannot call joinPaths on URI without path`);
|
||||
throw new Error(`[UriError]: cannot call joinPath on URI without path`);
|
||||
}
|
||||
let newPath: string;
|
||||
if (isWindows && uri.scheme === 'file') {
|
||||
|
||||
@@ -17,8 +17,9 @@ for (let i = 0; i < 256; i++) {
|
||||
_hex.push(i.toString(16).padStart(2, '0'));
|
||||
}
|
||||
|
||||
// todo@joh node nodejs use `crypto#randomBytes`, see: https://nodejs.org/docs/latest/api/crypto.html#crypto_crypto_randombytes_size_callback
|
||||
// todo@joh use browser-crypto
|
||||
// todo@jrieken
|
||||
// 1. node nodejs use`crypto#randomBytes`, see: https://nodejs.org/docs/latest/api/crypto.html#crypto_crypto_randombytes_size_callback
|
||||
// 2. use browser-crypto
|
||||
const _fillRandomValues = function (bucket: Uint8Array): Uint8Array {
|
||||
for (let i = 0; i < bucket.length; i++) {
|
||||
bucket[i] = Math.floor(Math.random() * 256);
|
||||
|
||||
@@ -31,7 +31,7 @@ export function logOnceWebWorkerWarning(err: any): void {
|
||||
}
|
||||
if (!webWorkerWarningLogged) {
|
||||
webWorkerWarningLogged = true;
|
||||
console.warn('Could not create web worker(s). Falling back to loading web worker code in main thread, which might cause UI freezes. Please see https://github.com/Microsoft/monaco-editor#faq');
|
||||
console.warn('Could not create web worker(s). Falling back to loading web worker code in main thread, which might cause UI freezes. Please see https://github.com/microsoft/monaco-editor#faq');
|
||||
}
|
||||
console.warn(err.message);
|
||||
}
|
||||
@@ -358,6 +358,10 @@ export class SimpleWorkerServer<H extends object> {
|
||||
delete loaderConfig.paths['vs'];
|
||||
}
|
||||
}
|
||||
if (typeof loaderConfig.trustedTypesPolicy !== undefined) {
|
||||
// don't use, it has been destroyed during serialize
|
||||
delete loaderConfig['trustedTypesPolicy'];
|
||||
}
|
||||
|
||||
// Since this is in a web worker, enable catching errors
|
||||
loaderConfig.catchError = true;
|
||||
|
||||
Reference in New Issue
Block a user