[html] use languageModes for language types

This commit is contained in:
Martin Aeschlimann 2019-12-13 11:50:52 +01:00
parent f07fae16be
commit eb7ea2c435
15 changed files with 58 additions and 69 deletions

View file

@ -6,11 +6,13 @@
import { import {
createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType, createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType,
DocumentRangeFormattingRequest, Disposable, DocumentSelector, TextDocumentPositionParams, ServerCapabilities, DocumentRangeFormattingRequest, Disposable, DocumentSelector, TextDocumentPositionParams, ServerCapabilities,
Position, ConfigurationRequest, ConfigurationParams, DidChangeWorkspaceFoldersNotification, Range, ConfigurationRequest, ConfigurationParams, DidChangeWorkspaceFoldersNotification,
WorkspaceFolder, DocumentColorRequest, ColorInformation, ColorPresentationRequest, TextDocumentSyncKind DocumentColorRequest, ColorPresentationRequest, TextDocumentSyncKind
} from 'vscode-languageserver'; } from 'vscode-languageserver';
import { TextDocument, Diagnostic, DocumentLink, SymbolInformation, TextDocumentIdentifier } from 'vscode-html-languageservice'; import {
import { getLanguageModes, LanguageModes, Settings } from './modes/languageModes'; getLanguageModes, LanguageModes, Settings, TextDocument, Position, Diagnostic, WorkspaceFolder, ColorInformation,
Range, DocumentLink, SymbolInformation, TextDocumentIdentifier
} from './modes/languageModes';
import { format } from './modes/formatting'; import { format } from './modes/formatting';
import { pushAll } from './utils/arrays'; import { pushAll } from './utils/arrays';

View file

@ -18,10 +18,10 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
let cleanupInterval: NodeJS.Timer | undefined = undefined; let cleanupInterval: NodeJS.Timer | undefined = undefined;
if (cleanupIntervalTimeInSec > 0) { if (cleanupIntervalTimeInSec > 0) {
cleanupInterval = setInterval(() => { cleanupInterval = setInterval(() => {
let cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000; const cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000;
let uris = Object.keys(languageModels); const uris = Object.keys(languageModels);
for (let uri of uris) { for (const uri of uris) {
let languageModelInfo = languageModels[uri]; const languageModelInfo = languageModels[uri];
if (languageModelInfo.cTime < cutoffTime) { if (languageModelInfo.cTime < cutoffTime) {
delete languageModels[uri]; delete languageModels[uri];
nModels--; nModels--;
@ -32,14 +32,14 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
return { return {
get(document: TextDocument): T { get(document: TextDocument): T {
let version = document.version; const version = document.version;
let languageId = document.languageId; const languageId = document.languageId;
let languageModelInfo = languageModels[document.uri]; const languageModelInfo = languageModels[document.uri];
if (languageModelInfo && languageModelInfo.version === version && languageModelInfo.languageId === languageId) { if (languageModelInfo && languageModelInfo.version === version && languageModelInfo.languageId === languageId) {
languageModelInfo.cTime = Date.now(); languageModelInfo.cTime = Date.now();
return languageModelInfo.languageModel; return languageModelInfo.languageModel;
} }
let languageModel = parse(document); const languageModel = parse(document);
languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() }; languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() };
if (!languageModelInfo) { if (!languageModelInfo) {
nModels++; nModels++;
@ -48,8 +48,8 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
if (nModels === maxEntries) { if (nModels === maxEntries) {
let oldestTime = Number.MAX_VALUE; let oldestTime = Number.MAX_VALUE;
let oldestUri = null; let oldestUri = null;
for (let uri in languageModels) { for (const uri in languageModels) {
let languageModelInfo = languageModels[uri]; const languageModelInfo = languageModels[uri];
if (languageModelInfo.cTime < oldestTime) { if (languageModelInfo.cTime < oldestTime) {
oldestUri = uri; oldestUri = uri;
oldestTime = languageModelInfo.cTime; oldestTime = languageModelInfo.cTime;
@ -64,7 +64,7 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
}, },
onDocumentRemoved(document: TextDocument) { onDocumentRemoved(document: TextDocument) {
let uri = document.uri; const uri = document.uri;
if (languageModels[uri]) { if (languageModels[uri]) {
delete languageModels[uri]; delete languageModels[uri];
nModels--; nModels--;

View file

@ -4,11 +4,9 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache'; import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
import { TextDocument, Position, Range, CompletionList } from 'vscode-html-languageservice'; import { Stylesheet, LanguageService as CSSLanguageService } from 'vscode-css-languageservice';
import { Stylesheet, FoldingRange, LanguageService as CSSLanguageService } from 'vscode-css-languageservice'; import { FoldingRange, LanguageMode, Workspace, Color, TextDocument, Position, Range, CompletionList } from './languageModes';
import { LanguageMode, Workspace } from './languageModes';
import { HTMLDocumentRegions, CSS_STYLE_RULE } from './embeddedSupport'; import { HTMLDocumentRegions, CSS_STYLE_RULE } from './embeddedSupport';
import { Color } from 'vscode-languageserver';
export function getCSSMode(cssLanguageService: CSSLanguageService, documentRegions: LanguageModelCache<HTMLDocumentRegions>, workspace: Workspace): LanguageMode { export function getCSSMode(cssLanguageService: CSSLanguageService, documentRegions: LanguageModelCache<HTMLDocumentRegions>, workspace: Workspace): LanguageMode {
let embeddedCSSDocuments = getLanguageModelCache<TextDocument>(10, 60, document => documentRegions.get(document).getEmbeddedDocument('css')); let embeddedCSSDocuments = getLanguageModelCache<TextDocument>(10, 60, document => documentRegions.get(document).getEmbeddedDocument('css'));

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { TextDocument, Position, LanguageService, TokenType, Range } from 'vscode-html-languageservice'; import { TextDocument, Position, LanguageService, TokenType, Range } from './languageModes';
export interface LanguageRange extends Range { export interface LanguageRange extends Range {
languageId: string | undefined; languageId: string | undefined;

View file

@ -3,8 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { TextDocument, Range, TextEdit, FormattingOptions, Position } from 'vscode-html-languageservice'; import { LanguageModes, Settings, LanguageModeRange, TextDocument, Range, TextEdit, FormattingOptions, Position } from './languageModes';
import { LanguageModes, Settings, LanguageModeRange } from './languageModes';
import { pushAll } from '../utils/arrays'; import { pushAll } from '../utils/arrays';
import { isEOL } from '../utils/strings'; import { isEOL } from '../utils/strings';

View file

@ -3,9 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { TextDocument, CancellationToken, Position, Range } from 'vscode-languageserver'; import { TextDocument, FoldingRange, Position, Range, LanguageModes, LanguageMode } from './languageModes';
import { FoldingRange } from 'vscode-html-languageservice'; import { CancellationToken } from 'vscode-languageserver';
import { LanguageModes, LanguageMode } from './languageModes';
export function getFoldingRanges(languageModes: LanguageModes, document: TextDocument, maxRanges: number | undefined, _cancellationToken: CancellationToken | null): FoldingRange[] { export function getFoldingRanges(languageModes: LanguageModes, document: TextDocument, maxRanges: number | undefined, _cancellationToken: CancellationToken | null): FoldingRange[] {
let htmlMode = languageModes.getMode('html'); let htmlMode = languageModes.getMode('html');

View file

@ -7,9 +7,9 @@ import { getLanguageModelCache } from '../languageModelCache';
import { import {
LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions, LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions,
HTMLFormatConfiguration, SelectionRange, HTMLFormatConfiguration, SelectionRange,
TextDocument, Position, Range, CompletionItem, FoldingRange TextDocument, Position, Range, CompletionItem, FoldingRange,
} from 'vscode-html-languageservice'; LanguageMode, Workspace
import { LanguageMode, Workspace } from './languageModes'; } from './languageModes';
import { getPathCompletionParticipant } from './pathCompletion'; import { getPathCompletionParticipant } from './pathCompletion';
export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace: Workspace): LanguageMode { export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace: Workspace): LanguageMode {

View file

@ -3,11 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { WorkspaceFolder } from 'vscode-languageserver';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import { URI } from 'vscode-uri'; import { URI } from 'vscode-uri';
import { ICompletionParticipant, TextDocument, CompletionItemKind, CompletionItem, TextEdit, Range, Position } from 'vscode-html-languageservice'; import { ICompletionParticipant, TextDocument, CompletionItemKind, CompletionItem, TextEdit, Range, Position, WorkspaceFolder } from './languageModes';
import { startsWith } from '../utils/strings'; import { startsWith } from '../utils/strings';
import { contains } from '../utils/arrays'; import { contains } from '../utils/arrays';

View file

@ -3,8 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { LanguageModes } from './languageModes'; import { LanguageModes, TextDocument, Position, Range, SelectionRange } from './languageModes';
import { TextDocument, Position, Range, SelectionRange } from 'vscode-html-languageservice';
export function getSelectionRanges(languageModes: LanguageModes, document: TextDocument, positions: Position[]) { export function getSelectionRanges(languageModes: LanguageModes, document: TextDocument, positions: Position[]) {
const htmlMode = languageModes.getMode('html'); const htmlMode = languageModes.getMode('html');

View file

@ -6,10 +6,7 @@ import 'mocha';
import * as assert from 'assert'; import * as assert from 'assert';
import * as path from 'path'; import * as path from 'path';
import { URI } from 'vscode-uri'; import { URI } from 'vscode-uri';
import { getLanguageModes } from '../modes/languageModes'; import { getLanguageModes, WorkspaceFolder, TextDocument, CompletionList, CompletionItemKind, ClientCapabilities} from '../modes/languageModes';
import { WorkspaceFolder } from 'vscode-languageserver';
import { TextDocument, CompletionList, CompletionItemKind, ClientCapabilities } from 'vscode-html-languageservice';
export interface ItemDescription { export interface ItemDescription {
label: string; label: string;
documentation?: string; documentation?: string;

View file

@ -5,31 +5,32 @@
import 'mocha'; import 'mocha';
import * as assert from 'assert'; import * as assert from 'assert';
import * as embeddedSupport from '../modes/embeddedSupport'; import * as embeddedSupport from '../modes/embeddedSupport';
import { getLanguageService, TextDocument } from 'vscode-html-languageservice'; import { getLanguageService } from 'vscode-html-languageservice';
import { TextDocument } from '../modes/languageModes';
suite('HTML Embedded Support', () => { suite('HTML Embedded Support', () => {
var htmlLanguageService = getLanguageService(); const htmlLanguageService = getLanguageService();
function assertLanguageId(value: string, expectedLanguageId: string | undefined): void { function assertLanguageId(value: string, expectedLanguageId: string | undefined): void {
let offset = value.indexOf('|'); const offset = value.indexOf('|');
value = value.substr(0, offset) + value.substr(offset + 1); value = value.substr(0, offset) + value.substr(offset + 1);
let document = TextDocument.create('test://test/test.html', 'html', 0, value); const document = TextDocument.create('test://test/test.html', 'html', 0, value);
let position = document.positionAt(offset); const position = document.positionAt(offset);
let docRegions = embeddedSupport.getDocumentRegions(htmlLanguageService, document); const docRegions = embeddedSupport.getDocumentRegions(htmlLanguageService, document);
let languageId = docRegions.getLanguageAtPosition(position); const languageId = docRegions.getLanguageAtPosition(position);
assert.equal(languageId, expectedLanguageId); assert.equal(languageId, expectedLanguageId);
} }
function assertEmbeddedLanguageContent(value: string, languageId: string, expectedContent: string): void { function assertEmbeddedLanguageContent(value: string, languageId: string, expectedContent: string): void {
let document = TextDocument.create('test://test/test.html', 'html', 0, value); const document = TextDocument.create('test://test/test.html', 'html', 0, value);
let docRegions = embeddedSupport.getDocumentRegions(htmlLanguageService, document); const docRegions = embeddedSupport.getDocumentRegions(htmlLanguageService, document);
let content = docRegions.getEmbeddedDocument(languageId); const content = docRegions.getEmbeddedDocument(languageId);
assert.equal(content.getText(), expectedContent); assert.equal(content.getText(), expectedContent);
} }

View file

@ -17,13 +17,13 @@ interface ExpectedIndentRange {
} }
function assertRanges(lines: string[], expected: ExpectedIndentRange[], message?: string, nRanges?: number): void { function assertRanges(lines: string[], expected: ExpectedIndentRange[], message?: string, nRanges?: number): void {
let document = TextDocument.create('test://foo/bar.json', 'json', 1, lines.join('\n')); const document = TextDocument.create('test://foo/bar.json', 'json', 1, lines.join('\n'));
let workspace = { const workspace = {
settings: {}, settings: {},
folders: [{ name: 'foo', uri: 'test://foo' }] folders: [{ name: 'foo', uri: 'test://foo' }]
}; };
let languageModes = getLanguageModes({ css: true, javascript: true }, workspace, ClientCapabilities.LATEST); const languageModes = getLanguageModes({ css: true, javascript: true }, workspace, ClientCapabilities.LATEST);
let actual = getFoldingRanges(languageModes, document, nRanges, null); const actual = getFoldingRanges(languageModes, document, nRanges, null);
let actualRanges = []; let actualRanges = [];
for (let i = 0; i < actual.length; i++) { for (let i = 0; i < actual.length; i++) {
@ -40,7 +40,7 @@ function r(startLine: number, endLine: number, kind?: string): ExpectedIndentRan
suite('HTML Folding', () => { suite('HTML Folding', () => {
test('Embedded JavaScript', () => { test('Embedded JavaScript', () => {
let input = [ const input = [
/*0*/'<html>', /*0*/'<html>',
/*1*/'<head>', /*1*/'<head>',
/*2*/'<script>', /*2*/'<script>',
@ -54,7 +54,7 @@ suite('HTML Folding', () => {
}); });
test('Embedded JavaScript - multiple areas', () => { test('Embedded JavaScript - multiple areas', () => {
let input = [ const input = [
/* 0*/'<html>', /* 0*/'<html>',
/* 1*/'<head>', /* 1*/'<head>',
/* 2*/'<script>', /* 2*/'<script>',
@ -75,7 +75,7 @@ suite('HTML Folding', () => {
}); });
test('Embedded JavaScript - incomplete', () => { test('Embedded JavaScript - incomplete', () => {
let input = [ const input = [
/* 0*/'<html>', /* 0*/'<html>',
/* 1*/'<head>', /* 1*/'<head>',
/* 2*/'<script>', /* 2*/'<script>',
@ -91,7 +91,7 @@ suite('HTML Folding', () => {
}); });
test('Embedded JavaScript - regions', () => { test('Embedded JavaScript - regions', () => {
let input = [ const input = [
/* 0*/'<html>', /* 0*/'<html>',
/* 1*/'<head>', /* 1*/'<head>',
/* 2*/'<script>', /* 2*/'<script>',
@ -108,7 +108,7 @@ suite('HTML Folding', () => {
}); });
test('Embedded CSS', () => { test('Embedded CSS', () => {
let input = [ const input = [
/* 0*/'<html>', /* 0*/'<html>',
/* 1*/'<head>', /* 1*/'<head>',
/* 2*/'<style>', /* 2*/'<style>',
@ -124,7 +124,7 @@ suite('HTML Folding', () => {
}); });
test('Embedded CSS - multiple areas', () => { test('Embedded CSS - multiple areas', () => {
let input = [ const input = [
/* 0*/'<html>', /* 0*/'<html>',
/* 1*/'<head style="color:red">', /* 1*/'<head style="color:red">',
/* 2*/'<style>', /* 2*/'<style>',
@ -145,7 +145,7 @@ suite('HTML Folding', () => {
}); });
test('Embedded CSS - regions', () => { test('Embedded CSS - regions', () => {
let input = [ const input = [
/* 0*/'<html>', /* 0*/'<html>',
/* 1*/'<head>', /* 1*/'<head>',
/* 2*/'<style>', /* 2*/'<style>',
@ -163,7 +163,7 @@ suite('HTML Folding', () => {
// test('Embedded JavaScript - multi line comment', () => { // test('Embedded JavaScript - multi line comment', () => {
// let input = [ // const input = [
// /* 0*/'<html>', // /* 0*/'<html>',
// /* 1*/'<head>', // /* 1*/'<head>',
// /* 2*/'<script>', // /* 2*/'<script>',
@ -178,7 +178,7 @@ suite('HTML Folding', () => {
// }); // });
test('Test limit', () => { test('Test limit', () => {
let input = [ const input = [
/* 0*/'<div>', /* 0*/'<div>',
/* 1*/' <span>', /* 1*/' <span>',
/* 2*/' <b>', /* 2*/' <b>',

View file

@ -7,8 +7,7 @@ import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as assert from 'assert'; import * as assert from 'assert';
import { getLanguageModes } from '../modes/languageModes'; import { getLanguageModes, TextDocument, Range, FormattingOptions, ClientCapabilities } from '../modes/languageModes';
import { TextDocument, Range, FormattingOptions, ClientCapabilities } from 'vscode-html-languageservice';
import { format } from '../modes/formatting'; import { format } from '../modes/formatting';
@ -168,7 +167,7 @@ suite('HTML Embedded Formatting', () => {
} }
}; };
var content = [ const content = [
'<html>', '<html>',
'', '',
'<body>', '<body>',
@ -179,7 +178,7 @@ suite('HTML Embedded Formatting', () => {
'</html>', '</html>',
].join('\n'); ].join('\n');
var expected = [ const expected = [
'<html>', '<html>',
'', '',
'<body>', '<body>',

View file

@ -5,10 +5,7 @@
import 'mocha'; import 'mocha';
import * as assert from 'assert'; import * as assert from 'assert';
import { SelectionRange } from 'vscode-languageserver-types'; import { getLanguageModes, ClientCapabilities, TextDocument, SelectionRange} from '../modes/languageModes';
import { TextDocument } from 'vscode-languageserver-textdocument';
import { getLanguageModes } from '../modes/languageModes';
import { ClientCapabilities } from 'vscode-html-languageservice';
import { getSelectionRanges } from '../modes/selectionRanges'; import { getSelectionRanges } from '../modes/selectionRanges';
function assertRanges(content: string, expected: (number | string)[][]): void { function assertRanges(content: string, expected: (number | string)[][]): void {

View file

@ -3,10 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { DocumentContext } from 'vscode-html-languageservice'; import { DocumentContext, WorkspaceFolder } from '../modes/languageModes';
import { endsWith, startsWith } from '../utils/strings'; import { endsWith, startsWith } from '../utils/strings';
import * as url from 'url'; import * as url from 'url';
import { WorkspaceFolder } from 'vscode-languageserver';
export function getDocumentContext(documentUri: string, workspaceFolders: WorkspaceFolder[]): DocumentContext { export function getDocumentContext(documentUri: string, workspaceFolders: WorkspaceFolder[]): DocumentContext {
function getRootFolder(): string | undefined { function getRootFolder(): string | undefined {