<commit_before>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

import * as strings from 'vs/base/common/strings';
import URI from 'vs/base/common/uri';
import * as dom from 'vs/base/browser/dom';
import {
	IDecorationRenderOptions, IModelDecorationOptions, IModelDecorationOverviewRulerOptions, IThemeDecorationRenderOptions,
	IContentDecorationRenderOptions, OverviewRulerLane, TrackedRangeStickiness, ThemeColor, isThemeColor
} from 'vs/editor/common/editorCommon';
import { AbstractCodeEditorService } from 'vs/editor/common/services/abstractCodeEditorService';
import { IDisposable, dispose as disposeAll } from 'vs/base/common/lifecycle';
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';

export class CodeEditorServiceImpl extends AbstractCodeEditorService {

	private _styleSheet: HTMLStyleElement;
	private _decorationOptionProviders: { [key: string]: IModelDecorationOptionsProvider };
	private _themeService: IThemeService;

	constructor( @IThemeService themeService: IThemeService, styleSheet = dom.createStyleSheet()) {
		super();
		this._styleSheet = styleSheet;
		this._decorationOptionProviders = Object.create(null);
		this._themeService = themeService;
	}

	public registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void {
		let provider = this._decorationOptionProviders[key];
		if (!provider) {
			let providerArgs: ProviderArguments = {
				styleSheet: this._styleSheet,
				key: key,
				parentTypeKey: parentTypeKey,
				options: options
			};
			if (!parentTypeKey) {
				provider = new DecorationTypeOptionsProvider(this._themeService, providerArgs);
			} else {
				provider = new DecorationSubTypeOptionsProvider(this._themeService, providerArgs);
			}
			this._decorationOptionProviders[key] = provider;
		}
		provider.refCount++;
	}

	public removeDecorationType(key: string): void {
		let provider = this._decorationOptionProviders[key];
		if (provider) {
			provider.refCount--;
			if (provider.refCount <= 0) {
				delete this._decorationOptionProviders[key];
				provider.dispose();
				this.listCodeEditors().forEach((ed) => ed.removeDecorations(key));
			}
		}
	}

	public resolveDecorationOptions(decorationTypeKey: string, writable: boolean): IModelDecorationOptions {
		let provider = this._decorationOptionProviders[decorationTypeKey];
		if (!provider) {
			throw new Error('Unknown decoration type key: ' + decorationTypeKey);
		}
		return provider.getOptions(this, writable);
	}

}

interface IModelDecorationOptionsProvider extends IDisposable {
	refCount: number;
	getOptions(codeEditorService: AbstractCodeEditorService, writable: boolean): IModelDecorationOptions;
}

class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvider {

	public refCount: number;

	private _parentTypeKey: string;
	private _beforeContentRules: DecorationCSSRules;
	private _afterContentRules: DecorationCSSRules;

	constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
		this._parentTypeKey = providerArgs.parentTypeKey;
		this.refCount = 0;

		this._beforeContentRules = new DecorationCSSRules(ModelDecorationCSSRuleType.BeforeContentClassName, providerArgs, themeService);
		this._afterContentRules = new DecorationCSSRules(ModelDecorationCSSRuleType.AfterContentClassName, providerArgs, themeService);
	}

	public getOptions(codeEditorService: AbstractCodeEditorService, writable: boolean): IModelDecorationOptions {
		let options = codeEditorService.resolveDecorationOptions(this._parentTypeKey, true);
		if (this._beforeContentRules) {
			options.beforeContentClassName = this._beforeContentRules.className;
		}
		if (this._afterContentRules) {
			options.afterContentClassName = this._afterContentRules.className;
		}
		return options;
	}

	public dispose(): void {
		if (this._beforeContentRules) {
			this._beforeContentRules.dispose();
			this._beforeContentRules = null;
		}
		if (this._afterContentRules) {
			this._afterContentRules.dispose();
			this._afterContentRules = null;
		}
	}
}

interface ProviderArguments {
	styleSheet: HTMLStyleElement;
	key: string;
	parentTypeKey?: string;
	options: IDecorationRenderOptions;
}


class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {

	private _disposables: IDisposable[];
	public refCount: number;

	public className: string;
	public inlineClassName: string;
	public beforeContentClassName: string;
	public afterContentClassName: string;
	public glyphMarginClassName: string;
	public isWholeLine: boolean;
	public overviewRuler: IModelDecorationOverviewRulerOptions;
	public stickiness: TrackedRangeStickiness;

	constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
		this.refCount = 0;
		this._disposables = [];

		let createCSSRules = (type: ModelDecorationCSSRuleType) => {
			let rules = new DecorationCSSRules(type, providerArgs, themeService);
			if (rules.hasContent) {
				this._disposables.push(rules);
				return rules.className;
			}
			return void 0;
		};

		this.className = createCSSRules(ModelDecorationCSSRuleType.ClassName);
		this.inlineClassName = createCSSRules(ModelDecorationCSSRuleType.InlineClassName);
		this.beforeContentClassName = createCSSRules(ModelDecorationCSSRuleType.BeforeContentClassName);
		this.beforeContentClassName = createCSSRules(ModelDecorationCSSRuleType.AfterContentClassName);
		this.glyphMarginClassName = createCSSRules(ModelDecorationCSSRuleType.GlyphMarginClassName);

		let options = providerArgs.options;
		this.isWholeLine = Boolean(options.isWholeLine);<commit_msg>Decoration text after decoration wrongly positioned. Fixes #27288<commit_after>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

import * as strings from 'vs/base/common/strings';
import URI from 'vs/base/common/uri';
import * as dom from 'vs/base/browser/dom';
import {
	IDecorationRenderOptions, IModelDecorationOptions, IModelDecorationOverviewRulerOptions, IThemeDecorationRenderOptions,
	IContentDecorationRenderOptions, OverviewRulerLane, TrackedRangeStickiness, ThemeColor, isThemeColor
} from 'vs/editor/common/editorCommon';
import { AbstractCodeEditorService } from 'vs/editor/common/services/abstractCodeEditorService';
import { IDisposable, dispose as disposeAll } from 'vs/base/common/lifecycle';
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';

export class CodeEditorServiceImpl extends AbstractCodeEditorService {

	private _styleSheet: HTMLStyleElement;
	private _decorationOptionProviders: { [key: string]: IModelDecorationOptionsProvider };
	private _themeService: IThemeService;

	constructor( @IThemeService themeService: IThemeService, styleSheet = dom.createStyleSheet()) {
		super();
		this._styleSheet = styleSheet;
		this._decorationOptionProviders = Object.create(null);
		this._themeService = themeService;
	}

	public registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void {
		let provider = this._decorationOptionProviders[key];
		if (!provider) {
			let providerArgs: ProviderArguments = {
				styleSheet: this._styleSheet,
				key: key,
				parentTypeKey: parentTypeKey,
				options: options
			};
			if (!parentTypeKey) {
				provider = new DecorationTypeOptionsProvider(this._themeService, providerArgs);
			} else {
				provider = new DecorationSubTypeOptionsProvider(this._themeService, providerArgs);
			}
			this._decorationOptionProviders[key] = provider;
		}
		provider.refCount++;
	}

	public removeDecorationType(key: string): void {
		let provider = this._decorationOptionProviders[key];
		if (provider) {
			provider.refCount--;
			if (provider.refCount <= 0) {
				delete this._decorationOptionProviders[key];
				provider.dispose();
				this.listCodeEditors().forEach((ed) => ed.removeDecorations(key));
			}
		}
	}

	public resolveDecorationOptions(decorationTypeKey: string, writable: boolean): IModelDecorationOptions {
		let provider = this._decorationOptionProviders[decorationTypeKey];
		if (!provider) {
			throw new Error('Unknown decoration type key: ' + decorationTypeKey);
		}
		return provider.getOptions(this, writable);
	}

}

interface IModelDecorationOptionsProvider extends IDisposable {
	refCount: number;
	getOptions(codeEditorService: AbstractCodeEditorService, writable: boolean): IModelDecorationOptions;
}

class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvider {

	public refCount: number;

	private _parentTypeKey: string;
	private _beforeContentRules: DecorationCSSRules;
	private _afterContentRules: DecorationCSSRules;

	constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
		this._parentTypeKey = providerArgs.parentTypeKey;
		this.refCount = 0;

		this._beforeContentRules = new DecorationCSSRules(ModelDecorationCSSRuleType.BeforeContentClassName, providerArgs, themeService);
		this._afterContentRules = new DecorationCSSRules(ModelDecorationCSSRuleType.AfterContentClassName, providerArgs, themeService);
	}

	public getOptions(codeEditorService: AbstractCodeEditorService, writable: boolean): IModelDecorationOptions {
		let options = codeEditorService.resolveDecorationOptions(this._parentTypeKey, true);
		if (this._beforeContentRules) {
			options.beforeContentClassName = this._beforeContentRules.className;
		}
		if (this._afterContentRules) {
			options.afterContentClassName = this._afterContentRules.className;
		}
		return options;
	}

	public dispose(): void {
		if (this._beforeContentRules) {
			this._beforeContentRules.dispose();
			this._beforeContentRules = null;
		}
		if (this._afterContentRules) {
			this._afterContentRules.dispose();
			this._afterContentRules = null;
		}
	}
}

interface ProviderArguments {
	styleSheet: HTMLStyleElement;
	key: string;
	parentTypeKey?: string;
	options: IDecorationRenderOptions;
}


class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {

	private _disposables: IDisposable[];
	public refCount: number;

	public className: string;
	public inlineClassName: string;
	public beforeContentClassName: string;
	public afterContentClassName: string;
	public glyphMarginClassName: string;
	public isWholeLine: boolean;
	public overviewRuler: IModelDecorationOverviewRulerOptions;
	public stickiness: TrackedRangeStickiness;

	constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
		this.refCount = 0;
		this._disposables = [];

		let createCSSRules = (type: ModelDecorationCSSRuleType) => {
			let rules = new DecorationCSSRules(type, providerArgs, themeService);
			if (rules.hasContent) {
				this._disposables.push(rules);
				return rules.className;
			}
			return void 0;
		};

		this.className = createCSSRules(ModelDecorationCSSRuleType.ClassName);
		this.inlineClassName = createCSSRules(ModelDecorationCSSRuleType.InlineClassName);
		this.beforeContentClassName = createCSSRules(ModelDecorationCSSRuleType.BeforeContentClassName);
		this.afterContentClassName = createCSSRules(ModelDecorationCSSRuleType.AfterContentClassName);
		this.glyphMarginClassName = createCSSRules(ModelDecorationCSSRuleType.GlyphMarginClassName);

		let options = providerArgs.options;
		this.isWholeLine = Boolean(options.isWholeLine);
{'fraction_non_alphanumeric': 0.11543987154567734, 'fraction_numerical': 0.0010986224964083496, 'mean_word_length': 5.065607380830343, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7147048', 'n_tokens_mistral': 3458, 'n_tokens_neox': 3138, 'n_words': 674}