How do you use code fragment mode in the Intellij debugger? - intellij-idea

In the debugger, you can press alt-f8 and evaluate an expression.
There's also a code fragment mode. The documentation in IntelliJ only says:
Code Fragment Mode for evaluating short code portions introducing them
in the Statements to evaluate text field. Supported constructs are
declarations, assignments, loops and if/else.
I can't find any examples on the web of how to use it and can't figure out myself.
Can you give examples of how to use the supported constructs?

Given
public class CodeFragment {
public static void main(String[] args) {
List<Foo> list = new ArrayList<Foo>();
list.add(new Foo("555"));
list.add(new Foo("777"));
list.add(new Foo("999"));
list.add(new Foo("bill"));
System.out.println();
}
public static class Foo {
String s;
public Foo(String s) {
this.s = s;
}
}
}
If we set a break point on the println, we can put the following into the code fragment
Foo resultFoo = null;
Iterator<Foo> it = list.iterator();
while (it.hasNext()) {
Foo foo = it.next();
if (foo.s.equals("777")) {
resultFoo = foo;
}
}
resultFoo = resultFoo;
This demonstrates declaration, assignment, a loop, and an if.
Note that the foreach loop is not supported, in older versions of intellij!
Also note the assignment at the end. As far as I can tell, the result that gets displayed is the result of the last statement. Without that last statement, this code would display 'false' - ie the result of the last call to it.next.

Related

JMockit Expectation for constructor with List parameters

Have no issues to mock constructor with non-list parameter but I cannot figure out how to mock constructor with List parameters in Expectations section.
Tested code:
public Mono<ParameterObject> create(UUID id, List<Foo> foos) {
return Mono.just(foos)
.zipWith(barRepository.findSomething(id).collectList())
.map(function((foos, bars)-> new ParameterObject(foos, bars)));
}
Test:
#Test
void testMe(#Injectable ParameterObject parameterObject) {
var foos = List.of(new Foo());
var bar = new Bar();
new Expectations(ParameterObject.class) {{
barRepository.findBySomething(ID);
result = Flux.just(bar);
new ParameterObject(foos, List.of(bar));
//new ParameterObject(foos, (List<Bar>) any)); // also won't work - still different instances` references
//new ParameterObject((List<Foo) any, (List<Bar>) any)); // also won't work - still different instances` references
result = parameterObject;
}};
StepVerifier.create(subject.create(ID, foos))
.expectNext(parameterObject)
.verifyComplete();
}
Result:
expected value: com.package.ParameterObject#662773f8;
actual value: com.package.ParameterObject#1c375a0b
As we might see there is difference in ParametObject instances` references.
It means our ParameterObject constructor mock wasn't even invoked.
What I do wrong here?
You're going down a weird road in your expectations block where it looks like you are trying to mock the constructor when certain parameters are supplied. Mocking constructors is something that can be done, but it's tricky and has special syntax. See the docs if you really want to go that way.
That said, there are 2 easier solutions.
1.) mock "create(..)" to just return parameterObject. Since you are trying to test the behavior of create(..), this is not for you, but may work in other situations.
2.) In your class-under-test, extract the "new ParameterObject(..)" piece of the lambda to a separate method, such that the lambda calls the "new"-method and the "new"-method does the actual new. Have 1 test that tests the lambda (with the "new"-method mocked) and a 2nd test that just tests the 'new'-method
public Mono<ParameterObject> create(UUID id, List<Foo> foos) {
return Mono.just(foos)
.zipWith(barRepository.findSomething(id).collectList())
.map(function((foos, bars)-> construct(foos,bars)));
}
public void construct(List<Foo> foos, List<Bar> bars) {
new ParameterObject(foos, bars)
}
#Test
void testMe(#Injectable ParameterObject parameterObject) {
var foos = List.of(new Foo());
var bar = new Bar();
new Expectations(ParameterObject.class) {{
barRepository.findBySomething(ID);
result = Flux.just(bar);
construct((List<Foo) any, (List<Bar>) any));
result = parameterObject;
}};
StepVerifier.create(subject.create(ID, foos))
.expectNext(parameterObject)
.verifyComplete();
}

how to get the fully qualified name of a method call when it exists in the source code using javaparser

My test code to excercise various functions of JavaParser:
public class test001 {
public static void main(String[] args) {
test001 t = new test001();
t.run();
}
#sample.mkGetSet
int g1;
#sample.start
test001(){
g1 = 14;
}
#sample.funky
void run() {
#sample.flagVar
int a,b,c;
a=1;
b=2;
c=a+b;
c=c+g1;
System.out.println("result:"+c);
}
}
My code correctly notes that I call println in the method run.
Is there a fairly easy way to get the 'System.out.' part in addition to the println part?
In the case where the qualification is not there, I dont need it but if it is i would like it.
The type of answer I'm looking for is along the line of 'In the MethodCallExpr look at XXXXX' (with the obligatory admonition to RTFD)
I've been over the documentation and its still not clear how to do this - or if i even can.

Java Setter Using User Input

To make sure this doesn't get closed, read this. This isn't a duplicate post because the only other user input setter is in C or c something and if not that it's for a completly different application. How can I set up my setWord method to use user input and not be null. My current code gives off a null pointer because the variable is null, but I can't find out a viable way to set it's value using user input. Current code: Subclass:
package hangman;
public class Hangman {
private String word;
public void setWord(String word) {
this.word = toString();
}
public String getWord() {
return this.word;
}
#Override
public String toString() {
System.out.println("Enter secret word: ");
return (this.getWord());
}
}
Main
public static void main(String[] args) {
Hangman hangman = new Hangman();
hangman.setWord();
String secretWord = hangman.getWord();
StringBuilder b = new StringBuilder(secretWord.length());
}
Again, the issue is that I can't find a way to set the private String "word" to user input without it ending up being null. Please dont mark this as duplicate I already looked at the generic cookie cutter nullpointerexception threads but haven't helped me at all. I've been stuck on this and it's my last part of my program. The null pointer is always at the stringbuilder, which suggests that secretWord is null.
Think about it: where do you ever set the word? setWord assigns the return of toString, which returns the result of getWord, but getWord just returns what this.word already was! Nowhere do you ever set a word, so it's never initialized! You just set this.word to what it was originally, which was null. This causes an NPE when you call secretWord.length(), since secretWord is null.
You have another problem, which I'm assuming is a typo here, where your call to setWord in your main isn't given an argument. That's illegal and creates an error of its own, so it should never reach the StringBuilder line.
Change setWord to:
public void setWord(String word) {
this.word = word; ; Set it to its argument
}
Then call it with a word as the argument:
hangman.setWord("Word");
Originally I had a toString which served no functional purpose. And the setWord method required a parameter which I didn't have so to fix it I replaced the setWord code with this
public void setWord() {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the secret word: (Under 7 letters)");
this.word = scan.nextLine();
this.word = word;
}

ArrayList method is creating an error upon calling

Hello everyone I'm tying to create a method that receives a list of string values and returns the list in reverse. The for loop is supposed to traverse the values in reverse order, starting with the last element. I'm getting an error message when I try to call the method in the main method, I don't know what argument to pass. Here is my code.
enter code here :import java.util.*;
public class ThisList
{
public static void main (String[] args)
{
list(ArrayList<String> words);
}
public static ArrayList<String> list(ArrayList<String> words)
{
ArrayList<String> phrase =new ArrayList<String>();
words.add("before");
words.add("gone");
words.add("has");
words.add("man");
words.add("no");
words.add("where");
words.add("go");
words.add("bodly");
words.add("To");
for(int i= words.size()-1; i>= 0; i--)
{
phrase.add(words.get(i));
}
return phrase;
}
}
Your problem lies in how you are calling your list() function in main, specifically in how you are improperly sending in your argument. You should not declare/initialize an object in the calling of a function. It is syntactically incorrect, plus how would you access it afterwards? Even if it was possible to declare an object in the calling of the function, the words array is also uninitialized when you are trying to use it. Also, your function list() is returning an ArrayList. You are not setting an ArrayList in your main() function to be set to the returning ArrayList(phrase) from list().
I would advise looking over Object-Oriented programming basics and a few beginner Java tutorials so you can get a better understanding to be able to solve this kind of problem on your own.
http://docs.oracle.com/javase/tutorial/java/concepts/
Below is the code you posted, with the proper way to call your function. If this is what you need, do not forget to upvote and select this answer as the correct one! (Upvote by pressing the up arrow next to the post, and accept answer by clicking the checkmark next to the post so that it turns green).
import java.util.*;
public class ThisList
{
public static void main (String[] args)
{
ArrayList<String> words = new ArrayList<String>();
ArrayList<String> phrase_returned = list(words);
}
public static ArrayList<String> list(ArrayList<String> words)
{
ArrayList<String> phrase =new ArrayList<String>();
words.add("before");
words.add("gone");
words.add("has");
words.add("man");
words.add("no");
words.add("where");
words.add("go");
words.add("bodly");
words.add("To");
for(int i= words.size()-1; i>= 0; i--)
{
phrase.add(words.get(i));
}
return phrase;
}
}

How to tell IDEA/Studio that the null check has been done?

I'm developing with Android Studio/IntelliJ IDEA.
I have enabled the inspection check called "Constant conditions & exceptions" that shows a warning if I am risking a NPE, such as:
String foo = foo.bar(); // Foo#bar() is #nullable
if (foo.contains("bar")) { // I'm living dangerously
...
}
I have the following in my code:
String encoding = contentEncoding == null ? null : contentEncoding.getValue();
if (!TextUtils.isEmpty(encoding) && encoding.equalsIgnoreCase("gzip")) {
inputStream = new GZIPInputStream(entity.getContent());
} else {
inputStream = entity.getContent();
}
Here's the source code of TextUtils#isEmpty(String):
/**
* Returns true if the string is null or 0-length.
* #param str the string to be examined
* #return true if str is null or zero length
*/
public static boolean isEmpty(CharSequence str) {
if (str == null || str.length() == 0)
return true;
else
return false;
}
I'm not risking any NPE because TextUtils#isEmpty(String) would return true to a null pointer.
However I'm still getting the little Method invocation 'encoding.equalsIgnoreCase("gzip")' may produce 'java.lang.NullPointerException' warning, which can be annoying.
Is it possible to make this check smarter and ignore the NPE warning if there's already a null-check done?
You can look into the link that Peter Gromov mention in his answer.
Created some simple classes that resemble your setup:
A class with a method annotated with #Nullable:
The TextUtil class with it's isEmpty method:
And finally the main class calling the TextUtil#isEmpty:
Now if you enter the File -> Settings... and go to Inspections ->Constant conditions & exceptions part you can change the Configure Assert/Check Methods to cater for your isEmpty method:
Add a new IsNull check method:
Enter the TextUtil class, isEmpty method and CharSequence parameter:
This gives this Assert/Check Method Configuration window:
Press Ok and then Ok again to go back to the editor view and you'll see that the inspection disappeared:
You are actually telling IntelliJ that the isEmpty method is doing a null check on the str parameter.
You could use //noinspection ConstantConditions that will remove the NPE warning for the following line, like this:
String encoding = contentEncoding == null ? null : contentEncoding.getValue();
//noinspection ConstantConditions
if (!TextUtils.isEmpty(encoding) && encoding.equalsIgnoreCase("gzip")) {
inputStream = new GZIPInputStream(entity.getContent());
} else {
inputStream = entity.getContent();
}
You can use #SuppressWarnings("ConstantConditions") annotation.
#SuppressWarnings("ConstantConditions")
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int indexViewType) {
if (inflater == null) {
inflater = LayoutInflater.from(parent.getContext());
}
ItemViewProvider provider = getProviderByIndex(indexViewType);
provider.adapter = MultiTypeAdapter.this;
return provider.onCreateViewHolder(inflater, parent);
}
Select "TextUtils.isEmpty".
Right Click -> Show Context Actions -> Add Method Contract.
Enter "null -> true".
Save the configuration xml.
Please check the details here
See http://www.jetbrains.com/idea/webhelp/configuring-check-assert-methods.html for IDEA 12.
In IDEA 13 EAP, you can add method contract: http://youtrack.jetbrains.com/issue/IDEA-93372
Unfortunately marked as "right answer" solution is of date. But I found equivalent for me solution.
The new versions of IDE work correctly with static methods. So the example from the question won't throw warning anymore.
TextUtils#isEmpty(String);
public static boolean isEmpty(CharSequence str) {
// your checks
}