getXtextElementAt(XtextResource resource, final int offset)
{
- var result = super.getXtextElementAt(resource, offset);
+ final var result = super.getXtextElementAt(resource, offset);
if (result == null)
{
- result = keywordAtOffsetHelper.resolveKeywordAt(resource, offset);
+ final var tmp = keywordAtOffsetHelper.resolveKeywordAt(resource, offset);
+ if (tmp == null)
+ {
+ return null;
+ }
+
+ final var textRegion = tmp.getSecond();
+ return Tuples.create(tmp.getFirst(),
+ (IRegion) new Region(textRegion.getOffset(), textRegion.getLength()));
}
return result;
}
diff --git a/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/hover/XsmpcatEObjectHoverProvider.java b/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/hover/XsmpcatEObjectHoverProvider.java
index 13f11e5d..7c0c336a 100644
--- a/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/hover/XsmpcatEObjectHoverProvider.java
+++ b/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/hover/XsmpcatEObjectHoverProvider.java
@@ -37,12 +37,7 @@ protected String getHoverInfoAsHtml(EObject o)
{
if (o instanceof Keyword)
{
- final var hover = keywordHovers.hoverText((Keyword) o);
-
- if (hover != null)
- {
- return hover;
- }
+ return keywordHovers.hoverText((Keyword) o);
}
final var hover = super.getHoverInfoAsHtml(o);
diff --git a/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/hover/XsmpcatKeywordHovers.xtend b/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/hover/XsmpcatKeywordHovers.xtend
index 947b5d3d..78dc982e 100644
--- a/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/hover/XsmpcatKeywordHovers.xtend
+++ b/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/hover/XsmpcatKeywordHovers.xtend
@@ -16,285 +16,284 @@ import org.eclipse.xtext.Keyword
class XsmpcatKeywordHovers {
- @Inject XsmpcatGrammarAccess ga;
+ @Inject XsmpcatGrammarAccess ga;
- def multiplicity() {
- '''
- multiplicity:
- - empty : 1 element
- - ? : 0 or 1 element
- - [] | [*] : 0 to infinitite
- - [ expr ] : expr elements
- - [ expr ... * ] : expr to infinitite
- - [ expr1 ... expr2 ] : expr1 to expr2
- '''
- }
+ def multiplicity() {
+ '''
+ multiplicity:
+ - empty : 1 element
+ - ? : 0 or 1 element
+ - [] | [*] : 0 to infinitite
+ - [ expr ] : expr elements
+ - [ expr ... * ] : expr to infinitite
+ - [ expr1 ... expr2 ] : expr1 to expr2
+ '''
+ }
- def hoverText(Keyword k) {
- val result = switch (k) {
- case ga.catalogueAccess.catalogueKeyword_1: '''
- catalogue name
-
- A Catalogue is a document that defines types.
- It contains namespaces as a primary ordering mechanism.
-
The names of these namespaces need to be unique within the catalogue.
- '''
- case ga.namespaceMemberAccess.namespaceKeyword_3_0_1,
- case ga.namespaceAccess.namespaceKeyword_4: '''
- namespace name { }
-
- A Namespace is a primary ordering mechanism.
- A namespace may contain other namespaces (nested namespaces), and does typically contain types.
-
In SMDL, namespaces are contained within a Catalogue (either directly, or within another namespace in a catalogue).
-
All sub-elements of a namespace (namespaces and types) must have unique names.
- '''
- case ga.namespaceMemberAccess.structKeyword_3_1_2: '''
- struct name { }
-
- A Structure type collects an arbitrary number of Fields representing the state of the structure.
- Within a structure, each field needs to be given a unique name.
-
In order to arrive at semantically correct (data) type definitions, a structure type may not be recursive, i.e. a structure may not have a field that is typed by the structure itself.
-
A structure can also serve as a namespace to define an arbitrary number of Constants.
- '''
- case ga.namespaceMemberAccess.classKeyword_3_2_2: '''
- [abstract] class name [extends base] { }
-
- The Class metaclass is derived from Structure.
-
A class may be abstract (attribute Abstract), and it may extend from a single base class (implementation inheritance), which is represented by the Base link.
-
As the Class metaclass is derived from Structure it can contain constants and fields.
-
Further, it can have arbitrary numbers of properties (Property elements), operations (Operation elements), and associations (Association elements).
- '''
- case ga.namespaceMemberAccess.exceptionKeyword_3_3_2: '''
- [abstract] exception name [extends base] { }
-
- An Exception represents a non-recoverable error that can occur when calling into an Operation or Property getter/setter (within an Operation this is represented by the RaisedException links and within a Property this is represented by the GetRaises and SetRaises links, respectively).
-
An Exception can contain constants and fields (from Structure) as well as operations, properties and associations (from Class). The fields represent the state variables of the exception which carry additional information when the exception is raised.
-
Furthermore, an Exception may be Abstract (from Class), and it may inherit from a single base exception (implementation inheritance), which is represented by the Base link (from Class).
- '''
- case ga.namespaceMemberAccess.interfaceKeyword_3_4_2: '''
- interface name [extends interface1, ..., interfaceN] { }
-
- An Interface is a reference type that serves as a contract in a loosely coupled architecture. It has the ability to contain constants, properties and operations (from ReferenceType).
-
An Interface may inherit from other interfaces (interface inheritance), which is represented via the Base links.
-
-
- Remark
-
- : It is strongly recommended to only use value types, references and other interfaces in the properties and operations of an interface (i.e. not to use models). Otherwise, a dependency between a model implementing the interface, and other models referenced by this interface is introduced, which is against the idea of interface-based or component-based design.
-
- '''
- case ga.namespaceMemberAccess.modelKeyword_3_5_2: '''
- [abstract] model name [extends base] [implements interface1, ..., interfaceN] { }
-
- The Model metaclass is a component and hence inherits all component mechanisms.
-
These mechanisms allow using various different modelling approaches.
-
For a class-based design, a Model may provide a collection of Field elements to define its internal state.
-
For scheduling and global events, a Model may provide a collection of EntryPoint elements that can be registered with the Scheduler or EventManager services of a Simulation Environment.
-
For an interface-based design, a Model may provide (i.e. implement) an arbitrary number of interfaces, which is represented via the Interface links.
-
For a component-based design, a Model may provide Container elements to contain other models (composition), and Reference elements to reference other components (aggregation).
-
These components can either be models or services.
-
For an event-based design, a Model may support inter-model events via the EventSink and EventSource elements.
-
For a dataflow-based design, the fields of a Model can be tagged as Input or Output fields.
-
In addition, a Model may have Association elements to express associations to other models or fields of other models.
- '''
- case ga.namespaceMemberAccess.serviceKeyword_3_6_2: '''
- [abstract] service name [extends base] [implements interface1, ..., interfaceN] { }
-
- The Service metaclass is a component and hence inherits all component mechanisms.
-
A Service can reference one or more interfaces via the Interface links (inherited from Component), where at least one of them must be derived from Smp::IService, which qualifies it as a service interface.
- '''
- // Array
- case ga.namespaceMemberAccess.arrayKeyword_3_7_2_0_0,
- case ga.namespaceMemberAccess.usingKeyword_3_7_2_0_1: '''
- array name = type [integerExpression]
-
- An Array type defines a fixed-size array of identically typed elements, where ItemType defines the type of the array items, and Size defines the number of array items.
-
Multi-dimensional arrays are defined when ItemType is an Array type as well.
-
Dynamic arrays are not supported by SMDL, as they are not supported by some potential target platforms, and introduce various difficulties in memory management.
-
-
- Remarks
-
- : Nevertheless, specific mechanisms are available to allow dynamic collections of components, either for containment (composition) or references (aggregation).
-
- '''
- // ValueReference
- case ga.namespaceMemberAccess.usingKeyword_3_8_2: '''
- using name = type *
-
- A ValueReference is a type that references a specific value type. It is the "missing link" between value types and reference types.
- '''
- case ga.namespaceMemberAccess.integerKeyword_3_9_2: '''
- integer name [extends (Int8|Int16|Int32|Int64|UInt8|UInt16|UInt32|UInt64)] [in (*|integralExpression) ... (*|integralExpression)]
-
- An Integer type represents integer values with a given range of valid values (via the Minimum and Maximum attributes).
-
The Unit element can hold a physical unit that can be used by applications to ensure physical unit integrity across models.
-
Optionally, the PrimitiveType used to encode the integer value may be specified (one of Int8, Int16, Int32, Int64, UIn8, UInt16, UInt32, UInt64, where the default is Int32).
- '''
- case ga.namespaceMemberAccess.floatKeyword_3_10_2: '''
- float name [extends (Float32|Float64)] [in (*|decimalExpression) ... (*|decimalExpression)]
-
- A Float type represents floating-point values with a given range of valid values (via the Minimum and Maximum attributes).
-
The MinInclusive and MaxInclusive attributes determine whether the boundaries are included in the range or not.
-
The Unit element can hold a physical unit that can be used by applications to ensure physical unit integrity across models.
-
Optionally, the PrimitiveType used to encode the floating-point value may be specified (one of Float32 or Float64, where the default is Float64).
- '''
- case ga.namespaceMemberAccess.eventKeyword_3_11_2: '''
- event name [extends simpleType]
-
- An Event Type is used to specify the type of an event.
-
This can be used not only to give a meaningful name to an event type, but also to link it to an existing simple type (via the EventArgs attribute) that is passed as an argument with every invocation of the event.
- '''
- case ga.namespaceMemberAccess.stringKeyword_3_12_2: '''
- string name [integerExpression]
-
- A String type represents fixed Length string values base on Char8.
-
The String language element defines an Array of Char8 values, but allows a more natural handling of it, e.g. by storing a string value as one string, not as an array of individual characters.
-
As with arrays, SMDL does not allow defining variable-sized strings, as these have the same problems as dynamic arrays (e.g. their size is not know up-front, and their use requires memory allocation).
- '''
- case ga.namespaceMemberAccess.primitiveKeyword_3_13_2: '''
- A number of pre-defined types are needed in order to bootstrap the type system.
-
- These pre-defined value types are represented by instances of the metaclass PrimitiveType.
-
This mechanism is only used in order to bootstrap the type system and may not be used to define new types for modelling.
-
This is an important restriction, as all values of primitive types may be held in a SimpleValue.
-
The metaclasses derived from SimpleValue, however, are pre-defined and cannot be extended.
- '''
- case ga.namespaceMemberAccess.nativeKeyword_3_14_2: '''
- A Native Type specifies a type with any number of platform mappings. It is used to anchor existing or user-defined types into different target platforms.
- This mechanism is used within the specification to define the SMDL primitive types with respect to the Metamodel, but it can also be used to define native types within an arbitrary SMDL catalogue for use by models.
-
In the latter case, native types are typically used to bind a model to some external library or existing Application Programming Interface (API).
- '''
- case ga.namespaceMemberAccess.attributeKeyword_3_15_2,
- case ga.namespaceMemberAccess.attributeKeyword_3_17_2: '''
- An Attribute Type defines a new type available for adding attributes to elements.
-
The AllowMultiple attribute specifies if a corresponding Attribute may be attached more than once to a language element, while the Usage element defines to which language elements attributes of this type can be attached.
-
An attribute type always references a value type, and specifies a Default value.
- '''
- case ga.namespaceMemberAccess.enumKeyword_3_16_2: '''
- enum name { }
-
- An Enumeration type represents one of a number of pre-defined enumeration literals.
- The Enumeration language element can be used to create user-defined enumeration types.
-
An enumeration must always contain at least one EnumerationLiteral, each having a name and an integer Value attached to it.
-
All enumeration literals of an enumeration type must have unique names and values, respectively.
- '''
- case ga.fieldDeclarationAccess.fieldKeyword_1: '''
- [input] [output] [transient] field type name [ = defaultValueExpression]
-
- A Field is a feature that is typed by any value type but String8, and that may have a Default value.
- The transient attribute defines how the field is published to the simulation environment.
-
Only non transient fields are stored using external persistence.
-
The visibility to the user within the simulation environment can be controlled via the standard SMP attribute "View".
-
By default, a field is not transient and the View attribute defaults to "None" when not applied.
-
The Input and Output attributes define whether the field value is an input for internal calculations (i.e. needed in order to perform these calculations), or an output of internal calculations (i.e. modified when performing these calculations).
-
These flags default to false, but can be changed from their default value to support dataflow-based design.
- '''
- case ga.constantDeclarationAccess.constantKeyword_1: '''
- constant type name = valueExpression
-
- A Constant is a feature that is typed by a simple type and that must have a Value.
- '''
- case ga.associationDeclarationAccess.associationKeyword_1: '''
- association type name
-
- An Association is a feature that is typed by a language type (Type link). An association always expresses a reference to an instance of the referenced language type.
-
This reference is either another model (if the Type link refers to a Model or Interface), or it is a field contained in another model (if the Type link refers to a ValueType).
- '''
- case ga.propertyDeclarationAccess.propertyKeyword_1: '''
- [(readOnly|writeOnly|readWrite)]property type name [get throws exception1, ..., exceptionN] [set throws exception1, ..., exceptionN] [ -> attachedField]
-
- A Property has a similar syntax as a Field: It is a feature that references a language type.
- However, the semantics is different in that a property does not represent a state and that it can be assigned an Access attribute to specify how the property can be accessed (either readWrite, readOnly, or writeOnly, see AccessKind).
-
Furthermore, a property can be assigned a Category attribute to help grouping the properties within its owning type, and a property may specify an arbitrary number of exceptions that it can raise in its getter (GetRaises) and/or setter (SetRaises).
-
-
- Remark
-
- : The category can be used in applications as ordering or filtering criterion, for example in a property grid. The term "property" used here closely corresponds in its semantics to the same term in the Java Beans specification and in the Microsoft .NET framework.
- That is, a property formally represents a "getter" or a "setter" operation or both which allow accessing state or configuration information (or derived information thereof) in a controlled way and which can also be exposed via interfaces (in contrast to fields).
-
- '''
- case ga.containerDeclarationAccess.containerKeyword_0: '''
- container type multiplicity? name [ = defaultComponent]
- «multiplicity()»
-
- A Container defines the rules of composition (containment of children) for a Component.
- The type of components that can be contained is specified via the Type link.
-
The Lower and Upper attributes specify the multiplicity, i.e. the number of possibly stored components.
-
Therein the upper bound may be unlimited, which is represented by Upper=-1.
-
Furthermore, a container may specify a default implementation of the container type via the DefaultComponentl link.
-
-
- Remark
-
- : SMDL support tools may use this during instantiation (i.e. during model integration) to select an initial implementation for newly created contained components.
-
- '''
- case ga.referenceDeclarationAccess.referenceKeyword_0: '''
- reference interface multiplicity? name
- «multiplicity()»
-
- A Reference defines the rules of aggregation (links to components) for a Component.
- The type of components (models or services) that can be referenced is specified by the Interface link.
-
Thereby, a service reference is characterized by an interface that is derived from Smp::IService
.
-
The Lower and Upper attributes specify the multiplicity, i.e. the number of possibly held references to components implementing this interface.
-
Therein the upper bound may be unlimited, which is represented by Upper=-1.
- '''
- case ga.entryPointDeclarationAccess.entrypointKeyword_0: '''
- entrypoint name
-
- An EntryPoint is a named element of a Component (Model or Service).
- It corresponds to a void operation taking no parameters that can be called from an external client (e.g. the Scheduler or Event Manager services).
-
An Entry Point can reference both Input fields (which must have their Input attribute set to true) and Output fields (which must have their Output attribute set to true).
-
These links can be used to ensure that all component output fields are updated before the entry point is called, or that all input fields can be used after the entry point has been called.
- '''
- case ga.eventSinkDeclarationAccess.eventsinkKeyword_0: '''
- eventsink type name
-
- An EventSink is used to specify that a Component can receive a specific event using a given name. An EventSink can be connected to any number of EventSource instances.
- '''
- case ga.eventSourceDeclarationAccess.eventsourceKeyword_0: '''
- eventsource type name
-
- An EventSource is used to specify that a Component publishes a specific event under a given name.
- The Multicast attribute can be used to specify whether any number of sinks can connect to the source (the default), or only a single sink can connect (Multicast=false).
-
-
- Remark
-
- : A tool for model integration can use the Multicast attribute to configure the user interface accordingly to ease the specification of event links.
-
- '''
- case ga.operationDeclarationAccess.defKeyword_1: '''
- def (returnType|void) name (p1, ..., pN) [throws exception1, ..., exceptionN]
- p*: [(in|out|inout)] type name [ = defaultValueExpression]
-
- An Operation may have an arbitrary number of parameters, where at most one of the parameters may be of Direction = ParameterDirectionKind.return.
- If such a parameter is absent, the operation is a void function (procedure) without return value.
-
An RaisedException may specify an arbitrary number of exceptions that it can raise (RaisedException).
- '''
- case ga.visibilityModifiersAccess.privateKeyword_0: '''
- The element is visible only within its containing classifier.
- '''
- case ga.visibilityModifiersAccess.protectedKeyword_1: '''
- The element is visible within its containing classifier and derived classifiers thereof.
- '''
- case ga.visibilityModifiersAccess.publicKeyword_2: '''
- The element is globally visible.
- '''
- case ga.parameterDirectionKindAccess.inInKeyword_0_0: '''
- The parameter is read-only to the operation, i.e. its value must be specified on call, and cannot be changed inside the operation.
- '''
- case ga.parameterDirectionKindAccess.outOutKeyword_1_0: '''
- The parameter is write-only to the operation, i.e. its value is unspecified on call, and must be set by the operation.
- '''
- case ga.parameterDirectionKindAccess.inoutInoutKeyword_2_0: '''
- The parameter must be specified on call, and may be changed by the operation.
- '''
- default:
- return null
- }
- result.toString;
- }
+ def hoverText(Keyword k) {
+ val result = switch (k) {
+ case ga.catalogueAccess.catalogueKeyword_1: '''
+ catalogue name
+
+ A Catalogue is a document that defines types.
+ It contains namespaces as a primary ordering mechanism.
+
The names of these namespaces need to be unique within the catalogue.
+ '''
+ case ga.namespaceMemberAccess.namespaceKeyword_3_0_1,
+ case ga.namespaceAccess.namespaceKeyword_4: '''
+ namespace name { }
+
+ A Namespace is a primary ordering mechanism.
+ A namespace may contain other namespaces (nested namespaces), and does typically contain types.
+
In SMDL, namespaces are contained within a Catalogue (either directly, or within another namespace in a catalogue).
+
All sub-elements of a namespace (namespaces and types) must have unique names.
+ '''
+ case ga.namespaceMemberAccess.structKeyword_3_1_2: '''
+ struct name { }
+
+ A Structure type collects an arbitrary number of Fields representing the state of the structure.
+ Within a structure, each field needs to be given a unique name.
+
In order to arrive at semantically correct (data) type definitions, a structure type may not be recursive, i.e. a structure may not have a field that is typed by the structure itself.
+
A structure can also serve as a namespace to define an arbitrary number of Constants.
+ '''
+ case ga.namespaceMemberAccess.classKeyword_3_2_2: '''
+ [abstract] class name [extends base] { }
+
+ The Class metaclass is derived from Structure.
+
A class may be abstract (attribute Abstract), and it may extend from a single base class (implementation inheritance), which is represented by the Base link.
+
As the Class metaclass is derived from Structure it can contain constants and fields.
+
Further, it can have arbitrary numbers of properties (Property elements), operations (Operation elements), and associations (Association elements).
+ '''
+ case ga.namespaceMemberAccess.exceptionKeyword_3_3_2: '''
+ [abstract] exception name [extends base] { }
+
+ An Exception represents a non-recoverable error that can occur when calling into an Operation or Property getter/setter (within an Operation this is represented by the RaisedException links and within a Property this is represented by the GetRaises and SetRaises links, respectively).
+
An Exception can contain constants and fields (from Structure) as well as operations, properties and associations (from Class). The fields represent the state variables of the exception which carry additional information when the exception is raised.
+
Furthermore, an Exception may be Abstract (from Class), and it may inherit from a single base exception (implementation inheritance), which is represented by the Base link (from Class).
+ '''
+ case ga.namespaceMemberAccess.interfaceKeyword_3_4_2: '''
+ interface name [extends interface1, ..., interfaceN] { }
+
+ An Interface is a reference type that serves as a contract in a loosely coupled architecture. It has the ability to contain constants, properties and operations (from ReferenceType).
+
An Interface may inherit from other interfaces (interface inheritance), which is represented via the Base links.
+
+
+ Remark
+
+ : It is strongly recommended to only use value types, references and other interfaces in the properties and operations of an interface (i.e. not to use models). Otherwise, a dependency between a model implementing the interface, and other models referenced by this interface is introduced, which is against the idea of interface-based or component-based design.
+
+ '''
+ case ga.namespaceMemberAccess.modelKeyword_3_5_2: '''
+ [abstract] model name [extends base] [implements interface1, ..., interfaceN] { }
+
+ The Model metaclass is a component and hence inherits all component mechanisms.
+
These mechanisms allow using various different modelling approaches.
+
For a class-based design, a Model may provide a collection of Field elements to define its internal state.
+
For scheduling and global events, a Model may provide a collection of EntryPoint elements that can be registered with the Scheduler or EventManager services of a Simulation Environment.
+
For an interface-based design, a Model may provide (i.e. implement) an arbitrary number of interfaces, which is represented via the Interface links.
+
For a component-based design, a Model may provide Container elements to contain other models (composition), and Reference elements to reference other components (aggregation).
+
These components can either be models or services.
+
For an event-based design, a Model may support inter-model events via the EventSink and EventSource elements.
+
For a dataflow-based design, the fields of a Model can be tagged as Input or Output fields.
+
In addition, a Model may have Association elements to express associations to other models or fields of other models.
+ '''
+ case ga.namespaceMemberAccess.serviceKeyword_3_6_2: '''
+ [abstract] service name [extends base] [implements interface1, ..., interfaceN] { }
+
+ The Service metaclass is a component and hence inherits all component mechanisms.
+
A Service can reference one or more interfaces via the Interface links (inherited from Component), where at least one of them must be derived from Smp::IService, which qualifies it as a service interface.
+ '''
+ // Array
+ case ga.namespaceMemberAccess.arrayKeyword_3_7_2_0_0,
+ case ga.namespaceMemberAccess.usingKeyword_3_7_2_0_1: '''
+ array name = type [integerExpression]
+
+ An Array type defines a fixed-size array of identically typed elements, where ItemType defines the type of the array items, and Size defines the number of array items.
+
Multi-dimensional arrays are defined when ItemType is an Array type as well.
+
Dynamic arrays are not supported by SMDL, as they are not supported by some potential target platforms, and introduce various difficulties in memory management.
+
+
+ Remarks
+
+ : Nevertheless, specific mechanisms are available to allow dynamic collections of components, either for containment (composition) or references (aggregation).
+
+ '''
+ // ValueReference
+ case ga.namespaceMemberAccess.usingKeyword_3_8_2: '''
+ using name = type *
+
+ A ValueReference is a type that references a specific value type. It is the "missing link" between value types and reference types.
+ '''
+ case ga.namespaceMemberAccess.integerKeyword_3_9_2: '''
+ integer name [extends (Int8|Int16|Int32|Int64|UInt8|UInt16|UInt32|UInt64)] [in (*|integralExpression) ... (*|integralExpression)]
+
+ An Integer type represents integer values with a given range of valid values (via the Minimum and Maximum attributes).
+
The Unit element can hold a physical unit that can be used by applications to ensure physical unit integrity across models.
+
Optionally, the PrimitiveType used to encode the integer value may be specified (one of Int8, Int16, Int32, Int64, UIn8, UInt16, UInt32, UInt64, where the default is Int32).
+ '''
+ case ga.namespaceMemberAccess.floatKeyword_3_10_2: '''
+ float name [extends (Float32|Float64)] [in (*|decimalExpression) ... (*|decimalExpression)]
+
+ A Float type represents floating-point values with a given range of valid values (via the Minimum and Maximum attributes).
+
The MinInclusive and MaxInclusive attributes determine whether the boundaries are included in the range or not.
+
The Unit element can hold a physical unit that can be used by applications to ensure physical unit integrity across models.
+
Optionally, the PrimitiveType used to encode the floating-point value may be specified (one of Float32 or Float64, where the default is Float64).
+ '''
+ case ga.namespaceMemberAccess.eventKeyword_3_11_2: '''
+ event name [extends simpleType]
+
+ An Event Type is used to specify the type of an event.
+
This can be used not only to give a meaningful name to an event type, but also to link it to an existing simple type (via the EventArgs attribute) that is passed as an argument with every invocation of the event.
+ '''
+ case ga.namespaceMemberAccess.stringKeyword_3_12_2: '''
+ string name [integerExpression]
+
+ A String type represents fixed Length string values base on Char8.
+
The String language element defines an Array of Char8 values, but allows a more natural handling of it, e.g. by storing a string value as one string, not as an array of individual characters.
+
As with arrays, SMDL does not allow defining variable-sized strings, as these have the same problems as dynamic arrays (e.g. their size is not know up-front, and their use requires memory allocation).
+ '''
+ case ga.namespaceMemberAccess.primitiveKeyword_3_13_2: '''
+ A number of pre-defined types are needed in order to bootstrap the type system.
+
+ These pre-defined value types are represented by instances of the metaclass PrimitiveType.
+
This mechanism is only used in order to bootstrap the type system and may not be used to define new types for modelling.
+
This is an important restriction, as all values of primitive types may be held in a SimpleValue.
+
The metaclasses derived from SimpleValue, however, are pre-defined and cannot be extended.
+ '''
+ case ga.namespaceMemberAccess.nativeKeyword_3_14_2: '''
+ A Native Type specifies a type with any number of platform mappings. It is used to anchor existing or user-defined types into different target platforms.
+ This mechanism is used within the specification to define the SMDL primitive types with respect to the Metamodel, but it can also be used to define native types within an arbitrary SMDL catalogue for use by models.
+
In the latter case, native types are typically used to bind a model to some external library or existing Application Programming Interface (API).
+ '''
+ case ga.namespaceMemberAccess.attributeKeyword_3_15_2,
+ case ga.namespaceMemberAccess.attributeKeyword_3_17_2: '''
+ An Attribute Type defines a new type available for adding attributes to elements.
+
The AllowMultiple attribute specifies if a corresponding Attribute may be attached more than once to a language element, while the Usage element defines to which language elements attributes of this type can be attached.
+
An attribute type always references a value type, and specifies a Default value.
+ '''
+ case ga.namespaceMemberAccess.enumKeyword_3_16_2: '''
+ enum name { }
+
+ An Enumeration type represents one of a number of pre-defined enumeration literals.
+ The Enumeration language element can be used to create user-defined enumeration types.
+
An enumeration must always contain at least one EnumerationLiteral, each having a name and an integer Value attached to it.
+
All enumeration literals of an enumeration type must have unique names and values, respectively.
+ '''
+ case ga.fieldDeclarationAccess.fieldKeyword_1: '''
+ [input] [output] [transient] field type name [ = defaultValueExpression]
+
+ A Field is a feature that is typed by any value type but String8, and that may have a Default value.
+ The transient attribute defines how the field is published to the simulation environment.
+
Only non transient fields are stored using external persistence.
+
The visibility to the user within the simulation environment can be controlled via the standard SMP attribute "View".
+
By default, a field is not transient and the View attribute defaults to "None" when not applied.
+
The Input and Output attributes define whether the field value is an input for internal calculations (i.e. needed in order to perform these calculations), or an output of internal calculations (i.e. modified when performing these calculations).
+
These flags default to false, but can be changed from their default value to support dataflow-based design.
+ '''
+ case ga.constantDeclarationAccess.constantKeyword_1: '''
+ constant type name = valueExpression
+
+ A Constant is a feature that is typed by a simple type and that must have a Value.
+ '''
+ case ga.associationDeclarationAccess.associationKeyword_1: '''
+ association type name
+
+ An Association is a feature that is typed by a language type (Type link). An association always expresses a reference to an instance of the referenced language type.
+
This reference is either another model (if the Type link refers to a Model or Interface), or it is a field contained in another model (if the Type link refers to a ValueType).
+ '''
+ case ga.propertyDeclarationAccess.propertyKeyword_1: '''
+ [(readOnly|writeOnly|readWrite)]property type name [get throws exception1, ..., exceptionN] [set throws exception1, ..., exceptionN] [ -> attachedField]
+
+ A Property has a similar syntax as a Field: It is a feature that references a language type.
+ However, the semantics is different in that a property does not represent a state and that it can be assigned an Access attribute to specify how the property can be accessed (either readWrite, readOnly, or writeOnly, see AccessKind).
+
Furthermore, a property can be assigned a Category attribute to help grouping the properties within its owning type, and a property may specify an arbitrary number of exceptions that it can raise in its getter (GetRaises) and/or setter (SetRaises).
+
+
+ Remark
+
+ : The category can be used in applications as ordering or filtering criterion, for example in a property grid. The term "property" used here closely corresponds in its semantics to the same term in the Java Beans specification and in the Microsoft .NET framework.
+ That is, a property formally represents a "getter" or a "setter" operation or both which allow accessing state or configuration information (or derived information thereof) in a controlled way and which can also be exposed via interfaces (in contrast to fields).
+
+ '''
+ case ga.containerDeclarationAccess.containerKeyword_0: '''
+ container type multiplicity? name [ = defaultComponent]
+ «multiplicity()»
+
+ A Container defines the rules of composition (containment of children) for a Component.
+ The type of components that can be contained is specified via the Type link.
+
The Lower and Upper attributes specify the multiplicity, i.e. the number of possibly stored components.
+
Therein the upper bound may be unlimited, which is represented by Upper=-1.
+
Furthermore, a container may specify a default implementation of the container type via the DefaultComponentl link.
+
+
+ Remark
+
+ : SMDL support tools may use this during instantiation (i.e. during model integration) to select an initial implementation for newly created contained components.
+
+ '''
+ case ga.referenceDeclarationAccess.referenceKeyword_0: '''
+ reference interface multiplicity? name
+ «multiplicity()»
+
+ A Reference defines the rules of aggregation (links to components) for a Component.
+ The type of components (models or services) that can be referenced is specified by the Interface link.
+
Thereby, a service reference is characterized by an interface that is derived from Smp::IService
.
+
The Lower and Upper attributes specify the multiplicity, i.e. the number of possibly held references to components implementing this interface.
+
Therein the upper bound may be unlimited, which is represented by Upper=-1.
+ '''
+ case ga.entryPointDeclarationAccess.entrypointKeyword_0: '''
+ entrypoint name
+
+ An EntryPoint is a named element of a Component (Model or Service).
+ It corresponds to a void operation taking no parameters that can be called from an external client (e.g. the Scheduler or Event Manager services).
+
An Entry Point can reference both Input fields (which must have their Input attribute set to true) and Output fields (which must have their Output attribute set to true).
+
These links can be used to ensure that all component output fields are updated before the entry point is called, or that all input fields can be used after the entry point has been called.
+ '''
+ case ga.eventSinkDeclarationAccess.eventsinkKeyword_0: '''
+ eventsink type name
+
+ An EventSink is used to specify that a Component can receive a specific event using a given name. An EventSink can be connected to any number of EventSource instances.
+ '''
+ case ga.eventSourceDeclarationAccess.eventsourceKeyword_0: '''
+ eventsource type name
+
+ An EventSource is used to specify that a Component publishes a specific event under a given name.
+ The Multicast attribute can be used to specify whether any number of sinks can connect to the source (the default), or only a single sink can connect (Multicast=false).
+
+
+ Remark
+
+ : A tool for model integration can use the Multicast attribute to configure the user interface accordingly to ease the specification of event links.
+
+ '''
+ case ga.operationDeclarationAccess.defKeyword_1: '''
+ def (returnType|void) name (p1, ..., pN) [throws exception1, ..., exceptionN]
+ p*: [(in|out|inout)] type name [ = defaultValueExpression]
+
+ An Operation may have an arbitrary number of parameters, where at most one of the parameters may be of Direction = ParameterDirectionKind.return.
+ If such a parameter is absent, the operation is a void function (procedure) without return value.
+
An RaisedException may specify an arbitrary number of exceptions that it can raise (RaisedException).
+ '''
+ case ga.visibilityModifiersAccess.privateKeyword_0: '''
+ The element is visible only within its containing classifier.
+ '''
+ case ga.visibilityModifiersAccess.protectedKeyword_1: '''
+ The element is visible within its containing classifier and derived classifiers thereof.
+ '''
+ case ga.visibilityModifiersAccess.publicKeyword_2: '''
+ The element is globally visible.
+ '''
+ case ga.parameterDirectionKindAccess.inInKeyword_0_0: '''
+ The parameter is read-only to the operation, i.e. its value must be specified on call, and cannot be changed inside the operation.
+ '''
+ case ga.parameterDirectionKindAccess.outOutKeyword_1_0: '''
+ The parameter is write-only to the operation, i.e. its value is unspecified on call, and must be set by the operation.
+ '''
+ case ga.parameterDirectionKindAccess.inoutInoutKeyword_2_0: '''
+ The parameter must be specified on call, and may be changed by the operation.
+ '''
+ default: ''''''
+ }
+ result.toString;
+ }
}
diff --git a/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/template/XsmpcatCrossReferenceTemplateVariableResolver.java b/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/template/XsmpcatCrossReferenceTemplateVariableResolver.java
index b75e7632..eb5abbf4 100644
--- a/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/template/XsmpcatCrossReferenceTemplateVariableResolver.java
+++ b/org.eclipse.xsmp.ui/src/org/eclipse/xsmp/ui/template/XsmpcatCrossReferenceTemplateVariableResolver.java
@@ -19,7 +19,7 @@
import org.apache.log4j.Logger;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.templates.TemplateVariable;
-import org.eclipse.xsmp.ui.contentassist.IReferenceFilter;
+import org.eclipse.xsmp.ide.contentassist.IReferenceFilter;
import org.eclipse.xsmp.util.QualifiedNames;
import org.eclipse.xsmp.xcatalogue.PrimitiveType;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
diff --git a/org.eclipse.xsmp.vscode_extension/.classpath b/org.eclipse.xsmp.vscode_extension/.classpath
new file mode 100644
index 00000000..fe1a2053
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.xsmp.vscode_extension/.gitignore b/org.eclipse.xsmp.vscode_extension/.gitignore
new file mode 100644
index 00000000..a88ef41e
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/.gitignore
@@ -0,0 +1,4 @@
+package-lock.json
+*.vsix
+
+node_modules/
\ No newline at end of file
diff --git a/org.eclipse.xsmp.vscode_extension/.project b/org.eclipse.xsmp.vscode_extension/.project
new file mode 100644
index 00000000..ce8fcbcd
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/.project
@@ -0,0 +1,34 @@
+
+
+ org.eclipse.xsmp.vscode_extension
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.pde.PluginNature
+
+
diff --git a/org.eclipse.xsmp.vscode_extension/.settings/org.eclipse.core.resources.prefs b/org.eclipse.xsmp.vscode_extension/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000..99f26c02
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/org.eclipse.xsmp.vscode_extension/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.xsmp.vscode_extension/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..9478cb16
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,15 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=17
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=17
diff --git a/org.eclipse.xsmp.vscode_extension/.settings/org.eclipse.xtend.core.Xtend.prefs b/org.eclipse.xsmp.vscode_extension/.settings/org.eclipse.xtend.core.Xtend.prefs
new file mode 100644
index 00000000..680a0f30
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/.settings/org.eclipse.xtend.core.Xtend.prefs
@@ -0,0 +1,5 @@
+BuilderConfiguration.is_project_specific=true
+eclipse.preferences.version=1
+outlet.DEFAULT_OUTPUT.hideLocalSyntheticVariables=true
+outlet.DEFAULT_OUTPUT.installDslAsPrimarySource=false
+outlet.DEFAULT_OUTPUT.userOutputPerSourceFolder=true
\ No newline at end of file
diff --git a/org.eclipse.xsmp.vscode_extension/.vscodeignore b/org.eclipse.xsmp.vscode_extension/.vscodeignore
new file mode 100644
index 00000000..3c8969c9
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/.vscodeignore
@@ -0,0 +1,9 @@
+.classpath
+.project
+.gitignore
+package.json
+package-lock.json
+build.properties
+
+.settings/
+META-INF/
\ No newline at end of file
diff --git a/org.eclipse.xsmp.vscode_extension/META-INF/MANIFEST.MF b/org.eclipse.xsmp.vscode_extension/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..5a86285f
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/META-INF/MANIFEST.MF
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Automatic-Module-Name: org.eclipse.xsmp.vscode_extension
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.xsmp.vscode_extension
+Bundle-Vendor: Thales Alenia Space
+Bundle-Version: 1.1.0.qualifier
+Bundle-SymbolicName: org.eclipse.xsmp.vscode_extension;singleton:=true
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-17
diff --git a/org.eclipse.xsmp.vscode_extension/build.properties b/org.eclipse.xsmp.vscode_extension/build.properties
new file mode 100644
index 00000000..ecaa4534
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/build.properties
@@ -0,0 +1,3 @@
+bin.includes = .,\
+ META-INF/
+source.. = src/
\ No newline at end of file
diff --git a/org.eclipse.xsmp.vscode_extension/images/xsmp.png b/org.eclipse.xsmp.vscode_extension/images/xsmp.png
new file mode 100644
index 00000000..03645539
Binary files /dev/null and b/org.eclipse.xsmp.vscode_extension/images/xsmp.png differ
diff --git a/org.eclipse.xsmp.vscode_extension/package.json b/org.eclipse.xsmp.vscode_extension/package.json
new file mode 100644
index 00000000..c9f11b10
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/package.json
@@ -0,0 +1,63 @@
+{
+ "name": "xsmp-modeler",
+ "displayName": "XSMP Modeler",
+ "description": "VSCode extension for XSMP Modeler",
+ "version": "1.1.0",
+ "publisher": "Thales Alenia Space",
+ "author": "Thales Alenia Space",
+ "icon": "images/xsmp.png",
+ "license": "EPL-2.0",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ThalesGroup/xsmp-modeler-core.git"
+ },
+ "bugs": {
+ "url": "https://github.com/ThalesGroup/xsmp-modeler-core/issues"
+ },
+ "engines": {
+ "vscode": "^1.75.0"
+ },
+ "categories": [
+ "Programming Languages"
+ ],
+ "activationEvents": [
+ "onLanguage:xsmpcat"
+ ],
+ "main": "target/extension",
+ "contributes": {
+ "languages": [
+ {
+ "id": "xsmpcat",
+ "aliases": [
+ "xsmpcat"
+ ],
+ "extensions": [
+ ".xsmpcat"
+ ],
+ "configuration": "./xsmp.configuration.json"
+ }
+ ],
+ "grammars": [
+ {
+ "language": "xsmpcat",
+ "scopeName": "source.xsmpcat",
+ "path": "./syntaxes/xsmp.tmLanguage.json"
+ }
+ ]
+ },
+ "devDependencies": {
+ "@types/node": "^17.0.34",
+ "@types/vscode": "^1.67.0",
+ "typescript": "^4.6.4",
+ "@vscode/test-electron": "^2.1.3"
+ },
+ "dependencies": {
+ "vscode-languageclient": "^8.0.1"
+ },
+ "scripts": {
+ "prepublish": "tsc -p ./src",
+ "compile": "tsc -p ./src",
+ "watch": "tsc -w -p ./src",
+ "update-vscode": "node ./node_modules/vscode/bin/install"
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.xsmp.vscode_extension/pom.xml b/org.eclipse.xsmp.vscode_extension/pom.xml
new file mode 100644
index 00000000..00f59c0f
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/pom.xml
@@ -0,0 +1,45 @@
+
+ 4.0.0
+
+ org.eclipse.xsmp
+ org.eclipse.xsmp.parent
+ 1.1.0-SNAPSHOT
+
+ org.eclipse.xsmp.vscode_extension
+ eclipse-plugin
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.2.0
+
+
+ copy-jar
+ prepare-package
+
+ copy-resources
+
+
+
+ ${project.build.directory}/language-server
+
+
+
+ ${project.basedir}/../org.eclipse.xsmp.ide/target
+
+
+ org.eclipse.xsmp.ide-ls.jar
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.xsmp.vscode_extension/src/extension.ts b/org.eclipse.xsmp.vscode_extension/src/extension.ts
new file mode 100644
index 00000000..7bebf309
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/src/extension.ts
@@ -0,0 +1,53 @@
+/*******************************************************************************
+* Copyright (C) 2023 THALES ALENIA SPACE FRANCE.
+*
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License 2.0
+* which accompanies this distribution, and is available at
+* https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+******************************************************************************/
+'use strict';
+
+import * as path from 'path';
+
+import { Trace } from 'vscode-jsonrpc';
+import { workspace, ExtensionContext } from 'vscode';
+import { LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node';
+
+let lc: LanguageClient;
+
+export function activate(context: ExtensionContext) {
+ let launcher = 'org.eclipse.xsmp.ide-ls.jar';
+ let script = context.asAbsolutePath(path.join('target', 'language-server', launcher));
+
+ let serverOptions: ServerOptions = {
+ run: { command: 'java', args: ['-jar', script] },
+ debug: { command: 'java', args: ['-jar', script], options: { env: createDebugEnv() } }
+ };
+
+ let clientOptions: LanguageClientOptions = {
+ documentSelector: ['xsmpcat'],
+ synchronize: {
+ fileEvents: workspace.createFileSystemWatcher('**/*.*')
+ }
+ };
+
+ // Create the language client and start the client.
+ lc = new LanguageClient('Xtext Server', serverOptions, clientOptions);
+
+ // enable tracing (.Off, .Messages, Verbose)
+ lc.setTrace(Trace.Verbose);
+ lc.start();
+}
+
+export function deactivate() {
+ return lc.stop();
+}
+
+function createDebugEnv() {
+ return Object.assign({
+ JAVA_OPTS: "-Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n,quiet=y"
+ }, process.env)
+}
\ No newline at end of file
diff --git a/org.eclipse.xsmp.vscode_extension/src/tsconfig.json b/org.eclipse.xsmp.vscode_extension/src/tsconfig.json
new file mode 100644
index 00000000..f3e002e3
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/src/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "compilerOptions": {
+ "target": "es6",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "sourceMap": false,
+ "inlineSources": false,
+ "declaration": true,
+ "stripInternal": true,
+ "lib": [ "es6" ],
+ "outDir": "../target"
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.xsmp.vscode_extension/syntaxes/xsmp.tmLanguage.json b/org.eclipse.xsmp.vscode_extension/syntaxes/xsmp.tmLanguage.json
new file mode 100644
index 00000000..6ec063ba
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/syntaxes/xsmp.tmLanguage.json
@@ -0,0 +1,57 @@
+{
+ "name": "Xsmpcat",
+ "scopeName": "source.xsmpcat",
+ "fileTypes": [
+ "xsmpcat"
+ ],
+ "repository": {
+ "general": {
+ "patterns": [
+ {
+ "include": "#linecomment"
+ },
+ {
+ "include": "#blockcomment"
+ },
+ {
+ "include": "#blockcommentdocumentation"
+ },
+ {
+ "include": "#keyword"
+ },
+ {
+ "include": "#keyword_operators"
+ }
+ ]
+ },
+ "linecomment": {
+ "name": "comment.line.double-dash.xsmpcat",
+ "begin": "(^[ \\t]+)?(?=//)",
+ "end": "(?=$)"
+ },
+ "blockcomment": {
+ "name": "comment.block.xsmpcat",
+ "begin": "/\\*(?!\\*)",
+ "end": "\\*/"
+ },
+ "blockcommentdocumentation": {
+ "name": "comment.block.documentation.xsmpcat",
+ "begin": "/\\*\\*",
+ "end": "\\*/"
+ },
+ "keyword": {
+ "name": "keyword.control.xsmpcat",
+ "match": "\\b(catalogue|model|struct|exception|container|writeOnly|constant|def|integer|float|eventsink|eventsource|reference|output|protected|entrypoint|property|using|void|readOnly|throws|enum|input|extends|field|transient|true|false|abstract|inout|service|namespace|array|native|get|readWrite|attribute|event|class|set|string|primitive|association|interface|out|public|private|import)\\b"
+ },
+ "keyword_operators": {
+ "name": "keyword.operator.xsmpcat",
+ "match": "\\b(\\|\\||<<|<=|>=|==|!=|<|>|&&|->|\\[|\\]|\\{|\\}|\\.|~|\\$|%|\\(|\\)|\\*|\\+|,|-|/|@|\\?|\\^)\\b"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#general"
+ }
+ ],
+ "uuid": "8383e49a-fa0d-4bb5-827b-10e8abb294ca"
+}
\ No newline at end of file
diff --git a/org.eclipse.xsmp.vscode_extension/xsmp.configuration.json b/org.eclipse.xsmp.vscode_extension/xsmp.configuration.json
new file mode 100644
index 00000000..b284b965
--- /dev/null
+++ b/org.eclipse.xsmp.vscode_extension/xsmp.configuration.json
@@ -0,0 +1,27 @@
+{
+ "comments": {
+ "lineComment": "//",
+ "blockComment": [ "/*", "*/" ],
+ "blockCommentDocumentation": [ "/**", "*/" ]
+ },
+ "brackets": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"]
+ ],
+ "autoClosingPairs": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"],
+ ["\"", "\""],
+ ["'", "'"],
+ ["/*", "*/"]
+ ],
+ "surroundingPairs": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"],
+ ["\"", "\""],
+ ["'", "'"]
+ ]
+}
\ No newline at end of file
diff --git a/org.eclipse.xsmp/.classpath b/org.eclipse.xsmp/.classpath
index 8c10dd05..494814cc 100644
--- a/org.eclipse.xsmp/.classpath
+++ b/org.eclipse.xsmp/.classpath
@@ -14,7 +14,6 @@
-
diff --git a/org.eclipse.xsmp/build.properties b/org.eclipse.xsmp/build.properties
index b7115e2d..18a5646e 100644
--- a/org.eclipse.xsmp/build.properties
+++ b/org.eclipse.xsmp/build.properties
@@ -9,7 +9,6 @@ jars.compile.order = .
source.. = emf-gen/,\
src/,\
src-gen/,\
- xtend-gen/,\
target/generated-sources/java-templates/
additional.bundles = org.eclipse.xtext.common.types,\
org.eclipse.xtext.xtext.generator,\
diff --git a/org.eclipse.xsmp/src/org/eclipse/xsmp/XsmpcatExtensionRuntimeModule.java b/org.eclipse.xsmp/src/org/eclipse/xsmp/XsmpcatExtensionRuntimeModule.java
index a84769a0..0494ab12 100644
--- a/org.eclipse.xsmp/src/org/eclipse/xsmp/XsmpcatExtensionRuntimeModule.java
+++ b/org.eclipse.xsmp/src/org/eclipse/xsmp/XsmpcatExtensionRuntimeModule.java
@@ -21,6 +21,7 @@
import org.eclipse.xsmp.validation.XsmpcatIssueCodesProvider;
import org.eclipse.xtext.conversion.IValueConverterService;
import org.eclipse.xtext.documentation.IEObjectDocumentationProvider;
+import org.eclipse.xtext.formatting.IIndentationInformation;
import org.eclipse.xtext.generator.IOutputConfigurationProvider;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy;
@@ -53,6 +54,11 @@ public void configureIScopeProviderDelegate(Binder binder)
return XsmpcatValueConverterService.class;
}
+ public Class< ? extends IIndentationInformation> bindIIndentationInformation()
+ {
+ return org.eclipse.xsmp.formatting2.XsmpcatFormatter.IndentationInformation.class;
+ }
+
/**
* @return the IEObjectDocumentationProvider class
*/
diff --git a/org.eclipse.xsmp/src/org/eclipse/xsmp/formatting2/XsmpcatFormatter.java b/org.eclipse.xsmp/src/org/eclipse/xsmp/formatting2/XsmpcatFormatter.java
index 8b4d8033..20a92446 100644
--- a/org.eclipse.xsmp/src/org/eclipse/xsmp/formatting2/XsmpcatFormatter.java
+++ b/org.eclipse.xsmp/src/org/eclipse/xsmp/formatting2/XsmpcatFormatter.java
@@ -88,6 +88,7 @@
import org.eclipse.xsmp.xcatalogue.UnaryOperation;
import org.eclipse.xsmp.xcatalogue.ValueReference;
import org.eclipse.xtext.Keyword;
+import org.eclipse.xtext.formatting.IIndentationInformation;
import org.eclipse.xtext.formatting2.AbstractJavaFormatter;
import org.eclipse.xtext.formatting2.IFormattableDocument;
import org.eclipse.xtext.formatting2.ITextReplacer;
@@ -108,6 +109,15 @@
@SuppressWarnings("restriction")
public class XsmpcatFormatter extends AbstractJavaFormatter
{
+ public static class IndentationInformation implements IIndentationInformation
+ {
+ @Override
+ public java.lang.String getIndentString()
+ {
+ return " ";
+ }
+ }
+
@Inject
private XsmpcatGrammarAccess ga;
diff --git a/org.eclipse.xsmp/src/org/eclipse/xsmp/util/XsmpUtil.java b/org.eclipse.xsmp/src/org/eclipse/xsmp/util/XsmpUtil.java
index ee6e8ce8..375101dc 100644
--- a/org.eclipse.xsmp/src/org/eclipse/xsmp/util/XsmpUtil.java
+++ b/org.eclipse.xsmp/src/org/eclipse/xsmp/util/XsmpUtil.java
@@ -318,30 +318,24 @@ protected boolean isBaseOf(EObject base, Interface derived)
protected boolean isBaseOf(EObject base, Model derived)
{
- final var baseFqn = fqn(base);
-
- return QualifiedNames.Smp_IModel.equals(baseFqn) || isBaseOf(base, (Component) derived);
+ return QualifiedNames.Smp_IModel.equals(fqn(base)) || isBaseOf(base, (Component) derived);
}
protected boolean isBaseOf(EObject base, Service derived)
{
- final var baseFqn = fqn(base);
-
- return QualifiedNames.Smp_IService.equals(baseFqn) || isBaseOf(base, (Component) derived);
+ return QualifiedNames.Smp_IService.equals(fqn(base)) || isBaseOf(base, (Component) derived);
}
protected boolean isBaseOf(EObject base, Component derived)
{
- final var baseFqn = fqn(base);
-
- return base == derived || QualifiedNames.Smp_IComponent.equals(baseFqn)
- || isBaseOf(base, derived.getBase())
+ return base == derived || QualifiedNames.Smp_IComponent.equals(fqn(base))
+ || derived.getBase() != null && isBaseOf(base, derived.getBase())
|| derived.getInterface().stream().anyMatch(b -> isBaseOf(base, b));
}
protected boolean isBaseOf(EObject base, Class derived)
{
- return base == derived || isBaseOf(base, derived.getBase());
+ return base == derived || derived.getBase() != null && isBaseOf(base, derived.getBase());
}
public VisibilityKind getMinVisibility(Type type, EObject from)
@@ -776,14 +770,13 @@ public boolean isSimpleArray(Array o)
public boolean isConst(Parameter o)
{
final var id = QualifiedNames.Attributes_Const;
- return cache.get(Tuples.pair(o, id), o.eResource(), () -> attributeBoolValue(o, id, () -> {
- return switch (o.getDirection())
- {
- case IN -> !(o.getType() instanceof ValueType);
- case RETURN, OUT, INOUT -> false;
- default -> false;
- };
- }));
+ return cache.get(Tuples.pair(o, id), o.eResource(),
+ () -> attributeBoolValue(o, id, () -> switch (o.getDirection())
+ {
+ case IN -> !(o.getType() instanceof ValueType);
+ case RETURN, OUT, INOUT -> false;
+ default -> false;
+ }));
}
@@ -823,7 +816,7 @@ public List getAssignableFields(Structure structure)
.map(Field.class::cast)
.filter(it -> getVisibility(it) == VisibilityKind.PUBLIC && !isStatic(it))
.collect(Collectors.toList());
- if (structure instanceof org.eclipse.xsmp.xcatalogue.Class clazz)
+ if (structure instanceof final org.eclipse.xsmp.xcatalogue.Class clazz)
{
final var base = clazz.getBase();
if (base instanceof Structure && !isBaseOf(base, clazz))
@@ -843,7 +836,7 @@ public Iterable getFields(Structure structure)
final var fields = Iterables.filter(Iterables.filter(structure.getMember(), Field.class),
it -> !isStatic(it));
- if (structure instanceof org.eclipse.xsmp.xcatalogue.Class clazz)
+ if (structure instanceof final org.eclipse.xsmp.xcatalogue.Class clazz)
{
final var base = clazz.getBase();
if (base instanceof Structure && !isBaseOf(base, clazz))
@@ -943,7 +936,8 @@ private Type findType(EObject parent)
case XcataloguePackage.CONSTANT -> ((Constant) parent).getType();
case XcataloguePackage.ASSOCIATION -> ((Association) parent).getType();
case XcataloguePackage.PARAMETER -> ((Parameter) parent).getType();
- case XcataloguePackage.STRING, XcataloguePackage.ARRAY, XcataloguePackage.MULTIPLICITY -> findPrimitiveType(parent, QualifiedNames.Smp_Int64);
+ case XcataloguePackage.STRING, XcataloguePackage.ARRAY, XcataloguePackage.MULTIPLICITY -> findPrimitiveType(
+ parent, QualifiedNames.Smp_Int64);
case XcataloguePackage.FLOAT ->
{
final var type = ((Float) parent).getPrimitiveType();
@@ -954,7 +948,8 @@ private Type findType(EObject parent)
final var type = ((org.eclipse.xsmp.xcatalogue.Integer) parent).getPrimitiveType();
yield type != null ? type : findPrimitiveType(parent, QualifiedNames.Smp_Int32);
}
- case XcataloguePackage.ENUMERATION_LITERAL -> findPrimitiveType(parent, QualifiedNames.Smp_Int32);
+ case XcataloguePackage.ENUMERATION_LITERAL -> findPrimitiveType(parent,
+ QualifiedNames.Smp_Int32);
case XcataloguePackage.ENUMERATION -> (Type) parent;
case XcataloguePackage.ATTRIBUTE ->
{
diff --git a/pom.xml b/pom.xml
index ad9df366..7d91852c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,6 +32,7 @@
org.eclipse.xsmp.lib
org.eclipse.xsmp.forms
org.eclipse.xsmp.ide
+ org.eclipse.xsmp.ide.tests
org.eclipse.xsmp.design
org.eclipse.xsmp.ui
org.eclipse.xsmp.ui.tests
@@ -48,6 +49,7 @@
org.eclipse.xsmp.profile.simsat.cli
org.eclipse.xsmp.profile.simsat.feature
org.eclipse.xsmp.profile.simsat.ui
+ org.eclipse.xsmp.vscode_extension