Java compiler warning for changing a method argument variable in method body - eclipse

public class InsertionSort {
public static <T extends Comparable<T>> void sort(T[] array) {
for (int indexOfNextToInsert = 1; indexOfNextToInsert < array.length; indexOfNextToInsert++) {
// array from array[0] to array[indexOfNextItemToReposition - 1] is sorted
// now insert array item at "indexOfNextItemToReposition" into
// the sorted left side of array
insert(array, indexOfNextToInsert);
}
}
private static <T extends Comparable<T>> void insert(T[] array, int indexOfNextToInsert) {
T nextValue = array[indexOfNextToInsert];
while (indexOfNextToInsert > 0 && nextValue.compareTo(array[indexOfNextToInsert - 1]) < 0) {
array[indexOfNextToInsert] = array[indexOfNextToInsert - 1];
indexOfNextToInsert--; //<-- I am getting an warning here in eclipse
}
array[indexOfNextToInsert] = nextValue;
}
}
Does anyone know how to fix this warning?

You shouldn't reassign method parameters. Assignment to a parameter could be confused with an attempt to use it as an output parameter. Further discussion: http://sourcemaking.com/refactoring/remove-assignments-to-parameters.

Related

How to copy a list into another in a StateNotifier, so it update with every change

The List EleccionSinSeleccionClase is just a list of a class who has a String on it.
class EleccionSinSeleccionClase {
String Eleccion;
}
The state List is another class:
class EleccionConSleccionClase {
String Eleccion;
bool selec;
}
The problem is that I want to copy the first into the state of the StateNotifier, this line break the code.
This is the line: state[i].Eleccion = ListaElecciones[i].Eleccion;
class EleccionesConSeleccionNotifier
extends StateNotifier<List<EleccionConSleccionClase>> {
final List<EleccionSinSeleccionClase> ListaElecciones;
EleccionesConSeleccionNotifier({required this.ListaElecciones}) : super([]);
void init(){
print(ListaElecciones.length.toString());
if(ListaElecciones.length != 0){
for (int i = 0; i < ListaElecciones.length; i++) {
state[i].Eleccion = ListaElecciones[i].Eleccion; ////HERE////
}
}
}
}
final eleccionConSleccionStateNotifierProvider = StateNotifierProvider<
EleccionesConSeleccionNotifier, List<EleccionConSleccionClase>>((ref) {
final eleccioneswatch =
ref.watch(eleccionesSinSeleccionStateNotifierProvider);
return EleccionesConSeleccionNotifier(ListaElecciones: eleccioneswatch)..init();
});
Maybe the problem is that you initialize state as an empty list super([]) and then you're trying to change a value in an index that doesn't exist (state[i] where the list is obviously empty and cannot access that position)
void init(){
print(ListaElecciones.length.toString());
if(ListaElecciones.length != 0){
/// you will need to check if both lists are the same lenght if you actually want to do this
/// without failling
/*for (int i = 0; i < ListaElecciones.length; i++) {
state[i].Eleccion = ListaElecciones[i].Eleccion; ////HERE////
}*/
/// if you only want to copy Eleccion parameter in a new class this would be the easiest way
state = ListaElecciones.map((cb) => EleccionConSleccionClase(Eleccion: cb.Eleccion)).toList();
}
}

Custom sonar rule for annotation parameters check

I have a task to create custom rule using SonarJava. Rule purpose is checking methods. If method is annottated with #Test it also needs to have #TestInfo annotation with not empty testCaseId parameter.
This is what I have prepared:
public class AvoidEmptyTestCaseIdParameterRule extends IssuableSubscriptionVisitor {
private static final String TEST_ANNOTATION_PATH = "org.testng.annotations.Test";
private static final String TEST_INFO_ANNOTATION_PATH = "toolkit.utils.TestInfo";
#Override
public List<Tree.Kind> nodesToVisit() {
return ImmutableList.of(Tree.Kind.METHOD);
}
#Override
public void visitNode(Tree tree) {
MethodTree methodTree = (MethodTree) tree;
if (methodTree.symbol().metadata().isAnnotatedWith(TEST_ANNOTATION_PATH)) {
if (methodTree.symbol().metadata().isAnnotatedWith(TEST_INFO_ANNOTATION_PATH)) {
List<AnnotationInstance> annotations = methodTree.symbol().metadata().annotations();
for (int i = 0; i < annotations.size(); i++) {
if (annotations.get(i).symbol().name().equals("TestInfo")
&& !testInfoAnnotationContainsNonEmptyTestCaseIdParameter(annotations.get(i))) {
reportIssue(methodTree.simpleName(),
"Method annotated with #TestInfo should have not empty testCaseId parameter");
}
}
} else {
reportIssue(methodTree.simpleName(),
"Method annotated with #Test should also be annotated with #TestInfo");
}
}
}
private boolean testInfoAnnotationContainsNonEmptyTestCaseIdParameter(AnnotationInstance annotation) {
return <--this is where I stuck-->;
}
}
this is how my test class look:
public class TestClass {
#Test
#TestInfo(testCaseId = "", component = "Policy.IndividualBenefits")
public void testMethod() {
}
}
Question:
-Is it possible to get annotation parameters (properly or as String line)?
-Is there other possible way to get this parameter?
I figured it out. I switched to using Tree.Kind.ANNOTATION.
This is the code for search of needed argument:
Arguments arguments = annotationTree.arguments();
if (!arguments.isEmpty()) {
for (int i = 0; i < arguments.size(); i++) {
String parameter = arguments.get(i).firstToken().text();
String parameterValue = arguments.get(i).lastToken().text();
if (isParameterTestCaseId(parameter) && isTestCaseIdEmpty(parameterValue)) {
reportIssue(arguments.get(i),
"Method annotated with #TestInfo should have not empty testCaseId parameter");
}
}
}
Methods for checking argument and its value:
private boolean isParameterTestCaseId(String parameter) {
return parameter.matches("testCaseId");
}
private boolean isTestCaseIdEmpty(String parameterValue) {
return parameterValue.length() != 0;
}

How to call the method of unknown class in MQL?

I've a Collection class which aims to store different kind of objects, however I'd like to call specific method name which these classes share (e.g. ToString()).
Here is my attempt:
class Collection {
public:
void *data[];
void Collection() {}
void ~Collection() {
for (int i = 0; i < ArraySize(data); i++) {
if (CheckPointer(data[i]) == POINTER_DYNAMIC) delete data[i];
}
}
void *Add(void *_object) {
uint _size = ArraySize(data);
ArrayResize(data, _size + 1, 100);
data[_size] = _object;
return _object;
}
string ToString(string _dlm = ",") {
string _out = "";
for (int i = 0; i < ArraySize(data); i++) {
if (CheckPointer(data[i]) == POINTER_DYNAMIC) {
_out += ((void *) data[i]).ToString(); // #fixme: Syntax error.
}
}
return _out;
}
};
However using ((void *) data[i]).ToString() syntax fails with:
'ToString' - member function not defined Collection.mqh
How can I call a ToString() method for each stored object?
It seems to me that it should be something like collection.toString() where collection is an object of your class Collection. Then each object that you add to your collection should implement this function... Maybe it is easier to mention some superclass that supports toString() (or interface with this method) and make sure that you add only correct objects? This also makes your code free of unexpected errors in runtime.
Also CArrayObj is at your disposal with most functions, if you need toString() or any other function then you can simply extend basic class. Maybe the only disadvantage of the default collection is that it stores CObject-inherited objects.
This can be achieved by creating an abstract class where all classes can share the same virtual method. For example:
class Object {
public:
virtual string ToString() = NULL;
};
class Foo : public Object {
public:
virtual string ToString() {
return "Foo";
};
};
class Bar : public Object {
public:
virtual string ToString() {
return "Bar";
};
};
Then in the Collection class the following method:
virtual string ToString(string _dlm = ",") {
string _out = "";
for (int i = 0; i < ArraySize(data); i++) {
if (CheckPointer(data[i]) == POINTER_DYNAMIC) {
_out += ((Object *) data[i]).ToString() + _dlm;
}
}
return _out;
}
Sample usage:
Collection *objects;
objects = new Collection;
Foo *foo = new Foo();
Bar *bar = new Bar();
objects.Add(foo);
objects.Add(bar);
Print(objects.ToString());
delete objects;

Why am I getting access violating reading location when I try to set value of shared_ptr<T> element

I'm getting access violation reading location when I try to set data of class object.
void make_heap_array()
{
//Example of ptr_arr is define: It's define in class variables: vector<shared_ptr<Data_Node<Item>>> ptr_arr;
int total_data = arr_data.size();
for (int i = 0; i < total_data; i++)
{
shared_ptr<Data_Node<Item>> new_node = shared_ptr<Data_Node<Item>>();
Item data = arr_data[i];
new_node->set_data(data); //Error: Access violation reading location
ptr_arr.push_back(new_node);
}
}
Data_Node is class using template with few methods and here is it's code:
template <class Item>
class Data_Node
{
Item info;
public:
const Item& data() const
{
return info;
}
void set_data(const Item& new_data)
{
info = new_data;
}
};
new_node is null (as you might well have checked yourself), so new_node->set_data(data) has undefined behaviour. (The default-constructed state of a shared pointer is null.)

ActionScript: How to sort a class vector based on int

I have a vector of TestClass objects that I would like to arrange in ascending order based on integer of each TestClass object. How would I do this?
Main Method:
public class testSave extends Sprite
{
public function testSave()
{
var testVector:Vector.<TestClass> = new Vector.<TestClass>;
testVector.push(new TestClass(5, "Testing"), new TestClass(2, "HelloWorld"), new TestClass(7, "Ohai");
}
}
TestClass
public class TestClass
{
public function TestClass(testi:int, tests:String)
{
this.stest = tests;
this.itest = testi
}
public var stest:String;
public var itest:int;
}
Unfortunately there is no sortOn for Vectors but there is a sort. So if you do this:
public function testSave():void {
var testVector:Vector.<TestClass> = new Vector.<TestClass>;
testVector.push(new TestClass(5, "Testing"), new TestClass(2, "HelloWorld"), new TestClass(7, "Ohai"));
testVector.sort(function(a:TestClass, b:TestClass):Boolean {
return a.itest > b.itest;
});
// confirm the vector is now sorted
for (var i = 0; i < testVector.length; i++){
trace(testVector[i].itest);
}
}
your vector will sort. Vector.sort takes a sorting function, it compares the two values and then figures out how to swap them when iterating through the array...
Checking if a is greater than b will result in ascending order.