Skip to content

Commit

Permalink
Apply PR feedback and use fixed property order in grammar
Browse files Browse the repository at this point in the history
- Slightly improve completion provider
- Fix up test cases with newly specified mandatory properties
  • Loading branch information
martin-fleck-at committed Mar 10, 2024
1 parent 87d0e88 commit 4cb931c
Show file tree
Hide file tree
Showing 22 changed files with 1,208 additions and 1,441 deletions.
Expand Up @@ -27,6 +27,10 @@ import { fixDocument } from './util/ast-util.js';
export class CrossModelCompletionProvider extends DefaultCompletionProvider {
protected packageId?: string;

readonly completionOptions = {
triggerCharacters: ['\n', ' ']
};

constructor(
services: CrossModelServices,
protected packageManager = services.shared.workspace.PackageManager
Expand All @@ -53,6 +57,14 @@ export class CrossModelCompletionProvider extends DefaultCompletionProvider {
return context;
}

protected override filterKeyword(context: CompletionContext, keyword: GrammarAST.Keyword): boolean {
return super.filterKeyword(context, keyword) && this.isUndefinedProperty(context.node, keyword.value);
}

protected isUndefinedProperty(obj: any, property: string): boolean {
return obj?.[property] === undefined || (Array.isArray(obj[property]) && obj[property].length === 0);
}

protected completionForAssignment(
context: CompletionContext,
assignment: GrammarAST.Assignment,
Expand Down
Expand Up @@ -95,9 +95,7 @@ export class CrossModelValidator {
if (attribute.parent.ref) {
if (attribute.parent?.ref?.$container !== relationship.parent?.ref) {
accept('error', 'Not a valid parent attribute.', { node: attribute, property: 'parent' });
}
if (usedParentAttributes.includes(attribute.parent.ref)) {
// duplicate detected
} else if (usedParentAttributes.includes(attribute.parent.ref)) {
accept('error', 'Each parent attribute can only be referenced once.', { node: attribute, property: 'parent' });
} else {
usedParentAttributes.push(attribute.parent.ref);
Expand All @@ -106,9 +104,7 @@ export class CrossModelValidator {
if (attribute.child.ref) {
if (attribute.child?.ref?.$container !== relationship.child?.ref) {
accept('error', 'Not a valid child attribute.', { node: attribute, property: 'child' });
}
if (usedChildAttributes.includes(attribute.child.ref)) {
// duplicate detected
} else if (usedChildAttributes.includes(attribute.child.ref)) {
accept('error', 'Each child attribute can only be referenced once.', { node: attribute, property: 'child' });
} else {
usedChildAttributes.push(attribute.child.ref);
Expand Down
36 changes: 14 additions & 22 deletions extensions/crossmodel-lang/src/language-server/entity.langium
Expand Up @@ -3,37 +3,29 @@ import 'terminals'
// Entity definition
Entity:
'entity' ':'
(
INDENT
(
'id' ':' id=ID |
'name' ':' name=STRING |
'description' ':' description=STRING |
'attributes' ':' EntityAttributes
)*
'id' ':' id=ID
('name' ':' name=STRING)?
('description' ':' description=STRING)?
('attributes' ':'
INDENT
('-' attributes+=EntityAttribute)+
DEDENT
)?
DEDENT
)*
;

interface Attribute {
id: string;
name?: string;
name: string;
datatype: string;
description?: string;
datatype: string;
}

interface EntityAttribute extends Attribute {}

EntityAttributes infers Entity:
INDENT
(attributes+=EntityAttribute)*
DEDENT;

EntityAttribute returns EntityAttribute:
'-' (
'id' ':' id=ID |
'name' ':' name=STRING |
'datatype' ':' datatype=STRING |
'description' ':' description=STRING
)*
;
'id' ':' id=ID
'name' ':' name=STRING
'datatype' ':' datatype=STRING
('description' ':' description=STRING)?;
33 changes: 16 additions & 17 deletions extensions/crossmodel-lang/src/language-server/generated/ast.ts
Expand Up @@ -51,7 +51,7 @@ export interface Attribute extends AstNode {
datatype: string
description?: string
id: string
name?: string
name: string
}

export const Attribute = 'Attribute';
Expand Down Expand Up @@ -104,7 +104,7 @@ export interface Entity extends AstNode {
readonly $type: 'Entity';
attributes: Array<EntityAttribute>
description?: string
id?: string
id: string
name?: string
}

Expand All @@ -118,13 +118,13 @@ export interface EntityNode extends AstNode {
readonly $container: SystemDiagram;
readonly $type: 'EntityNode';
description?: string
entity?: Reference<Entity>
height?: number
id?: string
entity: Reference<Entity>
height: number
id: string
name?: string
width?: number
x?: number
y?: number
width: number
x: number
y: number
}

export const EntityNode = 'EntityNode';
Expand Down Expand Up @@ -201,12 +201,12 @@ export interface Relationship extends AstNode {
readonly $container: CrossModelRoot;
readonly $type: 'Relationship';
attributes: Array<RelationshipAttribute>
child?: Reference<Entity>
child: Reference<Entity>
description?: string
id?: string
id: string
name?: string
parent?: Reference<Entity>
type?: string
parent: Reference<Entity>
type: string
}

export const Relationship = 'Relationship';
Expand All @@ -219,7 +219,6 @@ export interface RelationshipAttribute extends AstNode {
readonly $container: Relationship;
readonly $type: 'RelationshipAttribute';
child: Reference<Attribute>
description?: string
parent: Reference<Attribute>
}

Expand All @@ -244,10 +243,10 @@ export function isRelationshipCondition(item: unknown): item is RelationshipCond
export interface RelationshipEdge extends AstNode {
readonly $container: SystemDiagram;
readonly $type: 'RelationshipEdge';
id?: string
relationship?: Reference<Relationship>
sourceNode?: Reference<EntityNode>
targetNode?: Reference<EntityNode>
id: string
relationship: Reference<Relationship>
sourceNode: Reference<EntityNode>
targetNode: Reference<EntityNode>
}

export const RelationshipEdge = 'RelationshipEdge';
Expand Down

0 comments on commit 4cb931c

Please sign in to comment.