mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-02 01:25:39 -05:00
Merge vscode 1.67 (#20883)
* Fix initial build breaks from 1.67 merge (#2514) * Update yarn lock files * Update build scripts * Fix tsconfig * Build breaks * WIP * Update yarn lock files * Misc breaks * Updates to package.json * Breaks * Update yarn * Fix breaks * Breaks * Build breaks * Breaks * Breaks * Breaks * Breaks * Breaks * Missing file * Breaks * Breaks * Breaks * Breaks * Breaks * Fix several runtime breaks (#2515) * Missing files * Runtime breaks * Fix proxy ordering issue * Remove commented code * Fix breaks with opening query editor * Fix post merge break * Updates related to setup build and other breaks (#2516) * Fix bundle build issues * Update distro * Fix distro merge and update build JS files * Disable pipeline steps * Remove stats call * Update license name * Make new RPM dependencies a warning * Fix extension manager version checks * Update JS file * Fix a few runtime breaks * Fixes * Fix runtime issues * Fix build breaks * Update notebook tests (part 1) * Fix broken tests * Linting errors * Fix hygiene * Disable lint rules * Bump distro * Turn off smoke tests * Disable integration tests * Remove failing "activate" test * Remove failed test assertion * Disable other broken test * Disable query history tests * Disable extension unit tests * Disable failing tasks
This commit is contained in:
@@ -16,3 +16,10 @@ export function equals<T>(one: ReadonlyArray<T>, other: ReadonlyArray<T>, itemEq
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns New array with all falsy values removed. The original array IS NOT modified.
|
||||
*/
|
||||
export function coalesce<T>(array: ReadonlyArray<T | undefined | null>): T[] {
|
||||
return <T[]>array.filter(e => !!e);
|
||||
}
|
||||
|
||||
72
extensions/markdown-language-features/src/util/async.ts
Normal file
72
extensions/markdown-language-features/src/util/async.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from 'vscode';
|
||||
|
||||
export interface ITask<T> {
|
||||
(): T;
|
||||
}
|
||||
|
||||
export class Delayer<T> {
|
||||
|
||||
public defaultDelay: number;
|
||||
private timeout: any; // Timer
|
||||
private completionPromise: Promise<T | null> | null;
|
||||
private onSuccess: ((value: T | PromiseLike<T> | undefined) => void) | null;
|
||||
private task: ITask<T> | null;
|
||||
|
||||
constructor(defaultDelay: number) {
|
||||
this.defaultDelay = defaultDelay;
|
||||
this.timeout = null;
|
||||
this.completionPromise = null;
|
||||
this.onSuccess = null;
|
||||
this.task = null;
|
||||
}
|
||||
|
||||
public trigger(task: ITask<T>, delay: number = this.defaultDelay): Promise<T | null> {
|
||||
this.task = task;
|
||||
if (delay >= 0) {
|
||||
this.cancelTimeout();
|
||||
}
|
||||
|
||||
if (!this.completionPromise) {
|
||||
this.completionPromise = new Promise<T | undefined>((resolve) => {
|
||||
this.onSuccess = resolve;
|
||||
}).then(() => {
|
||||
this.completionPromise = null;
|
||||
this.onSuccess = null;
|
||||
const result = this.task && this.task();
|
||||
this.task = null;
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
if (delay >= 0 || this.timeout === null) {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.timeout = null;
|
||||
this.onSuccess?.(undefined);
|
||||
}, delay >= 0 ? delay : this.defaultDelay);
|
||||
}
|
||||
|
||||
return this.completionPromise;
|
||||
}
|
||||
|
||||
private cancelTimeout(): void {
|
||||
if (this.timeout !== null) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function setImmediate(callback: (...args: any[]) => void, ...args: any[]): Disposable {
|
||||
if (global.setImmediate) {
|
||||
const handle = global.setImmediate(callback, ...args);
|
||||
return { dispose: () => global.clearImmediate(handle) };
|
||||
} else {
|
||||
const handle = setTimeout(callback, 0, ...args);
|
||||
return { dispose: () => clearTimeout(handle) };
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,7 @@ import * as vscode from 'vscode';
|
||||
export function disposeAll(disposables: vscode.Disposable[]) {
|
||||
while (disposables.length) {
|
||||
const item = disposables.pop();
|
||||
if (item) {
|
||||
item.dispose();
|
||||
}
|
||||
item?.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,56 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Return a hash value for an object.
|
||||
*/
|
||||
export function hash(obj: any, hashVal = 0): number {
|
||||
switch (typeof obj) {
|
||||
case 'object':
|
||||
if (obj === null) {
|
||||
return numberHash(349, hashVal);
|
||||
} else if (Array.isArray(obj)) {
|
||||
return arrayHash(obj, hashVal);
|
||||
}
|
||||
return objectHash(obj, hashVal);
|
||||
case 'string':
|
||||
return stringHash(obj, hashVal);
|
||||
case 'boolean':
|
||||
return booleanHash(obj, hashVal);
|
||||
case 'number':
|
||||
return numberHash(obj, hashVal);
|
||||
case 'undefined':
|
||||
return 937 * 31;
|
||||
default:
|
||||
return numberHash(obj, 617);
|
||||
}
|
||||
}
|
||||
|
||||
function numberHash(val: number, initialHashVal: number): number {
|
||||
return (((initialHashVal << 5) - initialHashVal) + val) | 0; // hashVal * 31 + ch, keep as int32
|
||||
}
|
||||
|
||||
function booleanHash(b: boolean, initialHashVal: number): number {
|
||||
return numberHash(b ? 433 : 863, initialHashVal);
|
||||
}
|
||||
|
||||
function stringHash(s: string, hashVal: number) {
|
||||
hashVal = numberHash(149417, hashVal);
|
||||
export function stringHash(s: string) {
|
||||
let hashVal = numberHash(149417, 0);
|
||||
for (let i = 0, length = s.length; i < length; i++) {
|
||||
hashVal = numberHash(s.charCodeAt(i), hashVal);
|
||||
}
|
||||
return hashVal;
|
||||
}
|
||||
|
||||
function arrayHash(arr: any[], initialHashVal: number): number {
|
||||
initialHashVal = numberHash(104579, initialHashVal);
|
||||
return arr.reduce((hashVal, item) => hash(item, hashVal), initialHashVal);
|
||||
}
|
||||
|
||||
function objectHash(obj: any, initialHashVal: number): number {
|
||||
initialHashVal = numberHash(181387, initialHashVal);
|
||||
return Object.keys(obj).sort().reduce((hashVal, key) => {
|
||||
hashVal = stringHash(key, hashVal);
|
||||
return hash(obj[key], hashVal);
|
||||
}, initialHashVal);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import { SkinnyTextDocument, SkinnyTextLine } from '../workspaceContents';
|
||||
|
||||
export class InMemoryDocument implements SkinnyTextDocument {
|
||||
|
||||
private readonly _doc: TextDocument;
|
||||
|
||||
private lines: SkinnyTextLine[] | undefined;
|
||||
|
||||
constructor(
|
||||
public readonly uri: vscode.Uri, contents: string,
|
||||
public readonly version = 0,
|
||||
) {
|
||||
|
||||
this._doc = TextDocument.create(uri.toString(), 'markdown', version, contents);
|
||||
}
|
||||
|
||||
get lineCount(): number {
|
||||
return this._doc.lineCount;
|
||||
}
|
||||
|
||||
lineAt(index: any): SkinnyTextLine {
|
||||
if (!this.lines) {
|
||||
this.lines = this._doc.getText().split(/\r?\n/).map(text => ({
|
||||
text,
|
||||
get isEmptyOrWhitespace() { return /^\s*$/.test(text); }
|
||||
}));
|
||||
}
|
||||
return this.lines[index];
|
||||
}
|
||||
|
||||
positionAt(offset: number): vscode.Position {
|
||||
const pos = this._doc.positionAt(offset);
|
||||
return new vscode.Position(pos.line, pos.character);
|
||||
}
|
||||
|
||||
getText(range?: vscode.Range): string {
|
||||
return this._doc.getText(range);
|
||||
}
|
||||
}
|
||||
67
extensions/markdown-language-features/src/util/limiter.ts
Normal file
67
extensions/markdown-language-features/src/util/limiter.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
interface ILimitedTaskFactory<T> {
|
||||
factory: ITask<Promise<T>>;
|
||||
c: (value: T | Promise<T>) => void;
|
||||
e: (error?: unknown) => void;
|
||||
}
|
||||
|
||||
interface ITask<T> {
|
||||
(): T;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to queue N promises and run them all with a max degree of parallelism. The helper
|
||||
* ensures that at any time no more than M promises are running at the same time.
|
||||
*
|
||||
* Taken from 'src/vs/base/common/async.ts'
|
||||
*/
|
||||
export class Limiter<T> {
|
||||
|
||||
private _size = 0;
|
||||
private runningPromises: number;
|
||||
private readonly maxDegreeOfParalellism: number;
|
||||
private readonly outstandingPromises: ILimitedTaskFactory<T>[];
|
||||
|
||||
constructor(maxDegreeOfParalellism: number) {
|
||||
this.maxDegreeOfParalellism = maxDegreeOfParalellism;
|
||||
this.outstandingPromises = [];
|
||||
this.runningPromises = 0;
|
||||
}
|
||||
|
||||
get size(): number {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
queue(factory: ITask<Promise<T>>): Promise<T> {
|
||||
this._size++;
|
||||
|
||||
return new Promise<T>((c, e) => {
|
||||
this.outstandingPromises.push({ factory, c, e });
|
||||
this.consume();
|
||||
});
|
||||
}
|
||||
|
||||
private consume(): void {
|
||||
while (this.outstandingPromises.length && this.runningPromises < this.maxDegreeOfParalellism) {
|
||||
const iLimitedTask = this.outstandingPromises.shift()!;
|
||||
this.runningPromises++;
|
||||
|
||||
const promise = iLimitedTask.factory();
|
||||
promise.then(iLimitedTask.c, iLimitedTask.e);
|
||||
promise.then(() => this.consumed(), () => this.consumed());
|
||||
}
|
||||
}
|
||||
|
||||
private consumed(): void {
|
||||
this._size--;
|
||||
this.runningPromises--;
|
||||
|
||||
if (this.outstandingPromises.length > 0) {
|
||||
this.consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import * as uri from 'vscode-uri';
|
||||
import { MarkdownEngine } from '../markdownEngine';
|
||||
import { TableOfContentsProvider } from '../tableOfContentsProvider';
|
||||
import { TableOfContents } from '../tableOfContents';
|
||||
import { isMarkdownFile } from './file';
|
||||
import { extname } from './path';
|
||||
|
||||
export interface OpenDocumentLinkArgs {
|
||||
readonly parts: vscode.Uri;
|
||||
@@ -53,7 +53,7 @@ export async function openDocumentLink(engine: MarkdownEngine, targetResource: v
|
||||
|
||||
if (typeof targetResourceStat === 'undefined') {
|
||||
// We don't think the file exists. If it doesn't already have an extension, try tacking on a `.md` and using that instead
|
||||
if (extname(targetResource.path) === '') {
|
||||
if (uri.Utils.extname(targetResource) === '') {
|
||||
const dotMdResource = targetResource.with({ path: targetResource.path + '.md' });
|
||||
try {
|
||||
const stat = await vscode.workspace.fs.stat(dotMdResource);
|
||||
@@ -104,8 +104,8 @@ function getViewColumn(resource: vscode.Uri): vscode.ViewColumn {
|
||||
}
|
||||
|
||||
async function tryRevealLineUsingTocFragment(engine: MarkdownEngine, editor: vscode.TextEditor, fragment: string): Promise<boolean> {
|
||||
const toc = new TableOfContentsProvider(engine, editor.document);
|
||||
const entry = await toc.lookup(fragment);
|
||||
const toc = await TableOfContents.create(engine, editor.document);
|
||||
const entry = toc.lookup(fragment);
|
||||
if (entry) {
|
||||
const lineStart = new vscode.Range(entry.line, 0, entry.line, 0);
|
||||
editor.selection = new vscode.Selection(lineStart.start, lineStart.end);
|
||||
@@ -129,25 +129,25 @@ function tryRevealLineUsingLineFragment(editor: vscode.TextEditor, fragment: str
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function resolveLinkToMarkdownFile(resource: vscode.Uri): Promise<vscode.Uri | undefined> {
|
||||
export async function resolveUriToMarkdownFile(resource: vscode.Uri): Promise<vscode.TextDocument | undefined> {
|
||||
try {
|
||||
const standardLink = await tryResolveLinkToMarkdownFile(resource);
|
||||
if (standardLink) {
|
||||
return standardLink;
|
||||
const doc = await tryResolveUriToMarkdownFile(resource);
|
||||
if (doc) {
|
||||
return doc;
|
||||
}
|
||||
} catch {
|
||||
// Noop
|
||||
}
|
||||
|
||||
// If no extension, try with `.md` extension
|
||||
if (extname(resource.path) === '') {
|
||||
return tryResolveLinkToMarkdownFile(resource.with({ path: resource.path + '.md' }));
|
||||
if (uri.Utils.extname(resource) === '') {
|
||||
return tryResolveUriToMarkdownFile(resource.with({ path: resource.path + '.md' }));
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async function tryResolveLinkToMarkdownFile(resource: vscode.Uri): Promise<vscode.Uri | undefined> {
|
||||
async function tryResolveUriToMarkdownFile(resource: vscode.Uri): Promise<vscode.TextDocument | undefined> {
|
||||
let document: vscode.TextDocument;
|
||||
try {
|
||||
document = await vscode.workspace.openTextDocument(resource);
|
||||
@@ -155,7 +155,7 @@ async function tryResolveLinkToMarkdownFile(resource: vscode.Uri): Promise<vscod
|
||||
return undefined;
|
||||
}
|
||||
if (isMarkdownFile(document)) {
|
||||
return document.uri;
|
||||
return document;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference types='@types/node'/>
|
||||
|
||||
export { basename, dirname, extname, isAbsolute, join } from 'path';
|
||||
@@ -1,105 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { Disposable } from '../util/dispose';
|
||||
import { isMarkdownFile } from './file';
|
||||
|
||||
export interface LastScrollLocation {
|
||||
readonly line: number;
|
||||
readonly uri: vscode.Uri;
|
||||
}
|
||||
|
||||
export class TopmostLineMonitor extends Disposable {
|
||||
|
||||
private readonly pendingUpdates = new Map<string, number>();
|
||||
private readonly throttle = 50;
|
||||
private previousTextEditorInfo = new Map<string, LastScrollLocation>();
|
||||
private previousStaticEditorInfo = new Map<string, LastScrollLocation>();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
if (vscode.window.activeTextEditor) {
|
||||
const line = getVisibleLine(vscode.window.activeTextEditor);
|
||||
this.setPreviousTextEditorLine({ uri: vscode.window.activeTextEditor.document.uri, line: line ?? 0 });
|
||||
}
|
||||
|
||||
this._register(vscode.window.onDidChangeTextEditorVisibleRanges(event => {
|
||||
if (isMarkdownFile(event.textEditor.document)) {
|
||||
const line = getVisibleLine(event.textEditor);
|
||||
if (typeof line === 'number') {
|
||||
this.updateLine(event.textEditor.document.uri, line);
|
||||
this.setPreviousTextEditorLine({ uri: event.textEditor.document.uri, line: line });
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private readonly _onChanged = this._register(new vscode.EventEmitter<{ readonly resource: vscode.Uri, readonly line: number }>());
|
||||
public readonly onDidChanged = this._onChanged.event;
|
||||
|
||||
public setPreviousStaticEditorLine(scrollLocation: LastScrollLocation): void {
|
||||
this.previousStaticEditorInfo.set(scrollLocation.uri.toString(), scrollLocation);
|
||||
}
|
||||
|
||||
public getPreviousStaticEditorLineByUri(resource: vscode.Uri): number | undefined {
|
||||
const scrollLoc = this.previousStaticEditorInfo.get(resource.toString());
|
||||
this.previousStaticEditorInfo.delete(resource.toString());
|
||||
return scrollLoc?.line;
|
||||
}
|
||||
|
||||
|
||||
public setPreviousTextEditorLine(scrollLocation: LastScrollLocation): void {
|
||||
this.previousTextEditorInfo.set(scrollLocation.uri.toString(), scrollLocation);
|
||||
}
|
||||
|
||||
public getPreviousTextEditorLineByUri(resource: vscode.Uri): number | undefined {
|
||||
const scrollLoc = this.previousTextEditorInfo.get(resource.toString());
|
||||
this.previousTextEditorInfo.delete(resource.toString());
|
||||
return scrollLoc?.line;
|
||||
}
|
||||
|
||||
public updateLine(
|
||||
resource: vscode.Uri,
|
||||
line: number
|
||||
) {
|
||||
const key = resource.toString();
|
||||
if (!this.pendingUpdates.has(key)) {
|
||||
// schedule update
|
||||
setTimeout(() => {
|
||||
if (this.pendingUpdates.has(key)) {
|
||||
this._onChanged.fire({
|
||||
resource,
|
||||
line: this.pendingUpdates.get(key) as number
|
||||
});
|
||||
this.pendingUpdates.delete(key);
|
||||
}
|
||||
}, this.throttle);
|
||||
}
|
||||
|
||||
this.pendingUpdates.set(key, line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the top-most visible range of `editor`.
|
||||
*
|
||||
* Returns a fractional line number based the visible character within the line.
|
||||
* Floor to get real line number
|
||||
*/
|
||||
export function getVisibleLine(
|
||||
editor: vscode.TextEditor
|
||||
): number | undefined {
|
||||
if (!editor.visibleRanges.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const firstVisiblePosition = editor.visibleRanges[0].start;
|
||||
const lineNumber = firstVisiblePosition.line;
|
||||
const line = editor.document.lineAt(lineNumber);
|
||||
const progress = firstVisiblePosition.character / (line.text.length + 2);
|
||||
return lineNumber + progress;
|
||||
}
|
||||
Reference in New Issue
Block a user