diff --git a/extensions/crossmodel-lang/src/language-server/cross-model-completion-provider.ts b/extensions/crossmodel-lang/src/language-server/cross-model-completion-provider.ts index 5ab060b..e18b567 100644 --- a/extensions/crossmodel-lang/src/language-server/cross-model-completion-provider.ts +++ b/extensions/crossmodel-lang/src/language-server/cross-model-completion-provider.ts @@ -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 @@ -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, diff --git a/extensions/crossmodel-lang/src/language-server/cross-model-validator.ts b/extensions/crossmodel-lang/src/language-server/cross-model-validator.ts index 3c2a07d..cc2b14f 100644 --- a/extensions/crossmodel-lang/src/language-server/cross-model-validator.ts +++ b/extensions/crossmodel-lang/src/language-server/cross-model-validator.ts @@ -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); @@ -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); diff --git a/extensions/crossmodel-lang/src/language-server/entity.langium b/extensions/crossmodel-lang/src/language-server/entity.langium index d78032d..ac6a5dc 100644 --- a/extensions/crossmodel-lang/src/language-server/entity.langium +++ b/extensions/crossmodel-lang/src/language-server/entity.langium @@ -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)?; diff --git a/extensions/crossmodel-lang/src/language-server/generated/ast.ts b/extensions/crossmodel-lang/src/language-server/generated/ast.ts index 87584a3..fe2b912 100644 --- a/extensions/crossmodel-lang/src/language-server/generated/ast.ts +++ b/extensions/crossmodel-lang/src/language-server/generated/ast.ts @@ -51,7 +51,7 @@ export interface Attribute extends AstNode { datatype: string description?: string id: string - name?: string + name: string } export const Attribute = 'Attribute'; @@ -104,7 +104,7 @@ export interface Entity extends AstNode { readonly $type: 'Entity'; attributes: Array description?: string - id?: string + id: string name?: string } @@ -118,13 +118,13 @@ export interface EntityNode extends AstNode { readonly $container: SystemDiagram; readonly $type: 'EntityNode'; description?: string - entity?: Reference - height?: number - id?: string + entity: Reference + height: number + id: string name?: string - width?: number - x?: number - y?: number + width: number + x: number + y: number } export const EntityNode = 'EntityNode'; @@ -201,12 +201,12 @@ export interface Relationship extends AstNode { readonly $container: CrossModelRoot; readonly $type: 'Relationship'; attributes: Array - child?: Reference + child: Reference description?: string - id?: string + id: string name?: string - parent?: Reference - type?: string + parent: Reference + type: string } export const Relationship = 'Relationship'; @@ -219,7 +219,6 @@ export interface RelationshipAttribute extends AstNode { readonly $container: Relationship; readonly $type: 'RelationshipAttribute'; child: Reference - description?: string parent: Reference } @@ -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 - sourceNode?: Reference - targetNode?: Reference + id: string + relationship: Reference + sourceNode: Reference + targetNode: Reference } export const RelationshipEdge = 'RelationshipEdge'; diff --git a/extensions/crossmodel-lang/src/language-server/generated/grammar.ts b/extensions/crossmodel-lang/src/language-server/generated/grammar.ts index ceb1881..76d9eda 100644 --- a/extensions/crossmodel-lang/src/language-server/generated/grammar.ts +++ b/extensions/crossmodel-lang/src/language-server/generated/grammar.ts @@ -39,7 +39,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@13" + "$ref": "#/rules@12" }, "arguments": [] } @@ -51,7 +51,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@15" + "$ref": "#/rules@14" }, "arguments": [] } @@ -63,7 +63,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@23" + "$ref": "#/rules@17" }, "arguments": [] } @@ -91,126 +91,141 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "$type": "Keyword", "value": ":" }, + { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@9" + }, + "arguments": [] + }, + { + "$type": "Keyword", + "value": "id" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "id", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@11" + }, + "arguments": [] + } + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "name" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "name", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" + }, + "arguments": [] + } + } + ], + "cardinality": "?" + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "description" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "description", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" + }, + "arguments": [] + } + } + ], + "cardinality": "?" + }, { "$type": "Group", "elements": [ + { + "$type": "Keyword", + "value": "attributes" + }, + { + "$type": "Keyword", + "value": ":" + }, { "$type": "RuleCall", "rule": { - "$ref": "#/rules@10" + "$ref": "#/rules@9" }, "arguments": [] }, { - "$type": "Alternatives", + "$type": "Group", "elements": [ { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "id" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "id", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@12" - }, - "arguments": [] - } - } - ] - }, - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "name" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "name", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] - }, - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "description" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "description", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] + "$type": "Keyword", + "value": "-" }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "attributes" - }, - { - "$type": "Keyword", - "value": ":" + "$type": "Assignment", + "feature": "attributes", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@2" }, - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@2" - }, - "arguments": [] - } - ] + "arguments": [] + } } ], - "cardinality": "*" + "cardinality": "+" }, { "$type": "RuleCall", "rule": { - "$ref": "#/rules@9" + "$ref": "#/rules@8" }, "arguments": [] } ], - "cardinality": "*" + "cardinality": "?" + }, + { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@8" + }, + "arguments": [] } ] }, @@ -223,40 +238,98 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load }, { "$type": "ParserRule", - "name": "EntityAttributes", - "inferredType": { - "$type": "InferredType", - "name": "Entity" + "name": "EntityAttribute", + "returnType": { + "$ref": "#/interfaces@1" }, "definition": { "$type": "Group", "elements": [ { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@10" - }, - "arguments": [] + "$type": "Keyword", + "value": "id" + }, + { + "$type": "Keyword", + "value": ":" }, { "$type": "Assignment", - "feature": "attributes", - "operator": "+=", + "feature": "id", + "operator": "=", "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@3" + "$ref": "#/rules@11" }, "arguments": [] - }, - "cardinality": "*" + } }, { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@9" - }, - "arguments": [] + "$type": "Keyword", + "value": "name" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "name", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "datatype" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "datatype", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" + }, + "arguments": [] + } + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "description" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "description", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" + }, + "arguments": [] + } + } + ], + "cardinality": "?" } ] }, @@ -269,143 +342,15 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load }, { "$type": "ParserRule", - "name": "EntityAttribute", - "returnType": { - "$ref": "#/interfaces@1" - }, - "definition": { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "-" - }, - { - "$type": "Alternatives", - "elements": [ - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "id" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "id", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@12" - }, - "arguments": [] - } - } - ] - }, - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "name" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "name", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] - }, - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "datatype" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "datatype", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] - }, - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "description" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "description", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] - } - ], - "cardinality": "*" - } - ] - }, - "definesHiddenTokens": false, - "entry": false, - "fragment": false, - "hiddenTokens": [], - "parameters": [], - "wildcard": false - }, - { - "$type": "ParserRule", - "name": "IDReference", - "dataType": "string", + "name": "IDReference", + "dataType": "string", "definition": { "$type": "Group", "elements": [ { "$type": "RuleCall", "rule": { - "$ref": "#/rules@12" + "$ref": "#/rules@11" }, "arguments": [] }, @@ -419,7 +364,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@12" + "$ref": "#/rules@11" }, "arguments": [] } @@ -548,194 +493,180 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@10" + "$ref": "#/rules@9" }, "arguments": [] }, { - "$type": "Alternatives", + "$type": "Keyword", + "value": "id" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "id", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@11" + }, + "arguments": [] + } + }, + { + "$type": "Group", "elements": [ { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "id" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "id", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@12" - }, - "arguments": [] - } - } - ] + "$type": "Keyword", + "value": "name" }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "name" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "name", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] + "$type": "Keyword", + "value": ":" }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "description" - }, - { - "$type": "Keyword", - "value": ":" + "$type": "Assignment", + "feature": "name", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" }, - { - "$type": "Assignment", - "feature": "description", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] - }, + "arguments": [] + } + } + ], + "cardinality": "?" + }, + { + "$type": "Group", + "elements": [ { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "parent" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "parent", - "operator": "=", - "terminal": { - "$type": "CrossReference", - "type": { - "$ref": "#/rules@1" - }, - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@4" - }, - "arguments": [] - }, - "deprecatedSyntax": false - } - } - ] + "$type": "Keyword", + "value": "description" }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "child" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "child", - "operator": "=", - "terminal": { - "$type": "CrossReference", - "type": { - "$ref": "#/rules@1" - }, - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@4" - }, - "arguments": [] - }, - "deprecatedSyntax": false - } - } - ] + "$type": "Keyword", + "value": ":" }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "type" - }, - { - "$type": "Keyword", - "value": ":" + "$type": "Assignment", + "feature": "description", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" }, - { - "$type": "Assignment", - "feature": "type", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] + "arguments": [] + } + } + ], + "cardinality": "?" + }, + { + "$type": "Keyword", + "value": "parent" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "parent", + "operator": "=", + "terminal": { + "$type": "CrossReference", + "type": { + "$ref": "#/rules@1" + }, + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@3" + }, + "arguments": [] + }, + "deprecatedSyntax": false + } + }, + { + "$type": "Keyword", + "value": "child" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "child", + "operator": "=", + "terminal": { + "$type": "CrossReference", + "type": { + "$ref": "#/rules@1" + }, + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@3" + }, + "arguments": [] + }, + "deprecatedSyntax": false + } + }, + { + "$type": "Keyword", + "value": "type" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "type", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" + }, + "arguments": [] + } + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "attributes" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@9" + }, + "arguments": [] }, { "$type": "Group", "elements": [ { "$type": "Keyword", - "value": "attributes" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@10" - }, - "arguments": [] + "value": "-" }, { "$type": "Assignment", @@ -744,28 +675,28 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@14" + "$ref": "#/rules@13" }, "arguments": [] - }, - "cardinality": "+" - }, - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@9" - }, - "arguments": [] + } } - ] + ], + "cardinality": "+" + }, + { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@8" + }, + "arguments": [] } ], - "cardinality": "*" + "cardinality": "?" }, { "$type": "RuleCall", "rule": { - "$ref": "#/rules@9" + "$ref": "#/rules@8" }, "arguments": [] } @@ -784,10 +715,6 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "definition": { "$type": "Group", "elements": [ - { - "$type": "Keyword", - "value": "-" - }, { "$type": "Keyword", "value": "parent" @@ -808,7 +735,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, @@ -835,38 +762,12 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, "deprecatedSyntax": false } - }, - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "description" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "description", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ], - "cardinality": "?" } ] }, @@ -903,93 +804,13 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "Group", "elements": [ - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@10" - }, - "arguments": [] - }, - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@16" - }, - "arguments": [], - "cardinality": "*" - }, { "$type": "RuleCall", "rule": { "$ref": "#/rules@9" }, "arguments": [] - } - ], - "cardinality": "*" - } - ] - }, - "definesHiddenTokens": false, - "entry": false, - "fragment": false, - "hiddenTokens": [], - "parameters": [], - "wildcard": false - }, - { - "$type": "ParserRule", - "name": "SystemDiagramFields", - "inferredType": { - "$type": "InferredType", - "name": "SystemDiagram" - }, - "definition": { - "$type": "Alternatives", - "elements": [ - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "nodes" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@17" - }, - "arguments": [] - } - ] - }, - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "edges" - }, - { - "$type": "Keyword", - "value": ":" }, - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@20" - }, - "arguments": [] - } - ] - }, - { - "$type": "Group", - "elements": [ { "$type": "Keyword", "value": "id" @@ -1005,108 +826,172 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@12" + "$ref": "#/rules@11" }, "arguments": [] } - } - ] - }, - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "description" - }, - { - "$type": "Keyword", - "value": ":" }, { - "$type": "Assignment", - "feature": "description", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "name" }, - "arguments": [] - } - } - ] - }, - { - "$type": "Group", - "elements": [ + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "name", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" + }, + "arguments": [] + } + } + ], + "cardinality": "?" + }, { - "$type": "Keyword", - "value": "name" + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "description" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "description", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@4" + }, + "arguments": [] + } + } + ], + "cardinality": "?" }, { - "$type": "Keyword", - "value": ":" + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "nodes" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@9" + }, + "arguments": [] + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "-" + }, + { + "$type": "Assignment", + "feature": "nodes", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@15" + }, + "arguments": [] + } + } + ], + "cardinality": "+" + }, + { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@8" + }, + "arguments": [] + } + ], + "cardinality": "?" }, { - "$type": "Assignment", - "feature": "name", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "edges" }, - "arguments": [] - } - } - ] - } - ] - }, - "definesHiddenTokens": false, - "entry": false, - "fragment": false, - "hiddenTokens": [], - "parameters": [], - "wildcard": false - }, - { - "$type": "ParserRule", - "name": "SystemDiagramNodes", - "inferredType": { - "$type": "InferredType", - "name": "SystemDiagram" - }, - "definition": { - "$type": "Group", - "elements": [ - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@10" - }, - "arguments": [] - }, - { - "$type": "Assignment", - "feature": "nodes", - "operator": "+=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@18" + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@9" + }, + "arguments": [] + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "-" + }, + { + "$type": "Assignment", + "feature": "edges", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@16" + }, + "arguments": [] + } + } + ], + "cardinality": "+" + }, + { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@8" + }, + "arguments": [] + } + ], + "cardinality": "?" }, - "arguments": [] - }, + { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@8" + }, + "arguments": [] + } + ], "cardinality": "*" - }, - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@9" - }, - "arguments": [] } ] }, @@ -1125,123 +1010,30 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "elements": [ { "$type": "Keyword", - "value": "-" - }, - { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@19" - }, - "arguments": [], - "cardinality": "*" - } - ] - }, - "definesHiddenTokens": false, - "entry": false, - "fragment": false, - "hiddenTokens": [], - "parameters": [], - "wildcard": false - }, - { - "$type": "ParserRule", - "name": "EntityNodeFields", - "inferredType": { - "$type": "InferredType", - "name": "EntityNode" - }, - "definition": { - "$type": "Alternatives", - "elements": [ - { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "id" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "id", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@12" - }, - "arguments": [] - } - } - ] + "value": "id" }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "entity" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "entity", - "operator": "=", - "terminal": { - "$type": "CrossReference", - "type": { - "$ref": "#/rules@1" - }, - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@4" - }, - "arguments": [] - }, - "deprecatedSyntax": false - } - } - ] + "$type": "Keyword", + "value": ":" }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "x" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "x", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@6" - }, - "arguments": [] - } - } - ] + "$type": "Assignment", + "feature": "id", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@11" + }, + "arguments": [] + } }, { "$type": "Group", "elements": [ { "$type": "Keyword", - "value": "y" + "value": "name" }, { "$type": "Keyword", @@ -1249,24 +1041,25 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load }, { "$type": "Assignment", - "feature": "y", + "feature": "name", "operator": "=", "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@6" + "$ref": "#/rules@4" }, "arguments": [] } } - ] + ], + "cardinality": "?" }, { "$type": "Group", "elements": [ { "$type": "Keyword", - "value": "width" + "value": "description" }, { "$type": "Keyword", @@ -1274,138 +1067,125 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load }, { "$type": "Assignment", - "feature": "width", + "feature": "description", "operator": "=", "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@6" + "$ref": "#/rules@4" }, "arguments": [] } } - ] + ], + "cardinality": "?" }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "height" - }, - { - "$type": "Keyword", - "value": ":" - }, - { - "$type": "Assignment", - "feature": "height", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@6" - }, - "arguments": [] - } - } - ] + "$type": "Keyword", + "value": "entity" }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "name" + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "entity", + "operator": "=", + "terminal": { + "$type": "CrossReference", + "type": { + "$ref": "#/rules@1" }, - { - "$type": "Keyword", - "value": ":" + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@3" + }, + "arguments": [] }, - { - "$type": "Assignment", - "feature": "name", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] + "deprecatedSyntax": false + } }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "description" + "$type": "Keyword", + "value": "x" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "x", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@5" }, - { - "$type": "Keyword", - "value": ":" + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "y" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "y", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@5" }, - { - "$type": "Assignment", - "feature": "description", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@5" - }, - "arguments": [] - } - } - ] - } - ] - }, - "definesHiddenTokens": false, - "entry": false, - "fragment": false, - "hiddenTokens": [], - "parameters": [], - "wildcard": false - }, - { - "$type": "ParserRule", - "name": "SystemDiagramEdge", - "inferredType": { - "$type": "InferredType", - "name": "SystemDiagram" - }, - "definition": { - "$type": "Group", - "elements": [ + "arguments": [] + } + }, { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@10" - }, - "arguments": [] + "$type": "Keyword", + "value": "width" + }, + { + "$type": "Keyword", + "value": ":" }, { "$type": "Assignment", - "feature": "edges", - "operator": "+=", + "feature": "width", + "operator": "=", "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@21" + "$ref": "#/rules@5" }, "arguments": [] - }, - "cardinality": "*" + } }, { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@9" - }, - "arguments": [] + "$type": "Keyword", + "value": "height" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "height", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@5" + }, + "arguments": [] + } } ] }, @@ -1424,155 +1204,104 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "elements": [ { "$type": "Keyword", - "value": "-" + "value": "id" }, { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@22" - }, - "arguments": [], - "cardinality": "*" - } - ] - }, - "definesHiddenTokens": false, - "entry": false, - "fragment": false, - "hiddenTokens": [], - "parameters": [], - "wildcard": false - }, - { - "$type": "ParserRule", - "name": "RelationshipEdgeFields", - "inferredType": { - "$type": "InferredType", - "name": "RelationshipEdge" - }, - "definition": { - "$type": "Alternatives", - "elements": [ + "$type": "Keyword", + "value": ":" + }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "relationship" - }, - { - "$type": "Keyword", - "value": ":" + "$type": "Assignment", + "feature": "id", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@11" }, - { - "$type": "Assignment", - "feature": "relationship", - "operator": "=", - "terminal": { - "$type": "CrossReference", - "type": { - "$ref": "#/rules@13" - }, - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@4" - }, - "arguments": [] - }, - "deprecatedSyntax": false - } - } - ] + "arguments": [] + } }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "sourceNode" + "$type": "Keyword", + "value": "relationship" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "relationship", + "operator": "=", + "terminal": { + "$type": "CrossReference", + "type": { + "$ref": "#/rules@12" }, - { - "$type": "Keyword", - "value": ":" + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@3" + }, + "arguments": [] }, - { - "$type": "Assignment", - "feature": "sourceNode", - "operator": "=", - "terminal": { - "$type": "CrossReference", - "type": { - "$ref": "#/rules@18" - }, - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@4" - }, - "arguments": [] - }, - "deprecatedSyntax": false - } - } - ] + "deprecatedSyntax": false + } }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "targetNode" + "$type": "Keyword", + "value": "sourceNode" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "sourceNode", + "operator": "=", + "terminal": { + "$type": "CrossReference", + "type": { + "$ref": "#/rules@15" }, - { - "$type": "Keyword", - "value": ":" + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@3" + }, + "arguments": [] }, - { - "$type": "Assignment", - "feature": "targetNode", - "operator": "=", - "terminal": { - "$type": "CrossReference", - "type": { - "$ref": "#/rules@18" - }, - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@4" - }, - "arguments": [] - }, - "deprecatedSyntax": false - } - } - ] + "deprecatedSyntax": false + } }, { - "$type": "Group", - "elements": [ - { - "$type": "Keyword", - "value": "id" + "$type": "Keyword", + "value": "targetNode" + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "targetNode", + "operator": "=", + "terminal": { + "$type": "CrossReference", + "type": { + "$ref": "#/rules@15" }, - { - "$type": "Keyword", - "value": ":" + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@3" + }, + "arguments": [] }, - { - "$type": "Assignment", - "feature": "id", - "operator": "=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@12" - }, - "arguments": [] - } - } - ] + "deprecatedSyntax": false + } } ] }, @@ -1600,7 +1329,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@10" + "$ref": "#/rules@9" }, "arguments": [] }, @@ -1619,7 +1348,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@12" + "$ref": "#/rules@11" }, "arguments": [] } @@ -1638,27 +1367,36 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@10" + "$ref": "#/rules@9" }, "arguments": [] }, { - "$type": "Assignment", - "feature": "sources", - "operator": "+=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@24" + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "-" }, - "arguments": [] - }, - "cardinality": "*" + { + "$type": "Assignment", + "feature": "sources", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@18" + }, + "arguments": [] + } + } + ], + "cardinality": "+" }, { "$type": "RuleCall", "rule": { - "$ref": "#/rules@9" + "$ref": "#/rules@8" }, "arguments": [] } @@ -1680,7 +1418,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@31" + "$ref": "#/rules@25" }, "arguments": [] } @@ -1688,7 +1426,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@9" + "$ref": "#/rules@8" }, "arguments": [] } @@ -1707,10 +1445,6 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "definition": { "$type": "Group", "elements": [ - { - "$type": "Keyword", - "value": "-" - }, { "$type": "Keyword", "value": "id" @@ -1726,7 +1460,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@12" + "$ref": "#/rules@11" }, "arguments": [] } @@ -1751,7 +1485,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, @@ -1773,7 +1507,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@25" + "$ref": "#/rules@19" }, "arguments": [] } @@ -1792,27 +1526,36 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@10" + "$ref": "#/rules@9" }, "arguments": [] }, { - "$type": "Assignment", - "feature": "relations", - "operator": "+=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@26" + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "-" }, - "arguments": [] - }, + { + "$type": "Assignment", + "feature": "relations", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@20" + }, + "arguments": [] + } + } + ], "cardinality": "*" }, { "$type": "RuleCall", "rule": { - "$ref": "#/rules@9" + "$ref": "#/rules@8" }, "arguments": [] } @@ -1870,10 +1613,6 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "definition": { "$type": "Group", "elements": [ - { - "$type": "Keyword", - "value": "-" - }, { "$type": "Keyword", "value": "source" @@ -1889,12 +1628,12 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "CrossReference", "type": { - "$ref": "#/rules@24" + "$ref": "#/rules@18" }, "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, @@ -1912,27 +1651,36 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@10" + "$ref": "#/rules@9" }, "arguments": [] }, { - "$type": "Assignment", - "feature": "conditions", - "operator": "+=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@27" + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "-" }, - "arguments": [] - }, + { + "$type": "Assignment", + "feature": "conditions", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@21" + }, + "arguments": [] + } + } + ], "cardinality": "*" }, { "$type": "RuleCall", "rule": { - "$ref": "#/rules@9" + "$ref": "#/rules@8" }, "arguments": [] } @@ -1954,14 +1702,14 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@28" + "$ref": "#/rules@22" }, "arguments": [] }, { "$type": "RuleCall", "rule": { - "$ref": "#/rules@29" + "$ref": "#/rules@23" }, "arguments": [] } @@ -1980,10 +1728,6 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "definition": { "$type": "Group", "elements": [ - { - "$type": "Keyword", - "value": "-" - }, { "$type": "Keyword", "value": "relationship" @@ -1999,12 +1743,12 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "CrossReference", "type": { - "$ref": "#/rules@13" + "$ref": "#/rules@12" }, "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, @@ -2026,10 +1770,6 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "definition": { "$type": "Group", "elements": [ - { - "$type": "Keyword", - "value": "-" - }, { "$type": "Keyword", "value": "join" @@ -2045,7 +1785,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@30" + "$ref": "#/rules@24" }, "arguments": [] } @@ -2077,7 +1817,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, @@ -2105,7 +1845,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, @@ -2130,7 +1870,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@10" + "$ref": "#/rules@9" }, "arguments": [] }, @@ -2154,7 +1894,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, @@ -2175,27 +1915,36 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@10" + "$ref": "#/rules@9" }, "arguments": [] }, { - "$type": "Assignment", - "feature": "mappings", - "operator": "+=", - "terminal": { - "$type": "RuleCall", - "rule": { - "$ref": "#/rules@32" + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "-" }, - "arguments": [] - }, - "cardinality": "*" + { + "$type": "Assignment", + "feature": "mappings", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$ref": "#/rules@26" + }, + "arguments": [] + } + } + ], + "cardinality": "+" }, { "$type": "RuleCall", "rule": { - "$ref": "#/rules@9" + "$ref": "#/rules@8" }, "arguments": [] } @@ -2205,7 +1954,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "RuleCall", "rule": { - "$ref": "#/rules@9" + "$ref": "#/rules@8" }, "arguments": [] } @@ -2224,10 +1973,6 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "definition": { "$type": "Group", "elements": [ - { - "$type": "Keyword", - "value": "-" - }, { "$type": "Keyword", "value": "attribute" @@ -2243,7 +1988,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@33" + "$ref": "#/rules@27" }, "arguments": [] } @@ -2263,7 +2008,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@34" + "$ref": "#/rules@28" }, "arguments": [] } @@ -2292,7 +2037,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, @@ -2334,7 +2079,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@4" + "$ref": "#/rules@3" }, "arguments": [] }, @@ -2360,7 +2105,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@6" + "$ref": "#/rules@5" }, "arguments": [] } @@ -2384,7 +2129,7 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load "terminal": { "$type": "RuleCall", "rule": { - "$ref": "#/rules@5" + "$ref": "#/rules@4" }, "arguments": [] } @@ -2419,29 +2164,29 @@ export const CrossModelGrammar = (): Grammar => loadedCrossModelGrammar ?? (load { "$type": "TypeAttribute", "name": "name", - "isOptional": true, "type": { "$type": "SimpleType", "primitiveType": "string" - } + }, + "isOptional": false }, { "$type": "TypeAttribute", - "name": "description", - "isOptional": true, + "name": "datatype", "type": { "$type": "SimpleType", "primitiveType": "string" - } + }, + "isOptional": false }, { "$type": "TypeAttribute", - "name": "datatype", + "name": "description", + "isOptional": true, "type": { "$type": "SimpleType", "primitiveType": "string" - }, - "isOptional": false + } } ], "name": "Attribute", diff --git a/extensions/crossmodel-lang/src/language-server/mapping.langium b/extensions/crossmodel-lang/src/language-server/mapping.langium index eaafa88..ef02d69 100644 --- a/extensions/crossmodel-lang/src/language-server/mapping.langium +++ b/extensions/crossmodel-lang/src/language-server/mapping.langium @@ -14,40 +14,42 @@ Mapping: 'id' ':' id=ID ('sources' ':' INDENT - sources+=SourceObject* - DEDENT)? + ('-' sources+=SourceObject)+ + DEDENT + )? 'target' ':' target=TargetObject DEDENT ; SourceObject: - '-' 'id' ':' id=ID - 'entity' ':' entity=[Entity:IDReference] // implies attributes through entity - 'join' ':' join=JoinType - ('relations' ':' - INDENT - relations+=SourceObjectRelations* - DEDENT)? + 'id' ':' id=ID + 'entity' ':' entity=[Entity:IDReference] // implies attributes through entity + 'join' ':' join=JoinType + ('relations' ':' + INDENT + ('-' relations+=SourceObjectRelations)* + DEDENT + )? ; JoinType returns string: 'from' | 'inner-join' | 'cross-join' | 'left-join' | 'apply'; SourceObjectRelations: - '-' 'source' ':' source=[SourceObject:IDReference] - 'conditions' ':' - INDENT - conditions+=SourceObjectCondition* - DEDENT + 'source' ':' source=[SourceObject:IDReference] + 'conditions' ':' + INDENT + ('-' conditions+=SourceObjectCondition)* + DEDENT ; SourceObjectCondition: RelationshipCondition | JoinCondition; RelationshipCondition: - '-' 'relationship' ':' relationship=[Relationship:IDReference] + 'relationship' ':' relationship=[Relationship:IDReference] ; JoinCondition: - '-' 'join' ':' expression=JoinExpression + 'join' ':' expression=JoinExpression ; JoinExpression: @@ -59,14 +61,15 @@ TargetObject: 'entity' ':' entity=[Entity:IDReference] // implies attributes through entity ('mappings' ':' INDENT - mappings+=AttributeMapping* - DEDENT)? + ('-' mappings+=AttributeMapping)+ + DEDENT + )? DEDENT ; AttributeMapping: - '-' 'attribute' ':' attribute=AttributeMappingTarget - 'source' ':' source=AttributeMappingSource + 'attribute' ':' attribute=AttributeMappingTarget + 'source' ':' source=AttributeMappingSource ; AttributeMappingTarget: diff --git a/extensions/crossmodel-lang/src/language-server/relationship.langium b/extensions/crossmodel-lang/src/language-server/relationship.langium index 0d86e54..be90bf5 100644 --- a/extensions/crossmodel-lang/src/language-server/relationship.langium +++ b/extensions/crossmodel-lang/src/language-server/relationship.langium @@ -5,23 +5,21 @@ import 'entity' Relationship: 'relationship' ':' INDENT - ( - 'id' ':' id=ID | - 'name' ':' name=STRING | - 'description' ':' description=STRING | - 'parent' ':' parent=[Entity:IDReference] | - 'child' ':' child=[Entity:IDReference] | - 'type' ':' type=STRING | + 'id' ':' id=ID + ('name' ':' name=STRING)? + ('description' ':' description=STRING)? + 'parent' ':' parent=[Entity:IDReference] + 'child' ':' child=[Entity:IDReference] + 'type' ':' type=STRING ('attributes' ':' INDENT - attributes+=RelationshipAttribute+ - DEDENT) - )* + ('-' attributes+=RelationshipAttribute)+ + DEDENT + )? DEDENT ; RelationshipAttribute: - '-' 'parent' ':' parent=[Attribute:IDReference] - 'child' ':' child=[Attribute:IDReference] - ('description' ':' description=STRING)? + 'parent' ':' parent=[Attribute:IDReference] + 'child' ':' child=[Attribute:IDReference] ; diff --git a/extensions/crossmodel-lang/src/language-server/system-diagram.langium b/extensions/crossmodel-lang/src/language-server/system-diagram.langium index e5dafb8..1aea257 100644 --- a/extensions/crossmodel-lang/src/language-server/system-diagram.langium +++ b/extensions/crossmodel-lang/src/language-server/system-diagram.langium @@ -7,60 +7,41 @@ SystemDiagram: ('systemDiagram' | 'diagram') ':' ( INDENT - SystemDiagramFields* + 'id' ':' id=ID + ('name' ':' name=STRING)? + ('description' ':' description=STRING)? + ('nodes' ':' + INDENT + ('-' nodes+=EntityNode)+ + DEDENT + )? + ('edges' ':' + INDENT + ('-' edges+=RelationshipEdge)+ + DEDENT + )? DEDENT )* ; -SystemDiagramFields infers SystemDiagram: - ( - 'nodes' ':' SystemDiagramNodes | - 'edges' ':' SystemDiagramEdge | - 'id' ':' id=ID | - 'description' ':' description=STRING | - 'name' ':' name=STRING - ) -; - -SystemDiagramNodes infers SystemDiagram: - INDENT - (nodes+=EntityNode)* - DEDENT -; EntityNode: - '-' EntityNodeFields* -; - -EntityNodeFields infers EntityNode: - 'id' ':' id=ID | - 'entity' ':' entity=[Entity:IDReference] | - 'x' ':' x=NUMBER | - 'y' ':' y=NUMBER | - 'width' ':' width=NUMBER | - 'height' ':' height=NUMBER | - 'name' ':' name=STRING | - 'description' ':' description=STRING + 'id' ':' id=ID + ('name' ':' name=STRING)? + ('description' ':' description=STRING)? + 'entity' ':' entity=[Entity:IDReference] + 'x' ':' x=NUMBER + 'y' ':' y=NUMBER + 'width' ':' width=NUMBER + 'height' ':' height=NUMBER ; interface EntityNodeAttribute extends EntityAttribute { } -SystemDiagramEdge infers SystemDiagram: - INDENT - (edges+=RelationshipEdge)* - DEDENT -; - RelationshipEdge: - '-' RelationshipEdgeFields* -; - -RelationshipEdgeFields infers RelationshipEdge: - ( - 'relationship' ':' relationship=[Relationship:IDReference] | - 'sourceNode' ':' sourceNode=[EntityNode:IDReference] | - 'targetNode' ':' targetNode=[EntityNode:IDReference] | - 'id' ':' id=ID - ) + 'id' ':' id=ID + 'relationship' ':' relationship=[Relationship:IDReference] + 'sourceNode' ':' sourceNode=[EntityNode:IDReference] + 'targetNode' ':' targetNode=[EntityNode:IDReference] ; \ No newline at end of file