Java code - how to remove only annotated methods with script - java

I wonder if there is a way (a gradle script or any script or any other way without an IDE) to remove methods annotated with certain annotations. Example:
class x {
public static void main(String[] args) {
int x = getValue();
System.out.println(x);
}
#RemoveEnabled(id = "getValueMethod1", return = "10")
int getValue() {
return 20;
}
}
Now when I run the script or gradle target, it should remove the getValue() method, and the output code should become:
class x {
public static void main(String[] args) {
int x = 10;
System.out.println(x);
}
}
Is there an existing script or way to achieve this? It might be achievable with grep and String parsing etc., but I'm looking for a cleaner solution which is able to get all methods by an annotation id, and remove them with formatting. I tried searching on Google, Stack Overflow etc., but couldn't find a solution.

I wrote a module to process similiar task.
https://github.com/KnIfER/Metaline
#StripMethods(keys={"ToRemove","AlsoRemove"})
public class YourCLZ{
void ToRemove(){} // will be removed
void AlsoRemove(){} // will be removed
#StripMethods(strip=true)
void AnotherTest(){} // will also be removed
}
in your case
#StripMethods(keys="getValue")
class yourx {
public static void main(String[] args) {
int x = getValue();
System.out.println(x);
}
int getValue() {
return 20;
}
}
will become:
class yourx {
public static void main(String[] args) {
System.out.println(x);
}
}
you will get a compilation error since for now my module simply remove any methods or method body statements that contain the key you specified.

Related

How to get method signature (not method name) from Thread.currentThread().getStackTrace()?

Suppose I have the following methods and their invocations:
public static void main(String[] args) {zoo();}
public static void zoo() {zoo(0);}
public static void zoo(int i) {too(i);}
public static void too(int i) {...}
Thread.currentThread().getStackTrace() will return me with something like:
A.too(A.java:56)
A.zoo(A.java:65)
A.zoo(A.java:60)
A.main(A.java:80)
With this output, I cannot distinguish the 2 zoos I defined in my example, one without any parameter (zoo()) and one with an integer parameter (zoo(int i)). The reason is because only method names rather than their signatures are outputted. Is there a way to get a stack of method signatures?
The documentation of the StackTraceElement in Java 13 clearly shows that there is no way to do that. You can identify the overloaded method by its line number with your human brain. Automatizing this task would be overkill if even possible (would require using hard reflection), although I do not close out that some lib can do that.
Remark: the binary file format of the .class files actually has the method signature information (at least the parameter list), thus it is not impossible, only no one developed it until now.
You can not get the method signature from a StackTraceElement, but since you’re interested in getting the stack trace of the currentThread, you can use StackWalker instead. Since Java 10, it supports getting the method type from a StackFrame.
For example
public class StackWalkerExample {
public static void main(String[] args) {
zoo();
System.out.println();
Arrays.asList("foo", "bar").sort((a, b) -> { getMethods(); return 0; });
}
public static void zoo() {zoo(0);}
public static void zoo(int i) {too(i);}
public static void too(int i) { getMethods(); }
static void getMethods() {
var sw = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
var methods = sw.walk(frames ->
frames.skip(1).map(StackWalkerExample::toMethod).toArray(Method[]::new));
for(var m: methods) System.out.println(m);
}
static Method toMethod(StackWalker.StackFrame f) {
try {
return f.getDeclaringClass().getDeclaredMethod(
f.getMethodName(), f.getMethodType().parameterArray());
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
}
}
will print
public static void StackWalkerExample.too(int)
public static void StackWalkerExample.zoo(int)
public static void StackWalkerExample.zoo()
public static void StackWalkerExample.main(java.lang.String[])
private static int StackWalkerExample.lambda$0(java.lang.String,java.lang.String)
private static int java.util.TimSort.countRunAndMakeAscending(java.lang.Object[],int,int,java.util.Comparator)
static void java.util.TimSort.sort(java.lang.Object[],int,int,java.util.Comparator,java.lang.Object[],int,int)
public static void java.util.Arrays.sort(java.lang.Object[],java.util.Comparator)
public void java.util.Arrays$ArrayList.sort(java.util.Comparator)
public static void StackWalkerExample.main(java.lang.String[])
Details of the sorting implementation may vary

How do I call a method that has a variable passed through it?

I'm trying to call a method from within another method. I'm understanding this simply enough, until one of those methods needs a variable carried through, and then nothing I try works.
I know that I could do this in one method, but my coursework needs me to lay it out in such a way. Why doesn't this work?
public class test2 {
public static void testMethod() {
int randomNumber = 1;
}
public static void anotherTestMethod(int randomNumber) {
System.out.println(randomNumber);
}
public static void main(String[] args) {
anotherTestMethod();
}
}
You are calling a method that has an int parameter in its signature. You should pass that parameter when calling the method. I think you are trying to use a global variable, in that case, you should declare it outside any method, as a part of the class.
public class test2 {
public static int testMethod() {
int randomNumber = 1;
return randomNumber;
}
public static void anotherTestMethod() {
System.out.println(testMethod());
}
public static void main(String[] args) {
anotherTestMethod();
}
}

Testing a Calculator in JUnit 4 in Eclipse

I have this calculator .java from an online practice and I need to test it in JUnit in Eclipse;
package calculator;
import java.util.Scanner;
public class Calculator {
private double accumulator;
public Calculator() { }
public Calculator(double initialValue) { accumulator = initialValue; }
public void add(double number) { accumulator += number; }
public void subtract(double number) { accumulator -= number; }
public void multiply(double number) { accumulator *= number; }
public void divide(double number) { accumulator /= number; }
public void sqrt() { accumulator = Math.sqrt(accumulator); }
public void setAccumlator(double accumulator) { this.accumulator = accumulator; }
public double getAccumulator() { return accumulator; }
#Override
public String toString() { return "Result:" + accumulator; }
}
I've been pouring through documentation (I'm rather new to programming in general) and unsure of how to actually do this. I have JUnit set up and a test file set up, like;
#Test
public void testAdd(){
}
#Test
public void testDivideByZero(){
}
etc.
I've tried a few things and the syntax was wrong, stuff like
The method add(double) in the type Calculator is not applicable for the arguments (double, double)
or
Cannot make a static reference to the non static method add(double) from the type Calculator
Any suggestions?
Example of a test
private Calculator mCalculatorInstance;
#Before
public void setupTestEnvironment() {
// This method will be call before every single test.
mCalculatorInstance = new Calculator(2.0);
}
#Test
public void testAdd(){
mCalculatorInstance.add(2.0); // add 2 to the initial value of 2 which I instanitiate above should return 4.
assertEquals("Adding 2 to 2 should give me 4.", 4.0, c.getAccumulator());
}
In order to do testing, you need to know the expected output of the test. Let use the above test as scenario. I declared that I'm initializing a calculator object with accumulator value of 2.
mCalculatorInstance = new Calculator(2.0);
I know that using the add method of the instance will add the parameter to the accumulator. Hence I call the add method.
mCalculatorInstance.add(2.0);
So now I'm adding 2.0 to the accumulator which already have a value of 2.0
2.0 + 2.0 = 4.0
Since the object provide a method to get back the accumulator, I use the method to get back accumulator and check whether the addition is correct, the value of accumulator should be 4.0.
assertEquals("Adding 2 to 2 should give me 4.", 4.0, c.getAccumulator());

Newbie Java Programmer needs help involving for loops

I am just trying to create an example program to help me remember how to operate for loops, when I ran it through the compiler. The Compiler said missing return statement. Where do I add it?
Here is the code:
public class LoopExample {
public String bam() {
for (int i = 0; i < 8; i++) {
System.out.println(i);
}
}
}
EDIT
I received an answer, but now the main says 'cannot find symbol'... here is the code for the main:
public class LoopExampleTestDrive {
public static void main(String[] args) {
bam looper = new bam();
System.out.println(looper);
}
}
I would advise you to try to understand how Object Oriented languages work first.
That being said, the main reason why your code doesn't work, is because you try to make an object of the class bam with new bam(). This class unfortunately doesn't exist as it is only a method in a class. My solution would look like:
public class LoopExample {
public void bam() {
for (int i = 0; i < 8; i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
new LoopExample().bam();
}
}
As I said: try to understand object oriented programming first, before trying to continue programming in Java. It is too essential to be able to write working code.
PS: just to be complete, the best way to write what you want to do, would look as follows.
public class LoopExample {
public static void main(String[] args) {
for(int i = 0; i < 8; i++) {
System.out.println(i);
}
}
}
Change the signature of your method. Replace public String bam() with public void bam(). voidmeans that you return nothing instead of a String as before.
For further information see http://www.tutorialspoint.com/java/java_methods.htm

Getting "cannot find symbol" error while using static methods

I have really simple code, I have deleted odd code.
So this my class, one of his method is static and I would like to use it later in Main class:
public class TradeInformationReader {
private static String tradeType = "FX_SPOT";
public static double tradePrice = -1;
private double price;
public static int setTradeInformation(String path_to_file) {
return 1;
}
}
And here how I trying to call this last method:
public class Main {
public static int main(String[] args) {
String path_to_file = "D:\\1.txt";
if (0 > TradeInformationReader.setTradeInformation(path_to_file)) {
return -1;
}
return 1;
}
}
I read many posts with a similar issue, but couldn't find a solution. Everything looks fine to me. IDE doesn't show any mistakes and I'm trying just to call static method setTradeInformation, why it does not recognize it (cannot find symbol method setTradeInformation)? Any ideas? I will really appreciate your help.
Your main is not a valid main, so I guess your IDE cannot find a launching class. This should be
public static void main(String[] args)
First you have to put TradeInformationReader class in a seperate file called : TradeInformationReader.java
as follows : `
public class TradeInformationReader {
private static String tradeType = "FX_SPOT";
public static double tradePrice = -1;
private double price;
public static int setTradeInformation(String path_to_file) {
//integer to identify whether the file is found or not 1 if found and 0 if not
int isFileFound = 1;
// the code required to get the file and modify the state of the of isFileFound variable
return isFileFound;
}
}
`
then the main class should have void return type and should be in a file that has the same name as the Main Class as follows:
public class firstApp {
public static void main(String[] args) {
String path_to_file = "D:\\1.txt";
if (0 > TradeInformationReader.setTradeInformation(path_to_file)) {
System.out.println("File not found");
}
}
}
`

Categories

Resources