Skip to content

Commit

Permalink
refactor(reference): replace toValue method with function (#3207)
Browse files Browse the repository at this point in the history
Refs #3198
  • Loading branch information
char0n authored Oct 2, 2023
1 parent 376530f commit ed66e19
Show file tree
Hide file tree
Showing 21 changed files with 205 additions and 181 deletions.
20 changes: 19 additions & 1 deletion packages/apidom-core/src/transformers/serializers/value/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ import {
ArrayElement,
ObjectElement,
MemberElement,
NullElement,
} from 'minim';

import { visit } from './visitor';
import EphemeralArray from './ast/ephemeral-array';
import EphemeralObject from './ast/ephemeral-object';
import { isElement } from '../../../predicates';
import {
isElement,
isBooleanElement,
isNumberElement,
isStringElement,
isNullElement,
} from '../../../predicates';

/* eslint-disable @typescript-eslint/naming-convention */
const Visitor = stampit.init(function _Visitor() {
Expand Down Expand Up @@ -72,9 +79,20 @@ const Visitor = stampit.init(function _Visitor() {
});
/* eslint-enable */

type ShortCutElementTypes = StringElement | NumberElement | BooleanElement | NullElement;
const serializer = <T extends Element | unknown>(element: T): any => {
if (!isElement(element)) return element;

// shortcut optimization for certain element types
if (
isStringElement(element) ||
isNumberElement(element) ||
isBooleanElement(element) ||
isNullElement(element)
) {
return (element as ShortCutElementTypes).toValue();
}

return visit(element as Exclude<T, unknown>, Visitor());
};

Expand Down
65 changes: 28 additions & 37 deletions packages/apidom-ls/src/services/completion/completion-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
isObjectElement,
isStringElement,
MemberElement,
toValue,
} from '@swagger-api/apidom-core';

import {
Expand Down Expand Up @@ -161,11 +162,11 @@ export class DefaultCompletionService implements CompletionService {
// TODO move to NS adapter plugin
// TODO replace this with checking metadata refObject in parent
// assume it's a value node within a member
if (isMember(node) && (node.key as Element).toValue() === '$ref') {
if (isMember(node) && toValue(node.key) === '$ref') {
return true;
}
const { parent } = node;
return parent && isMember(parent) && (parent.key as Element).toValue() === '$ref';
return parent && isMember(parent) && toValue(parent.key) === '$ref';
}

// eslint-disable-next-line class-methods-use-this
Expand Down Expand Up @@ -552,8 +553,8 @@ export class DefaultCompletionService implements CompletionService {
completionNode = this.resolveCompletionNode(node, caretContext);
const completionNodeContext = this.resolveCompletionNodeContext(caretContext);

debug('doCompletion - node', node.element, node.toValue());
debug('doCompletion - completionNode', completionNode.element, completionNode.toValue());
debug('doCompletion - node', node.element, toValue(node));
debug('doCompletion - completionNode', completionNode.element, toValue(completionNode));
debug('doCompletion - caretContext', caretContext);
debug('doCompletion - completionNodeContext', completionNodeContext);

Expand Down Expand Up @@ -620,7 +621,7 @@ export class DefaultCompletionService implements CompletionService {
debug('doCompletion - adding property');
for (const p of completionNode) {
if (!node.parent || node.parent !== p || emptyLine) {
proposed[p.key.toValue()] = CompletionItem.create('__');
proposed[toValue(p.key)] = CompletionItem.create('__');
}
}
const nonEmptyContentRange = getNonEmptyContentRange(textDocument, offset);
Expand Down Expand Up @@ -737,7 +738,7 @@ export class DefaultCompletionService implements CompletionService {
nodeValueFromText.charAt(0) === '"' || nodeValueFromText.charAt(0) === "'"
? nodeValueFromText.charAt(0)
: undefined;
proposed[completionNode.toValue()] = CompletionItem.create('__');
proposed[toValue(completionNode)] = CompletionItem.create('__');
proposed[nodeValueFromText] = CompletionItem.create('__');
// if node is not empty we must replace text
if (nodeValueFromText.length > 0) {
Expand Down Expand Up @@ -889,9 +890,7 @@ export class DefaultCompletionService implements CompletionService {
): Promise<CompletionItem[]> {
const result: CompletionItem[] = [];
// get type of node (element)
const refElementType = node.parent?.parent
?.getMetaProperty('referenced-element', '')
?.toValue();
const refElementType = toValue(node.parent?.parent?.getMetaProperty('referenced-element', ''));
const nodeElement =
refElementType && refElementType.length > 0 ? refElementType : node.parent?.parent?.element;
if (!nodeElement) return result;
Expand Down Expand Up @@ -989,21 +988,19 @@ export class DefaultCompletionService implements CompletionService {
const apidomCompletions: ApidomCompletionItem[] = [];
let set: string[] = [];
if (node.classes) {
set = Array.from(new Set(node.classes.toValue()));
set = Array.from(new Set(toValue(node.classes)));
}
const referencedElement = node.getMetaProperty('referenced-element', '').toValue();
const referencedElement = toValue(node.getMetaProperty('referenced-element', ''));
// TODO maybe move to adapter
if (referencedElement.length > 0 && referencedElement === 'schema') {
set.unshift('schema');
}
set.unshift(node.element);
set.forEach((s) => {
debug('getMetadataPropertyCompletions - class', s);
const classCompletions: ApidomCompletionItem[] = doc.meta
.get('metadataMap')
?.get(s)
?.get('completion')
?.toValue();
const classCompletions: ApidomCompletionItem[] = toValue(
doc.meta.get('metadataMap')?.get(s)?.get('completion'),
);
if (classCompletions) {
apidomCompletions.push(...classCompletions.filter((ci) => !ci.target));
}
Expand All @@ -1012,16 +1009,14 @@ export class DefaultCompletionService implements CompletionService {
// get parent
if (node.parent && isMember(node.parent)) {
const containerNode = node.parent.parent;
const key = (node.parent.key as Element).toValue();
const key = toValue(node.parent.key);
// get metadata of parent with target
const containerNodeSet: string[] = Array.from(new Set(containerNode.classes.toValue()));
const containerNodeSet: string[] = Array.from(new Set(toValue(containerNode.classes)));
containerNodeSet.unshift(containerNode.element);
containerNodeSet.forEach((containerNodeSymbol) => {
const containerNodeClassCompletions: ApidomCompletionItem[] = doc.meta
.get('metadataMap')
?.get(containerNodeSymbol)
?.get('completion')
?.toValue();
const containerNodeClassCompletions: ApidomCompletionItem[] = toValue(
doc.meta.get('metadataMap')?.get(containerNodeSymbol)?.get('completion'),
);
if (containerNodeClassCompletions) {
apidomCompletions.push(
...containerNodeClassCompletions.filter((ci) => ci.target === key && !ci.arrayMember),
Expand All @@ -1036,16 +1031,14 @@ export class DefaultCompletionService implements CompletionService {
const arrayParent = node.parent;
if (arrayParent.parent && isMember(arrayParent.parent)) {
const containerNode = arrayParent.parent.parent;
const key = (arrayParent.parent.key as Element).toValue();
const key = toValue(arrayParent.parent.key);
// get metadata of parent with target
const containerNodeSet: string[] = Array.from(new Set(containerNode.classes.toValue()));
const containerNodeSet: string[] = Array.from(new Set(toValue(containerNode.classes)));
containerNodeSet.unshift(containerNode.element);
containerNodeSet.forEach((containerNodeSymbol) => {
const containerNodeClassCompletions: ApidomCompletionItem[] = doc.meta
.get('metadataMap')
?.get(containerNodeSymbol)
?.get('completion')
?.toValue();
const containerNodeClassCompletions: ApidomCompletionItem[] = toValue(
doc.meta.get('metadataMap')?.get(containerNodeSymbol)?.get('completion'),
);
if (containerNodeClassCompletions) {
apidomCompletions.push(
...containerNodeClassCompletions.filter((ci) => {
Expand Down Expand Up @@ -1076,16 +1069,14 @@ export class DefaultCompletionService implements CompletionService {
if (!yaml && isArray(node)) {
if (node.parent && isMember(node.parent)) {
const containerNode = node.parent.parent;
const key = (node.parent.key as Element).toValue();
const key = toValue(node.parent.key);
// get metadata of parent with target
const containerNodeSet: string[] = Array.from(new Set(containerNode.classes.toValue()));
const containerNodeSet: string[] = Array.from(new Set(toValue(containerNode.classes)));
containerNodeSet.unshift(containerNode.element);
containerNodeSet.forEach((containerNodeSymbol) => {
const containerNodeClassCompletions: ApidomCompletionItem[] = doc.meta
.get('metadataMap')
?.get(containerNodeSymbol)
?.get('completion')
?.toValue();
const containerNodeClassCompletions: ApidomCompletionItem[] = toValue(
doc.meta.get('metadataMap')?.get(containerNodeSymbol)?.get('completion'),
);
if (containerNodeClassCompletions) {
apidomCompletions.push(
...containerNodeClassCompletions.filter((ci) => {
Expand Down
24 changes: 15 additions & 9 deletions packages/apidom-ls/src/services/definition/definition-service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { TextDocument } from 'vscode-languageserver-textdocument';
import { Element, findAtOffset, ObjectElement, MemberElement } from '@swagger-api/apidom-core';
import {
findAtOffset,
toValue,
Element,
ObjectElement,
MemberElement,
} from '@swagger-api/apidom-core';
import { Location, Range } from 'vscode-languageserver-types';
import { DefinitionParams, ReferenceParams } from 'vscode-languageserver-protocol';
import { evaluate as jsonPointerEvaluate } from '@swagger-api/apidom-json-pointer';
Expand Down Expand Up @@ -59,11 +65,11 @@ export class DefaultDefinitionService implements DefinitionService {
} else {
el = (<MemberElement>node.parent).key as ObjectElement;
}
if (el?.toValue() !== '$ref') {
if (toValue(el) !== '$ref') {
return null;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ref = node.toValue();
const ref = toValue(node);
// TODO ([email protected]): handle by URL parsing
if (!ref.startsWith('#') && node.parent?.parent) {
try {
Expand All @@ -87,8 +93,8 @@ export class DefaultDefinitionService implements DefinitionService {
'definitionService - go to external ref',
`mediaType: ${mediaType}`,
`textDocument.uri: ${textDocument.uri}`,
`node value: ${JSON.stringify(node.toValue())}`,
`parent value: ${JSON.stringify(node.parent.parent.toValue())}`,
`node value: ${JSON.stringify(toValue(node))}`,
`parent value: ${JSON.stringify(toValue(node.parent.parent))}`,
);
const dereferenced = await dereferenceApiDOM(node.parent.parent, {
parse: { mediaType, parserOpts: { sourceMap: true } },
Expand All @@ -101,9 +107,9 @@ export class DefaultDefinitionService implements DefinitionService {
});
debug(
'definitionService - go to external ref',
`dereferenced value: ${dereferenced.toValue()}`,
`dereferenced value: ${toValue(dereferenced)}`,
);
const newUri = dereferenced.meta.get('ref-origin').toValue();
const newUri = toValue(dereferenced.meta.get('ref-origin'));
debug('definitionService - go to external ref', `dereferenced file URI: ${newUri}`);
const nodeSourceMap = getSourceMap(dereferenced);
const range = Range.create(
Expand Down Expand Up @@ -163,11 +169,11 @@ export class DefaultDefinitionService implements DefinitionService {
} else {
el = (<MemberElement>node.parent).key as ObjectElement;
}
if (el?.toValue() !== '$ref') {
if (toValue(el) !== '$ref') {
return null;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ref = node.toValue();
const ref = toValue(node);
// TODO ([email protected]): handle by URL parsing
if (!ref.startsWith('#')) {
return null;
Expand Down
7 changes: 4 additions & 3 deletions packages/apidom-ls/src/services/deref/deref-service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { TextDocument } from 'vscode-languageserver-textdocument';
import { dereferenceApiDOM } from '@swagger-api/apidom-reference';
import { isString } from 'ramda-adjunct';
import {
ArraySlice,
Expand All @@ -9,7 +8,9 @@ import {
toJSON,
toString,
toYAML,
toValue,
} from '@swagger-api/apidom-core';
import { dereferenceApiDOM } from '@swagger-api/apidom-reference';

import { DerefContext, Format, LanguageSettings } from '../../apidom-language-types';
import { parse } from '../../parser-factory';
Expand Down Expand Up @@ -56,12 +57,12 @@ export class DefaultDerefService implements DerefService {
let baseURI: string | undefined = '/foo';

const servers: ArraySlice = filter((el: Element) => {
return el.classes.toValue().includes('servers');
return toValue(el.classes).includes('servers');
}, api);

// TODO ([email protected]): this needs to be replaced by good metadata ('serverURL' to URLS and/or adapter/plugin
if (servers && !servers.isEmpty) {
const serversValue = servers.first.toValue();
const serversValue = toValue(servers.first);
// OAS
if (Array.isArray(serversValue)) {
if (!servers.isEmpty) {
Expand Down
34 changes: 20 additions & 14 deletions packages/apidom-ls/src/services/hover/hover-service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { TextDocument } from 'vscode-languageserver-textdocument';
import { Hover } from 'vscode-languageserver-protocol';
import { findAtOffset, ObjectElement, MemberElement, Element } from '@swagger-api/apidom-core';
import {
findAtOffset,
toValue,
ObjectElement,
MemberElement,
Element,
} from '@swagger-api/apidom-core';
import { MarkupContent, Position, Range } from 'vscode-languageserver-types';
import { dereferenceApiDOM } from '@swagger-api/apidom-reference';
import { evaluate as jsonPointerEvaluate } from '@swagger-api/apidom-json-pointer';
Expand Down Expand Up @@ -123,14 +129,14 @@ export class DefaultHoverService implements HoverService {
}
let elementValue = el.element;

const referencedElement = el.getMetaProperty('referenced-element', '').toValue();
const referencedElement = toValue(el.getMetaProperty('referenced-element', ''));
if (referencedElement.length > 0) {
elementValue = referencedElement;
}

let hoverLine = '';
if (el.parent && isMember(el.parent)) {
hoverLine = `***${(node.parent.key as Element).toValue()}***: `;
hoverLine = `***${toValue(node.parent.key)}***: `;
}
hoverLine = `${hoverLine}**${elementValue}**\n`;

Expand All @@ -148,7 +154,7 @@ export class DefaultHoverService implements HoverService {
docs = this.getMetadataPropertyDocs(el, docNs, el.element, specVersion);
}
if (!docs) {
const classes = el.classes.toValue();
const classes = toValue(el.classes);
for (const c of classes) {
docs = this.getMetadataPropertyDocs(el, docNs, c, specVersion);
if (docs) {
Expand All @@ -166,8 +172,8 @@ export class DefaultHoverService implements HoverService {
} else {
el = (<MemberElement>node.parent).key as ObjectElement;
}
if (el?.toValue() === '$ref') {
const ref = node.toValue();
if (toValue(el) === '$ref') {
const ref = toValue(node);
// TODO ([email protected]): handle by URL parsing
if (!ref.startsWith('#') && node.parent?.parent) {
try {
Expand All @@ -191,8 +197,8 @@ export class DefaultHoverService implements HoverService {
'hoverService - computeHover',
`mediaType: ${mediaType}`,
`textDocument.uri: ${textDocument.uri}`,
`node value: ${JSON.stringify(node.toValue())}`,
`parent value: ${JSON.stringify(node.parent.parent.toValue())}`,
`node value: ${JSON.stringify(toValue(node))}`,
`parent value: ${JSON.stringify(toValue(node.parent.parent))}`,
);
const dereferenced = await dereferenceApiDOM(node.parent.parent, {
parse: { mediaType, parserOpts: { sourceMap: true } },
Expand All @@ -206,9 +212,9 @@ export class DefaultHoverService implements HoverService {
if (dereferenced) {
debug(
'hoverService - computeHover',
`dereferenced value: ${dereferenced.toValue()}`,
`dereferenced value: ${toValue(dereferenced)}`,
);
const targetVal = JSON.stringify(dereferenced.toValue(), null, 2);
const targetVal = JSON.stringify(toValue(dereferenced), null, 2);
contents.push(`\n\n\n\n\`\`\`json\n${targetVal}\n\`\`\``);
}
} catch (e) {
Expand Down Expand Up @@ -280,7 +286,7 @@ export class DefaultHoverService implements HoverService {
}
} else if (this.settings?.hoverFollowLinkEntry) {
// check if we have a "URL like" value, and add a link in case
const nodeValue = node.toValue();
const nodeValue = toValue(node);
// if (/^https?:\/\/[^\s]+.*/.test(nodeValue)) {
if (WEB_LINK_REGEX.test(nodeValue)) {
contents.push(`[follow link](${nodeValue})`);
Expand Down Expand Up @@ -360,10 +366,10 @@ export class DefaultHoverService implements HoverService {
const map: MetadataMap = this.settings?.metadata?.metadataMaps[ns] || {};
if (node.parent && isMember(node.parent)) {
const containerNode = node.parent.parent;
const nodeKey = (node.parent.key as Element).toValue();
const containerNodeSet: string[] = Array.from(new Set(containerNode.classes.toValue()));
const nodeKey = toValue(node.parent.key);
const containerNodeSet: string[] = Array.from(new Set(toValue(containerNode.classes)));
containerNodeSet.unshift(containerNode.element);
const referencedElement = containerNode.getMetaProperty('referenced-element', '').toValue();
const referencedElement = toValue(containerNode.getMetaProperty('referenced-element', ''));
if (referencedElement.length > 0) {
containerNodeSet.unshift(referencedElement);
}
Expand Down
Loading

0 comments on commit ed66e19

Please sign in to comment.