The parameter `RuleFunction rf` in `ActionTranslater#translateActionChunk` may be `null`.
The method's implementation takes care of this by checking `rf` before making its `ruleCtx` the translator's nodeContext:
```
if ( rf!=null ) translator.nodeContext = rf.ruleCtx;
```
However in the statement following this code the check for `rf!=null` is missing. This will lead to a `NullPointerException` when `altLabel` is defined and `rf` is `null`:
```
if ( altLabel!=null ) translator.nodeContext = rf.altLabelCtxs.get(altLabel);
```
To avoid the problem only access `rf.altLabelCtxs` when `rf` is not null:
```
if ( rf!=null ) {
translator.nodeContext = rf.ruleCtx;
if ( altLabel!=null ) translator.nodeContext = rf.altLabelCtxs.get(altLabel);
}
```
After loading and casting the parserClass in TestRig#process using
`cl.loadClass(parserName).asSubclass(Parser.class)` there is a check if
the class returned by `#asSubclass` is not null:
```
parserClass = cl.loadClass(parserName).asSubclass(Parser.class);
if ( parserClass==null ) {
System.err.println("Can't load "+parserName);
}
```
The method `#asSubclass` will never return `null`, but throw an
`ClassCastException` when the cast is not valid, therefore the check
can be removed.
See also: [TestRig#process Documentation](http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#asSubclass(java.lang.Class\))
The `selectedTree.getSelectionPath()` return null if nothing is selected.
Added check to avoid NPE:
```java
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at org.antlr.v4.gui.TreeViewer$4.valueChanged(TreeViewer.java:376)
at javax.swing.JTree.fireValueChanged(JTree.java:2921)
at javax.swing.JTree$TreeSelectionRedirector.valueChanged(JTree.java:3382)
at javax.swing.tree.DefaultTreeSelectionModel.fireValueChanged(DefaultTreeSelectionModel.java:635)
at javax.swing.tree.DefaultTreeSelectionModel.notifyPathChange(DefaultTreeSelectionModel.java:1093)
at javax.swing.tree.DefaultTreeSelectionModel.removeSelectionPaths(DefaultTreeSelectionModel.java:502)
at javax.swing.JTree.removeDescendantSelectedPaths(JTree.java:3714)
at javax.swing.JTree.setExpandedState(JTree.java:3597)
at javax.swing.JTree.collapsePath(JTree.java:2231)
at javax.swing.plaf.basic.BasicTreeUI.toggleExpandState(BasicTreeUI.java:2297)
at javax.swing.plaf.basic.BasicTreeUI.handleExpandControlClick(BasicTreeUI.java:2273)
at javax.swing.plaf.basic.BasicTreeUI.checkForClickInExpandControl(BasicTreeUI.java:2231)
at javax.swing.plaf.basic.BasicTreeUI$Handler.handleSelection(BasicTreeUI.java:3600)
at javax.swing.plaf.basic.BasicTreeUI$Handler.mousePressed(BasicTreeUI.java:3548)
at java.awt.Component.processMouseEvent(Component.java:6524)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6292)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4883)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4530)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
at java.awt.Container.dispatchEventImpl(Container.java:2278)
at java.awt.Window.dispatchEventImpl(Window.java:2739)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:719)
at java.awt.EventQueue$4.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
```
The help and error message from the TestRig program refers to the old `runtime.misc` instead of the new `gui` package:
```
java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName
[-tokens] [-tree] [-gui] [-ps file.ps] [-encoding encodingname]
[-trace] [-diagnostics] [-SLL]
[input-filename(s)]
Use startRuleName='tokens' if GrammarName is a lexer grammar.
Omitting input-filename makes rig read from stdin.
```
These sync calls are truly redundant - when we are in a simple
alternative block, we can recover sufficiently with `recoverInline`, and
so the syncs do not add anything.
This commit enables the runtime test generator during the Maven build,
process which means the Java runtime receives the same comprehensive
testing during a Maven build as it does during a build with bild.py.
- A profile "rts" has been created which runs the integration tests. By default the the project containing the runtimes tests will not run so that users casually checking out and building the project do not have to install the tools required to test all the supported Antlr targets.
- The base test classes that are required for running the integration tests are downloaded from the other Antlr repos, dynamically added to the compile classpath and used by the currently checked in integration tests
To run the the full build with all the integration tests use the following:
mvn clean install -Prts
Account for the following:
- deploying snapshots to OSSRH
- releasing to Maven Central
- Shaded JAR including the treelayout dependency
- OSGi manifest
- remove Eclipse IDE metadata for clean import
- remove IDEA IDE metadata for clean import
recoverInline should handle making sure that the token stream is
advanced to the appropriate position. It is difficult for the caller to
do that, as recoverInline may create a "new" token that is not actually
in the stream.