greybel-languageserver-core
Version:
Core functionality of language server for GreyScript
158 lines • 7.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTypeBody = exports.createHover = exports.createSignatureInfo = exports.appendTooltipBody = exports.appendTooltipHeader = exports.createTooltipHeader = exports.formatDefaultValue = exports.formatTypes = exports.sortTypes = exports.formatKind = void 0;
const greybel_type_analyzer_1 = require("greybel-type-analyzer");
const meta_utils_1 = require("meta-utils");
const signature_definition_1 = require("meta-utils/dist/types/signature-definition");
const types_1 = require("../types");
const markdown_string_1 = require("./markdown-string");
const CompletionItemKindMapping = {
[greybel_type_analyzer_1.CompletionItemKind.Constant]: 'constant',
[greybel_type_analyzer_1.CompletionItemKind.Expression]: 'expr',
[greybel_type_analyzer_1.CompletionItemKind.Function]: 'function',
[greybel_type_analyzer_1.CompletionItemKind.Internal]: 'internal',
[greybel_type_analyzer_1.CompletionItemKind.InternalFunction]: 'function',
[greybel_type_analyzer_1.CompletionItemKind.InternalProperty]: 'var',
[greybel_type_analyzer_1.CompletionItemKind.ListConstructor]: 'list',
[greybel_type_analyzer_1.CompletionItemKind.Literal]: 'literal',
[greybel_type_analyzer_1.CompletionItemKind.MapConstructor]: 'map',
[greybel_type_analyzer_1.CompletionItemKind.Property]: 'var',
[greybel_type_analyzer_1.CompletionItemKind.Unknown]: 'unknown',
[greybel_type_analyzer_1.CompletionItemKind.Variable]: 'var'
};
function formatKind(kind) {
return CompletionItemKindMapping[kind] || 'unknown';
}
exports.formatKind = formatKind;
const TYPE_CUSTOM_SORT_PRIORITY = {
[signature_definition_1.SignatureDefinitionBaseType.Any]: 1000,
[greybel_type_analyzer_1.UNKNOWN_TYPE_ID]: 1001,
[greybel_type_analyzer_1.NIL_TYPE_ID]: 1002
};
function sortTypes(types) {
return types.sort((a, b) => {
const aPriority = TYPE_CUSTOM_SORT_PRIORITY[a] || 0;
const bPriority = TYPE_CUSTOM_SORT_PRIORITY[b] || 0;
if (aPriority !== bPriority) {
return aPriority - bPriority;
}
return a.localeCompare(b);
});
}
exports.sortTypes = sortTypes;
function formatTypes(types) {
if (types == null)
return '';
return sortTypes(types.map((item) => item.toString().replace(',', '٫'))).join(' or ');
}
exports.formatTypes = formatTypes;
function formatDefaultValue(value) {
if (typeof value === 'string') {
return `"${value}"`;
}
return value.toString();
}
exports.formatDefaultValue = formatDefaultValue;
const createTooltipHeader = (item, definition) => {
const args = definition.getArguments() || [];
const returnValues = formatTypes(definition.getReturns()) || 'null';
if (args.length === 0) {
return `(${formatKind(item.completionItemKind)}) ${item.path} (): ${returnValues}`;
}
const argValues = args
.map((item) => `${item.getLabel()}${item.isOptional() ? '?' : ''}: ${formatTypes(item.getTypes())}${item.getDefault()
? ` = ${formatDefaultValue(item.getDefault().value)}`
: ''}`)
.join(', ');
return `(${formatKind(item.completionItemKind)}) ${item.path} (${argValues}): ${returnValues}`;
};
exports.createTooltipHeader = createTooltipHeader;
const appendTooltipHeader = (text, item, definition) => {
text.appendCodeblock(types_1.LanguageId, (0, exports.createTooltipHeader)(item, definition));
text.appendMarkdown('***\n');
};
exports.appendTooltipHeader = appendTooltipHeader;
const appendTooltipBody = (text, definition) => {
const example = definition.getExample() || [];
text.appendMarkdown(definition.getDescription() + '\n');
if (example.length > 0) {
text.appendMarkdown('#### Examples:\n');
text.appendCodeblock(types_1.LanguageId, example.join('\n'));
}
};
exports.appendTooltipBody = appendTooltipBody;
const createSignatureInfo = (entity) => {
if (!(0, greybel_type_analyzer_1.isFunctionType)(entity.item) && !(0, greybel_type_analyzer_1.isUnionType)(entity.item))
return null;
const items = (0, greybel_type_analyzer_1.isFunctionType)(entity.item)
? [entity.item]
: entity.item.variants.filter(greybel_type_analyzer_1.isFunctionType);
const signatureInfos = [];
for (const item of items) {
const fnDef = item.signature;
const label = (0, exports.createTooltipHeader)(entity, fnDef);
const signatureInfo = { label };
const args = fnDef.getArguments() ?? [];
const text = new markdown_string_1.MarkdownString('');
(0, exports.appendTooltipBody)(text, fnDef);
signatureInfo.parameters = args.map((argItem) => {
return {
label: `${argItem.getLabel()}${argItem.isOptional() ? '?' : ''}: ${argItem
.getTypes()
.join(' or ')}`
};
});
signatureInfo.documentation = text.toString();
signatureInfos.push(signatureInfo);
}
return signatureInfos;
};
exports.createSignatureInfo = createSignatureInfo;
const createHover = (entity) => {
if (!(0, greybel_type_analyzer_1.isFunctionType)(entity.item) && !(0, greybel_type_analyzer_1.isUnionType)(entity.item))
return null;
const items = (0, greybel_type_analyzer_1.isFunctionType)(entity.item)
? [entity.item]
: entity.item.variants.filter(greybel_type_analyzer_1.isFunctionType);
const texts = [];
for (const item of items) {
const text = new markdown_string_1.MarkdownString('');
const fnDef = item.signature;
(0, exports.appendTooltipHeader)(text, entity, fnDef);
(0, exports.appendTooltipBody)(text, fnDef);
texts.push(text);
}
return {
contents: texts.map((it) => it.toString())
};
};
exports.createHover = createHover;
const createTypeBody = (item) => {
const queue = [];
if ((0, greybel_type_analyzer_1.isMapType)(item) || (0, greybel_type_analyzer_1.isUnknownType)(item) || (0, greybel_type_analyzer_1.isClassType)(item)) {
queue.push(item);
}
else if ((0, greybel_type_analyzer_1.isUnionType)(item)) {
queue.push(...item.variants.filter((it) => (0, greybel_type_analyzer_1.isMapType)(it) || (0, greybel_type_analyzer_1.isUnknownType)(it) || (0, greybel_type_analyzer_1.isClassType)(it)));
}
const records = new Map();
for (const entity of queue) {
if (entity.properties == null)
continue;
for (const [key, item] of entity.properties) {
if (typeof key !== 'string')
continue;
const metaTypes = item.type
.toMeta()
.map(meta_utils_1.SignatureDefinitionTypeMeta.parse);
records.set(key, formatTypes(metaTypes));
}
}
if (records.size === 0) {
return null;
}
const sortedEntries = Array.from(records.entries()).sort(([a], [b]) => a.localeCompare(b));
return Object.fromEntries(sortedEntries);
};
exports.createTypeBody = createTypeBody;
//# sourceMappingURL=tooltip.js.map