diff --git a/build/azure-pipelines/os-monaco-core-pipeline.yml b/build/azure-pipelines/os-monaco-core-pipeline.yml new file mode 100644 index 0000000000000..257514f163e8f --- /dev/null +++ b/build/azure-pipelines/os-monaco-core-pipeline.yml @@ -0,0 +1,63 @@ +pool: + vmImage: 'windows-2019' + +trigger: + branches: + include: + - main-os +pr: none + +variables: + TagName: 'v$(Build.BuildNumber)' + +stages: +- stage: Build + displayName: 'Build' + jobs: + - job: Build + displayName: 'Build Job' + steps: + - task: NodeTool@0 + inputs: + versionSpec: "14.17.3" + - script: | + yarn + - script: | + ./node_modules/.bin/gulp editor-distro + - task: PublishPipelineArtifact@1 + inputs: + targetPath: './out-monaco-editor-core' + artifact: 'artifacts' + publishLocation: 'pipeline' + + +- stage: Deploy + displayName: 'Deploy' + jobs: + - deployment: Deploy + displayName: 'Deploy to npm private repository and creates a git release' + pool: + vmImage: 'windows-2019' + environment: Automatic-Release + strategy: + runOnce: + deploy: + steps: + #Creates a Github release + - task: GitHubRelease@1 + inputs: + gitHubConnection: 'GitHub Release' + repositoryName: '$(Build.Repository.Name)' + action: 'create' + target: '$(Build.SourceVersion)' + tagSource: 'userSpecifiedTag' + tag: '$(TagName)' + changeLogCompareToRelease: 'lastFullRelease' + changeLogType: 'commitBased' + #Publishes the package into the private artifact repository + - task: Npm@1 + inputs: + command: 'publish' + workingDir: '$(Pipeline.Workspace)/artifacts/' + publishRegistry: 'useFeed' + publishFeed: 'd8b4d1eb-aeb3-4b5b-9b43-37b4fc985e2f' diff --git a/build/lib/treeshaking.js b/build/lib/treeshaking.js index 41cb33809b04d..6f65b0fc363af 100644 --- a/build/lib/treeshaking.js +++ b/build/lib/treeshaking.js @@ -244,6 +244,28 @@ function nodeOrChildIsBlack(node) { function isSymbolWithDeclarations(symbol) { return !!(symbol && symbol.declarations); } +function isVariableStatementWithSideEffects(ts, node) { + if (!ts.isVariableStatement(node)) { + return false; + } + let hasSideEffects = false; + const visitNode = (node) => { + if (hasSideEffects) { + // no need to go on + return; + } + if (ts.isCallExpression(node)) { + // TODO: assuming `createDecorator` and `refineServiceDecorator` calls are side-effect free + const isSideEffectFree = /(createDecorator|refineServiceDecorator)/.test(node.getText()); + if (!isSideEffectFree) { + hasSideEffects = true; + } + } + node.forEachChild(visitNode); + }; + node.forEachChild(visitNode); + return hasSideEffects; +} function markNodes(ts, languageService, options) { const program = languageService.getProgram(); if (!program) { @@ -282,6 +304,9 @@ function markNodes(ts, languageService, options) { } return; } + if (isVariableStatementWithSideEffects(ts, node)) { + enqueue_black(node); + } if (ts.isExpressionStatement(node) || ts.isIfStatement(node) || ts.isIterationStatement(node, true) diff --git a/build/lib/treeshaking.ts b/build/lib/treeshaking.ts index f24b31e26ac90..483b7b07e049d 100644 --- a/build/lib/treeshaking.ts +++ b/build/lib/treeshaking.ts @@ -327,6 +327,29 @@ function isSymbolWithDeclarations(symbol: ts.Symbol | undefined | null): symbol return !!(symbol && symbol.declarations); } +function isVariableStatementWithSideEffects(ts: typeof import('typescript'), node: ts.Node): boolean { + if (!ts.isVariableStatement(node)) { + return false; + } + let hasSideEffects = false; + const visitNode = (node: ts.Node) => { + if (hasSideEffects) { + // no need to go on + return; + } + if (ts.isCallExpression(node)) { + // TODO: assuming `createDecorator` and `refineServiceDecorator` calls are side-effect free + const isSideEffectFree = /(createDecorator|refineServiceDecorator)/.test(node.getText()); + if (!isSideEffectFree) { + hasSideEffects = true; + } + } + node.forEachChild(visitNode); + }; + node.forEachChild(visitNode); + return hasSideEffects; +} + function markNodes(ts: typeof import('typescript'), languageService: ts.LanguageService, options: ITreeShakingOptions) { const program = languageService.getProgram(); if (!program) { @@ -372,6 +395,10 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language return; } + if (isVariableStatementWithSideEffects(ts, node)) { + enqueue_black(node); + } + if ( ts.isExpressionStatement(node) || ts.isIfStatement(node) diff --git a/build/monaco/package.json b/build/monaco/package.json index 48f2d3a50b3d7..dca91c1c044aa 100644 --- a/build/monaco/package.json +++ b/build/monaco/package.json @@ -1,7 +1,7 @@ { "name": "monaco-editor-core", "private": true, - "version": "0.31.0", + "version": "0.31.1-os2", "description": "A browser based code editor", "author": "Microsoft Corporation", "license": "MIT", diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index aa1e3dc4e1a59..dd5cd3c9e2fc6 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -39,6 +39,7 @@ export interface INodeProcess { platform: string; arch: string; env: IProcessEnvironment; + nextTick?: (callback: (...args: any[]) => void) => void; versions?: { electron?: string; }; @@ -189,6 +190,10 @@ export const locale = _locale; */ export const translationsConfigFile = _translationsConfigFile; +interface ISetImmediate { + (callback: (...args: unknown[]) => void): void; +} + /** * See https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#:~:text=than%204%2C%20then-,set%20timeout%20to%204,-. * @@ -227,6 +232,20 @@ export const setTimeout0 = (() => { return (callback: () => void) => setTimeout(callback); })(); +export const setImmediate: ISetImmediate = (function defineSetImmediate() { + if (globals.setImmediate) { + return globals.setImmediate.bind(globals); + } + if (typeof globals.postMessage === 'function' && !globals.importScripts) { + return setTimeout0; + } + if (typeof nodeProcess?.nextTick === 'function') { + return nodeProcess.nextTick.bind(nodeProcess); + } + const _promise = Promise.resolve(); + return (callback: (...args: unknown[]) => void) => _promise.then(callback); +})(); + export const enum OperatingSystem { Windows = 1, Macintosh = 2, diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index e6dc5ca034a30..aab294bb4bbd1 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -991,8 +991,14 @@ export function shadowCaretRangeFromPoint(shadowRoot: ShadowRoot, x: number, y: // Grab its rect const rect = el.getBoundingClientRect(); - // And its font - const font = window.getComputedStyle(el, null).getPropertyValue('font'); + // And its font (the computed shorthand font property might be empty, see #3217) + const fontStyle = window.getComputedStyle(el, null).getPropertyValue('font-style'); + const fontVariant = window.getComputedStyle(el, null).getPropertyValue('font-variant'); + const fontWeight = window.getComputedStyle(el, null).getPropertyValue('font-weight'); + const fontSize = window.getComputedStyle(el, null).getPropertyValue('font-size'); + const lineHeight = window.getComputedStyle(el, null).getPropertyValue('line-height'); + const fontFamily = window.getComputedStyle(el, null).getPropertyValue('font-family'); + const font = `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize}/${lineHeight} ${fontFamily}`; // And also its txt content const text = (el as any).innerText; diff --git a/src/vs/editor/common/model/textModelTokens.ts b/src/vs/editor/common/model/textModelTokens.ts index cabbec3264226..45ca7d8658716 100644 --- a/src/vs/editor/common/model/textModelTokens.ts +++ b/src/vs/editor/common/model/textModelTokens.ts @@ -15,7 +15,7 @@ import { TextModel } from 'vs/editor/common/model/textModel'; import { Disposable } from 'vs/base/common/lifecycle'; import { StopWatch } from 'vs/base/common/stopwatch'; import { MultilineTokensBuilder, countEOL } from 'vs/editor/common/model/tokensStore'; -import { runWhenIdle, IdleDeadline } from 'vs/base/common/async'; +import { setImmediate } from 'vs/base/common/platform'; const enum Constants { CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048 @@ -262,7 +262,7 @@ export class TextModelTokenization extends Disposable { } this._isScheduled = true; - runWhenIdle((deadline) => { + setImmediate(() => { this._isScheduled = false; if (this._isDisposed) { @@ -270,11 +270,11 @@ export class TextModelTokenization extends Disposable { return; } - this._revalidateTokensNow(deadline); + this._revalidateTokensNow(); }); } - private _revalidateTokensNow(deadline: IdleDeadline): void { + private _revalidateTokensNow(): void { const textModelLastLineNumber = this._textModel.getLineCount(); const MAX_ALLOWED_TIME = 1; @@ -293,7 +293,7 @@ export class TextModelTokenization extends Disposable { if (tokenizedLineNumber >= textModelLastLineNumber) { break; } - } while (this._hasLinesToTokenize() && deadline.timeRemaining() > 0); + } while (this._hasLinesToTokenize()); this._beginBackgroundTokenization(); this._textModel.setTokens(builder.tokens, !this._hasLinesToTokenize()); diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index ceaff9385dd1f..1282a56fead60 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -572,6 +572,10 @@ export interface CompletionItem { * A command that should be run upon acceptance of this item. */ command?: Command; + /** + * Custom icon to be used (instead of those ones that depend on the completionItem kind) + */ + customIcon?: HTMLElement; /** * @internal diff --git a/src/vs/editor/contrib/suggest/suggestWidgetRenderer.ts b/src/vs/editor/contrib/suggest/suggestWidgetRenderer.ts index aca7b0cbcce99..466bf6340d003 100644 --- a/src/vs/editor/contrib/suggest/suggestWidgetRenderer.ts +++ b/src/vs/editor/contrib/suggest/suggestWidgetRenderer.ts @@ -171,8 +171,16 @@ export class ItemRenderer implements IListRenderer { const headers: IHeaders = { 'X-Market-Client-Id': `VSCode ${version}`, - 'X-Market-Client-Version': version, - 'User-Agent': `VSCode (${productService.nameShort})`, + 'User-Agent': `VSCode ${version}` }; const uuid = await getServiceMachineId(environmentService, fileService, storageService); if (supportsTelemetry(productService, environmentService) && getTelemetryLevel(configurationService) === TelemetryLevel.USAGE) { diff --git a/src/vs/platform/log/common/log.ts b/src/vs/platform/log/common/log.ts index a8a6ea1c7b505..88cc084a20246 100644 --- a/src/vs/platform/log/common/log.ts +++ b/src/vs/platform/log/common/log.ts @@ -9,10 +9,10 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { isWindows } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { createDecorator as createServiceDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -export const ILogService = createServiceDecorator('logService'); -export const ILoggerService = createServiceDecorator('loggerService'); +export const ILogService = createDecorator('logService'); +export const ILoggerService = createDecorator('loggerService'); function now(): string { return new Date().toISOString(); diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts index 9c022a93c240e..fabc8219d807d 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts @@ -104,10 +104,8 @@ export abstract class BaseCellViewModel extends Disposable { return this._focusMode; } set focusMode(newMode: CellFocusMode) { - if (this._focusMode !== newMode) { - this._focusMode = newMode; - this._onDidChangeState.fire({ focusModeChanged: true }); - } + this._focusMode = newMode; + this._onDidChangeState.fire({ focusModeChanged: true }); } protected _textEditor?: ICodeEditor; diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 6797ecaec0b17..a85f8dd96aa63 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -95,7 +95,7 @@ namespace WebviewState { export class WebviewElement extends Disposable implements IWebview, WebviewFindDelegate { public readonly id: string; - private readonly iframeId: string; + protected readonly iframeId: string; protected get platform(): string { return 'browser'; } diff --git a/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts index d1318e247ae2b..55ee9927e7628 100644 --- a/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts @@ -91,7 +91,7 @@ export class ElectronWebviewElement extends WebviewElement { } protected override get webviewContentEndpoint(): string { - return `${Schemas.vscodeWebview}://${this.id}`; + return `${Schemas.vscodeWebview}://${this.iframeId}`; } /** diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index 08073f0ea6538..3f95ee603d0fd 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -481,6 +481,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (settingId !== this.currentColorTheme.settingsId) { await this.internalSetColorTheme(theme.id, undefined); } else if (theme !== this.currentColorTheme) { + await theme.ensureLoaded(this.extensionResourceLoaderService); theme.setCustomizations(this.settings); await this.applyTheme(theme, undefined, true); } @@ -656,6 +657,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (settingId !== this.currentFileIconTheme.settingsId) { await this.internalSetFileIconTheme(theme.id, undefined); } else if (theme !== this.currentFileIconTheme) { + await theme.ensureLoaded(this.extensionResourceLoaderService); this.applyAndSetFileIconTheme(theme, true); } return true; @@ -761,6 +763,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (settingId !== this.currentProductIconTheme.settingsId) { await this.internalSetProductIconTheme(theme.id, undefined); } else if (theme !== this.currentProductIconTheme) { + await theme.ensureLoaded(this.extensionResourceLoaderService, this.logService); this.applyAndSetProductIconTheme(theme, true); } return true;