Skip to content

Commit

Permalink
feat: improve ts and export (#112)
Browse files Browse the repository at this point in the history
* feat: improve declaration files

* feat: improve tsconfig.json and fix ts check errors

* feat: improve languageFeatures

* feat: improve debounce types

* feat: improve ts type

* feat: enhance languageFeatures

* feat: languages are loaded on demand

* feat: remove useless exports

* docs: update website
  • Loading branch information
HaydenOrz committed Mar 29, 2024
1 parent 51777c6 commit 7fceed2
Show file tree
Hide file tree
Showing 41 changed files with 186 additions and 153 deletions.
10 changes: 1 addition & 9 deletions src/baseSQLWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,6 @@ export abstract class BaseSQLWorker {
return Promise.resolve([]);
}

async valid(code: string): Promise<ParseError[]> {
if (code) {
const result = this.parser.validate(code);
return Promise.resolve(result);
}
return Promise.resolve([]);
}

async parserTreeToString(code: string): Promise<string> {
if (code) {
const parser = this.parser.createParser(code);
Expand Down Expand Up @@ -60,7 +52,7 @@ export abstract class BaseSQLWorker {
return Promise.resolve([null, null]);
}

async getAllEntities(code: string, position: Position): Promise<EntityContext[] | null> {
async getAllEntities(code: string, position?: Position): Promise<EntityContext[] | null> {
code = code || this.getTextDocument();
if (code) {
const allEntities = this.parser.getAllEntities(code, position);
Expand Down
14 changes: 9 additions & 5 deletions src/common/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
export function debounce(func: Function, timeout: number, immediate?: boolean) {
let timer: any = null;
return (...args: any) => {
export function debounce<T extends (...args: unknown[]) => unknown>(
func: T,
timeout: number,
immediate?: boolean
): (...args: Parameters<T>) => unknown {
let timer: NodeJS.Timeout | null = null;
return (...args) => {
if (timer) {
clearTimeout(timer);
}
if (immediate && !timer) {
func?.(...args);
return func?.(...args);
}

timer = setTimeout(() => {
clearTimeout(timer);
timer && clearTimeout(timer);
timer = null;
func?.(...args);
}, timeout);
Expand Down
3 changes: 3 additions & 0 deletions src/editor.worker.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module 'monaco-editor/esm/vs/editor/editor.worker.js' {
export function initialize(callback: (ctx: any, createData: any) => any): void;
}
3 changes: 2 additions & 1 deletion src/flinksql/flinkSQLWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { ICreateData } from '../_.contribution';
export class FLinkSQLWorker extends BaseSQLWorker {
protected _ctx: worker.IWorkerContext;
protected parser: FlinkSQL;
constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
constructor(ctx: worker.IWorkerContext, _createData: ICreateData) {
// CreatedData is not required now.
super();
this._ctx = ctx;
this.parser = new FlinkSQL();
Expand Down
4 changes: 1 addition & 3 deletions src/flinksql/flinksql.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { loadLanguage, registerLanguage } from '../_.contribution';
import { registerLanguage } from '../_.contribution';
import { setupLanguageFeatures } from '../setupLanguageFeatures';
import { LanguageIdEnum } from '../common/constants';

Expand All @@ -14,8 +14,6 @@ registerLanguage({
loader: () => import('./flinksql')
});

loadLanguage(LanguageIdEnum.FLINK);

setupLanguageFeatures({
languageId: LanguageIdEnum.FLINK,
completionItems: true,
Expand Down
3 changes: 2 additions & 1 deletion src/flinksql/flinksql.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import * as EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker.js';
import { FLinkSQLWorker } from './flinkSQLWorker';
import { ICreateData } from '../_.contribution';

self.onmessage = (e: any) => {
self.onmessage = () => {
// ignore the first message
EditorWorker.initialize((ctx: worker.IWorkerContext, createData: ICreateData) => {
return new FLinkSQLWorker(ctx, createData);
});
Expand Down
3 changes: 2 additions & 1 deletion src/hivesql/hiveSQLWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { BaseSQLWorker } from '../baseSQLWorker';
export class HiveSQLWorker extends BaseSQLWorker {
protected _ctx: worker.IWorkerContext;
protected parser: HiveSQL;
constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
constructor(ctx: worker.IWorkerContext, _createData: ICreateData) {
// CreatedData is not required now.
super();
this._ctx = ctx;
this.parser = new HiveSQL();
Expand Down
4 changes: 1 addition & 3 deletions src/hivesql/hivesql.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { loadLanguage, registerLanguage } from '../_.contribution';
import { registerLanguage } from '../_.contribution';
import { setupLanguageFeatures } from '../setupLanguageFeatures';
import { LanguageIdEnum } from '../common/constants';

Expand All @@ -14,8 +14,6 @@ registerLanguage({
loader: () => import('./hivesql')
});

loadLanguage(LanguageIdEnum.HIVE);

setupLanguageFeatures({
languageId: LanguageIdEnum.HIVE,
completionItems: true,
Expand Down
3 changes: 2 additions & 1 deletion src/hivesql/hivesql.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import * as EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker.js';
import { ICreateData } from '../_.contribution';
import { HiveSQLWorker } from './hiveSQLWorker';

self.onmessage = (e: any) => {
self.onmessage = () => {
// ignore the first message
EditorWorker.initialize((ctx: worker.IWorkerContext, createData: ICreateData) => {
return new HiveSQLWorker(ctx, createData);
});
Expand Down
3 changes: 2 additions & 1 deletion src/impalasql/impalaSQLWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { ICreateData } from '../_.contribution';
export class ImpalaSQLWorker extends BaseSQLWorker {
protected _ctx: worker.IWorkerContext;
protected parser: ImpalaSQL;
constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
constructor(ctx: worker.IWorkerContext, _createData: ICreateData) {
// CreatedData is not required now.
super();
this._ctx = ctx;
this.parser = new ImpalaSQL();
Expand Down
4 changes: 1 addition & 3 deletions src/impalasql/impalasql.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { loadLanguage, registerLanguage } from '../_.contribution';
import { registerLanguage } from '../_.contribution';
import { setupLanguageFeatures } from '../setupLanguageFeatures';
import { LanguageIdEnum } from '../common/constants';

Expand All @@ -14,8 +14,6 @@ registerLanguage({
loader: () => import('./impalasql')
});

loadLanguage(LanguageIdEnum.IMPALA);

setupLanguageFeatures({
languageId: LanguageIdEnum.IMPALA,
completionItems: true,
Expand Down
3 changes: 2 additions & 1 deletion src/impalasql/impalasql.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import * as EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker.js';
import { ImpalaSQLWorker } from './impalaSQLWorker';
import { ICreateData } from '../_.contribution';

self.onmessage = (e: any) => {
self.onmessage = () => {
// ignore the first message
EditorWorker.initialize((ctx: worker.IWorkerContext, createData: ICreateData) => {
return new ImpalaSQLWorker(ctx, createData);
});
Expand Down
1 change: 0 additions & 1 deletion src/index.d.ts

This file was deleted.

37 changes: 19 additions & 18 deletions src/languageFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { ParseError } from 'dt-sql-parser';
import type { LanguageServiceDefaults, CompletionService, ICompletionItem } from './_.contribution';

export interface WorkerAccessor<T extends BaseSQLWorker> {
(first: Uri, ...more: Uri[]): Promise<T>;
(...uris: Uri[]): Promise<T>;
}

export class DiagnosticsAdapter<T extends BaseSQLWorker> {
Expand All @@ -24,7 +24,7 @@ export class DiagnosticsAdapter<T extends BaseSQLWorker> {
constructor(
private _languageId: string,
private _worker: WorkerAccessor<T>,
private _defaults: LanguageServiceDefaults
private readonly _defaults: LanguageServiceDefaults
) {
const onModelAdd = (model: editor.IModel): void => {
let modeId = model.getLanguageId();
Expand All @@ -35,7 +35,7 @@ export class DiagnosticsAdapter<T extends BaseSQLWorker> {
this._listener[model.uri.toString()] = model.onDidChangeContent(
debounce(() => {
this._doValidate(model.uri, modeId);
}, 600)
}, 500)
);

this._doValidate(model.uri, modeId);
Expand All @@ -61,14 +61,16 @@ export class DiagnosticsAdapter<T extends BaseSQLWorker> {
})
);

this._defaults.onDidChange((_) => {
editor.getModels().forEach((model) => {
if (model.getLanguageId() === this._languageId) {
onModelRemoved(model);
onModelAdd(model);
}
});
});
this._disposables.push(
this._defaults.onDidChange((_) => {
editor.getModels().forEach((model) => {
if (model.getLanguageId() === this._languageId) {
onModelRemoved(model);
onModelAdd(model);
}
});
})
);

this._disposables.push({
dispose: () => {
Expand Down Expand Up @@ -115,7 +117,7 @@ function toSeverity(lsSeverity?: number): MarkerSeverity {
}
}

function toDiagnostics(resource: Uri, diag: ParseError): editor.IMarkerData {
function toDiagnostics(_resource: Uri, diag: ParseError): editor.IMarkerData {
return {
severity: toSeverity(),
startLineNumber: diag.startLine,
Expand All @@ -131,11 +133,10 @@ function toDiagnostics(resource: Uri, diag: ParseError): editor.IMarkerData {
export class CompletionAdapter<T extends BaseSQLWorker>
implements languages.CompletionItemProvider
{
constructor(private readonly _worker: WorkerAccessor<T>, defaults: LanguageServiceDefaults) {
this._defaults = defaults;
}

private _defaults: LanguageServiceDefaults;
constructor(
private readonly _worker: WorkerAccessor<T>,
private readonly _defaults: LanguageServiceDefaults
) {}

public get triggerCharacters(): string[] {
return ['.', ' '];
Expand All @@ -145,7 +146,7 @@ export class CompletionAdapter<T extends BaseSQLWorker>
model: editor.IReadOnlyModel,
position: Position,
context: languages.CompletionContext,
token: CancellationToken
_token: CancellationToken
): Promise<languages.CompletionList> {
const resource = model.uri;
return this._worker(resource)
Expand Down
77 changes: 55 additions & 22 deletions src/languageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,73 @@ import {
diagnosticDefault,
modeConfigurationDefault
} from './_.contribution';
import { WorkerAccessor } from './languageFeatures';
import { WorkerManager } from './workerManager';
import { BaseSQLWorker } from './baseSQLWorker';
import { Position, Uri, editor } from './fillers/monaco-editor-core';

type ClientWorker = (...uris: any) => Promise<BaseSQLWorker>;
export class LanguageService<T extends BaseSQLWorker = BaseSQLWorker> {
private workerClients: Map<string, WorkerManager<T>> = new Map();

export class LanguageService {
private worker: Map<string, WorkerAccessor<any>> = new Map();
public valid(language: string, model: editor.IReadOnlyModel | string) {
const text = typeof model === 'string' ? model : model.getValue();
const uri = typeof model === 'string' ? void 0 : model.uri;

public valid(language: string, sqlContent: string): Promise<any> {
const clientWorker = this.getClientWorker(language);
return clientWorker(sqlContent).then((worker) => {
return worker.valid(sqlContent);
const clientWorker = this.getClientWorker(language, uri as Uri);
return clientWorker.then((worker) => {
return worker.doValidation(text);
});
}

public parserTreeToString(language: string, sqlContent: string): Promise<any> {
const clientWorker = this.getClientWorker(language);
return clientWorker(sqlContent).then((worker) => {
return worker.parserTreeToString(sqlContent);
public parserTreeToString(language: string, model: editor.IReadOnlyModel | string) {
const text = typeof model === 'string' ? model : model.getValue();
const uri = typeof model === 'string' ? void 0 : model.uri;

const clientWorker = this.getClientWorker(language, uri as Uri);
return clientWorker.then((worker) => {
return worker.parserTreeToString(text);
});
}

public getAllEntities(
language: string,
model: editor.IReadOnlyModel | string,
position?: Position
) {
const text = typeof model === 'string' ? model : model.getValue();
const uri = typeof model === 'string' ? void 0 : model.uri;

const clientWorker = this.getClientWorker(language, uri as Uri);
return clientWorker.then((worker) => {
return worker.getAllEntities(text, position);
});
}

private getClientWorker(language: string): ClientWorker {
let existWorker = this.worker.get(language);
if (!existWorker) {
const client = new WorkerManager(this.getLanguageServiceDefault(language));
const worker: WorkerAccessor<any> = (...uris): Promise<any> => {
return client.getLanguageServiceWorker(...uris);
};
this.worker.set(language, worker);
return worker;
/**
* Dispose a language service.
* If the language is null, dispose all language services.
*/
public dispose(language?: string): void {
if (language) {
if (this.workerClients.has(language)) {
this.workerClients.get(language)?.dispose();
this.workerClients.delete(language);
}
} else {
this.workerClients.forEach((client) => {
client.dispose();
});
this.workerClients.clear();
}
}

private getClientWorker(language: string, ...uri: Uri[]): Promise<T> {
let existClient = this.workerClients.get(language);
if (!existClient) {
const client = new WorkerManager<T>(this.getLanguageServiceDefault(language));
this.workerClients.set(language, client);
return client.getLanguageServiceWorker(...uri);
}
return existWorker;
return existClient.getLanguageServiceWorker(...uri);
}

private getLanguageServiceDefault(languageId: string): LanguageServiceDefaults {
Expand Down
20 changes: 14 additions & 6 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
export * from './_.contribution';
export * from './languageService';
export * from './languageFeatures';
export * from './setupLanguageMode';
export * from './setupLanguageFeatures';
export * from './workerManager';
export * from './common/utils';
export * from './common/constants';
export * from './theme';

export { SyntaxContextType } from 'dt-sql-parser';
export {
EntityContextType,
StmtContextType,
/** @deprecated use {@link EntityContextType} to instead. */
SyntaxContextType
} from 'dt-sql-parser';

export type { WordRange, SyntaxSuggestion, Suggestions, TextSlice } from 'dt-sql-parser';
export type {
WordRange,
SyntaxSuggestion,
Suggestions,
TextSlice,
ParseError,
EntityContext
} from 'dt-sql-parser';
13 changes: 0 additions & 13 deletions src/mocha.d.ts

This file was deleted.

Loading

0 comments on commit 7fceed2

Please sign in to comment.