Anyone know of a way of getting rid of the "empty block should be documented" warning in generated files when using ANTLR. I know I can disable the warning in Eclipse but I would like to keep it enabled and I like having a clean compile.
PathBaseListener.java
#Override public void enterPath(#NotNull PathParser.PathContext ctx) { }
So I think, you have to insert a command. E.g.:
#Override
public void enterPath(#NotNull PathParser.PathContext ctx){
/* not implemented */
}
Related
I'm making a basic IntelliJ plugin that lets a user define Run Configuration (following the tutorial at [1]), and use said Run Configurations to execute the file open in the editor on a remote server.
My Run Configuration is simple (3 text fields), and I have it all working, however, after editing the Run Configuration, and click "Apply" or "OK" after changing values, the entered values are lost.
What is the correct way to persist and read-back values (both when the Run Configuration is re-opened as well as when the Run Configuration's Runner invoked)? It looks like I could try to create a custom persistence using [2], however, it seems like the Plugin framework should have a way to handle this already or at least hooks for when Apply/OK is pressed.
[1] https://www.jetbrains.org/intellij/sdk/docs/tutorials/run_configurations.html
[2] https://www.jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html
Hopefully, this post is a bit more clear to those new to IntelliJ plugin development and illustrates how persisting/loading Run Configurations can be achieved. Please read through the code comments as this is where much of the explanation takes place.
Also now that SettingsEditorImpl is my custom implementation of the SettingsEditor abstract class, and likewise, RunConfigurationImpl is my custom implementation of the RunConfigiration abstract class.
The first thing to do is to expose the form fields via custom getters on your SettingsEditorImpl (ie. getHost())
public class SettingsEditorImpl extends SettingsEditor<RunConfigurationImpl> {
private JPanel configurationPanel; // This is the outer-most JPanel
private JTextField hostJTextField;
public SettingsEditorImpl() {
super();
}
#NotNull
#Override
protected JComponent createEditor() {
return configurationPanel;
}
/* Gets the Form fields value */
private String getHost() {
return hostJTextField.getText();
}
/* Copy value FROM your custom runConfiguration back INTO the Form UI; This is to load previously saved values into the Form when it's opened. */
#Override
protected void resetEditorFrom(RunConfigurationImpl runConfiguration) {
hostJTextField.setText(StringUtils.defaultIfBlank(runConfiguration.getHost(), RUN_CONFIGURATION_HOST_DEFAULT));
}
/* Sync the value from the Form UI INTO the RunConfiguration which is what the rest of your code will interact with. This requires a way to set this value on your custom RunConfiguration, ie. RunConfigurationImpl##setHost(host) */
#Override
protected void applyEditorTo(RunConfigurationImpl runConfiguration) throws ConfigurationException {
runConfiguration.setHost(getHost());
}
}
So now, the custom SettingsEditor, which backs the Form UI, is set up to Sync field values In and Out of itself. Remember, the custom RunConfiguration is what is going to actually represent this configuration; the SettingsEditor implementation just represents the FORM (a subtle difference, but important).
Now we need a custom RunConfiguration ...
/* Annotate the class with #State and #Storage, which is used to define how this RunConfiguration's data will be persisted/loaded. */
#State(
name = Constants.PLUGIN_NAME,
storages = {#Storage(Constants.PLUGIN_NAME + "__run-configuration.xml")}
)
public class RunConfigurationImpl extends RunConfigurationBase {
// Its good to 'namespace' keys to your component;
public static final String KEY_HOST = Constants.PLUGIN_NAME + ".host";
private String host;
public RunConfigurationImpl(Project project, ConfigurationFactory factory, String name) {
super(project, factory, name);
}
/* Return an instances of the custom SettingsEditor ... see class defined above */
#NotNull
#Override
public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
return new SettingsEditorImpl();
}
/* Return null, else we'll get a Startup/Connection tab in our Run Configuration UI in IntelliJ */
#Nullable
#Override
public SettingsEditor<ConfigurationPerRunnerSettings> getRunnerSettingsEditor(ProgramRunner runner) {
return null;
}
/* This is a pretty cool method. Every time SettingsEditor#applyEditorTo() is changed the values in this class, this method is run and can check/validate any fields! If RuntimeConfigurationException is thrown, the exceptions message is shown at the bottom of the Run Configuration UI in IntelliJ! */
#Override
public void checkConfiguration() throws RuntimeConfigurationException {
if (!StringUtils.startsWithAny(getHost(), "http://", "https://")) {
throw new RuntimeConfigurationException("Invalid host");
}
}
#Nullable
#Override
public RunProfileState getState(#NotNull Executor executor, #NotNull ExecutionEnvironment executionEnvironment) throws ExecutionException {
return null;
}
/* This READS any prior persisted configuration from the State/Storage defined by this classes annotations ... see above.
You must manually read and populate the fields using JDOMExternalizerUtil.readField(..).
This method is invoked at the "right time" by the plugin framework. You dont need to call this.
*/
#Override
public void readExternal(Element element) throws InvalidDataException {
super.readExternal(element);
host = JDOMExternalizerUtil.readField(element, KEY_HOST);
}
/* This WRITES/persists configurations TO the State/Storage defined by this classes annotations ... see above.
You must manually read and populate the fields using JDOMExternalizerUtil.writeField(..).
This method is invoked at the "right time" by the plugin framework. You dont need to call this.
*/
#Override
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
JDOMExternalizerUtil.writeField(element, KEY_HOST, host);
}
/* This method is what's used by the rest of the plugin code to access the configured 'host' value. The host field (variable) is written by
1. when writeExternal(..) loads a value from a persisted config.
2. when SettingsEditor#applyEditorTo(..) is called when the Form itself changes.
*/
public String getHost() {
return host;
}
/* This method sets the value, and is primarily used by the custom SettingEditor's SettingsEditor#applyEditorTo(..) method call */
public void setHost(String host) {
this.host = host;
}
}
To read these configuration values elsewhere, say for example a custom ProgramRunner, you would do something like:
final RunConfigurationImpl runConfiguration = (RunConfigurationImpl) executionEnvironment.getRunnerAndConfigurationSettings().getConfiguration();
runConfiguration.getHost(); // Returns the configured host value
See com.intellij.execution.configurations.RunConfigurationBase#readExternal as well as com.intellij.execution.configurations.RunConfigurationBase#loadState and com.intellij.execution.configurations.RunConfigurationBase#writeExternal
I noticed that when I hover my mouse over a local variable when my debugger is stopped inside a lambda it will report Cannot find local variable 'variable_name' even if it's visible inside the lambda and it's used.
Example code
public class Main {
public static void main(String[] args) {
String a = "hello_world";
m1(a);
}
private static void m1(String a) {
AccessController.doPrivileged((PrivilegedAction<String>) () -> {
System.out.println("blala " + a);
return "abc";
});
}
}
Try with a breakpoint in System.out.println("blala " + a); and after return "abc" and it always report the same error.
I used AccessController.doPrivileged because it's what I used in my original code and of course i'm using Java 8.
It says the same thing in Watchers and Evaluate Expression.
I tried using the "anonymous class" version and the debugger sees the value of a correctly
private static void m1(String a) {
AccessController.doPrivileged(new PrivilegedAction<String>() {
#Override
public String run() {
System.out.println("blala " + a);
return "abc";
}
});
}
I'm missing something about lambda expressions or it's an IntellIJ IDEA 14 bug?
I don't want to report the bug right now because I already reported a bug that was caused by my code instead of IntellIJ IDEA, so I want to be sure before do something (and because I don't use Java 8 so often, so I could be wrong).
This appears to be a know issue. According to JetBrains the root causes of this behavior is with the JDK. For more info see: IDEA-126257
I can confirm what is written in IDEA bug report linked by Mike Rylander: this is a JDK bug and update to version 8u60_25 of the JDK solves it.
I am just getting started with Arquillian Warp and seems to have hit a stumbling block.
I have a basic UI Test for a registration page
#WarpTest
#RunWith(Arquillian.class)
public class TestProfileEdit extends AbstractUsersTest {
#Drone
FirefoxDriver browser;
#Page
EditProfilePage editProfilePage;
#Page
LoginPage loginPage;
#ArquillianResource
private URL baseURL;
#Deployment
public static Archive<?> createLoginDeployment() throws IOException {
// trimmed for brevity
}
#Before
public void setup() throws MalformedURLException{
final URL loginURL = new URL(baseURL, "login.jsf");
browser.navigate().to(loginURL);
loginPage.login("test#domain.com", "password");
final URL pageURL = new URL(baseURL, "profile/edit.jsf");
System.out.println(pageURL.toExternalForm());
browser.navigate().to(pageURL);
}
#After
public void tearDown() {
browser.manage().deleteAllCookies();
}
#Test
#RunAsClient
public void testSaveData() {
editProfilePage.getDialog().setFirstName("Test First Name");
Warp.execute(new ClientAction() {
#Override
public void action() {
editProfilePage.getDialog().save();
}
}).verify(new TestProfileOnServer());
}
#SuppressWarnings("serial")
public static class TestProfileOnServer extends ServerAssertion {
#Inject
private EntityManager em;
#Inject
private Identity identity;
#Inject
Credentials credentials;
#AfterPhase(Phase.RENDER_RESPONSE)
public void testSavedUserProfile() {
System.out.println("RUNNING TEST");
String username = identity.getUser().getId();
TypedQuery<UserProfile> q = em.createQuery(
"SELECT u from UserProfile u where u.userIdentity.name like :username", UserProfile.class);
UserProfile p;
p = q.setParameter("username", username).getSingleResult();
assertEquals("Test First Name", p.getFirstName());
}
}
}
I have tried the various combinations on testSavedUserProfile() method with absolutely no luck in getting that to trigger.
The test always ends with
java.lang.IllegalStateException: java.util.concurrent.ExecutionException: org.jboss.arquillian.warp.client.execution.AssertionHolder$ServerResponseTimeoutException
I can see the page getting posted and redirected correctly on the firefox window that gets opened up. I tried to get it to not redirect etc. and nothing has helped.
I feel like I am missing something basic and simple but no idea what!
Any help much appreciated.
Thanks.
I've recently encountered a similar problem with Arquillian Warp.
One of the reasons my code didn't get called was that Arquillian merges the server-sde servlet filter into a web archive (WAR) deplyoment only. Neither EAR nor JAR deployments work off the shelf.
For my concrete problem (EAR deployment) I modified the test classes in a way that I merge in the Arquillian filter myself when assembling the tested WAR which in turn is packed into an EAR deployment.
The other problem I ran across was that the AfterServlet event is simply not fired within the unit test execution scope but as part of the servlet filter cleanup code. I believe this logic is totally broken and I build a private fork of the servlet filter which IMHO is handling the logic correctly.
I would like to catch any throwable during a Selenium test e.g. in order to make a screenshot. The only solution I could come up with for now is to separately surround the test steps with a try and catch block in every test method as following:
#Test
public void testYouTubeVideo() throws Throwable {
try {
// My test steps go here
} catch (Throwable t) {
captureScreenshots();
throw t;
}
}
I'm sure there is a better solution for this. I would like a higher, more centralized location for this try-catch-makeScreenshot routine, so that my test would be able to include just the test steps again. Any ideas would be greatly appreciated.
You need to declare a TestRule, probably a TestWatcher or if you want to define the rules more explicitly, ExternalResource. This would look something like:
public class WatchmanTest {
#Rule
public TestRule watchman= new TestWatcher() {
#Override
protected void failed(Description d) {
// take screenshot here
}
};
#Test
public void fails() {
fail();
}
#Test
public void succeeds() {
}
}
The TestWatcher anonymous class can of course be factored out, and just referenced from the test classes.
I solved a similar problem using Spring's AOP. In summary:
Declare the selenium object as a bean
Add an aspect using
#AfterThrowing
The aspect can take the screenshot and save it to a
file with a semirandom generated name.
The aspect also rethrows the exception, with the exception message including the filename so you can look at it afterwards.
I found it more helpful to save the HTML of the page due to flakiness of grabbing screenshots.
I've got a rule like this:
declaration returns [RuntimeObject obj]:
DECLARE label value { $obj = new RuntimeObject($label.text, $value.text); };
Unfortunately, it throws an exception in the RuntimeObject constructor because $label.text is null. Examining the debug output and some other things reveals that the match against "label" actually failed, but the Antlr runtime "helpfully" continues with the match for the purpose of giving a more helpful error message (http://www.antlr.org/blog/antlr3/error.handling.tml).
Okay, I can see how this would be useful for some situations, but how can I tell Antlr to stop doing that? The defaultErrorHandler=false option from v2 seems to be gone.
I don't know much about Antlr, so this may be way off base, but the section entitled "Error Handling" on this migration page looks helpful.
It suggests you can either use #rulecatch { } to disable error handling entirely, or override the mismatch() method of the BaseRecogniser with your own implementation that doesn't attempt to recover. From your problem description, the example on that page seems like it does exactly what you want.
You could also override the reportError(RecognitionException) method, to make it rethrow the exception instead of print it, like so:
#parser::members {
#Override
public void reportError(RecognitionException e) {
throw new RuntimeException(e);
}
}
However, I'm not sure you want this (or the solution by ire_and_curses), because you will only get one error per parse attempt, which you can then fix, just to find the next error. If you try to recover (ANTLR does it okay) you can get multiple errors in one try, and fix all of them.
You need to override the mismatch and recoverFromMismatchedSet methods to ensure an exception is thrown immediately (examples are for Java):
#members {
protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException {
throw new MismatchedTokenException(ttype, input);
}
public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException {
throw e;
}
}
then you need to change how the parser deals with those exceptions so they're not swallowed:
#rulecatch {
catch (RecognitionException e) {
throw e;
}
}
(The bodies of all the rule-matching methods in your parser will be enclosed in try blocks, with this as the catch block.)
For comparison, the default implementation of recoverFromMismatchedSet inherited from BaseRecognizer:
public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException {
if (mismatchIsMissingToken(input, follow)) {
reportError(e);
return getMissingSymbol(input, e, Token.INVALID_TOKEN_TYPE, follow);
}
throw e;
}
and the default rulecatch:
catch (RecognitionException re) {
reportError(re);
recover(input,re);
}