From 733043f9ceb443600f5fc53b2a26847eddcedb5e Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Thu, 28 Nov 2024 09:46:24 +0100 Subject: [PATCH] ren docs after repo move Signed-off-by: Christian Dietrich --- .../contents/101_gettingstarted.html | 2 +- .../contents/102_moviesexample.html | 10 +- org.eclipse.xtend.doc/contents/201_types.html | 2 +- .../contents/202_xtend_classes_members.html | 16 +- .../contents/203_xtend_expressions.html | 10 +- .../contents/204_activeannotations.html | 52 +++---- .../contents/103_domainmodelnextsteps.html | 18 +-- .../contents/104_jvmdomainmodel.html | 14 +- .../contents/301_grammarlanguage.html | 6 +- .../contents/302_configuration.html | 36 ++--- .../contents/303_runtime_concepts.html | 144 +++++++++--------- org.eclipse.xtext.doc/contents/305_xbase.html | 60 ++++---- .../contents/307_special_languages.html | 4 +- .../contents/308_emf_integration.html | 20 +-- .../contents/310_eclipse_support.html | 136 ++++++++--------- .../contents/330_web_support.html | 22 +-- .../contents/340_lsp_support.html | 2 +- .../images/LSP_04B_AddTextMateGrammarFile.png | Bin 0 -> 120384 bytes 18 files changed, 277 insertions(+), 277 deletions(-) create mode 100644 org.eclipse.xtext.doc/contents/images/LSP_04B_AddTextMateGrammarFile.png diff --git a/org.eclipse.xtend.doc/contents/101_gettingstarted.html b/org.eclipse.xtend.doc/contents/101_gettingstarted.html index a86a38f6f5e..286fc3b05c7 100644 --- a/org.eclipse.xtend.doc/contents/101_gettingstarted.html +++ b/org.eclipse.xtend.doc/contents/101_gettingstarted.html @@ -33,7 +33,7 @@

Hello World

} -

The only surprising fact in the generated Java code may be the referenced library class InputOutput. It is part of the runtime library and a nice utility that is quite handy when used in expressions.

+

The only surprising fact in the generated Java code may be the referenced library class InputOutput. It is part of the runtime library and a nice utility that is quite handy when used in expressions.

You can put an Xtend class into a source folder of any Java project within Eclipse or any Maven project. If the project is not yet configured properly, Eclipse will complain about the missing library. The xtend.lib has to be on the class path. The IDE will provide a quick fix to add it.

diff --git a/org.eclipse.xtend.doc/contents/102_moviesexample.html b/org.eclipse.xtend.doc/contents/102_moviesexample.html index 85dc75ff438..6475098c0ef 100644 --- a/org.eclipse.xtend.doc/contents/102_moviesexample.html +++ b/org.eclipse.xtend.doc/contents/102_moviesexample.html @@ -79,14 +79,14 @@

Parsing The Data

import static extension com.google.common.io.CharStreams.*
 
-

CharStreams.readLines(Reader) returns a List<String> on which we call another extension method map. This one is defined in the runtime library (ListExtensions.map(…)) and is automatically imported and therefore available on all lists. The map extension expects a function as a parameter. It basically invokes that function for each value in the list and returns another list containing the results of the function invocations. Actually this mapping is performed lazily so if you never access the values of the result list, the mapping function is never executed.

+

CharStreams.readLines(Reader) returns a List<String> on which we call another extension method map. This one is defined in the runtime library (ListExtensions.map(…)) and is automatically imported and therefore available on all lists. The map extension expects a function as a parameter. It basically invokes that function for each value in the list and returns another list containing the results of the function invocations. Actually this mapping is performed lazily so if you never access the values of the result list, the mapping function is never executed.

Function objects are created using lambda expressions (the code in squared brackets). Within the lambda we process a single line from the text file and turn it into a movie by splitting the string using two whitespace characters as the separator. On the result of the split operation, the method iterator() is invoked. As you might know String.split(String) returns a string array (String[]), which Xtend auto-converts to a list when we call Iterable.iterator() on it.

val segments = line.split('  ').iterator
 
-

Now we use the iterator to create an instance of Movie for each String that it yields. The data type conversion (e.g. String to int) is done by calling static methods from the wrapper types. The rest of the Iterable is turned into a set of categories. Therefore, the extension method IteratorExtensions.toSet(Iterator<T>) is invoked on the iterator to consume its remaining values.

+

Now we use the iterator to create an instance of Movie for each String that it yields. The data type conversion (e.g. String to int) is done by calling static methods from the wrapper types. The rest of the Iterable is turned into a set of categories. Therefore, the extension method IteratorExtensions.toSet(Iterator<T>) is invoked on the iterator to consume its remaining values.

return new Movie (
   segments.next, 
@@ -124,7 +124,7 @@ 

Question 1 : What Is The Number Of Action Movies?

movies.filter[ categories.contains('Action') ].size
 
-

Eventually we call size on the resulting iterable which is an extension method, too. It is defined in the utility class IterableExtensions.

+

Eventually we call size on the resulting iterable which is an extension method, too. It is defined in the utility class IterableExtensions.

Question 2 : What Is The Year The Best Movie From The 80’s Was Released?

@@ -134,9 +134,9 @@

Question 2 : What Is The Year The Best Movie From The 80’s }

-

Here we filter for all movies whose year is included in the range from 1980 to 1989 (the 80’s). The .. operator is again an extension defined in IntegerExtensions and returns an instance of IntegerRange. Operator overloading is explained in section.

+

Here we filter for all movies whose year is included in the range from 1980 to 1989 (the 80’s). The .. operator is again an extension defined in IntegerExtensions and returns an instance of IntegerRange. Operator overloading is explained in section.

-

The resulting iterable is sorted (IterableExtensions.sortBy) by the rating of the movies. Since it is sorted in ascending order, we take the last movie from the list and return its year.

+

The resulting iterable is sorted (IterableExtensions.sortBy) by the rating of the movies. Since it is sorted in ascending order, we take the last movie from the list and return its year.

We could have sorted descending and take the head of the list as well:

diff --git a/org.eclipse.xtend.doc/contents/201_types.html b/org.eclipse.xtend.doc/contents/201_types.html index 6fe6773986b..b8d0ca99d4d 100644 --- a/org.eclipse.xtend.doc/contents/201_types.html +++ b/org.eclipse.xtend.doc/contents/201_types.html @@ -48,7 +48,7 @@

Conversion Rules

The conversion works the other way round, too. In fact, all subtypes of Iterable are automatically converted to arrays on demand.

-

Another very useful conversion applies to lambda expressions. A lambda expression usually is of one of the types declared in Functions or Procedures. However, if the expected type is an interface or a class with a single abstract method declaration, a lambda expression is automatically converted to that type. This allows to use lambda expressions with many existing Java libraries. See Lambda Expression Typing for more details.

+

Another very useful conversion applies to lambda expressions. A lambda expression usually is of one of the types declared in Functions or Procedures. However, if the expected type is an interface or a class with a single abstract method declaration, a lambda expression is automatically converted to that type. This allows to use lambda expressions with many existing Java libraries. See Lambda Expression Typing for more details.


diff --git a/org.eclipse.xtend.doc/contents/202_xtend_classes_members.html b/org.eclipse.xtend.doc/contents/202_xtend_classes_members.html index abff4831d15..b69e00ab496 100644 --- a/org.eclipse.xtend.doc/contents/202_xtend_classes_members.html +++ b/org.eclipse.xtend.doc/contents/202_xtend_classes_members.html @@ -488,14 +488,14 @@

Extensions from the Library

Have a look at the JavaDoc to learn about the available functionality:

Local Extension Methods

diff --git a/org.eclipse.xtend.doc/contents/203_xtend_expressions.html b/org.eclipse.xtend.doc/contents/203_xtend_expressions.html index 934daadfffc..77689d47495 100644 --- a/org.eclipse.xtend.doc/contents/203_xtend_expressions.html +++ b/org.eclipse.xtend.doc/contents/203_xtend_expressions.html @@ -99,7 +99,7 @@

Type Literals

Collection Literals

-

The methods in CollectionLiterals are automatically imported so it’s very easy and convenient to create instances of the various collection types the JDK offers.

+

The methods in CollectionLiterals are automatically imported so it’s very easy and convenient to create instances of the various collection types the JDK offers.

val myList = newArrayList('Hello', 'World')
 val myMap = newLinkedHashMap('a' -> 1, 'b' -> 2) 
@@ -127,7 +127,7 @@ 

Collection Literals

Arrays

-

Java arrays can be created either using a literal as described in the previous section, or if it should be a new array with a fixed size, one of the methods from ArrayLiterals can be used. The generic newArrayOfSize(int) method works for all reference types, while there is a specific factory method for each primitive type.

+

Java arrays can be created either using a literal as described in the previous section, or if it should be a new array with a fixed size, one of the methods from ArrayLiterals can be used. The generic newArrayOfSize(int) method works for all reference types, while there is a specific factory method for each primitive type.

Example:

@@ -161,7 +161,7 @@

Type Casts

Infix Operators and Operator Overloading

-

There are a couple of common predefined infix operators. These operators are not limited to operations on certain types. Instead an operator-to-method mapping allows to redefine the operators for any type just by implementing the corresponding method signature. As an example, the runtime library contains a class BigDecimalExtensions that defines operators for BigDecimals. The following code is therefore perfectly valid:

+

There are a couple of common predefined infix operators. These operators are not limited to operations on certain types. Instead an operator-to-method mapping allows to redefine the operators for any type just by implementing the corresponding method signature. As an example, the runtime library contains a class BigDecimalExtensions that defines operators for BigDecimals. The following code is therefore perfectly valid:

val x = 2.71BD
 val y = 3.14BD
@@ -343,7 +343,7 @@ 

Infix Operators and Operator Overloading

Short-Circuit Boolean Operators

-

If the operators ||, &&, and ?: are bound to the library methods BooleanExtensions.operator_and(boolean l, boolean r), BooleanExtensions.operator_or(boolean l, boolean r) resp. <T> T operator_elvis(T first, T second) the operation is inlined and evaluated in short circuit mode. That means that the right hand operand might not be evaluated at all in the following cases:

+

If the operators ||, &&, and ?: are bound to the library methods BooleanExtensions.operator_and(boolean l, boolean r), BooleanExtensions.operator_or(boolean l, boolean r) resp. <T> T operator_elvis(T first, T second) the operation is inlined and evaluated in short circuit mode. That means that the right hand operand might not be evaluated at all in the following cases:

  1. in the case of || the operand on the right hand side is not evaluated if the left operand evaluates to true.
  2. @@ -779,7 +779,7 @@

    Typing

    val toUpperCaseFunction = [ String s | s.toUpperCase ] // inferred type is (String)=>String
     
    -

    The type will be one of the inner types found in Functions or Procedures. It is a procedure if the return type is void, otherwise it is a function.

    +

    The type will be one of the inner types found in Functions or Procedures. It is a procedure if the return type is void, otherwise it is a function.

    Xtend supports a shorthand syntax for function types. Instead of writing Function1<? super String,? extends String> which is what you will find in the generated Java code, you can simply write (String)=>String.

    diff --git a/org.eclipse.xtend.doc/contents/204_activeannotations.html b/org.eclipse.xtend.doc/contents/204_activeannotations.html index eb749853d1e..06ecb3c9c9a 100644 --- a/org.eclipse.xtend.doc/contents/204_activeannotations.html +++ b/org.eclipse.xtend.doc/contents/204_activeannotations.html @@ -12,7 +12,7 @@

    Active Annotations

    Active annotations allow developers to participate in the translation process of Xtend source code to Java code via library. That’s useful in cases where Java requires to write a lot of boilerplate manually. For instance, many of the good old design patterns fall into this category. With active annotations you no longer need to remember how the Visitor or the Observer pattern should be implemented. In Xtend you can implement the expansion of such patterns in a library and let the compiler do the heavy lifting for you.

    -

    An active annotation is just an annotation declared either in Java or Xtend, which is itself annotated with Active. @Active takes a type literal as a parameter pointing to the processor.

    +

    An active annotation is just an annotation declared either in Java or Xtend, which is itself annotated with Active. @Active takes a type literal as a parameter pointing to the processor.

    The IDE plugin comes with an example project, which you can easily materialize into your workspace. To do so use the new project wizard and in the category Xtend Examples choose the active annotation example. The examples contain three different annotations which we will use for further explanation.

    @@ -27,28 +27,28 @@

    Annotation Processor

    A processor class must implement one or more of the lifecycle call-back interfaces provided by the compiler. This interfaces are:

    There are base classes that implment all callback interfaces. You should subclass one of those depending on your annotation target:

    -

    If you want to annotate other elements such as parameters or constructors, you should have a look at the bases classes and adapt their implementation (basically the type parameter) accordingly. It is also possible to have a very generic processor by using Declaration, the super type of all declared elements.

    +

    If you want to annotate other elements such as parameters or constructors, you should have a look at the bases classes and adapt their implementation (basically the type parameter) accordingly. It is also possible to have a very generic processor by using Declaration, the super type of all declared elements.

    Phase 1: Register Globals

    -

    The first phase in the lifecycle of the compiler is about indexing the types as globally available symbols. By implementing a RegisterGlobalsParticipant you have the chance to create and register new Java types during this phase. It’s important to do this in a first phase so later on the compiler can find and access these types.

    +

    The first phase in the lifecycle of the compiler is about indexing the types as globally available symbols. By implementing a RegisterGlobalsParticipant you have the chance to create and register new Java types during this phase. It’s important to do this in a first phase so later on the compiler can find and access these types.

    For example the ExtractProcessor adds one interface per annotated class:

    @@ -66,13 +66,13 @@

    Phase 1: Register Globals

    }
-

The RegisterGlobalsContext provides all the services that are available during this compilation step. It is passed into the method doRegisterGlobals() along with a read-only representation of the annotated source elements. The AbstractClassProcessor in this example is invoked for all classes that are annotated with @Extract.

+

The RegisterGlobalsContext provides all the services that are available during this compilation step. It is passed into the method doRegisterGlobals() along with a read-only representation of the annotated source elements. The AbstractClassProcessor in this example is invoked for all classes that are annotated with @Extract.

-

The compiler calls RegisterGlobalsParticipant once per compilation unit and provides access to all elements which are annotated with the active annotation this processor is registered for. Therefore the ExtractProcessor is invoked with a list of all classes that are defined in the same Xtend file for all the files that are being compiled.

+

The compiler calls RegisterGlobalsParticipant once per compilation unit and provides access to all elements which are annotated with the active annotation this processor is registered for. Therefore the ExtractProcessor is invoked with a list of all classes that are defined in the same Xtend file for all the files that are being compiled.

Phase 2: Transformation

-

In the second phase developers can modify the compiled Java classes and Java code. Annotation processors that implement TransformationParticipant participate in this compile step. Similar to the RegisterGlobalsParticipant interface the compiler provides two arguments: The list of annotated translated and now mutable Java elements and a TransformationContext. The context provides services that are specific for this second step.

+

In the second phase developers can modify the compiled Java classes and Java code. Annotation processors that implement TransformationParticipant participate in this compile step. Similar to the RegisterGlobalsParticipant interface the compiler provides two arguments: The list of annotated translated and now mutable Java elements and a TransformationContext. The context provides services that are specific for this second step.

A transformation participant can access and modify mutable Java elements. These are an in-memory representation of the generated Java code. They are usually very similar to the source elements, but can be modified and new methods, fields or constructors can be added. It is not possible to create new types during the transformation step. Also note, that other annotation processors might already have altered the model.

@@ -111,7 +111,7 @@

Phase 2: Transformation

}
-

In the first line, findInterface retrieves the interface which was registered during the registration of global symbols in the first phase: The method is defined in TransformationContext which is used as an extension provider.

+

In the first line, findInterface retrieves the interface which was registered during the registration of global symbols in the first phase: The method is defined in TransformationContext which is used as an extension provider.

Next up the newly created interface is added to the existing list of implemented interfaces.

@@ -120,7 +120,7 @@

Phase 2: Transformation

The code calls setImplementedInterfaces(Iterable<TypeReference>) on the annotated class. The right hand side of the assignment is a concatenation of the existing implemented interfaces and a type reference pointing to the freshly created interface.

-

A TypeReference can be created using one of the various methods from TypeReferenceProvider which is a super type of TransformationContext. These utilities are available as extensions, too.

+

A TypeReference can be created using one of the various methods from TypeReferenceProvider which is a super type of TransformationContext. These utilities are available as extensions, too.

Phase 3: Validation

@@ -128,7 +128,7 @@

Phase 3: Validation

Phase 4: Code Generation

-

The last phase in the lifecycle of the compiler lets you participate in writing and updating the files. In the IDE this phase is only executed on save , while the previous two get executed after minor edits in the editor as well. In order to participate your processor needs to implement CodeGenerationParticipant. The extract interface example doesn’t make use of this hook, but another example for internationalization which is also included, generates a *.properties file, like this:

+

The last phase in the lifecycle of the compiler lets you participate in writing and updating the files. In the IDE this phase is only executed on save , while the previous two get executed after minor edits in the editor as well. In order to participate your processor needs to implement CodeGenerationParticipant. The extract interface example doesn’t make use of this hook, but another example for internationalization which is also included, generates a *.properties file, like this:

class ExternalizedProcessor extends AbstractClassProcessor {
   
@@ -149,11 +149,11 @@ 

Phase 4: Code Generation

}
-

The CodeGenerationContext provides all the services that are available during this phase. Have a look at the Java doc for more details.

+

The CodeGenerationContext provides all the services that are available during this phase. Have a look at the Java doc for more details.

On Expressions and Statements

-

Most of the generated Java code is represented in the form of in-memory elements. Basically all the structural elements are represented as a dedicated Element. If you want to generate the body of a method or the initializer of a field, you have two options.

+

Most of the generated Java code is represented in the form of in-memory elements. Basically all the structural elements are represented as a dedicated Element. If you want to generate the body of a method or the initializer of a field, you have two options.

Generating Blackbox Java Code

@@ -209,7 +209,7 @@

Custom Compiler Checks

The previous example requires each annotated field to have an initializer. Otherwise it would not be possible to use lazy initialization to assign its value. Also a simple check for a null reference could cause trouble with primitive values. A validation for that case would be sensible, too. In order to guide the user dedicated compilation errors should be raised if these constrains are violated.

-

The TransformationContext inherits methods for exactly that purpose from the ProblemSupport service.

+

The TransformationContext inherits methods for exactly that purpose from the ProblemSupport service.

Since the context is declared as an extension provider, those methods can be used as extensions and it allows to implement the constraint check accordingly:

@@ -333,7 +333,7 @@

Existing Active Annotations

@Accessors

-

If you want to add getter and or setter methods for your fields @Accessors is your friend. Here’s a basic example.

+

If you want to add getter and or setter methods for your fields @Accessors is your friend. Here’s a basic example.

@Accessors String name
 
@@ -351,7 +351,7 @@

@Accessors

} -

So by default a public getter and a public setter method is created. The @Accessors can be configured to tell that you only want one or the other and to change the visibility. this is done by means of AccessorType You can also use the annotation on class level to do the same for all fields.

+

So by default a public getter and a public setter method is created. The @Accessors can be configured to tell that you only want one or the other and to change the visibility. this is done by means of AccessorType You can also use the annotation on class level to do the same for all fields.

Here is a more complex example, that shows how it works:

@@ -400,7 +400,7 @@

@Accessors

@Data

-

The annotation @Data, will turn an annotated class into a value object class. A class annotated with @Data is processed according to the following rules:

+

The annotation @Data, will turn an annotated class into a value object class. A class annotated with @Data is processed according to the following rules:

-

To use concrete syntax validation you can let Guice inject an instance of IConcreteSyntaxValidator and use it directly. Furthermore, there is an adapter which allows to use the concrete syntax validator as an EValidator. You can, for example, enable it in your runtime module, by adding:

+

To use concrete syntax validation you can let Guice inject an instance of IConcreteSyntaxValidator and use it directly. Furthermore, there is an adapter which allows to use the concrete syntax validator as an EValidator. You can, for example, enable it in your runtime module, by adding:

@SingletonBinding(eager = true)
 public Class<? extends ConcreteSyntaxEValidator> bindConcreteSyntaxEValidator() {
@@ -108,13 +108,13 @@ 

Serializer: Concrete Syntax Validation

}
-

To customize the error messages please see IConcreteSyntaxDiagnosticProvider and subclass ConcreteSyntaxDiagnosticProvider.

+

To customize the error messages please see IConcreteSyntaxDiagnosticProvider and subclass ConcreteSyntaxDiagnosticProvider.

Custom Validation

-

In addition to the afore mentioned kinds of validation, which are more or less done automatically, you can specify additional constraints specific for your Ecore model. The Xtext language generator will provide you two Java classes. The first is an abstract class generated to src-gen/ which extends the library class AbstractDeclarativeValidator. This one just registers the EPackages for which this validator introduces constraints. The other class is a subclass of that abstract class and is generated to the src/ folder in order to be edited by you. That is where you put the constraints in.

+

In addition to the afore mentioned kinds of validation, which are more or less done automatically, you can specify additional constraints specific for your Ecore model. The Xtext language generator will provide you two Java classes. The first is an abstract class generated to src-gen/ which extends the library class AbstractDeclarativeValidator. This one just registers the EPackages for which this validator introduces constraints. The other class is a subclass of that abstract class and is generated to the src/ folder in order to be edited by you. That is where you put the constraints in.

-

The purpose of the AbstractDeclarativeValidator is to allow you to write constraints in a declarative way - as the class name already suggests. That is instead of writing exhaustive if-else constructs or extending the generated EMF switch you just have to add the Check annotation to any method and it will be invoked automatically when validation takes place. Moreover you can state for what type the respective constraint method is, just by declaring a typed parameter. This also lets you avoid any type casts. In addition to the reflective invocation of validation methods the AbstractDeclarativeValidator provides a few convenient assertions.

+

The purpose of the AbstractDeclarativeValidator is to allow you to write constraints in a declarative way - as the class name already suggests. That is instead of writing exhaustive if-else constructs or extending the generated EMF switch you just have to add the Check annotation to any method and it will be invoked automatically when validation takes place. Moreover you can state for what type the respective constraint method is, just by declaring a typed parameter. This also lets you avoid any type casts. In addition to the reflective invocation of validation methods the AbstractDeclarativeValidator provides a few convenient assertions.

The Check annotation has a parameter that can be used to declare when a check should run: FAST will run whenever a file is modified, NORMAL checks will run when saving the file, and EXPENSIVE checks will run when explicitly validating the file via the menu option. Here is an example written in Java:

@@ -130,7 +130,7 @@

Custom Validation

}
-

You can use the IResourceValidator to validate a given resource programmatically. Example:

+

You can use the IResourceValidator to validate a given resource programmatically. Example:

@Inject IResourceValidator resourceValidator;
 
@@ -170,9 +170,9 @@ 

Lazy Linking

ref Entity01

-

the LazyLinker first creates an EMF proxy and assigns it to the corresponding EReference. In EMF a proxy is described by a URI, which points to the real EObject. In the case of lazy linking the stored URI comprises of the context information given at parse time, which is the EObject containing the cross-reference, the actual EReference, the list index (in case it’s a multi-valued cross-reference) and the string which represented the cross-link in the concrete syntax. The latter usually corresponds to the name of the referenced EObject. In EMF a URI consists of information about the resource the EObject is contained in as well as a so called fragment part, which is used to find the EObject within that resource. When an EMF proxy is resolved, the current ResourceSet is asked. The resource set uses the first part to obtain (i.e. load if it is not already loaded) the resource. Then the resource is asked to return the EObject based on the fragment in the URI. The actual cross-reference resolution is done by LazyLinkingResource.getEObject(String) which receives the fragment and delegates to the implementation of the ILinkingService. The default implementation in turn delegates to the scoping API.

+

the LazyLinker first creates an EMF proxy and assigns it to the corresponding EReference. In EMF a proxy is described by a URI, which points to the real EObject. In the case of lazy linking the stored URI comprises of the context information given at parse time, which is the EObject containing the cross-reference, the actual EReference, the list index (in case it’s a multi-valued cross-reference) and the string which represented the cross-link in the concrete syntax. The latter usually corresponds to the name of the referenced EObject. In EMF a URI consists of information about the resource the EObject is contained in as well as a so called fragment part, which is used to find the EObject within that resource. When an EMF proxy is resolved, the current ResourceSet is asked. The resource set uses the first part to obtain (i.e. load if it is not already loaded) the resource. Then the resource is asked to return the EObject based on the fragment in the URI. The actual cross-reference resolution is done by LazyLinkingResource.getEObject(String) which receives the fragment and delegates to the implementation of the ILinkingService. The default implementation in turn delegates to the scoping API.

-

A simple implementation of the linking service is shipped with Xtext and used for any grammar as default. Usually any necessary customization of the linking behavior can best be described using the scoping API.

+

A simple implementation of the linking service is shipped with Xtext and used for any grammar as default. Usually any necessary customization of the linking behavior can best be described using the scoping API.

Scoping

@@ -193,7 +193,7 @@

Scoping

The grammar declares that for the reference type only instances of the type Type are allowed. However, this simple declaration doesn’t say anything about where to find the type. That is the duty of scopes.

-

An IScopeProvider is responsible for providing an IScope for a given context EObject and EReference. The returned IScope should contain all target candidates for the given object and cross-reference.

+

An IScopeProvider is responsible for providing an IScope for a given context EObject and EReference. The returned IScope should contain all target candidates for the given object and cross-reference.

public interface IScopeProvider {
 
@@ -213,7 +213,7 @@ 

Scoping

}
-

A single IScope represents an element of a linked list of scopes. That means that a scope can be nested within an outer scope. Each scope works like a symbol table or a map where the keys are strings and the values are so-called IEObjectDescription, which is effectively an abstract description of a real EObject. In order to create IEObjectDescriptions for your model elements, the class Scopes is very useful.

+

A single IScope represents an element of a linked list of scopes. That means that a scope can be nested within an outer scope. Each scope works like a symbol table or a map where the keys are strings and the values are so-called IEObjectDescription, which is effectively an abstract description of a real EObject. In order to create IEObjectDescriptions for your model elements, the class Scopes is very useful.

To have a concrete example, let’s deal with the following simple grammar.

@@ -251,7 +251,7 @@

Scoping

There are different useful implementations for IScope shipped with Xtext. We want to mention only some of them here.

-

The MapBasedScope comes with the efficiency of a map to look up a certain name. If you prefer to deal with Multimaps the MultimapBasedScope should work for you. For situations where some elements should be filtered out of an existing scope, the FilteringScope is the right way to go. As scopes can be nested, we strongly recommend to use FilteringScope only for leaf scopes without nested scopes.

+

The MapBasedScope comes with the efficiency of a map to look up a certain name. If you prefer to deal with Multimaps the MultimapBasedScope should work for you. For situations where some elements should be filtered out of an existing scope, the FilteringScope is the right way to go. As scopes can be nested, we strongly recommend to use FilteringScope only for leaf scopes without nested scopes.

Coming back to our example, one possible scenario for the FilteringScope could be to exclude the context element from the list of candidates as it should not be a super-element of itself.

@@ -273,27 +273,27 @@

Global Scopes and Resource Descriptions

In the simple scoping example above we don’t have references across model files. Neither is there a concept like a namespace which would make scoping a bit more complicated. Basically, every Element declared in the same resource is visible by its name. However, in the real world things are most likely not that simple: What if you want to reuse certain declared elements across different files and you want to share those as library between different users? You would want to introduce some kind of cross-resource reference.

-

Defining what is visible from outside the current resource is the responsibility of global scopes. As the name suggests, global scopes are provided by instances of the IGlobalScopeProvider. The data structures (called index) used to store its elements are described in the next section.

+

Defining what is visible from outside the current resource is the responsibility of global scopes. As the name suggests, global scopes are provided by instances of the IGlobalScopeProvider. The data structures (called index) used to store its elements are described in the next section.

Resource and EObject Descriptions

-

In order to make elements of one file referable from another file, you need to export them as part of a so called IResourceDescription.

+

In order to make elements of one file referable from another file, you need to export them as part of a so called IResourceDescription.

-

An IResourceDescription contains information about the resource itself, which primarily its URI, a list of exported EObjects in the form of IEObjectDescriptions, as well as information about outgoing cross-references and qualified names it references. The cross-references contain only resolved references, while the list of imported qualified names also contains the names that couldn’t be resolved. This information is leveraged by the indexing infrastructure of Xtext in order to compute the transitive hull of dependent resources.

+

An IResourceDescription contains information about the resource itself, which primarily its URI, a list of exported EObjects in the form of IEObjectDescriptions, as well as information about outgoing cross-references and qualified names it references. The cross-references contain only resolved references, while the list of imported qualified names also contains the names that couldn’t be resolved. This information is leveraged by the indexing infrastructure of Xtext in order to compute the transitive hull of dependent resources.

-

For users, and especially in the context of scoping, the most important information is the list of exported EObjects. An IEObjectDescription stores the URI of the actual EObject, its QualifiedName, as well as its EClass. In addition one can export arbitrary information using the user data map. The following diagram gives an overview on the description classes and their relationships.

+

For users, and especially in the context of scoping, the most important information is the list of exported EObjects. An IEObjectDescription stores the URI of the actual EObject, its QualifiedName, as well as its EClass. In addition one can export arbitrary information using the user data map. The following diagram gives an overview on the description classes and their relationships.

The data model of Xtext's index

-

A language is configured with default implementations of IResourceDescription.Manager and DefaultResourceDescriptionStrategy, which are responsible to compute the list of exported IEObjectDescriptions. The Manager iterates over the whole EMF model for each Resource and asks the ResourceDescriptionStrategy to compute an IEObjectDescription for each EObject. The ResourceDescriptionStrategy applies the getQualifiedName(EObject obj) from IQualifiedNameProvider on the object, and if it has a qualified name an IEObjectDescription is created and passed back to the Manager which adds it to the list of exported objects. If an EObject doesn’t have a qualified name, the element is considered to be not referable from outside the resource and consequently not indexed. If you don’t like this behavior, you can implement and bind your own implementation of IDefaultResourceDescriptionStrategy.

+

A language is configured with default implementations of IResourceDescription.Manager and DefaultResourceDescriptionStrategy, which are responsible to compute the list of exported IEObjectDescriptions. The Manager iterates over the whole EMF model for each Resource and asks the ResourceDescriptionStrategy to compute an IEObjectDescription for each EObject. The ResourceDescriptionStrategy applies the getQualifiedName(EObject obj) from IQualifiedNameProvider on the object, and if it has a qualified name an IEObjectDescription is created and passed back to the Manager which adds it to the list of exported objects. If an EObject doesn’t have a qualified name, the element is considered to be not referable from outside the resource and consequently not indexed. If you don’t like this behavior, you can implement and bind your own implementation of IDefaultResourceDescriptionStrategy.

-

There are two different default implementations of IQualifiedNameProvider. Both work by looking up an EAttributename’. The SimpleNameProvider simply returns the plain value, while the DefaultDeclarativeQualifiedNameProvider concatenates the simple name with the qualified name of its parent exported EObject. This effectively simulates the qualified name computation of most namespace-based languages such as Java. It also allows to override the name computation declaratively: Just add methods named qualifiedName in a subclass and give each of them one argument with the type of element you wish to compute a name for.

+

There are two different default implementations of IQualifiedNameProvider. Both work by looking up an EAttributename’. The SimpleNameProvider simply returns the plain value, while the DefaultDeclarativeQualifiedNameProvider concatenates the simple name with the qualified name of its parent exported EObject. This effectively simulates the qualified name computation of most namespace-based languages such as Java. It also allows to override the name computation declaratively: Just add methods named qualifiedName in a subclass and give each of them one argument with the type of element you wish to compute a name for.

-

As already mentioned, the default implementation strategy exports every model element that the IQualifiedNameProvider can provide a name for. This is a good starting point, but when your models become bigger and you have a lot of them the index will become larger and larger. In most scenarios only a small part of your model should be visible from outside, hence only that small part needs to be in the index. In order to do this, bind a custom implementation of IDefaultResourceDescriptionStrategy and create index representations only for those elements that you want to reference from outside the resource they are contained in. From within the resource, references to those filtered elements are still possible as long as they have a name.

+

As already mentioned, the default implementation strategy exports every model element that the IQualifiedNameProvider can provide a name for. This is a good starting point, but when your models become bigger and you have a lot of them the index will become larger and larger. In most scenarios only a small part of your model should be visible from outside, hence only that small part needs to be in the index. In order to do this, bind a custom implementation of IDefaultResourceDescriptionStrategy and create index representations only for those elements that you want to reference from outside the resource they are contained in. From within the resource, references to those filtered elements are still possible as long as they have a name.

-

Beside the exported elements the index contains IReferenceDescriptions that contain the information who is referencing who. They are created through the IResourceDescription.Manager and IDefaultResourceDescriptionStrategy, too. If there is a model element that references another model element, the IDefaultResourceDescriptionStrategy creates an IReferenceDescription that contains the URI of the referencing element (sourceEObjectURI) and the referenced element (targetEObjectURI). These IReferenceDescriptions are very useful to find references and calculate affected resources.

+

Beside the exported elements the index contains IReferenceDescriptions that contain the information who is referencing who. They are created through the IResourceDescription.Manager and IDefaultResourceDescriptionStrategy, too. If there is a model element that references another model element, the IDefaultResourceDescriptionStrategy creates an IReferenceDescription that contains the URI of the referencing element (sourceEObjectURI) and the referenced element (targetEObjectURI). These IReferenceDescriptions are very useful to find references and calculate affected resources.

-

As mentioned above, in order to compute an IResourceDescription for a resource the framework asks the IResourceDescription.Manager which delegates to the IDefaultResourceDescriptionStrategy. To convert between a QualifiedName and its String representation you can use the IQualifiedNameConverter. Here is some Xtend code showing how to do that:

+

As mentioned above, in order to compute an IResourceDescription for a resource the framework asks the IResourceDescription.Manager which delegates to the IDefaultResourceDescriptionStrategy. To convert between a QualifiedName and its String representation you can use the IQualifiedNameConverter. Here is some Xtend code showing how to do that:

@Inject IResourceServiceProvider.Registry rspr
 @Inject IQualifiedNameConverter converter
@@ -308,9 +308,9 @@ 

Resource and EObject Descriptions

}
-

In order to obtain a Manager it is best to ask the corresponding IResourceServiceProvider as shown above. That is because each language might have a totally different implementation, and as you might refer from one language to a different language you cannot reuse the Manager of the first language.

+

In order to obtain a Manager it is best to ask the corresponding IResourceServiceProvider as shown above. That is because each language might have a totally different implementation, and as you might refer from one language to a different language you cannot reuse the Manager of the first language.

-

Now that we know how to export elements to be referable from other resources, we need to learn how those exported IEObjectDescriptions can be made available to the referencing resources. That is the responsibility of global scoping which is described in the following section.

+

Now that we know how to export elements to be referable from other resources, we need to learn how those exported IEObjectDescriptions can be made available to the referencing resources. That is the responsibility of global scoping which is described in the following section.

If you would like to see what’s in the index, you could use the ‘Open Model Element’ dialog from the navigation menu entry.

@@ -318,17 +318,17 @@

Global Scopes Based On External Configuration

Instead of explicitly referring to imported resources, another option is to have some kind of external configuration in order to define what is visible from outside a resource. Java for instance uses the notion of the class path to define containers (jars and class folders) which contain referenceable elements. In the case of Java the order of such entries is also important.

-

To enable support for this kind of global scoping in Xtext, a DefaultGlobalScopeProvider has to be bound to the IGlobalScopeProvider interface. By default Xtext leverages the class path mechanism since it is well designed and already understood by most of our users. The available tooling provided by JDT and PDE to configure the class path adds even more value. However, it is just a default: you can reuse the infrastructure without using Java and be independent of the JDT.

+

To enable support for this kind of global scoping in Xtext, a DefaultGlobalScopeProvider has to be bound to the IGlobalScopeProvider interface. By default Xtext leverages the class path mechanism since it is well designed and already understood by most of our users. The available tooling provided by JDT and PDE to configure the class path adds even more value. However, it is just a default: you can reuse the infrastructure without using Java and be independent of the JDT.

-

In order to know what is available in the “world”, a global scope provider which relies on external configuration needs to read that configuration in and be able to find all candidates for a certain EReference. If you don’t want to force users to have a folder and file name structure reflecting the actual qualified names of the referenceable EObjects, you’ll have to load all resources up front and either keep holding them in memory or remember all information which is needed for the resolution of cross-references. In Xtext that information is provided by a so-called IEObjectDescription.

+

In order to know what is available in the “world”, a global scope provider which relies on external configuration needs to read that configuration in and be able to find all candidates for a certain EReference. If you don’t want to force users to have a folder and file name structure reflecting the actual qualified names of the referenceable EObjects, you’ll have to load all resources up front and either keep holding them in memory or remember all information which is needed for the resolution of cross-references. In Xtext that information is provided by a so-called IEObjectDescription.

About the Index, Containers and Their Manager
-

Xtext ships with an index which remembers all IResourceDescription and their IEObjectDescription objects. In the IDE-context (i.e. when running the editor, etc.) the index is updated by an incremental project builder. As opposed to that, in a non-UI context you typically do not have to deal with changes, hence the infrastructure can be much simpler. In both situations the global index state is held by an implementation of IResourceDescriptions (note the plural form!). The bound singleton in the UI scenario is even aware of unsaved editor changes, such that all linking happens to the latest possibly unsaved version of the resources. You will find the Guice configuration of the global index in the UI scenario in SharedModule.

+

Xtext ships with an index which remembers all IResourceDescription and their IEObjectDescription objects. In the IDE-context (i.e. when running the editor, etc.) the index is updated by an incremental project builder. As opposed to that, in a non-UI context you typically do not have to deal with changes, hence the infrastructure can be much simpler. In both situations the global index state is held by an implementation of IResourceDescriptions (note the plural form!). The bound singleton in the UI scenario is even aware of unsaved editor changes, such that all linking happens to the latest possibly unsaved version of the resources. You will find the Guice configuration of the global index in the UI scenario in SharedModule.

-

The index is basically a flat list of instances of IResourceDescription. The index itself doesn’t know about visibility constraints due to class path restriction. Rather than that, they are defined by the referencing language by means of so called IContainers: While Java might load a resource via ClassLoader.loadResource() (i.e. using the class path mechanism), another language could load the same resource using the file system paths.

+

The index is basically a flat list of instances of IResourceDescription. The index itself doesn’t know about visibility constraints due to class path restriction. Rather than that, they are defined by the referencing language by means of so called IContainers: While Java might load a resource via ClassLoader.loadResource() (i.e. using the class path mechanism), another language could load the same resource using the file system paths.

-

Consequently, the information which container a resource belongs to depends on the referencing context. Therefore an IResourceServiceProvider provides another interesting service, which is called IContainer.Manager. For a given IResourceDescription, the Manager provides you the IContainer as well as a list of all IContainers which are visible from there. Note that the index is globally shared between all languages while the Manager, which adds the semantics of containers, can be very different depending on the language. The following method lists all resources visible from a given Resource:

+

Consequently, the information which container a resource belongs to depends on the referencing context. Therefore an IResourceServiceProvider provides another interesting service, which is called IContainer.Manager. For a given IResourceDescription, the Manager provides you the IContainer as well as a list of all IContainers which are visible from there. Note that the index is globally shared between all languages while the Manager, which adds the semantics of containers, can be very different depending on the language. The following method lists all resources visible from a given Resource:

@Inject IContainer.Manager manager
  
@@ -342,9 +342,9 @@ 
About the Index, Containers and Their Manager
}
-

Xtext ships two implementations of IContainer.Manager which are bound with Guice: The default binding is to SimpleResourceDescriptionsBasedContainerManager, which assumes all IResourceDescriptions to be in a single common container. If you don’t care about container support, you’ll be fine with this one. Alternatively, you can bind StateBasedContainerManager and an additional IAllContainersState which keeps track of the set of available containers and their visibility relationships.

+

Xtext ships two implementations of IContainer.Manager which are bound with Guice: The default binding is to SimpleResourceDescriptionsBasedContainerManager, which assumes all IResourceDescriptions to be in a single common container. If you don’t care about container support, you’ll be fine with this one. Alternatively, you can bind StateBasedContainerManager and an additional IAllContainersState which keeps track of the set of available containers and their visibility relationships.

-

Xtext offers a couple of strategies for managing containers: If you’re running an Eclipse workbench, you can define containers based on Java projects and their class paths or based on plain Eclipse projects. Outside Eclipse, you can provide a set of file system paths to be scanned for models. All of these only differ in the bound instance of IAllContainersState of the referring language. These will be described in detail in the following sections.

+

Xtext offers a couple of strategies for managing containers: If you’re running an Eclipse workbench, you can define containers based on Java projects and their class paths or based on plain Eclipse projects. Outside Eclipse, you can provide a set of file system paths to be scanned for models. All of these only differ in the bound instance of IAllContainersState of the referring language. These will be described in detail in the following sections.

IContainer Management

@@ -375,7 +375,7 @@
JDT-Based Container Manager
}
-

in the Eclipse UI module of the referencing language. The latter looks a bit more difficult than a common binding, as we have to bind a global singleton to a Guice provider. A StrictJavaProjectsState requires all elements to be on the class path, while the default JavaProjectsState also allows models in non-source folders.

+

in the Eclipse UI module of the referencing language. The latter looks a bit more difficult than a common binding, as we have to bind a global singleton to a Guice provider. A StrictJavaProjectsState requires all elements to be on the class path, while the default JavaProjectsState also allows models in non-source folders.

Eclipse Project-Based Containers
@@ -390,7 +390,7 @@
Eclipse Project-Based Containers
ResourceSet-Based Containers
-

If you need an IContainer.Manager that is independent of Eclipse projects, you can use the ResourceSetBasedAllContainersState. This one can be configured with a mapping of container handles to resource URIs.

+

If you need an IContainer.Manager that is independent of Eclipse projects, you can use the ResourceSetBasedAllContainersState. This one can be configured with a mapping of container handles to resource URIs.

Local Scoping

@@ -437,11 +437,11 @@

Local Scoping

Imported Namespace Aware Scoping

-

The imported namespace aware scoping is based on qualified names and namespaces. It adds namespace support to your language, which is comparable and similar to namespaces in Scala and C#. Scala and C# both allow to have multiple nested packages within one file, and you can put imports per namespace, such that imported names are only visible within that namespace. See the domain model example: its scope provider extends ImportedNamespaceAwareLocalScopeProvider.

+

The imported namespace aware scoping is based on qualified names and namespaces. It adds namespace support to your language, which is comparable and similar to namespaces in Scala and C#. Scala and C# both allow to have multiple nested packages within one file, and you can put imports per namespace, such that imported names are only visible within that namespace. See the domain model example: its scope provider extends ImportedNamespaceAwareLocalScopeProvider.

Importing Namespaces

-

The ImportedNamespaceAwareLocalScopeProvider looks up EAttributes with name importedNamespace and interprets them as import statements.

+

The ImportedNamespaceAwareLocalScopeProvider looks up EAttributes with name importedNamespace and interprets them as import statements.

PackageDeclaration:
     'package' name=QualifiedName '{'
@@ -484,14 +484,14 @@ 

Importing Namespaces

Value Converter

-

Value converters are registered to convert the parsed text into a data type instance and vice versa. The primary hook is the IValueConverterService and the concrete implementation can be registered via the runtime Guice module. Simply override the corresponding binding in your runtime module like shown in this example:

+

Value converters are registered to convert the parsed text into a data type instance and vice versa. The primary hook is the IValueConverterService and the concrete implementation can be registered via the runtime Guice module. Simply override the corresponding binding in your runtime module like shown in this example:

public Class<? extends IValueConverterService> bindIValueConverterService() {
     return MySpecialValueConverterService.class;
 }
 
-

The easiest way to register additional value converters is to make use of AbstractDeclarativeValueConverterService, which allows to declaratively register an IValueConverter by means of an annotated method.

+

The easiest way to register additional value converters is to make use of AbstractDeclarativeValueConverterService, which allows to declaratively register an IValueConverter by means of an annotated method.

@ValueConverter(rule = "MyRuleName")
 public IValueConverter<MyDataType> getMyRuleNameConverter() {
@@ -499,11 +499,11 @@ 

Value Converter

}
-

If you use the common terminals grammar org.eclipse.xtext.common.Terminals you should extend the DefaultTerminalConverters and override or add value converters by adding the respective methods. In addition to the explicitly defined converters in the default implementation, a delegating converter is registered for each available EDataType. The delegating converter reuses the functionality of the corresponding EMF EFactory.

+

If you use the common terminals grammar org.eclipse.xtext.common.Terminals you should extend the DefaultTerminalConverters and override or add value converters by adding the respective methods. In addition to the explicitly defined converters in the default implementation, a delegating converter is registered for each available EDataType. The delegating converter reuses the functionality of the corresponding EMF EFactory.

-

Many languages introduce a concept for qualified names, i.e. names composed of namespaces separated by a delimiter. Since this is such a common use case, Xtext provides an extensible converter implementation for qualified names. The QualifiedNameValueConverter handles comments and white spaces gracefully and is capable to use the appropriate value converter for each segment of a qualified name. This allows for individually quoted segments. The domainmodel example shows how to use it.

+

Many languages introduce a concept for qualified names, i.e. names composed of namespaces separated by a delimiter. Since this is such a common use case, Xtext provides an extensible converter implementation for qualified names. The QualifiedNameValueConverter handles comments and white spaces gracefully and is capable to use the appropriate value converter for each segment of a qualified name. This allows for individually quoted segments. The domainmodel example shows how to use it.

-

The protocol of an IValueConverter allows to throw a ValueConverterException if something went wrong. The exception is propagated as a syntax error by the parser or as a validation problem by the ConcreteSyntaxValidator if the value cannot be converted to a valid string. The AbstractLexerBasedConverter is useful when implementing a custom value converter. If the converter needs to know about the rule that it currently works with, it may implement the interface RuleSpecific. The framework will set the rule such that the implementation can use it afterwards.

+

The protocol of an IValueConverter allows to throw a ValueConverterException if something went wrong. The exception is propagated as a syntax error by the parser or as a validation problem by the ConcreteSyntaxValidator if the value cannot be converted to a valid string. The AbstractLexerBasedConverter is useful when implementing a custom value converter. If the converter needs to know about the rule that it currently works with, it may implement the interface RuleSpecific. The framework will set the rule such that the implementation can use it afterwards.

Serialization

@@ -520,7 +520,7 @@

Serialization

  • Adding further needed white space or replacing all white space using a formatter.
  • -

    Serialization is invoked when calling XtextResource.save(..). Furthermore, the Serializer provides resource-independent support for serialization. Another situation that triggers serialization is applying quick fixes with semantic modifications. Serialization is not called when a textual editors contents is saved to disk.

    +

    Serialization is invoked when calling XtextResource.save(..). Furthermore, the Serializer provides resource-independent support for serialization. Another situation that triggers serialization is applying quick fixes with semantic modifications. Serialization is not called when a textual editors contents is saved to disk.

    The Contract

    @@ -539,7 +539,7 @@

    Rol
    • preserves existing white spaces from the node model.
    • preserves existing comments from the node model.
    • -
    • preserves the representation of cross-references: If a cross-referenced object can be identified by multiple names (i.e. scoping returns multiple IEObjectDescriptions for the same object), the serializer tries to keep the name that was used in the input file.
    • +
    • preserves the representation of cross-references: If a cross-referenced object can be identified by multiple names (i.e. scoping returns multiple IEObjectDescriptions for the same object), the serializer tries to keep the name that was used in the input file.
    • preserves the representation of values: For values handled by the value converter, the serializer checks whether the textual representation converted to a value equals the value from the semantic model. If that is true, the textual representation is kept.
    @@ -549,7 +549,7 @@

    Parse Tree Constructor

    For serialization to succeed, the parse tree constructor must be able to consume every non-transient element of the to-be-serialized EMF model. To consume means, in this context, to write the element to the textual representation of the model. This can turn out to be a not-so-easy-to-fulfill requirement, since a grammar usually introduces implicit constraints to the EMF model as explained for the concrete syntax validator.

    -

    If a model can not be serialized, an XtextSerializationException is thrown. Possible reasons are listed below:

    +

    If a model can not be serialized, an XtextSerializationException is thrown. Possible reasons are listed below:

    • A model element can not be consumed. This can have the following reasons/solutions: @@ -566,7 +566,7 @@

      Parse Tree Constructor

  • The type of the model element differs from the type in the grammar. The type of the model element must be identical to the return type of the grammar rule or the action’s type. Subtypes are not allowed.
  • -
  • Value conversion fails. The value converter can indicate that a value is not serializable by throwing a ValueConverterException.
  • +
  • Value conversion fails. The value converter can indicate that a value is not serializable by throwing a ValueConverterException.
  • An enum literal is not allowed at this position. This can happen if the referenced enum rule only lists a subset of the literals of the actual enumeration.
  • @@ -579,7 +579,7 @@

    Parse Tree Constructor

    Options

    -

    SaveOptions can be passed to XtextResource.save(options) and to Serializer.serialize(..). Available options are:

    +

    SaveOptions can be passed to XtextResource.save(options) and to Serializer.serialize(..). Available options are:

    • Formatting. Default: false. If enabled, it is the formatters job to determine all white space information during serialization. If disabled, the formatter only defines white space information for the places in which no white space information can be preserved from the node model. E.g. When new model elements are inserted or there is no node model.
    • @@ -588,9 +588,9 @@

      Options

      Preserving Comments from the Node Model

      -

      The ICommentAssociater associates comments with semantic objects. This is important in case an element in the semantic model is moved to a different position and the model is serialized, one expects the comments to be moved to the new position in the document as well.

      +

      The ICommentAssociater associates comments with semantic objects. This is important in case an element in the semantic model is moved to a different position and the model is serialized, one expects the comments to be moved to the new position in the document as well.

      -

      Which comment belongs to which semantic object is surely a very subjective issue. The default implementation behaves as follows, but can be customized:

      +

      Which comment belongs to which semantic object is surely a very subjective issue. The default implementation behaves as follows, but can be customized:

      • If there is a semantic token before a comment and in the same line, the comment is associated with this token’s semantic object.
      • @@ -599,7 +599,7 @@

        Preserving Comments from the Node Model

        Transient Values

        -

        Transient values are values or model elements which are not persisted (written to the textual representation in the serialization phase). If a model contains model elements which can not be serialized with the current grammar, it is critical to mark them transient using the ITransientValueService, or serialization will fail. The default implementation marks all model elements transient, which are eStructuralFeature.isTransient() or not eObject.eIsSet(eStructuralFeature). By default, EMF returns false for eIsSet(..) if the value equals the default value.

        +

        Transient values are values or model elements which are not persisted (written to the textual representation in the serialization phase). If a model contains model elements which can not be serialized with the current grammar, it is critical to mark them transient using the ITransientValueService, or serialization will fail. The default implementation marks all model elements transient, which are eStructuralFeature.isTransient() or not eObject.eIsSet(eStructuralFeature). By default, EMF returns false for eIsSet(..) if the value equals the default value.

        Unassigned Text

        @@ -614,11 +614,11 @@

        Unassigned Text

        'item' | 'items';
    -

    Valid models for this example are contents 1 item or contents 5 items. However, it is not stored in the semantic model whether the keyword item or items has been parsed. This is due to the fact that the rule call Plural is unassigned. However, the parse tree constructor needs to decide which value to write during serialization. This decision can be be made by customizing the IValueSerializer.serializeUnassignedValue(EObject, RuleCall, INode).

    +

    Valid models for this example are contents 1 item or contents 5 items. However, it is not stored in the semantic model whether the keyword item or items has been parsed. This is due to the fact that the rule call Plural is unassigned. However, the parse tree constructor needs to decide which value to write during serialization. This decision can be be made by customizing the IValueSerializer.serializeUnassignedValue(EObject, RuleCall, INode).

    Cross-Reference Serializer

    -

    The cross-reference serializer specifies which values are to be written to the textual representation for cross-references. This behavior can be customized by implementing ICrossReferenceSerializer. The default implementation delegates to various other services such as the IScopeProvider or the LinkingHelper each of which may be the better place for customization.

    +

    The cross-reference serializer specifies which values are to be written to the textual representation for cross-references. This behavior can be customized by implementing ICrossReferenceSerializer. The default implementation delegates to various other services such as the IScopeProvider or the LinkingHelper each of which may be the better place for customization.

    Merge White Space

    @@ -628,7 +628,7 @@

    Merge White Space

    Token Stream

    -

    The parse tree constructor and the formatter use an ITokenStream for their output, and the latter for its input as well. This allows for chaining the two components. Token streams can be converted to a String using the TokenStringBuffer and to a Writer using the WriterTokenStream.

    +

    The parse tree constructor and the formatter use an ITokenStream for their output, and the latter for its input as well. This allows for chaining the two components. Token streams can be converted to a String using the TokenStringBuffer and to a Writer using the WriterTokenStream.

    public interface ITokenStream {
     
    @@ -644,11 +644,11 @@ 

    Formatting

    The actual formatting is done by constructing a list of text replacements. A text replacement describes a new text which should replace an existing part of the document, described by offset and length. Applying the text replacements turns the unformatted document into a formatted document.

    -

    To invoke the formatter programmatically, you need to instantiate a request and pass it to the formatter. The formatter will return a list of text replacements. The document modification itself can be performed by an ITextRegionRewriter.

    +

    To invoke the formatter programmatically, you need to instantiate a request and pass it to the formatter. The formatter will return a list of text replacements. The document modification itself can be performed by an ITextRegionRewriter.

    -

    Implementors of a formatter should extend AbstractFormatter2 and add dispatch methods for the model elements that should be formatted. The format routine has to be invoked recursively if the children of an object should be formatted, too.

    +

    Implementors of a formatter should extend AbstractFormatter2 and add dispatch methods for the model elements that should be formatted. The format routine has to be invoked recursively if the children of an object should be formatted, too.

    -

    The following example illustrates that pattern. An instance of PackageDeclaration is passed to the format method along with the current formattable document. In this scenario, the package name is surrounded by a single space, the curly brace is followed by a new line and increased indentation etc. All elements within that package should be formatted, too, thus format(..) is invoked on these as well.

    +

    The following example illustrates that pattern. An instance of PackageDeclaration is passed to the format method along with the current formattable document. In this scenario, the package name is surrounded by a single space, the curly brace is followed by a new line and increased indentation etc. All elements within that package should be formatted, too, thus format(..) is invoked on these as well.

    def dispatch void format(PackageDeclaration p, extension IFormattableDocument doc) {
         p.regionFor.feature(PACKAGE_DECLARATION__NAME).surround[oneSpace]
    @@ -664,9 +664,9 @@ 

    Formatting

    }
    -

    The API is designed in a way that allows to describe the formatting in a declarative way by calling methods on the IHiddenRegionFormatter which is made available inside invocations of prepend, surround or append to specify the formatting rules. This can be done in arbitrary order – the infrastructure will reorder all the configurations to execute them from top to bottom of the document. If the configuration-based approach is not sufficient for a particular use case, the document also accepts imperative logic that is associated with a given range. The ITextReplacer that can be added directly to the document allows to perform all kinds of modifications to the text in the region that it is associated with.

    +

    The API is designed in a way that allows to describe the formatting in a declarative way by calling methods on the IHiddenRegionFormatter which is made available inside invocations of prepend, surround or append to specify the formatting rules. This can be done in arbitrary order – the infrastructure will reorder all the configurations to execute them from top to bottom of the document. If the configuration-based approach is not sufficient for a particular use case, the document also accepts imperative logic that is associated with a given range. The ITextReplacer that can be added directly to the document allows to perform all kinds of modifications to the text in the region that it is associated with.

    -

    More detailed information about the API is available as JavaDoc on the org.eclipse.xtext.formatting2 package.

    +

    More detailed information about the API is available as JavaDoc on the org.eclipse.xtext.formatting2 package.

    Character Encoding

    @@ -694,11 +694,11 @@

    Encoding at Language Design Time

    Encoding at Language Runtime

    -

    As each language could handle the encoding problem differently, Xtext offers a service here. The IEncodingProvider has a single method getEncoding(URI) to define the encoding of the resource with the given URI. Users can implement their own strategy, but keep in mind that this is not intended to be a long running method. If the encoding is stored within the model file itself, it should be extractable in an easy way, like from the first line in an XML file. The default implementation returns the default Java character set in a standalone scenario.

    +

    As each language could handle the encoding problem differently, Xtext offers a service here. The IEncodingProvider has a single method getEncoding(URI) to define the encoding of the resource with the given URI. Users can implement their own strategy, but keep in mind that this is not intended to be a long running method. If the encoding is stored within the model file itself, it should be extractable in an easy way, like from the first line in an XML file. The default implementation returns the default Java character set in a standalone scenario.

    -

    In the Eclipse UI scenario, when there is a workspace, users will expect the encoding of the model files to be settable the same way as for other files in the workspace. The default implementation of the IEncodingProvider in the Eclipse context therefore returns the file’s workspace encoding for files in the workspace and delegates to the runtime implementation for all other resources, e.g. models in a jar or from a deployed plug-in. Keep in mind that you are going to lose the workspace encoding information as soon as you leave this workspace, e.g. deploy your project.

    +

    In the Eclipse UI scenario, when there is a workspace, users will expect the encoding of the model files to be settable the same way as for other files in the workspace. The default implementation of the IEncodingProvider in the Eclipse context therefore returns the file’s workspace encoding for files in the workspace and delegates to the runtime implementation for all other resources, e.g. models in a jar or from a deployed plug-in. Keep in mind that you are going to lose the workspace encoding information as soon as you leave this workspace, e.g. deploy your project.

    -

    Unless you want to enforce a uniform encoding for all models of your language, we advise to override the runtime service only. It is bound in the runtime module using the binding annotation @Runtime:

    +

    Unless you want to enforce a uniform encoding for all models of your language, we advise to override the runtime service only. It is bound in the runtime module using the binding annotation @Runtime:

    @Override
     public void configureRuntimeEncodingProvider(Binder binder) {
    @@ -708,11 +708,11 @@ 

    Encoding at Language Runtime

    }
    -

    For a uniform encoding, bind the plain IEncodingProvider to the same implementation in all modules. In the Eclipse UI module you can use similar code as above, but with DispatchingProvider.Ui instead of Runtime.

    +

    For a uniform encoding, bind the plain IEncodingProvider to the same implementation in all modules. In the Eclipse UI module you can use similar code as above, but with DispatchingProvider.Ui instead of Runtime.

    Encoding of an XtextResource

    -

    An XtextResource uses the IEncodingProvider of your language by default. You can override that by passing an option on load and save, e.g.

    +

    An XtextResource uses the IEncodingProvider of your language by default. You can override that by passing an option on load and save, e.g.

    myXtextResource.load(#{XtextResource.OPTION_ENCODING -> "UTF-8"})
     
    @@ -728,7 +728,7 @@

    Unit Testing

    Creating a Simple Test Class

    -

    The core of the test infrastructure for JUnit 4 is the XtextRunner and the language specific IInjectorProvider. Both have to be provided by means of class annotations. Your test cases should be annotated with org.junit.Test. A static import org.junit.Assert makes your tests more readable.

    +

    The core of the test infrastructure for JUnit 4 is the XtextRunner and the language specific IInjectorProvider. Both have to be provided by means of class annotations. Your test cases should be annotated with org.junit.Test. A static import org.junit.Assert makes your tests more readable.

    import org.eclipse.xtext.testing.InjectWith
     import org.eclipse.xtext.testing.XtextRunner
    @@ -748,7 +748,7 @@ 

    Creating a Simple Test Class

    This configuration will make sure that you can use dependency injection in your test class, and that the global EMF registries are properly populated before and cleaned up after each test.

    -

    A test class for JUnit 5 looks quite similar. Instead of runners JUnit 5 has a notion of Extensions. While there can only be one runner per test class for JUnit 4 there could be multiple extensions for JUnit 5. The replacement for the XtextRunner is the new InjectionExtension. Still needed is the language specific IInjectorProvider. Instead of org.junit.Test you have to annotate your cases with org.junit.jupiter.api.Test and import the methods from org.junit.jupiter.api.Assertions. A simple test class for JUnit 5 will then look like this:

    +

    A test class for JUnit 5 looks quite similar. Instead of runners JUnit 5 has a notion of Extensions. While there can only be one runner per test class for JUnit 4 there could be multiple extensions for JUnit 5. The replacement for the XtextRunner is the new InjectionExtension. Still needed is the language specific IInjectorProvider. Instead of org.junit.Test you have to annotate your cases with org.junit.jupiter.api.Test and import the methods from org.junit.jupiter.api.Assertions. A simple test class for JUnit 5 will then look like this:

    import org.eclipse.xtext.testing.InjectWith
     import org.eclipse.xtext.testing.extensions.InjectionExtension
    @@ -768,7 +768,7 @@ 

    Creating a Simple Test Class

    Testing the Parser

    -

    The class ParseHelper allows to parse an arbitrary string into an AST model. The AST model itself can be traversed and checked afterwards.

    +

    The class ParseHelper allows to parse an arbitrary string into an AST model. The AST model itself can be traversed and checked afterwards.

    import org.eclipse.xtext.testing.util.ParseHelper
     ...
    @@ -789,7 +789,7 @@ 

    Testing the Parser

    Testing the Validator

    -

    Testing your validation is very simple with the ValidationTestHelper:

    +

    Testing your validation is very simple with the ValidationTestHelper:

    ...
      
    @@ -810,7 +810,7 @@ 

    Testing Multiple Languages

    If in addition to the main language your tests require using other languages for references from/to your main language, you’ll have to parse and load dependent resources into the same ResourceSet first for cross-reference resolution to work.

    -

    As the default generated IInjectorProvider of your main language (e.g. DomainmodelInjectorProvider) does not know about any other dependent languages, they must be initialized explicitly. The recommended pattern for this is to create a new subclass of the generated MyLanguageInjectorProvider in your *.test project and make sure the dependent language is intizialized properly. Then you can use this new injector provider instead of the original one in your test’s @InjectWith:

    +

    As the default generated IInjectorProvider of your main language (e.g. DomainmodelInjectorProvider) does not know about any other dependent languages, they must be initialized explicitly. The recommended pattern for this is to create a new subclass of the generated MyLanguageInjectorProvider in your *.test project and make sure the dependent language is intizialized properly. Then you can use this new injector provider instead of the original one in your test’s @InjectWith:

    public class MyLanguageWithDependenciesInjectorProvider extends MyLanguageInjectorProvider {
         @Override
    diff --git a/org.eclipse.xtext.doc/contents/305_xbase.html b/org.eclipse.xtext.doc/contents/305_xbase.html
    index 467a008413d..9673c71e86a 100644
    --- a/org.eclipse.xtext.doc/contents/305_xbase.html
    +++ b/org.eclipse.xtext.doc/contents/305_xbase.html
    @@ -16,7 +16,7 @@ 

    Integration with Java

    Referring to Java Elements using JVM Types

    -

    A common case when developing languages is the requirement to refer to existing concepts of other languages. Xtext makes this very easy for other self defined DSLs. However, it is often very useful to have access to the available types of the Java Virtual Machine as well. The JVM types Ecore model enables clients to do exactly this. It is possible to create cross-references to classes, interfaces, and their fields and methods. Basically every information about the structural concepts of the Java type system is available via the JVM types. This includes annotations and their specific values and enumeration literals, too.

    +

    A common case when developing languages is the requirement to refer to existing concepts of other languages. Xtext makes this very easy for other self defined DSLs. However, it is often very useful to have access to the available types of the Java Virtual Machine as well. The JVM types Ecore model enables clients to do exactly this. It is possible to create cross-references to classes, interfaces, and their fields and methods. Basically every information about the structural concepts of the Java type system is available via the JVM types. This includes annotations and their specific values and enumeration literals, too.

    The implementation will be selected transparently depending on how the client code is executed. If the environment is a plain stand-alone Java or OSGi environment, the java.lang.reflect API will be used to deduce the necessary data. On the contrary, the type-model will be created from the live data of the JDT in an interactive Eclipse environment. All this happens transparently for the clients behind the scenes via different implementations that are bound to specific interfaces by means of Google Guice.

    @@ -46,17 +46,17 @@

    Customization Points

    There are several customization hooks in the runtime layer of the JVM types and on the editor side as well:

    -

    The AbstractTypeScopeProvider can be used to create scopes for members with respect to the override semantics of the Java language. Of course it is possible to use this implementation to create scopes for types as well.

    +

    The AbstractTypeScopeProvider can be used to create scopes for members with respect to the override semantics of the Java language. Of course it is possible to use this implementation to create scopes for types as well.

    As the Java VM types expose a lot of information about visibility, parameter types and return types, generics, available annotations or enumeration literals, it is very easy to define constraints for the referred types.

    -

    The ITypesProposalProvider can be used to provide optimized proposals based on various filter criteria. The most common selector can be used directly via createSubTypeProposals(..). The implementation is optimized and uses the JDT Index directly to minimize the effort for object instantiation. The class TypeMatchFilters provides a comprehensive set of reusable filters that can be easily combined to reduce the list of proposals to a smaller number of valid entries.

    +

    The ITypesProposalProvider can be used to provide optimized proposals based on various filter criteria. The most common selector can be used directly via createSubTypeProposals(..). The implementation is optimized and uses the JDT Index directly to minimize the effort for object instantiation. The class TypeMatchFilters provides a comprehensive set of reusable filters that can be easily combined to reduce the list of proposals to a smaller number of valid entries.

    Referring to Java Types Using Xbase

    While the JVM types approach from the previous chapter allows to refer to any Java element, it is quite limited when it comes to generics. Usually, a type reference in Java can have type arguments which can also include wildcards, upper and lower bounds etc. A simple cross-reference using a qualified name is not enough to express neither the syntax nor the structure of such a type reference.

    -

    Xbase offers a parser rule JvmTypeReference which supports the full syntax of a Java type reference and instantiates a JVM element of type JvmTypeReference. So let us start by inheriting from Xbase:

    +

    Xbase offers a parser rule JvmTypeReference which supports the full syntax of a Java type reference and instantiates a JVM element of type JvmTypeReference. So let us start by inheriting from Xbase:

    grammar org.eclipse.xtext.example.Domainmodel
        with org.eclipse.xtext.xbase.Xbase
    @@ -99,9 +99,9 @@ 

    Referring to Java Types Using Xbase

    As we changed the grammar, we have to regenerate the language now.

    -

    Being able to parse a Java type reference is already nice, but we also have to write them back to their string representation when we generate Java code. Unfortunately, a generic type reference with fully qualified class names can become a bit bulky. Therefore, the ImportManager shortens fully qualified names, keeps track of imported namespaces, avoids name collisions, and helps to serialize JvmTypeReferences by means of the TypeReferenceSerializer. This utility encapsulates how type references may be serialized depending on the concrete context in the output.

    +

    Being able to parse a Java type reference is already nice, but we also have to write them back to their string representation when we generate Java code. Unfortunately, a generic type reference with fully qualified class names can become a bit bulky. Therefore, the ImportManager shortens fully qualified names, keeps track of imported namespaces, avoids name collisions, and helps to serialize JvmTypeReferences by means of the TypeReferenceSerializer. This utility encapsulates how type references may be serialized depending on the concrete context in the output.

    -

    The following snippet shows our code generator using an ImportManager in conjunction with a TypeReferenceSerializer. We create a new instance and pass it through the generation functions, collecting types on the way. As the import section in a Java file precedes the class body, we create the body into a String variable and assemble the whole file’s content in a second step.

    +

    The following snippet shows our code generator using an ImportManager in conjunction with a TypeReferenceSerializer. We create a new instance and pass it through the generation functions, collecting types on the way. As the import section in a Java file precedes the class body, we create the body into a String variable and assemble the whole file’s content in a second step.

    class DomainmodelGenerator implements IGenerator {
     
    @@ -162,7 +162,7 @@ 

    Referring to Java Types Using Xbase

    }
    -

    Please note that when org.eclipse.xtext.xbase.Xbase is used the default binding for the interface IGenerator is JvmModelGenerator. To use a custom one we have to bind our own implementation in org.example.domainmodel.DomainmodelRuntimeModule like this:

    +

    Please note that when org.eclipse.xtext.xbase.Xbase is used the default binding for the interface IGenerator is JvmModelGenerator. To use a custom one we have to bind our own implementation in org.example.domainmodel.DomainmodelRuntimeModule like this:

    public class DomainmodelRuntimeModule extends org.example.domainmodel.AbstractDomainmodelRuntimeModule {
     	public Class<? extends org.eclipse.xtext.generator.IGenerator> bindIGenerator() {
    @@ -184,11 +184,11 @@ 

    Inferring a JVM Model

    ...
    -

    You can use entities instead of Java types or even mix Java types as List with entities such as Person. One way to achieve this is to let your concepts inherit from a corresponding JVM type, e.g. let Entity inherit from JvmGenericType. But this would result in a lot of accidentally inherited properties in your domain model. In Xbase there is an alternative: You can simply define how to derive a JVM model from your model. This inferred JVM model is the representation of your concepts in the type system of Xbase.

    +

    You can use entities instead of Java types or even mix Java types as List with entities such as Person. One way to achieve this is to let your concepts inherit from a corresponding JVM type, e.g. let Entity inherit from JvmGenericType. But this would result in a lot of accidentally inherited properties in your domain model. In Xbase there is an alternative: You can simply define how to derive a JVM model from your model. This inferred JVM model is the representation of your concepts in the type system of Xbase.

    -

    The main component for the inferred JVM model is the IJvmModelInferrer. It has a single method that takes the root model element as an argument and produces a number of JvmDeclaredTypes. As Xbase cannot guess how you would like to map your concepts to JVM elements, you have to implement this component yourself. This usually boils down to using an injected JvmTypesBuilder to create a hierarchy of JVM elements. The builder helps to initialize the produced types with sensible defaults and encapsulates the logic that associates the source elements with the derived JVM concepts. As this kind of transformation can be elegantly implemented using polymorphic dispatch functions and extension methods, it is a good choice to write the IJvmModelInferrer in Xtend. It becomes even simpler if you inherit from the AbstractModelInferrer which traverses the input model and dispatches to its contents until you decide which elements to handle.

    +

    The main component for the inferred JVM model is the IJvmModelInferrer. It has a single method that takes the root model element as an argument and produces a number of JvmDeclaredTypes. As Xbase cannot guess how you would like to map your concepts to JVM elements, you have to implement this component yourself. This usually boils down to using an injected JvmTypesBuilder to create a hierarchy of JVM elements. The builder helps to initialize the produced types with sensible defaults and encapsulates the logic that associates the source elements with the derived JVM concepts. As this kind of transformation can be elegantly implemented using polymorphic dispatch functions and extension methods, it is a good choice to write the IJvmModelInferrer in Xtend. It becomes even simpler if you inherit from the AbstractModelInferrer which traverses the input model and dispatches to its contents until you decide which elements to handle.

    -

    The inference runs in two phases: In the first phase all the types are created with empty bodies. This way you make sure all types exist when you might lookup types during initializing the members in the second phase. Use acceptor.accept(JvmDeclaredType, Procedure1<JvmDeclaredType>) and pass in the created Java type as the first argument and the initialization block as the second. For our domain model example, we implement a polymorphic dispatch function infer for Entities to transform them into JvmGenericTypes in the first phase. In the second phase, we add a JvmField and corresponding accessors for each Property. The final DomainmodelJvmModelInferrer looks like this:

    +

    The inference runs in two phases: In the first phase all the types are created with empty bodies. This way you make sure all types exist when you might lookup types during initializing the members in the second phase. Use acceptor.accept(JvmDeclaredType, Procedure1<JvmDeclaredType>) and pass in the created Java type as the first argument and the initialization block as the second. For our domain model example, we implement a polymorphic dispatch function infer for Entities to transform them into JvmGenericTypes in the first phase. In the second phase, we add a JvmField and corresponding accessors for each Property. The final DomainmodelJvmModelInferrer looks like this:

    class DomainmodelJvmModelInferrer extends AbstractModelInferrer {
     
    @@ -212,25 +212,25 @@ 

    Inferring a JVM Model

    }
    -

    Out of the inferred model the corresponding Java class gets generated. To ensure that this will work make sure that the binding in the rumtime module for IGenerator is pointing to JvmModelGenerator. This is the default case, but as we dealt with a custom implementation in the last section this may lead to problems.

    +

    Out of the inferred model the corresponding Java class gets generated. To ensure that this will work make sure that the binding in the rumtime module for IGenerator is pointing to JvmModelGenerator. This is the default case, but as we dealt with a custom implementation in the last section this may lead to problems.

    Linking and Indexing

    As Java elements and your concepts are now represented as JVM model elements, other models can now transparently link to Java or your DSL. In other words, you can use a mapped element of your DSL in the same places as the corresponding Java type.

    -

    The Xbase framework will automatically switch between the JVM element or the DSL element when needed, e.g. when following hyperlinks. The component allowing to navigate between the source model and the JVM model is called IJvmModelAssociations, the read-only antagonist of the IJvmModelAssociator that is used by the JvmTypesBuilder.

    +

    The Xbase framework will automatically switch between the JVM element or the DSL element when needed, e.g. when following hyperlinks. The component allowing to navigate between the source model and the JVM model is called IJvmModelAssociations, the read-only antagonist of the IJvmModelAssociator that is used by the JvmTypesBuilder.

    By default, the inferred model is indexed, so it can be cross referenced from other models.

    Validation

    -

    Besides your custom validations, you can use JvmGenericTypeValidator, introduced in version 2.35.0. This automatically perform several Java-related checks in the hierarchy of the inferred JvmGenericTypes of an Xbase language, with the corresponding error reporting.
    +

    Besides your custom validations, you can use JvmGenericTypeValidator, introduced in version 2.35.0. This automatically perform several Java-related checks in the hierarchy of the inferred JvmGenericTypes of an Xbase language, with the corresponding error reporting.
    For example, cycles in a hierarchy, extension of a final class, proper extension of an abstract class (do you implement all the abstract methods or declare the inferred class as abstract?), proper method overriding, etc. It also performs duplicate elements checks, like duplicate parameter names, duplicate fields and duplicate methods (keeping the type-erasure into consideration when using types with arguments).

    -

    This mechanism assumes that you implement the IJvmModelInferrer “correctly”.
    +

    This mechanism assumes that you implement the IJvmModelInferrer “correctly”.
    It only checks the first inferred JvmGenericType for the same DSL element (i.e., if for an element Entity you infer two JvmGenericTypes, t1 and t2, only the first one will be checked).
    Moreover, it only checks Jvm model elements with an associated source element.
    -Concerning intended classes to extend and interfaces to extend/implement, it assumes the model inferrer uses the JvmTypesBuilder methods setSuperClass(JvmDeclaredType, JvmTypeReference) and addSuperInterface(JvmDeclaredType, JvmTypeReference), respectively.

    +Concerning intended classes to extend and interfaces to extend/implement, it assumes the model inferrer uses the JvmTypesBuilder methods setSuperClass(JvmDeclaredType, JvmTypeReference) and addSuperInterface(JvmDeclaredType, JvmTypeReference), respectively.

    Currently, this validator must be enabled explicitly through the composedCheck in the MWE2 file or the @ComposedChecks annotation in the validator, e.g., @ComposedChecks(validators = JvmGenericTypeValidator.class).

    @@ -276,24 +276,24 @@

    Making Your Grammar Refer To Xbase

    -

    Note: You will have to adapt the IJvmModelInferrer to these changes, i.e. rename Feature to Property and create a JvmOperation for each Operation. We leave that as an exercise :-)

    +

    Note: You will have to adapt the IJvmModelInferrer to these changes, i.e. rename Feature to Property and create a JvmOperation for each Operation. We leave that as an exercise :-)

    -

    If you are done with that, everything will work out of the box. Since each expression is now logically contained in an operation, all the scoping rules and visibility constraints are implied from that context. The framework will take care that the operation’s parameters are visible inside the operation’s body and that the declared return types are validated against the actual expression types.

    +

    If you are done with that, everything will work out of the box. Since each expression is now logically contained in an operation, all the scoping rules and visibility constraints are implied from that context. The framework will take care that the operation’s parameters are visible inside the operation’s body and that the declared return types are validated against the actual expression types.

    -

    There is yet another aspect of the JVM model that can be explored. Since all the coarse grained concepts such as types and operations were already derived from the model, a generator can be used to serialize that information to Java code. There is no need to write a code generator on top of that. The JvmModelGenerator knows how to generate operation bodies properly.

    +

    There is yet another aspect of the JVM model that can be explored. Since all the coarse grained concepts such as types and operations were already derived from the model, a generator can be used to serialize that information to Java code. There is no need to write a code generator on top of that. The JvmModelGenerator knows how to generate operation bodies properly.

    Using the Xbase Interpreter

    -

    Sometimes it is more convenient to interpret a model that uses Xbase than to generate code from it. Xbase ships with the XbaseInterpreter which makes this rather easy.

    +

    Sometimes it is more convenient to interpret a model that uses Xbase than to generate code from it. Xbase ships with the XbaseInterpreter which makes this rather easy.

    -

    An interpreter is essentially an external visitor, that recursively processes a model based on the model element’s types. In the XbaseInterpreter, the method doEvaluate(XExpression, IEvaluationContext, CancelIndicator) delegates to more specialised implementations e.g.

    +

    An interpreter is essentially an external visitor, that recursively processes a model based on the model element’s types. In the XbaseInterpreter, the method doEvaluate(XExpression, IEvaluationContext, CancelIndicator) delegates to more specialised implementations e.g.

    protected Object _doEvaluate(XBlockExpression literal,
                                  IEvaluationContext context,
                                  CancelIndicator indicator)
     
    -

    The IEvaluationContext keeps the state of the running application, i.e. the local variables and their values. Additionally, it can be forked, thus allowing to shadow the elements of the original context. Here is an example code snippet how to call the XbaseInterpreter:

    +

    The IEvaluationContext keeps the state of the running application, i.e. the local variables and their values. Additionally, it can be forked, thus allowing to shadow the elements of the original context. Here is an example code snippet how to call the XbaseInterpreter:

    @Inject private XbaseInterpreter xbaseInterpreter;
     
    @@ -461,7 +461,7 @@ 

    Arrays

    Function Types

    -

    Xbase introduces lambda expressions, and therefore an additional function type signature. On the JVM-Level a lambda expression (or more generally any function object) is just an instance of one of the types in Functions, depending on the number of arguments. However, as lambda expressions are a very important language feature, a special sugared syntax for function types has been introduced. So instead of writing Function1<String, Boolean> one can write (String)=>boolean.

    +

    Xbase introduces lambda expressions, and therefore an additional function type signature. On the JVM-Level a lambda expression (or more generally any function object) is just an instance of one of the types in Functions, depending on the number of arguments. However, as lambda expressions are a very important language feature, a special sugared syntax for function types has been introduced. So instead of writing Function1<String, Boolean> one can write (String)=>boolean.

    For more information on lambda expressions see the corresponding section.

    @@ -1009,21 +1009,21 @@
    Function Mapping

    An Xbase lambda expression is a Java object of one of the Function interfaces that are part of the runtime library of Xbase. There is an interface for each number of parameters (up to six parameters). The names of the interfaces are

    or

    if the return type is void.

    diff --git a/org.eclipse.xtext.doc/contents/307_special_languages.html b/org.eclipse.xtext.doc/contents/307_special_languages.html index 6686594b737..511038184e1 100644 --- a/org.eclipse.xtext.doc/contents/307_special_languages.html +++ b/org.eclipse.xtext.doc/contents/307_special_languages.html @@ -74,9 +74,9 @@

    Whitespace-Aware Languages

    END;
    -

    After running the workflow, a stub implementation of AbstractIndentationTokenSource is generated in the parser.antlr subpackage, e.g. RuleEngineTokenSource. Here you can specify which terminal rule should be applied to your synthetic tokens. For the Xtext Home Automation language the WS (whitespace) rule is selected, which brings the indentation awareness as seen above.

    +

    After running the workflow, a stub implementation of AbstractIndentationTokenSource is generated in the parser.antlr subpackage, e.g. RuleEngineTokenSource. Here you can specify which terminal rule should be applied to your synthetic tokens. For the Xtext Home Automation language the WS (whitespace) rule is selected, which brings the indentation awareness as seen above.

    -

    In case of a whitespace-aware language, the formatter must be either adapted to produce whitespace that correctly reflects the document structure, or it must be deactivated. Otherwise automatic formatting might produce code with different semantics or even syntax errors. See how we customized the formatter in the Xtext Home Automation example.

    +

    In case of a whitespace-aware language, the formatter must be either adapted to produce whitespace that correctly reflects the document structure, or it must be deactivated. Otherwise automatic formatting might produce code with different semantics or even syntax errors. See how we customized the formatter in the Xtext Home Automation example.

    Languages Independent of JDT

    diff --git a/org.eclipse.xtext.doc/contents/308_emf_integration.html b/org.eclipse.xtext.doc/contents/308_emf_integration.html index 707b8744bab..9688b677618 100644 --- a/org.eclipse.xtext.doc/contents/308_emf_integration.html +++ b/org.eclipse.xtext.doc/contents/308_emf_integration.html @@ -58,11 +58,11 @@

    EMF Code Generation

    XtextResource Implementation

    -

    Xtext provides an implementation of EMF’s resource, the XtextResource. This does not only encapsulate the parser that converts text to an EMF model but also the serializer working the opposite direction. That way, an Xtext model just looks like any other Ecore-based model from the outside, making it amenable for the use by other EMF based tools. So in the ideal case, you can switch the serialization format of your models to your self-defined DSL by just replacing the resource implementation used by your other modeling tools.

    +

    Xtext provides an implementation of EMF’s resource, the XtextResource. This does not only encapsulate the parser that converts text to an EMF model but also the serializer working the opposite direction. That way, an Xtext model just looks like any other Ecore-based model from the outside, making it amenable for the use by other EMF based tools. So in the ideal case, you can switch the serialization format of your models to your self-defined DSL by just replacing the resource implementation used by your other modeling tools.

    -

    The generator fragment ResourceFactoryFragment2 registers a factory for the XtextResource to EMF’s resource factory registry, such that all tools using the default mechanism to resolve a resource implementation will automatically get that resource implementation.

    +

    The generator fragment ResourceFactoryFragment2 registers a factory for the XtextResource to EMF’s resource factory registry, such that all tools using the default mechanism to resolve a resource implementation will automatically get that resource implementation.

    Using a self-defined textual syntax as the primary storage format has a number of advantages over the default XMI serialization, e.g.

    @@ -79,10 +79,10 @@

    XtextResource Implementation

  • Prefer optional rule calls (cardinality ? or *) to mandatory ones (cardinality + or default), such that missing references will not obstruct serialization.
  • You should not use an Xtext-Editor on the same model instance as a self-synchronizing other editor, e.g. a canonical GMF editor (see the EMF integration chapter for details). The Xtext parser replaces re-parsed subtrees of the AST rather than modifying it, so elements will become stale. As the Xtext editor continuously re-parses the model on changes, this will happen rather often. It is safer to synchronize editors more loosely, e.g. on file changes.
  • Implement an IFragmentProvider to make the XtextResource return stable fragments for its contained elements, e.g. based on composite names rather than order of appearance.
  • -
  • Implement an IQualifiedNameProvider and an IScopeProvider (how-to) to make the names of all linkable elements in cross-references unique.
  • -
  • Provide an IFormatter (how-to) to improve the readability of the generated textual models.
  • -
  • Register an IReferableElementsUnloader to turn deleted/replaced model elements into EMF proxies. Design the rest of your application such that it does never keep references to EObjects or to cope with proxies. That will improve the stability of your application drastically.
  • -
  • Xtext will register an EMF Factory, so resources with the file extension you entered when generating the Xtext plug-ins will be automatically loaded in an XtextResource when you use EMF’s ResourceSet API to load it.
  • +
  • Implement an IQualifiedNameProvider and an IScopeProvider (how-to) to make the names of all linkable elements in cross-references unique.
  • +
  • Provide an IFormatter (how-to) to improve the readability of the generated textual models.
  • +
  • Register an IReferableElementsUnloader to turn deleted/replaced model elements into EMF proxies. Design the rest of your application such that it does never keep references to EObjects or to cope with proxies. That will improve the stability of your application drastically.
  • +
  • Xtext will register an EMF Factory, so resources with the file extension you entered when generating the Xtext plug-ins will be automatically loaded in an XtextResource when you use EMF’s ResourceSet API to load it.
  • Referencing From EMF

    @@ -97,7 +97,7 @@

    Referencing From EMF

    However with a textual concrete syntax we want to be able to compute fragments out of the human readable information. We don’t want to force people to use UUIDs (i.e. synthetic identifiers) or fragile, relative, generic paths in order to refer to EObjects.

    -

    Therefore one can contribute an IFragmentProvider per language. It has two methods: getFragment(EObject, Fallback) to calculate the fragment of an EObject and getEObject(Resource, String, Fallback) to go the opposite direction. The Fallback interface allows to delegate to the default strategy - which usually uses the fragment paths described above.

    +

    Therefore one can contribute an IFragmentProvider per language. It has two methods: getFragment(EObject, Fallback) to calculate the fragment of an EObject and getEObject(Resource, String, Fallback) to go the opposite direction. The Fallback interface allows to delegate to the default strategy - which usually uses the fragment paths described above.

    The following snippet shows how to use qualified names as fragments:

    @@ -138,7 +138,7 @@

    Integration with GMF Editors

    We do no longer maintain the GMF example code and have removed it from our installation. You can still access the last version of the source code form our source code repository.

    -

    The Graphical Modeling Framework (GMF) allows to create graphical diagram editors for Ecore models. To illustrate how to build a GMF editor on top of an XtextResource we have provided an example. You must have the Helios version 2.3 of GMF Notation, Runtime and Tooling and their dependencies installed in your workbench to run the example. With other versions of GMF it might work to regenerate the diagram code.

    +

    The Graphical Modeling Framework (GMF) allows to create graphical diagram editors for Ecore models. To illustrate how to build a GMF editor on top of an XtextResource we have provided an example. You must have the Helios version 2.3 of GMF Notation, Runtime and Tooling and their dependencies installed in your workbench to run the example. With other versions of GMF it might work to regenerate the diagram code.

    The example consists of a number of plug-ins

    @@ -205,7 +205,7 @@

    Stage 1: Make GMF Read and Write the Semantic Mo

    To keep the semantic model and the diagram model in sync, GMF uses a so called CanonicalEditPolicy. This component registers as a listener to the semantic model and automatically updates diagram elements when their semantic counterparts change, are added or are removed. Some notational information can be derived from the semantic model by some default mapping, but usually there is a lot of graphical stuff that the user wants to change to make the diagram look better.

    -

    In an Xtext editor, changes in the text are transferred to the underlying XtextResource by a call to the method XtextResource.update(int, int, String), which will trigger a partial parsing of the dirty text region and a replacement of the corresponding subtree in the AST model (semantic model).

    +

    In an Xtext editor, changes in the text are transferred to the underlying XtextResource by a call to the method XtextResource.update(int, int, String), which will trigger a partial parsing of the dirty text region and a replacement of the corresponding subtree in the AST model (semantic model).

    Having an Xtext editor and a canonical GMF editor on the same resource can therefore lead to loss of notational information, as a change in the Xtext editor will remove a subtree in the AST, causing the CanonicalEditPolicy to remove all notational elements, even though it was customized by the user. Xtext rebuilds the AST and the notation model is restored using the default mapping. It is therefore not recommended to let an Xtext editor and a canonical GMF editor work on the same resource.

    @@ -221,7 +221,7 @@

    Stage 2: Calling the Xtext Parser to Parse GMF L

    GMF’s generated parser for the labels is a bit poor: It will work on attributes only, and will fail for cross-references, e.g. an attribute’s type. So why not use the Xtext parser to process the user’s input?

    -

    An XtextResource keeps track of it’s concrete syntax representation by means of a so called node model (see parser rules section for a more detailed description). The node model represents the parse tree and provides information on the offset, length and text that has been parsed to create a semantic model element. The nodes are attached to their semantic elements by means of a node adapter.

    +

    An XtextResource keeps track of it’s concrete syntax representation by means of a so called node model (see parser rules section for a more detailed description). The node model represents the parse tree and provides information on the offset, length and text that has been parsed to create a semantic model element. The nodes are attached to their semantic elements by means of a node adapter.

    We can use the node adapter to access the text block that represents an attribute, and call the Xtext parser to parse the user input. The example code is contained in org.eclipse.xtext.gmf.glue.edit.part.AntlrParserWrapper. SimplePropertyWrapperEditPartOverride shows how this is integrated into the generated GMF editor. Use the EntitiesEditPartFactoryOverride to instantiate it and the EntitiesEditPartProviderOverride to create the overridden factory, and register the latter to the extension point. Note that this is a non-invasive way to extend the generated GMF editors.

    diff --git a/org.eclipse.xtext.doc/contents/310_eclipse_support.html b/org.eclipse.xtext.doc/contents/310_eclipse_support.html index 11124a4f764..f9f6182591f 100644 --- a/org.eclipse.xtext.doc/contents/310_eclipse_support.html +++ b/org.eclipse.xtext.doc/contents/310_eclipse_support.html @@ -18,15 +18,15 @@

    Label Provider

    An ILabelProvider has two methods: getText(Object) returns the text in an object’s label, while getImage(Object) returns the icon. In addition, the Eclipse UI framework offers the IStyledLabelProvider, which returns a StyledString (i.e. with custom fonts, colors etc.) in the getStyledText(Object) method.

    -

    Almost all label providers in the Xtext framework inherit from the base class AbstractLabelProvider which unifies both approaches. Subclasses can either return a styled string or a string in the doGetText(Object) method. The framework will automatically convert it to a styled text (with default styles) or to a plain text in the respective methods.

    +

    Almost all label providers in the Xtext framework inherit from the base class AbstractLabelProvider which unifies both approaches. Subclasses can either return a styled string or a string in the doGetText(Object) method. The framework will automatically convert it to a styled text (with default styles) or to a plain text in the respective methods.

    -

    Dealing with images can be cumbersome, too, as image handles tend to be scarce system resources. The AbstractLabelProvider helps you managing the images: In your implementation of doGetImage(Object) you can as well return an Image, an ImageDescriptor or a string, representing a path in the icons/ folder of the containing plug-in. This path is actually configurable by Google Guice. Have a look at the PluginImageHelper to learn about the customizing possibilities.

    +

    Dealing with images can be cumbersome, too, as image handles tend to be scarce system resources. The AbstractLabelProvider helps you managing the images: In your implementation of doGetImage(Object) you can as well return an Image, an ImageDescriptor or a string, representing a path in the icons/ folder of the containing plug-in. This path is actually configurable by Google Guice. Have a look at the PluginImageHelper to learn about the customizing possibilities.

    -

    If you have the LabelProviderFragment2 in the list of generator fragments in the MWE2 workflow of your language, it will automatically create stubs and bindings for an {MyLang}EObjectLabelProvider and an {MyLang}DescriptionLabelProvider which you can implement manually.

    +

    If you have the LabelProviderFragment2 in the list of generator fragments in the MWE2 workflow of your language, it will automatically create stubs and bindings for an {MyLang}EObjectLabelProvider and an {MyLang}DescriptionLabelProvider which you can implement manually.

    Label Providers For EObjects

    -

    The EObject label provider refers to actually loaded and thereby available model elements. By default, Xtext binds the DefaultEObjectLabelProvider to all use cases, but you can change the binding individually for the Outline, Content Assist or other places. For that purpose, there is a so called binding annotation for each use case. For example, to use a custom MyContentAssistLabelProvider to display elements in the content assist, you have to override configureContentProposalLabelProvider(..) in your language’s UI module:

    +

    The EObject label provider refers to actually loaded and thereby available model elements. By default, Xtext binds the DefaultEObjectLabelProvider to all use cases, but you can change the binding individually for the Outline, Content Assist or other places. For that purpose, there is a so called binding annotation for each use case. For example, to use a custom MyContentAssistLabelProvider to display elements in the content assist, you have to override configureContentProposalLabelProvider(..) in your language’s UI module:

    @Override
     public void configureContentProposalLabelProvider(Binder binder) {
    @@ -48,7 +48,7 @@ 

    Label Providers For EObjects

    DefaultEObjectLabelProvider

    -

    The default implementation of the ILabelProvider interface utilizes the polymorphic dispatcher idiom to implement an external visitor as the requirements of the label provider are kind of a best match for this pattern. It boils down to the fact that the only thing you need to do is to implement a method that matches a specific signature. It either provides an image filename or the text to be used to represent your model element. Have a look at the following example to get a more detailed idea about the DefaultEObjectLabelProvider.

    +

    The default implementation of the ILabelProvider interface utilizes the polymorphic dispatcher idiom to implement an external visitor as the requirements of the label provider are kind of a best match for this pattern. It boils down to the fact that the only thing you need to do is to implement a method that matches a specific signature. It either provides an image filename or the text to be used to represent your model element. Have a look at the following example to get a more detailed idea about the DefaultEObjectLabelProvider.

    public class StatemachineLabelProvider 
         extends DefaultLabelProvider {
    @@ -73,9 +73,9 @@ 

    DefaultEObjectLabelProvider

    Label Providers For Index Entries

    -

    Xtext maintains an index of all model elements to allow quick searching and linking without loading the referenced resource (see the chapter on index-based scopes for details). The elements from this index also appear in some UI contexts, e.g. in the Find model elements dialog or in the Find references view. For reasons of scalability, the UI should not automatically load resources, so we need another implementation of a label provider that works with the elements from the index, i.e. IResourceDescription, IEObjectDescription, and IReferenceDescription.

    +

    Xtext maintains an index of all model elements to allow quick searching and linking without loading the referenced resource (see the chapter on index-based scopes for details). The elements from this index also appear in some UI contexts, e.g. in the Find model elements dialog or in the Find references view. For reasons of scalability, the UI should not automatically load resources, so we need another implementation of a label provider that works with the elements from the index, i.e. IResourceDescription, IEObjectDescription, and IReferenceDescription.

    -

    The default implementation of this service is the DefaultDescriptionLabelProvider. It employs the same polymorphic dispatch mechanism as the DefaultEObjectLabelProvider. The default text of an IEObjectDescription is its indexed name. The image is resolved by dispatching to image(EClass) with the EClass of the described object. This is likely the only method you want to override. Instances of IResourceDescription will be represented with their path and the icon registered for your language’s editor.

    +

    The default implementation of this service is the DefaultDescriptionLabelProvider. It employs the same polymorphic dispatch mechanism as the DefaultEObjectLabelProvider. The default text of an IEObjectDescription is its indexed name. The image is resolved by dispatching to image(EClass) with the EClass of the described object. This is likely the only method you want to override. Instances of IResourceDescription will be represented with their path and the icon registered for your language’s editor.

    To have a custom description label provider, make sure it is bound in your UI module:

    @@ -112,7 +112,7 @@

    Content Assist

    The snippet above indicates that the generated class contains a complete*-method for each assigned feature in the grammar and for each rule. The braces in the snippet are place-holders that should give a clue about the naming scheme used to create the various entry points for implementors. The generated proposal provider falls back to some default behavior for cross-references and keywords. Furthermore it inherits the logic that was introduced in grammars that were mixed into the current language.

    -

    Clients who want to customize the behavior may override the methods from the AbstractJavaBasedContentProposalProvider or introduce new methods with a specialized first parameter. The framework inspects the type of the model object and dispatches method calls to the most concrete implementation that can be found.

    +

    Clients who want to customize the behavior may override the methods from the AbstractJavaBasedContentProposalProvider or introduce new methods with a specialized first parameter. The framework inspects the type of the model object and dispatches method calls to the most concrete implementation that can be found.

    It is important to know that, for a given offset in a model file, many possible grammar elements exist. The framework dispatches to the method declarations for any valid element. This means that a bunch of complete* methods may be called.

    @@ -146,7 +146,7 @@

    Quick Fixes

    DomainmodelPackage.TYPE__NAME, IssueCodes.INVALID_TYPE_NAME, type.getName());
    -

    Now that the validation has a unique code identifying the problem we can register quick fixes for it. We start by adding the QuickfixProviderFragment2 to our workflow and after regenerating the code we should find an empty class MyDslQuickfixProvider in our DSL’s UI project and new entries in the plugin.xml_gen file.

    +

    Now that the validation has a unique code identifying the problem we can register quick fixes for it. We start by adding the QuickfixProviderFragment2 to our workflow and after regenerating the code we should find an empty class MyDslQuickfixProvider in our DSL’s UI project and new entries in the plugin.xml_gen file.

    Continuing with the INVALID_TYPE_NAME problem from the domain model example we add a method with which the problem can be fixed (have a look at the DomainmodelQuickfixProvider for details):

    @@ -165,13 +165,13 @@

    Quick Fixes

    }
    -

    By using the correct signature (see below) and annotating the method with the @Fix annotation referencing the previously specified issue code from the validator, Xtext knows that this method implements a fix for the problem. This also allows us to annotate multiple methods as fixes for the same problem.

    +

    By using the correct signature (see below) and annotating the method with the @Fix annotation referencing the previously specified issue code from the validator, Xtext knows that this method implements a fix for the problem. This also allows us to annotate multiple methods as fixes for the same problem.

    -

    The first three parameters given to the IssueResolutionAcceptor define the UI representation of the quick fix. As the document is not necessarily loaded when the quick fix is offered, we need to provide any additional data from the model that we want to refer to in the UI when creating the issue in the validator above. In this case, we provided the existing type name. The additional data is available as Issue.getData(). As it is persisted in markers, only strings are allowed.

    +

    The first three parameters given to the IssueResolutionAcceptor define the UI representation of the quick fix. As the document is not necessarily loaded when the quick fix is offered, we need to provide any additional data from the model that we want to refer to in the UI when creating the issue in the validator above. In this case, we provided the existing type name. The additional data is available as Issue.getData(). As it is persisted in markers, only strings are allowed.

    -

    The actual model modification is implemented in the IModification. The IModificationContext provides access to the erroneous document. In this case, we’re using Eclipse’s IDocument API to replace a text region.

    +

    The actual model modification is implemented in the IModification. The IModificationContext provides access to the erroneous document. In this case, we’re using Eclipse’s IDocument API to replace a text region.

    -

    If you prefer to implement the quick fix in terms of the semantic model use an ISemanticModification instead. Its apply(EObject, IModificationContext) method will be invoked inside a modify-transaction and the first argument will be the erroneous semantic element. This makes it very easy for the fix method to modify the model as necessary. After the method returns the model as well as the Xtext editor’s content will be updated accordingly. If the method fails (throws an exception) the change will not be committed. The following snippet shows a semantic quick fix for a similar problem.

    +

    If you prefer to implement the quick fix in terms of the semantic model use an ISemanticModification instead. Its apply(EObject, IModificationContext) method will be invoked inside a modify-transaction and the first argument will be the erroneous semantic element. This makes it very easy for the fix method to modify the model as necessary. After the method returns the model as well as the Xtext editor’s content will be updated accordingly. If the method fails (throws an exception) the change will not be committed. The following snippet shows a semantic quick fix for a similar problem.

    @Fix(IssueCodes.INVALID_FEATURE_NAME)
     public void fixFeatureName(final Issue issue, 
    @@ -219,7 +219,7 @@ 

    Multi-Quickfixes

    Quick Fixes for Linking Errors and Syntax Errors

    -

    You can even define quick fixes for linking errors. The issue codes are assigned by the ILinkingDiagnosticMessageProvider. Have a look at the domain model example how to add quick fixes for these errors:

    +

    You can even define quick fixes for linking errors. The issue codes are assigned by the ILinkingDiagnosticMessageProvider. Have a look at the domain model example how to add quick fixes for these errors:

    @Fix(IssueCodes.MISSING_TYPE)
     public void createReferenceType(Issue issue, IssueResolutionAcceptor acceptor) {
    @@ -227,12 +227,12 @@ 

    Quick Fixes for Linkin }

    -

    Hence, there is the ISyntaxErrorMessageProvider to assign issue codes to syntactical errors.

    +

    Hence, there is the ISyntaxErrorMessageProvider to assign issue codes to syntactical errors.

    Auto Editing

    Xtext-based editors automatically assist the user by inserting/deleting certain text at typetime, e.g. inserting/removing closing single quotes, double quotes, parenthesis, square brackets or curly braces when the user inserts/removes the opening ones. Moreover, the auto-indentation functionality ensures the indentation-awareness of new lines: after hitting the ENTER key e.g. in a block enclosed by curly braces the cursor is automatically placed on the indented position in the subsequent new line.

    -

    This default behaviour can be customized by extending the DefaultAutoEditStrategyProvider class. The Xtext Simple Arithmetics example provides an interactive interpreter as an auto editing strategy by binding the customized AutoEditStrategy class in the ArithmeticsUiModule.

    +

    This default behaviour can be customized by extending the DefaultAutoEditStrategyProvider class. The Xtext Simple Arithmetics example provides an interactive interpreter as an auto editing strategy by binding the customized AutoEditStrategy class in the ArithmeticsUiModule.

    @@ -249,7 +249,7 @@

    Template Proposals

  • for each keyword ({languageName}.kw_{keyword}).
  • -

    If you don’t like these defaults you’ll have to subclass XtextTemplateContextTypeRegistry and configure it via Guice.

    +

    If you don’t like these defaults you’ll have to subclass XtextTemplateContextTypeRegistry and configure it via Guice.

    In addition to the standard template proposal extension mechanism, Xtext ships with a predefined set of TemplateVariableResolvers to resolve special variable types in templates. Besides the standard template variables available in GlobalTemplateVariables like ${user}, ${date}, ${time}, ${cursor}, etc., these TemplateVariableResolvers support the automatic resolution of cross references enumeration values. Both resolvers are explained in the following sections.

    @@ -257,7 +257,7 @@

    Template Proposals

    Cross Reference Template Variable Resolver

    -

    Xtext comes with a specific template variable resolver called CrossReferenceTemplateVariableResolver, which can be used to pre-populate placeholders for cross-references within a template. The respective template variable is called CrossReference and its syntax is as follows:

    +

    Xtext comes with a specific template variable resolver called CrossReferenceTemplateVariableResolver, which can be used to pre-populate placeholders for cross-references within a template. The respective template variable is called CrossReference and its syntax is as follows:

    ${<displayText>:CrossReference([<MyPackageName>.]<MyType>.<myRef>)}

    @@ -279,7 +279,7 @@

    Cross Reference Template Var

    Enumeration Template Variable Resolver

    -

    The EnumTemplateVariableResolver resolves a template variable to EEnumLiterals which are assignment-compatible to the enumeration type declared as the first parameter of the Enum template variable.

    +

    The EnumTemplateVariableResolver resolves a template variable to EEnumLiterals which are assignment-compatible to the enumeration type declared as the first parameter of the Enum template variable.

    The syntax is as follows:

    @@ -307,15 +307,15 @@

    Outline View

    -

    In its default implementation, the outline view shows the containment hierarchy of your model. This should be sufficient in most cases. If you want to adjust the structure of the outline, i.e. by omitting a certain kind of node or by introducing additional nodes, you can customize the outline by implementing your own IOutlineTreeProvider.

    +

    In its default implementation, the outline view shows the containment hierarchy of your model. This should be sufficient in most cases. If you want to adjust the structure of the outline, i.e. by omitting a certain kind of node or by introducing additional nodes, you can customize the outline by implementing your own IOutlineTreeProvider.

    -

    If your workflow defines the OutlineTreeProviderFragment2, Xtext generates a stub for your own IOutlineTreeProvider that allows you to customize every aspect of the outline by inheriting the powerful customization methods of DefaultOutlineTreeProvider. The following sections show how to fill this stub with life.

    +

    If your workflow defines the OutlineTreeProviderFragment2, Xtext generates a stub for your own IOutlineTreeProvider that allows you to customize every aspect of the outline by inheriting the powerful customization methods of DefaultOutlineTreeProvider. The following sections show how to fill this stub with life.

    Influencing the outline structure

    -

    Each node in the outline tree is an instance of IOutlineNode. The outline tree is always rooted in a DocumentRootNode. This node is automatically created for you. Its children are the root nodes in the displayed view.

    +

    Each node in the outline tree is an instance of IOutlineNode. The outline tree is always rooted in a DocumentRootNode. This node is automatically created for you. Its children are the root nodes in the displayed view.

    -

    An EObjectNode represents a model element. By default, Xtext creates an EObjectNode for each model element in the node of its container. Nodes are created by calling the method createNode(parentNode, modelElement) which delegates to createEObjectNode(..) if not specified differently.

    +

    An EObjectNode represents a model element. By default, Xtext creates an EObjectNode for each model element in the node of its container. Nodes are created by calling the method createNode(parentNode, modelElement) which delegates to createEObjectNode(..) if not specified differently.

    To change the children of specific nodes, you have to implement the method

    @@ -341,7 +341,7 @@

    Influencing the outline structure

    -

    Xtext provides a third type of node: EStructuralFeatureNode. It is used to represent a feature of a model element rather than the element itself. The following simplified snippet from Xtend2 illustrates how to use it:

    +

    Xtext provides a third type of node: EStructuralFeatureNode. It is used to represent a feature of a model element rather than the element itself. The following simplified snippet from Xtend2 illustrates how to use it:

    protected void _createChildren(DocumentRootNode parentNode,
                                    XtendFile xtendFile) {
    @@ -364,13 +364,13 @@ 

    Influencing the outline structure

    -

    Of course you can add further custom types of nodes. For consistency, make sure to inherit from AbstractOutlineNode. To instantiate these, you have to implement _createNode(parentNode, semanticElement) with the appropriate parameter types.

    +

    Of course you can add further custom types of nodes. For consistency, make sure to inherit from AbstractOutlineNode. To instantiate these, you have to implement _createNode(parentNode, semanticElement) with the appropriate parameter types.

    Styling the outline

    -

    You can also customize the icons and texts for an outline node. By default, Xtext uses the label provider of your language. If you want the labels to be specific to the outline, you can override the methods _text(modelElement) and _image(modelElement) in your DefaultOutlineTreeProvider.

    +

    You can also customize the icons and texts for an outline node. By default, Xtext uses the label provider of your language. If you want the labels to be specific to the outline, you can override the methods _text(modelElement) and _image(modelElement) in your DefaultOutlineTreeProvider.

    -

    Note that the method _text(modelElement) can return a String or a StyledString. The StylerFactory can be used to create StyledStrings, like in the following example:

    +

    Note that the method _text(modelElement) can return a String or a StyledString. The StylerFactory can be used to create StyledStrings, like in the following example:

    @Inject 
     private StylerFactory stylerFactory;
    @@ -392,11 +392,11 @@ 

    Styling the outline

    }
    -

    To access images we recommend to use the PluginImageHelper.

    +

    To access images we recommend to use the PluginImageHelper.

    Filtering actions

    -

    Often, you want to allow users to filter the contents of the outline to make it easier to concentrate on the relevant aspects of the model. To add filtering capabilities to your outline, you need to add a filter action to your outline. Filter actions must extend AbstractFilterOutlineContribution to ensure that the action toggle state is handled correctly. Here is an example from the Xtext Domainmodel example:

    +

    Often, you want to allow users to filter the contents of the outline to make it easier to concentrate on the relevant aspects of the model. To add filtering capabilities to your outline, you need to add a filter action to your outline. Filter actions must extend AbstractFilterOutlineContribution to ensure that the action toggle state is handled correctly. Here is an example from the Xtext Domainmodel example:

    public class FilterOperationsContribution
         extends AbstractFilterOutlineContribution {
    @@ -441,9 +441,9 @@ 

    Filtering actions

    Sorting actions

    -

    Xtext already adds a sorting action to your outline. By default, nodes are sorted lexically by their text. You can change this behavior by binding your own IComparator.

    +

    Xtext already adds a sorting action to your outline. By default, nodes are sorted lexically by their text. You can change this behavior by binding your own IComparator.

    -

    A very common use case is to group the children by categories first, e.g. show the imports before the types in a package declaration, and sort the categories separately. That is why the DefaultComparator has a method getCategory(IOutlineNode) that allows to specify such categories. The example shows how to use such categories:

    +

    A very common use case is to group the children by categories first, e.g. show the imports before the types in a package declaration, and sort the categories separately. That is why the DefaultComparator has a method getCategory(IOutlineNode) that allows to specify such categories. The example shows how to use such categories:

    public class MydslOutlineNodeComparator extends DefaultComparator {
       @Override
    @@ -471,7 +471,7 @@ 

    Sorting actions

    Quick Outline

    -

    Xtext also provides a quick outline: If you press CTRL-O in an Xtext editor, the outline of the model is shown in a popup window. The quick outline also supports drill-down search with wildcards. To enable the quick outline, you have to put the QuickOutlineFragment2 into your workflow.

    +

    Xtext also provides a quick outline: If you press CTRL-O in an Xtext editor, the outline of the model is shown in a popup window. The quick outline also supports drill-down search with wildcards. To enable the quick outline, you have to put the QuickOutlineFragment2 into your workflow.

    Folding

    @@ -481,7 +481,7 @@

    Folding

    -

    In order to make events, resetEvents and commands foldable too, a custom implementation of the DefaultFoldingRegionProvider is necessary:

    +

    In order to make events, resetEvents and commands foldable too, a custom implementation of the DefaultFoldingRegionProvider is necessary:

    public class StatemachineFoldingRegionProvider extends DefaultFoldingRegionProvider {
     
    @@ -521,7 +521,7 @@ 

    Folding

    }
    -

    Additionally, the StatemachineFoldingRegionProvider class has to be bound in the StatemachineUiModule:

    +

    Additionally, the StatemachineFoldingRegionProvider class has to be bound in the StatemachineUiModule:

    public class StatemachineUiModule extends AbstractStatemachineUiModule {
     
       ...
    @@ -541,7 +541,7 @@ 

    Hyperlinking

    Location Provider

    -

    When navigating a hyperlink, Xtext will also select the text region corresponding to the referenced model element. Determining this text region is the responsibility of the ILocationInFileProvider. The default implementation implements a best effort strategy which can be summarized as:

    +

    When navigating a hyperlink, Xtext will also select the text region corresponding to the referenced model element. Determining this text region is the responsibility of the ILocationInFileProvider. The default implementation implements a best effort strategy which can be summarized as:

    1. If the model element’s type declares a feature name then return the region of the corresponding token(s). As a fallback also check for a feature id.
    2. @@ -551,7 +551,7 @@

      Location Provider

      The location service offers different methods to obtain the region of interest for special use cases. You can either obtain the complete region for an object or only the identifying string which is usually the name of the instance (see getSignificantTextRegion(EObject)). You can also query for the text region of a specific EStructuralFeature by means of getFullTextRegion(EObject, EStructuralFeature, int).

      -

      As the default strategy is a best effort it may not always result in the selection you want. If that’s the case you can override the ILocationInFileProvider binding in the runtime module as in the following example:

      +

      As the default strategy is a best effort it may not always result in the selection you want. If that’s the case you can override the ILocationInFileProvider binding in the runtime module as in the following example:

      public class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
         @Override
      @@ -562,18 +562,18 @@ 

      Location Provider

      }
      -

      Often the default strategy only needs some guidance (e.g. selecting the text corresponding to another feature than name). In that case you can simply subclass the DefaultLocationInFileProvider and override the methods getIdentifierFeature() or useKeyword() to guide the first and last steps of the strategy as described above (see XtextLocationInFileProvider for an example).

      +

      Often the default strategy only needs some guidance (e.g. selecting the text corresponding to another feature than name). In that case you can simply subclass the DefaultLocationInFileProvider and override the methods getIdentifierFeature() or useKeyword() to guide the first and last steps of the strategy as described above (see XtextLocationInFileProvider for an example).

      -

      The hyperlinks are provided by the HyperlinkHelper which will create links for cross-referenced objects by default. Clients may want to override createHyperlinksByOffset(XtextResource, int, IHyperlinkAcceptor) to provide additional links or supersede the default implementation.

      +

      The hyperlinks are provided by the HyperlinkHelper which will create links for cross-referenced objects by default. Clients may want to override createHyperlinksByOffset(XtextResource, int, IHyperlinkAcceptor) to provide additional links or supersede the default implementation.

      Hovering

      Similar to hyperlinking, Xtext-based editors provide hovering support on certain tokens: e.g. hovering over a cross-reference token, the Xtext framework shows the documentation of the element the cross-reference is referring to. Considering the Xtext Simple Arithmetics example, when hovering over a function call, a popup window displays the documentation of the called function:

      -

      This functionality is implemented in the DefaultEObjectHoverProvider that delegates to the MultiLineCommentDocumentationProvider class via the IEObjectDocumentationProvider interface by default. Customization can happen e.g. by extending the DefaultEObjectHoverProvider class, overriding the getHoverInfoAsHtml(EObject o) method and binding the custom implementation in the corresponding UI module:

      +

      This functionality is implemented in the DefaultEObjectHoverProvider that delegates to the MultiLineCommentDocumentationProvider class via the IEObjectDocumentationProvider interface by default. Customization can happen e.g. by extending the DefaultEObjectHoverProvider class, overriding the getHoverInfoAsHtml(EObject o) method and binding the custom implementation in the corresponding UI module:

      public class MyDslHoverProvider extends DefaultEObjectHoverProvider {
       
      @@ -599,7 +599,7 @@ 

      Mark Occurrences

      -

      Customization can happen by either extending the DefaultOccurrenceComputer class or even providing a complete implementation of the IOccurrenceComputer interface.

      +

      Customization can happen by either extending the DefaultOccurrenceComputer class or even providing a complete implementation of the IOccurrenceComputer interface.

      public class MyDslOccurrenceComputer extends DefaultOccurrenceComputer {
       	...
      @@ -620,7 +620,7 @@ 

      Find References

      -

      The org.eclipse.xtext.findReferences.IReferenceFinder and the org.eclipse.xtext.ui.editor.findrefs.IReferenceFinder interfaces are responsible for this functionality. These interfaces are implemented by the ReferenceFinder and the DelegatingReferenceFinder classes. As almost everything in the Xtext framework, these components can also be customized if the default implementations do not satisfy your needs.

      +

      The org.eclipse.xtext.findReferences.IReferenceFinder and the org.eclipse.xtext.ui.editor.findrefs.IReferenceFinder interfaces are responsible for this functionality. These interfaces are implemented by the ReferenceFinder and the DelegatingReferenceFinder classes. As almost everything in the Xtext framework, these components can also be customized if the default implementations do not satisfy your needs.

      Syntax Coloring

      @@ -636,9 +636,9 @@

      Syntax Coloring

      Lexical Highlighting

      -

      The lexical highlighting can be customized by providing implementations of the interface IHighlightingConfiguration and the abstract class AbstractTokenScanner. The latter fulfills the interface ITokenScanner from the underlying JFace framework, which may be implemented by clients directly.

      +

      The lexical highlighting can be customized by providing implementations of the interface IHighlightingConfiguration and the abstract class AbstractTokenScanner. The latter fulfills the interface ITokenScanner from the underlying JFace framework, which may be implemented by clients directly.

      -

      The IHighlightingConfiguration is used to register any default style without a specific binding to a pattern in the model file. It is used to populate the preferences page and to initialize the ITextAttributeProvider, which in turn is the component that is used to obtain the actual settings for a style’s id. An implementation will usually be very similar to the DefaultHighlightingConfiguration and read like this:

      +

      The IHighlightingConfiguration is used to register any default style without a specific binding to a pattern in the model file. It is used to populate the preferences page and to initialize the ITextAttributeProvider, which in turn is the component that is used to obtain the actual settings for a style’s id. An implementation will usually be very similar to the DefaultHighlightingConfiguration and read like this:

      public class DefaultHighlightingConfiguration
           implements IHighlightingConfiguration {
      @@ -661,15 +661,15 @@ 

      Lexical Highlighting

      }
      -

      Implementations of the ITokenScanner are responsible for splitting the content of a document into various parts, the so called tokens, and return the highlighting information for each identified range. It is critical that this is done very fast because this component is used on each keystroke. Xtext ships with a default implementation that is based on the lexer that is generated by ANTLR which is very lightweight and fast. This default implementation can be customized by clients easily. They simply have to bind another implementation of the AbstractAntlrTokenToAttributeIdMapper. To get an idea about it, have a look at the DefaultAntlrTokenToAttributeIdMapper.

      +

      Implementations of the ITokenScanner are responsible for splitting the content of a document into various parts, the so called tokens, and return the highlighting information for each identified range. It is critical that this is done very fast because this component is used on each keystroke. Xtext ships with a default implementation that is based on the lexer that is generated by ANTLR which is very lightweight and fast. This default implementation can be customized by clients easily. They simply have to bind another implementation of the AbstractAntlrTokenToAttributeIdMapper. To get an idea about it, have a look at the DefaultAntlrTokenToAttributeIdMapper.

      Semantic Highlighting

      The semantic highlighting stage is executed asynchronously in the background and can be used to calculate highlighting states based on the meaning of the different model elements. Users of the editor will notice a very short delay after they have edited the text until the styles are actually applied to the document. This keeps the editor responsive while providing aid when reading and writing your model.

      -

      As for the lexical highlighting the interface to register the available styles is the IHighlightingConfiguration. The ISemanticHighlightingCalculator is the primary hook to implement the logic that will compute the to-be-highlighted ranges based on the model elements.

      +

      As for the lexical highlighting the interface to register the available styles is the IHighlightingConfiguration. The ISemanticHighlightingCalculator is the primary hook to implement the logic that will compute the to-be-highlighted ranges based on the model elements.

      -

      The framework will pass the current XtextResource and an IHighlightedPositionAcceptor to the calculator. It is ensured that the resource will not be altered externally until the called method provideHighlightingFor() returns. However, the resource may be null in case of errors in the model. The implementor’s task is to navigate the semantic model and compute various ranges based on the attached node information and associate styles with them. This may read similar to the following snippet:

      +

      The framework will pass the current XtextResource and an IHighlightedPositionAcceptor to the calculator. It is ensured that the resource will not be altered externally until the called method provideHighlightingFor() returns. However, the resource may be null in case of errors in the model. The implementor’s task is to navigate the semantic model and compute various ranges based on the attached node information and associate styles with them. This may read similar to the following snippet:

      public void provideHighlightingFor(XtextResource resource,
           IHighlightedPositionAcceptor acceptor) {
      @@ -686,7 +686,7 @@ 

      Semantic Highlighting

      }
      -

      This example refers to an implementation of the IHighlightingConfiguration that registers an own style for each cross-reference. It is pretty much the same implementation as for the previously mentioned sample of a lexical IHighlightingConfiguration.

      +

      This example refers to an implementation of the IHighlightingConfiguration that registers an own style for each cross-reference. It is pretty much the same implementation as for the previously mentioned sample of a lexical IHighlightingConfiguration.

      public class HighlightingConfiguration
           implements IHighlightingConfiguration {
      @@ -710,7 +710,7 @@ 

      Semantic Highlighting

      }
      -

      The implementor of an ISemanticHighlightingCalculator should be aware of performance to ensure a good user experience. It is probably not a good idea to traverse everything of your model when you will only register a few highlighted ranges that can be found easier with some typed method calls. It is strongly advised to use purposeful ways to navigate your model. The parts of Xtext’s core that are responsible for the semantic highlighting are pretty optimized in this regard as well. The framework will only update the ranges that actually have been altered, for example. This speeds up the redraw process. It will even move, shrink or enlarge previously announced regions based on a best guess before the next semantic highlighting pass has been triggered after the user has changed the document.

      +

      The implementor of an ISemanticHighlightingCalculator should be aware of performance to ensure a good user experience. It is probably not a good idea to traverse everything of your model when you will only register a few highlighted ranges that can be found easier with some typed method calls. It is strongly advised to use purposeful ways to navigate your model. The parts of Xtext’s core that are responsible for the semantic highlighting are pretty optimized in this regard as well. The framework will only update the ranges that actually have been altered, for example. This speeds up the redraw process. It will even move, shrink or enlarge previously announced regions based on a best guess before the next semantic highlighting pass has been triggered after the user has changed the document.

      Rename Refactoring

      @@ -723,7 +723,7 @@

      Rename Refactoring

    3. renaming of declaration and all references even across language boundaries.
    4. -

      To enable refactoring support make sure the RefactorElementNameFragment2 is enabled in the fragment section of the MWE workflow of your language, e.g.

      +

      To enable refactoring support make sure the RefactorElementNameFragment2 is enabled in the fragment section of the MWE workflow of your language, e.g.

      // rename refactoring
       fragment = refactoring.RefactorElementNameFragment2 {}
      @@ -735,20 +735,20 @@ 

      Rename Refactoring

      Customizing

      -

      The most likely component you want to customize is the IRenameStrategy. This component defines how the declaration of the target element is performed. It has two major responsibilities:

      +

      The most likely component you want to customize is the IRenameStrategy. This component defines how the declaration of the target element is performed. It has two major responsibilities:

      • Apply and revert the declaration change on the semantic model (methods applyDeclarationChange and revertDeclarationChange). The default is to look for an EAttribute name on the target object and set its value using EMFs reflective API.
      • -
      • Create the LTK Change objects of the declaration change. These changes will be aggregated, checked for overlaps, presented to you in the preview and finally executed if you apply the refactoring. The default is to use the ILocationInFileProvider to locate the text range representing the name and create a ReplaceEdit for it.
      • +
      • Create the LTK Change objects of the declaration change. These changes will be aggregated, checked for overlaps, presented to you in the preview and finally executed if you apply the refactoring. The default is to use the ILocationInFileProvider to locate the text range representing the name and create a ReplaceEdit for it.
      -

      As the IRenameStrategy is a stateful object, you have to bind a custom Provider to create it.

      +

      As the IRenameStrategy is a stateful object, you have to bind a custom Provider to create it.

      -

      The second component you might want to customize is the IDependentElementsCalculator. Dependent elements are those elements whose name change when the target element is renamed. For example, when you rename a Java class the qualified names of its inner classes change, too, thus references to these have to be updated as well. This calculation is performed by the IDependentElementsCalculator. By default, all elements contained in the target element are added. This matches Xtext’s default strategy of qualified name computation.

      +

      The second component you might want to customize is the IDependentElementsCalculator. Dependent elements are those elements whose name change when the target element is renamed. For example, when you rename a Java class the qualified names of its inner classes change, too, thus references to these have to be updated as well. This calculation is performed by the IDependentElementsCalculator. By default, all elements contained in the target element are added. This matches Xtext’s default strategy of qualified name computation.

      Rename Participants

      -

      One refactoring can trigger another: When renaming a rule in an Xtext grammar, the returned EClass should be renamed, too. For these cases, you can register a RenameParticipant by the common means of LTK. If the target of the participant is Xtext based, you can use a AbstractProcessorBasedRenameParticipant.

      +

      One refactoring can trigger another: When renaming a rule in an Xtext grammar, the returned EClass should be renamed, too. For these cases, you can register a RenameParticipant by the common means of LTK. If the target of the participant is Xtext based, you can use a AbstractProcessorBasedRenameParticipant.

      Project Wizard

      @@ -773,11 +773,11 @@

      Project Wizard

      The templates define two things. On the one hand they define how the template is presented to the user. A name, a description and the layout of the widgets the user gets presented to select values for the parameters of the template. On the other hand the content of the projects that the template generates is defined. The wizard is able to generate any number and kind of projects with any number and kind of files as content.

      -

      The templates are contributed to the wizard by the extension point org.eclipse.xtext.ui.projectTemplate. An implementor of IProjectTemplateProvider is registered for the language it provides templates to. The method of this interface returns instances of AbstractProjectTemplate. Each of these instances defines one template.

      +

      The templates are contributed to the wizard by the extension point org.eclipse.xtext.ui.projectTemplate. An implementor of IProjectTemplateProvider is registered for the language it provides templates to. The method of this interface returns instances of AbstractProjectTemplate. Each of these instances defines one template.

      -

      To create a subclass of AbstractProjectTemplate it is advisable to annotate a class with the active annotation ProjectTemplate. With this annotation the name and description can be defined and will be made available to the user interface. Also the extension of AbstractProjectTemplate will be done for you.

      +

      To create a subclass of AbstractProjectTemplate it is advisable to annotate a class with the active annotation ProjectTemplate. With this annotation the name and description can be defined and will be made available to the user interface. Also the extension of AbstractProjectTemplate will be done for you.

      -

      In a project template the method generateProjects(IProjectGenerator) needs to be overridden. The parameter instance offers a single generate method that takes an instance of ProjectFactory. Using this class, or available subclasses, all kind of projects can be generated by the template. The following illustrates a simple example to generate a plugin project with a template:

      +

      In a project template the method generateProjects(IProjectGenerator) needs to be overridden. The parameter instance offers a single generate method that takes an instance of ProjectFactory. Using this class, or available subclasses, all kind of projects can be generated by the template. The following illustrates a simple example to generate a plugin project with a template:

      generator.generate(new PluginProjectFactory => [
           projectName = projectInfo.projectName
      @@ -827,7 +827,7 @@ 

      File Wizard

      }
      -

      The API for the file wizard is very similar to the one of the project wizard. The templates are defined with the same widgets/parameters but instead of generating whole projects one or many files are generated. To add new template providers there is the extension point org.eclipse.xtext.ui.fileTemplate to register a IFileTemplateProvider. To create instances of AbstractFileTemplate one should use the active annotation FileTemplate.

      +

      The API for the file wizard is very similar to the one of the project wizard. The templates are defined with the same widgets/parameters but instead of generating whole projects one or many files are generated. To add new template providers there is the extension point org.eclipse.xtext.ui.fileTemplate to register a IFileTemplateProvider. To create instances of AbstractFileTemplate one should use the active annotation FileTemplate.

      An simple example template might look like this:

      @@ -886,16 +886,16 @@

      UI Testing

      Automated UI tests are crucial for the maintainability and the quality of a software product. That’s why it is strongly recommended to write not only automated unit tests for your language, but also automated UI tests for your language editor. The org.eclipse.xtext.ui.testing package contains some base classes that come in handy when implementing automated UI tests:

      diff --git a/org.eclipse.xtext.doc/contents/330_web_support.html b/org.eclipse.xtext.doc/contents/330_web_support.html index ab1e8d42c05..df569e8db17 100644 --- a/org.eclipse.xtext.doc/contents/330_web_support.html +++ b/org.eclipse.xtext.doc/contents/330_web_support.html @@ -334,41 +334,41 @@

      Full List of Options

      The Server

      -

      The language-specific resources are provided through HTTP requests which are processed by the XtextServlet. This class is also responsible for managing the lifecycle of the language Injector (see Dependency Injection). The default approach is to create an injector when the servlet is started and to register it in the IResourceServiceProvider.Registry. In order to override the default behavior, you can change or add bindings in the <LanguageName>WebModule or <LanguageName>IdeModule of your language.

      +

      The language-specific resources are provided through HTTP requests which are processed by the XtextServlet. This class is also responsible for managing the lifecycle of the language Injector (see Dependency Injection). The default approach is to create an injector when the servlet is started and to register it in the IResourceServiceProvider.Registry. In order to override the default behavior, you can change or add bindings in the <LanguageName>WebModule or <LanguageName>IdeModule of your language.

      -

      The usual way to include the Xtext servlet in a server application is to create a subclass of XtextServlet, override init() and destroy() to manage the runtime resources, and add a WebServlet annotation with urlPatterns = "/xtext-service/*" as parameter. See MyXtextServlet for an example.

      +

      The usual way to include the Xtext servlet in a server application is to create a subclass of XtextServlet, override init() and destroy() to manage the runtime resources, and add a WebServlet annotation with urlPatterns = "/xtext-service/*" as parameter. See MyXtextServlet for an example.

      -

      If you want to implement your own communication channel to provide the language-specific services without using XtextServlet, you can do so by injecting an instance of XtextServiceDispatcher and calling getService(IServiceContext). The input to this method is an IServiceContext, which must be implemented to provide the request parameters and the client session. The return value is a descriptor that can be used to invoke the actual service. Furthermore, XtextServiceDispatcher can be subclassed in order to add custom services with access to the document AST and all related Xtext APIs.

      +

      If you want to implement your own communication channel to provide the language-specific services without using XtextServlet, you can do so by injecting an instance of XtextServiceDispatcher and calling getService(IServiceContext). The input to this method is an IServiceContext, which must be implemented to provide the request parameters and the client session. The return value is a descriptor that can be used to invoke the actual service. Furthermore, XtextServiceDispatcher can be subclassed in order to add custom services with access to the document AST and all related Xtext APIs.

      The following sections describe how to customize the standard services for web editors.

      Content Assist

      -

      Content assist proposals for cross-references are created by IdeCrossrefProposalProvider, while for other grammar elements IdeContentProposalProvider is used. In order to customize the proposals, create subclasses of these providers and register them in your IDE Guice module.

      +

      Content assist proposals for cross-references are created by IdeCrossrefProposalProvider, while for other grammar elements IdeContentProposalProvider is used. In order to customize the proposals, create subclasses of these providers and register them in your IDE Guice module.

      -

      IdeContentProposalProvider has one _createProposals(...) dispatch method for each type of grammar element. In most cases the best choice is to override the method for Assignments and to filter the correct assignments by comparing them with the instances in the generated GrammarAccess of your language. A proposal is submitted by creating and configuring an instance of ContentAssistEntry and passing it to the given acceptor. This entry class contains all information required to display the proposal in the web browser and to apply it to the document. Usually it is sent to the client in JSON format.

      +

      IdeContentProposalProvider has one _createProposals(...) dispatch method for each type of grammar element. In most cases the best choice is to override the method for Assignments and to filter the correct assignments by comparing them with the instances in the generated GrammarAccess of your language. A proposal is submitted by creating and configuring an instance of ContentAssistEntry and passing it to the given acceptor. This entry class contains all information required to display the proposal in the web browser and to apply it to the document. Usually it is sent to the client in JSON format.

      -

      The typical customization point for IdeCrossrefProposalProvider is the method createProposal(...), which is called for each element found by the scope provider. Here you can fine-tune the information to put into the ContentAssistEntry.

      +

      The typical customization point for IdeCrossrefProposalProvider is the method createProposal(...), which is called for each element found by the scope provider. Here you can fine-tune the information to put into the ContentAssistEntry.

      Semantic Highlighting

      -

      The default behavior of Xtext editors is to have no semantic highlighting (syntactic highlighting, e.g. for keywords and strings, is done on the client side as described in Syntax Highlighting). In order to add styling to your text, create a subclass of DefaultSemanticHighlightingCalculator and override highlightElement(...). Here you can mark text regions with CSS classes by submitting a text offset, a length, and the CSS class name to the given acceptor. You can specify the actual text style in a CSS file that is included by the web page containing the Xtext editor.

      +

      The default behavior of Xtext editors is to have no semantic highlighting (syntactic highlighting, e.g. for keywords and strings, is done on the client side as described in Syntax Highlighting). In order to add styling to your text, create a subclass of DefaultSemanticHighlightingCalculator and override highlightElement(...). Here you can mark text regions with CSS classes by submitting a text offset, a length, and the CSS class name to the given acceptor. You can specify the actual text style in a CSS file that is included by the web page containing the Xtext editor.

      Mark Occurrences

      -

      The service for marking occurrences of a selected element is handled by OccurrencesService. Here you can override filter(EObject) to exclude some elements from this service. The actual text regions to be marked are computed automatically from the cross-references present in the model.

      +

      The service for marking occurrences of a selected element is handled by OccurrencesService. Here you can override filter(EObject) to exclude some elements from this service. The actual text regions to be marked are computed automatically from the cross-references present in the model.

      Hover Information

      The information displayed for mouse hover popups is created in HTML format and consists of two parts: a title and a description.

      -

      The title is composed of a text label and an image. The label is computed by the INameLabelProvider, and the default is the value of the name property of an element, if it exists. The image is determined by an implementation of IImageDescriptionProvider. The default behavior is to generate a <div> and annotate it with a CSS class of the form <class>-icon, where <class> is the name of the EClass of the corresponding element. The actual images can be assigned to these classes in a CSS file using the background-image CSS property.

      +

      The title is composed of a text label and an image. The label is computed by the INameLabelProvider, and the default is the value of the name property of an element, if it exists. The image is determined by an implementation of IImageDescriptionProvider. The default behavior is to generate a <div> and annotate it with a CSS class of the form <class>-icon, where <class> is the name of the EClass of the corresponding element. The actual images can be assigned to these classes in a CSS file using the background-image CSS property.

      -

      The description part of the hover popup is determined by the IEObjectDocumentationProvider. For this part the default content is fetched from the comments in the document: if the definition of the element is preceded by a multi-line comment (e.g. /* ... */), the content of that comment is used as description.

      +

      The description part of the hover popup is determined by the IEObjectDocumentationProvider. For this part the default content is fetched from the comments in the document: if the definition of the element is preceded by a multi-line comment (e.g. /* ... */), the content of that comment is used as description.

      Persistence

      -

      Without further adaptation the Xtext server does not provide any persistence functionality. As described in the Getting the Text Content section, there are multiple ways to fill the web editor with text. If you would like to use the persistence service included in the Xtext server, you need to implement IServerResourceHandler. The get and put operations declared in that interface should delegate to the persistence layer you would like to connect. For a simple example see FileResourceHandler.

      +

      Without further adaptation the Xtext server does not provide any persistence functionality. As described in the Getting the Text Content section, there are multiple ways to fill the web editor with text. If you would like to use the persistence service included in the Xtext server, you need to implement IServerResourceHandler. The get and put operations declared in that interface should delegate to the persistence layer you would like to connect. For a simple example see FileResourceHandler.


      diff --git a/org.eclipse.xtext.doc/contents/340_lsp_support.html b/org.eclipse.xtext.doc/contents/340_lsp_support.html index 3ff5740f9a2..1b6c7a52b63 100644 --- a/org.eclipse.xtext.doc/contents/340_lsp_support.html +++ b/org.eclipse.xtext.doc/contents/340_lsp_support.html @@ -236,7 +236,7 @@

      Language Features

      Unit Testing

      -

      Automated tests are crucial for the maintainability and the quality of a software product. That is why it is strongly recommended to write unit tests for your language server, too. Xtext provides the org.eclipse.xtext.testing.AbstractLanguageServerTest base class that comes in handy when implementing automated LSP unit tests. The org.eclipse.xtext.ide.tests.server package contains JUnit test cases for almost all supported language features. Feel free to study them to get some inspirations on how to implement automated unit tests for your Xtext-based language server.

      +

      Automated tests are crucial for the maintainability and the quality of a software product. That is why it is strongly recommended to write unit tests for your language server, too. Xtext provides the org.eclipse.xtext.testing.AbstractLanguageServerTest base class that comes in handy when implementing automated LSP unit tests. The org.eclipse.xtext.ide.tests.server package contains JUnit test cases for almost all supported language features. Feel free to study them to get some inspirations on how to implement automated unit tests for your Xtext-based language server.

      Next Chapter: Continuous Integration

      diff --git a/org.eclipse.xtext.doc/contents/images/LSP_04B_AddTextMateGrammarFile.png b/org.eclipse.xtext.doc/contents/images/LSP_04B_AddTextMateGrammarFile.png new file mode 100644 index 0000000000000000000000000000000000000000..903d85b8d1583e8dbc95e078755be516c83e6f36 GIT binary patch literal 120384 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

      9pu=ek(${) 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�FlUz}uD5K}#aIpUeZ+ro2y+QA={xHLru=%R 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