Compatibility is a complex issue, but we do our best to maintaining three types of compatibilities between any two sequential versions of SSLR (e.g. between 1.17 and 1.18, but not between 1.16 and 1.18):
- binary compatibility: we don't guarantee that your code can be linked with new version without recompilation, however for most releases this might be possible;
- source compatibility: in most cases (see below) you should be able to recompile your code with a newer version of SSLR without any changes;
- behavioral compatibility: in most cases (see below) your code will behave exactly as it did with the previous version of SSLR without any changes.
We can't guarantee that your code can be compiled or linked with new version of SSLR and behave exactly as before the upgrade in the following situations:
- You use internal classes or interfaces, i.e. those that are located under package "org.sonar.sslr.internal".
- You create instances or subclasses of classes, which are not intended for this. Such classes are marked by Javadoc ("This class is not intended to be instantiated or subclassed by clients").
- You implement interfaces which are not intended for this. Such interfaces are marked by Javadoc ("This interface is not intended to be implemented by clients").
- You use methods marked as internal. Such methods are marked by annotation "@VisibleForTesting" or by Javadoc ("For internal use only").
- You use beta code. Such code is marked by annotation "@Beta".
- You use deprecated code. Such code is marked by annotation "@Deprecated" and Javadoc.
We try to maintain deprecated code as long as possible, but generally it may be removed in a the release after the one in which it was marked as deprecated. That's why we highly recommend not to jump over two versions at once, but perform upgrades in several steps - one version per step. Each such step should include the removal of uses of deprecated code. Thus, it is recommended to upgrade as soon as a new version is available.
Recommended upgrade steps:
- Recompile your code with the next version of SSLR. If it can't be compiled, then don't hesitate to inform us.
- Check release notes and upgrade notes for the existence of behavioral incompatibilities (see below). If there are any, you should fix them by following the instructions in the notes. Good coverage of your code by unit tests is highly recommended (SonarQube can help you to enforce this), so you will be able to perform tests to verify that it behaves exactly as before upgrade. If not, then don't hesitate to ask for help.
- Remove uses of deprecated code by following the instructions you'll find in the deprecation Javadocs (SonarQube can help you to find such code). And don't forget to execute tests to verify that regressions were not introduced by such changes.
Sincerely yours, SonarSource Language Team.
- Source: Deprecated hamcrest matchers were removed in preference to Fest-assertions.
- Behavioral: No difference between usual grammar rule and "recovery rule" - both will be presented in AST and so can be handled via AST visitor. Thus ParseErrorCheck in SonarQube plugins must be reworked, if plugin uses "recovery rule".
- Behavioral: Modifications made in grammar do not affect lexerless parser, which was created before those modifications.
- Behavioral: Previously was possible to execute parser with grammar, which contains references on undefined rules, but now this is forbidden.
- Deprecation: Old ways to construct Grammars were marked as deprecated - use Builders instead.
- If you extend "org.sonar.sslr.toolkit.AbstractConfigurationModel", then make sure to override method "getCharset".
- Migration to new Grammar API is highly recommended, because most likely old API will be marked as deprecated in next release and fully removed later. Tip on migration: create new grammar (all tests pass as they don't depend on this grammar), migrate tests for grammar (they should pass), migrate the rest (AST Visitors and so on).
- For lexerful grammar tests, setRootRule() can still be used, but Grammar.rule() must be called
- Replace the calls to mock() by override("rule name"), do this before you change the names of all your rules
- To refactor the previous rule names (camel case) to the enum naming convention (all caps and underscores), do: 1) For all rules, insert the underscores by using the Eclipse rename binding, 2) then, for all rules, apply the rename binding immediately followed by the "to upper case" one. Don't hesitate to commit in the middle in order to secure your changes, as Eclipse might go havoc...
- Behavioral: UnknownCharacterChannel can't be used to consume BOM character - use new BOMCharacterChannel.
- Behavioral: In grammars for lexerless parsing no need to use "GrammarOperators.token", but mandatory to use "GrammarOperators.commentTrivia" for comments and "GrammarOperators.skippedTrivia" for white spaces.
- Deprecation: Some methods for navigation in AstNode. Especially pay attention on "hasChildren" and "findChildren".
- Deprecation: The toolkit parser and list of tokenizers is no more provided to the constructor of the "Toolkit" class. Instead, one must extend the "AbstractConfigurationModel" class, where the "doGetParser()" and "doGetTokenizer()" methods will be called when a parser for the current configuration is needed.
- Distribution of Toolkit should embed "com.google.guava:guava" instead of "com.google.collections:google-collections" and thus it will have bigger size.
- Deprecation: Replace "GrammarFunctions.Standard.or(" by "GrammarFunctions.Standard.firstOf(". In most cases you should be able to do this by using "find text and replace".
- Deprecation: Replace the hamcrest parse() and notParse() matches by Fest ones: Use a global regular expression based find & replace: "assertThat\(p, parse\((.*?)\)\);" by ".matches\($1\)" and add the assertThat(Parser) and final semicolon manually. Do the same for notParse().
- Source: Replace artifactId "sslr-devkit" by "sslr-toolkit".