Skip to content

Commit 576d597

Browse files
committed
feat(lsp): Add completion for the constraint reference inside value types
1 parent 334d83d commit 576d597

File tree

1 file changed

+71
-22
lines changed

1 file changed

+71
-22
lines changed

libs/language-server/src/lib/lsp/jayvee-completion-provider.ts

Lines changed: 71 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
type LangiumDocument,
1212
type LangiumDocuments,
1313
type MaybePromise,
14+
type Stream,
1415
UriUtils,
1516
} from 'langium';
1617
import {
@@ -36,6 +37,7 @@ import {
3637
type ValueTypeConstraintReference,
3738
ValueTypeReference,
3839
isBlockDefinition,
40+
isConstraintDefinition,
3941
isImportDefinition,
4042
isJayveeModel,
4143
isPropertyAssignment,
@@ -83,11 +85,22 @@ export class JayveeCompletionProvider extends DefaultCompletionProvider {
8385
return this.completionForValuetype(context, acceptor);
8486
}
8587

86-
const isValueTypeConstraintReferenceCompletion =
88+
const isValueTypeConstraintReferenceDefinitionCompletion =
89+
isValueTypeConstraintReference(astNode) &&
90+
next.property === 'definition';
91+
if (isValueTypeConstraintReferenceDefinitionCompletion) {
92+
return this.completionForValueTypeConstraintDefinitionReference(
93+
astNode,
94+
context,
95+
acceptor,
96+
);
97+
}
98+
99+
const isValueTypeConstraintReferenceAttributeCompletion =
87100
isValueTypeConstraintReference(astNode) &&
88101
next.property === 'attribute';
89-
if (isValueTypeConstraintReferenceCompletion) {
90-
return this.completionForValueTypeConstraintReference(
102+
if (isValueTypeConstraintReferenceAttributeCompletion) {
103+
return this.completionForValueTypeConstraintAttributeReference(
91104
astNode,
92105
context,
93106
acceptor,
@@ -143,34 +156,70 @@ export class JayveeCompletionProvider extends DefaultCompletionProvider {
143156
});
144157
}
145158

159+
private allAstNodes(): Stream<AstNode> {
160+
return this.langiumDocuments.all
161+
.map((document) => document.parseResult.value)
162+
.flatMap((parsedDocument) => {
163+
if (!isJayveeModel(parsedDocument)) {
164+
throw new Error('Expected parsed document to be a JayveeModel');
165+
}
166+
return AstUtils.streamAllContents(parsedDocument);
167+
});
168+
}
169+
146170
private completionForValuetype(
147171
context: CompletionContext,
148172
acceptor: CompletionAcceptor,
149173
): MaybePromise<void> {
150-
this.langiumDocuments.all
151-
.map((document) => document.parseResult.value)
152-
.forEach((parsedDocument) => {
153-
if (!isJayveeModel(parsedDocument)) {
154-
throw new Error('Expected parsed document to be a JayveeModel');
174+
this.allAstNodes()
175+
.filter(isValuetypeDefinition)
176+
.forEach((valueTypeDefinition) => {
177+
const valueType =
178+
this.wrapperFactories.ValueType.wrap(valueTypeDefinition);
179+
if (valueType !== undefined && valueType.isReferenceableByUser()) {
180+
acceptor(context, {
181+
label: valueTypeDefinition.name,
182+
kind: CompletionItemKind.Class,
183+
detail: `(valueType)`,
184+
});
155185
}
156-
const allValueTypes = AstUtils.streamAllContents(parsedDocument).filter(
157-
isValuetypeDefinition,
186+
});
187+
}
188+
189+
private completionForValueTypeConstraintDefinitionReference(
190+
astNode: ValueTypeConstraintReference,
191+
context: CompletionContext,
192+
acceptor: CompletionAcceptor,
193+
) {
194+
const propertyValueType = this.wrapperFactories.ValueType.wrap(
195+
astNode.$container.attribute?.valueType.reference.ref,
196+
);
197+
198+
const constraintDefinitionsWithSameValueType = this.allAstNodes()
199+
.filter(isConstraintDefinition)
200+
.filter((constraintDefinition) => {
201+
if (propertyValueType === undefined) {
202+
return true;
203+
}
204+
const constraintValueType = this.wrapperFactories.ValueType.wrap(
205+
constraintDefinition.valueType.reference.ref,
158206
);
159-
allValueTypes.forEach((valueTypeDefinition) => {
160-
const valueType =
161-
this.wrapperFactories.ValueType.wrap(valueTypeDefinition);
162-
if (valueType !== undefined && valueType.isReferenceableByUser()) {
163-
acceptor(context, {
164-
label: valueTypeDefinition.name,
165-
kind: CompletionItemKind.Class,
166-
detail: `(valueType)`,
167-
});
168-
}
169-
});
207+
if (constraintValueType === undefined) {
208+
return false;
209+
}
210+
return constraintValueType.equals(propertyValueType);
211+
});
212+
213+
constraintDefinitionsWithSameValueType.forEach((constraintDefinition) => {
214+
acceptor(context, {
215+
label: constraintDefinition.name,
216+
kind: CompletionItemKind.Reference,
217+
detail: '(constraint definition)',
170218
});
219+
});
171220
}
172221

173-
private completionForValueTypeConstraintReference(
222+
private completionForValueTypeConstraintAttributeReference(
174223
astNode: ValueTypeConstraintReference,
175224
context: CompletionContext,
176225
acceptor: CompletionAcceptor,

0 commit comments

Comments
 (0)