Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions src/languageFeatures.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ParseError } from 'dt-sql-parser';
import { ColumnEntityContext, CommonEntityContext, EntityContextType } from 'dt-sql-parser';
import { EntityContext } from 'dt-sql-parser/dist/parser/common/entityCollector';
import { WordPosition } from 'dt-sql-parser/dist/parser/common/textAndWord';
import * as monaco from 'monaco-editor';
Expand All @@ -17,6 +18,16 @@ import {
} from './fillers/monaco-editor-core';
import type { CompletionSnippet, LanguageServiceDefaults } from './monaco.contribution';

export interface ColumnInfo {
/** 字段名 */
column: string;
/** 字段类型 */
type: string | undefined;
/** 注释 */
comment?: string;
/** 别名 */
alias?: string;
}
export interface WorkerAccessor<T extends BaseSQLWorker> {
(...uris: Uri[]): Promise<T>;
}
Expand Down Expand Up @@ -352,3 +363,131 @@ export class ReferenceAdapter<T extends BaseSQLWorker> implements languages.Refe
});
}
}
/**
* The adapter is for the hover provider interface defines the contract between extensions and
* the [hover](https://code.visualstudio.com/docs/editor/intellisense)-feature.
**/
export class HoverAdapter<T extends BaseSQLWorker> implements languages.HoverProvider {
constructor(
private readonly _worker: WorkerAccessor<T>,
private readonly _defaults: LanguageServiceDefaults
) {}
provideHover(
model: editor.IReadOnlyModel,
position: Position,
_token: CancellationToken
): languages.ProviderResult<languages.Hover> {
const resource = model.uri;
const lineContent = model.getLineContent(position.lineNumber);
if (lineContent.trim().startsWith('--')) return null;
return this._worker(resource)
.then((worker) => {
let code = model?.getValue() || '';
if (typeof this._defaults.preprocessCode === 'function') {
code = this._defaults.preprocessCode(code);
}
return worker.getAllEntities(code, position);
})
.then((entities) => {
if (!entities || !entities.length) return null;
let isAlias = false;
const curEntity = entities.find((entity: EntityContext) => {
const p = entity.position;
const alias = entity._alias;
isAlias = !!(
alias &&
alias.startColumn <= position.column &&
alias.endColumn >= position.column &&
alias.line === position.lineNumber
);
return (
(p.startColumn <= position.column &&
p.endColumn >= position.column &&
p.line === position.lineNumber) ||
isAlias
);
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

当hover在表别名上时,也可以查找到的,展示的时候可以把表和别名一起展示

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确实,我加一下

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

加了

if (!curEntity) return null;
const tableCreate = findTableCreateEntity(curEntity, entities);
const columns = tableCreate ? toColumnsInfo(tableCreate) || [] : [];
const columnsDesc = columns.reduce((res, cur) => {
const { column, type, comment, alias } = cur;
return (
res +
`\`${column}\` ${type ? `&nbsp;&nbsp; **${type}**` : ''} ${
comment ? `&nbsp;&nbsp; *${comment}*` : ''
} ${alias ? `&nbsp;&nbsp; *${alias}*` : ''} \n`
);
}, '');
const tableText = isAlias
? (curEntity._alias?.text ?? curEntity.text)
: curEntity.text;
let range: monaco.Range;
if (isAlias && curEntity._alias) {
range = new monaco.Range(
curEntity._alias.line,
curEntity._alias.startColumn,
curEntity._alias.line,
curEntity._alias.endColumn
);
} else {
const p = curEntity.position;
range = new monaco.Range(p.line, p.startColumn, p.line, p.endColumn);
}
const contents: monaco.IMarkdownString[] = [
{ value: `**${tableText}**` },
{ value: columnsDesc }
];
return { contents, range };
});
}
}

/**
* According to the table name or table entity field, get the corresponding create table information
*/
export function findTableCreateEntity(
tableEntity: EntityContext | string,
allEntities: EntityContext[]
): CommonEntityContext | null {
if (
typeof tableEntity !== 'string' &&
tableEntity.entityContextType !== EntityContextType.TABLE
) {
return null;
}

const tableName: string = typeof tableEntity === 'string' ? tableEntity : tableEntity.text;
function removeQuotes(str: string): string {
return str.replace(/^['"`“”‘’«»]|['"`“”‘’«»]$/g, '');
}
return (
allEntities.find(
(en): en is CommonEntityContext =>
en.entityContextType === EntityContextType.TABLE_CREATE &&
removeQuotes(en.text) === removeQuotes(tableName)
) ?? null
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

考虑实体一边加反引号,一边没加的情况应该也匹配上

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这种情况我调试一下看看

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

加了加了

);
}

/**
* Transform table create entity to columns info
*/
export function toColumnsInfo(tableEntity: CommonEntityContext): ColumnInfo[] | null {
if (
!tableEntity ||
tableEntity.entityContextType !== EntityContextType.TABLE_CREATE ||
!tableEntity.columns?.length
)
return null;
const columnsInfo: ColumnInfo[] = [];
tableEntity.columns.forEach((col: ColumnEntityContext) => {
columnsInfo.push({
column: col.text,
type: col._colType?.text,
comment: col._comment?.text,
alias: col._alias?.text
});
});
return columnsInfo;
}
5 changes: 3 additions & 2 deletions src/languages/flink/flink.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ registerLanguage({
setupLanguageFeatures(LanguageIdEnum.FLINK, {
completionItems: true,
diagnostics: true,
references: true,
definitions: true
references: false,
definitions: false,
hover: false
});
5 changes: 3 additions & 2 deletions src/languages/hive/hive.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ registerLanguage({
setupLanguageFeatures(LanguageIdEnum.HIVE, {
completionItems: true,
diagnostics: true,
references: true,
definitions: true
references: false,
definitions: false,
hover: false
});
5 changes: 3 additions & 2 deletions src/languages/impala/impala.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ registerLanguage({
setupLanguageFeatures(LanguageIdEnum.IMPALA, {
completionItems: true,
diagnostics: true,
references: true,
definitions: true
references: false,
definitions: false,
hover: false
});
5 changes: 3 additions & 2 deletions src/languages/mysql/mysql.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ registerLanguage({
setupLanguageFeatures(LanguageIdEnum.MYSQL, {
completionItems: true,
diagnostics: true,
references: true,
definitions: true
references: false,
definitions: false,
hover: false
});
5 changes: 3 additions & 2 deletions src/languages/pgsql/pgsql.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ registerLanguage({
setupLanguageFeatures(LanguageIdEnum.PG, {
completionItems: true,
diagnostics: true,
references: true,
definitions: true
references: false,
definitions: false,
hover: false
});
5 changes: 3 additions & 2 deletions src/languages/spark/spark.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ registerLanguage({
setupLanguageFeatures(LanguageIdEnum.SPARK, {
completionItems: true,
diagnostics: true,
references: true,
definitions: true
references: false,
definitions: false,
hover: false
});
9 changes: 7 additions & 2 deletions src/monaco.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ export interface ModeConfiguration {
* Defines whether the built-in references provider is enabled.
*/
readonly references?: boolean;
/**
* Defines whether the built-in hover provider is enabled.
*/
readonly hover?: boolean;
}

/**
Expand Down Expand Up @@ -205,6 +209,7 @@ export const modeConfigurationDefault: Required<ModeConfiguration> = {
triggerCharacters: ['.', ' ']
},
diagnostics: true,
definitions: true,
references: true
definitions: false,
references: false,
hover: false
};
11 changes: 10 additions & 1 deletion src/setupLanguageFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export interface FeatureConfiguration {
* Defines whether the built-in references provider is enabled.
*/
references?: boolean;
/**
* Defines whether the built-in hover provider is enabled.
*/
hover?: boolean;
/**
* Define a function to preprocess code.
* By default, do not something.
Expand Down Expand Up @@ -148,6 +152,10 @@ function processConfiguration(
typeof configuration.definitions === 'boolean'
? configuration.definitions
: (defaults?.modeConfiguration.definitions ?? modeConfigurationDefault.definitions);
const hover =
typeof configuration.hover === 'boolean'
? configuration.hover
: (defaults?.modeConfiguration.hover ?? modeConfigurationDefault.hover);

const snippets =
typeof configuration.completionItems !== 'boolean' &&
Expand All @@ -165,6 +173,7 @@ function processConfiguration(
snippets
},
references,
definitions
definitions,
hover
};
}
8 changes: 8 additions & 0 deletions src/setupLanguageMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ export function setupLanguageMode<T extends BaseSQLWorker>(
)
);
}
if (modeConfiguration.hover) {
providers.push(
languages.registerHoverProvider(
languageId,
new languageFeatures.HoverAdapter(worker, defaults)
)
);
}
}

registerProviders();
Expand Down
25 changes: 24 additions & 1 deletion website/src/languages/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'monaco-sql-languages/esm/all.contributions.js';
import './languageWorker';
import './theme';
import { setupLanguageFeatures, LanguageIdEnum } from 'monaco-sql-languages/esm/main.js';

import { LanguageIdEnum, setupLanguageFeatures } from 'monaco-sql-languages/esm/main.js';

import { completionService } from './helpers/completionService';

/**
Expand Down Expand Up @@ -65,6 +67,9 @@ setupLanguageFeatures(LanguageIdEnum.FLINK, {
enable: true,
completionService
},
references: true,
definitions: true,
hover: true,
preprocessCode
});

Expand All @@ -73,6 +78,9 @@ setupLanguageFeatures(LanguageIdEnum.SPARK, {
enable: true,
completionService
},
references: true,
definitions: true,
hover: true,
preprocessCode
});

Expand All @@ -81,6 +89,9 @@ setupLanguageFeatures(LanguageIdEnum.HIVE, {
enable: true,
completionService
},
references: true,
definitions: true,
hover: true,
preprocessCode: (code: string) => preprocessCodeHive(code, '`')
});

Expand All @@ -89,6 +100,9 @@ setupLanguageFeatures(LanguageIdEnum.MYSQL, {
enable: true,
completionService
},
references: true,
definitions: true,
hover: true,
preprocessCode
});

Expand All @@ -97,6 +111,9 @@ setupLanguageFeatures(LanguageIdEnum.TRINO, {
enable: true,
completionService
},
references: true,
definitions: true,
hover: true,
preprocessCode
});

Expand All @@ -105,6 +122,9 @@ setupLanguageFeatures(LanguageIdEnum.PG, {
enable: true,
completionService
},
references: true,
definitions: true,
hover: true,
preprocessCode
});

Expand All @@ -113,5 +133,8 @@ setupLanguageFeatures(LanguageIdEnum.IMPALA, {
enable: true,
completionService
},
references: true,
definitions: true,
hover: true,
preprocessCode
});