Let's say that I have a class class Foo : Base and I want to perform a certain method call with signature
public void someStuf(Iterable<? extends Base> param)
For the search template I just take as starting point the pre-existing one
$Instance$.$MethodCall$($Parameter$)
Is it possible to match a parameter of any kind Iterable of a specific Base subclass (Foo in this example)??
List<Foo> fooList = new ArrayList<>();
fooList.add(new Foo("A"));
List<Bar> barList = new ArrayList<>();
barList.add(new Bar(1));
someStuff(fooList); // find this!
someStuff(barList); // don't find this one
someStuff(Collections.singletonList(new Foo("B"))); // also match this one
I've tried several combinations without any luck, is it even possible to do?
This was previously not possible without resorting to a hack. See further below for that. Currently, the code can be found using a Type modifier.
search template
$Instance$.$MethodCall$($Parameter$)
variables
$Instance$ Count=[0,1]
$MethodCall Text=someStuff
$Parameter$ Type=Iterable<Foo>, within type hierarchy
hack
The hack previously needed used a Script modifier and a simple Type modifier on the $Parameter$ variable:
$Parameter$
Script=__context__.type.parameters[0].presentableText.contains("Foo")
Type=Iterable
The related bug report is fixed since IntelliJ IDEA 2017.3.
Related
I have a #PlanningSolution class, that has one field with a custom List implementation as type.
When solving I run into the following issue (as described in the optaplanner documentation):
java.lang.IllegalStateException: The cloneCollectionClass (class java.util.ArrayList) created for originalCollectionClass (class Solution$1) is not assignable to the field's type (class CustomListImpl).
Maybe consider replacing the default SolutionCloner.
As this field has no impact on planning, can I prevent FieldAccessingSolutionCloner from trying to clone that particular field e.g. by adding some annotation? I dont want to provide a complete custom SolutionCloner.
When inspecting the sources of FieldAccessingSolutionCloner I found out that I only needed to override the method retrieveCachedFields(...) or constructCloneCollection(...) so I tried to extend FieldAccessingSolutionCloner but then I need a public no-args-constructor. There I dont know how to initialise the field solutionDescriptor in the no-args-constructor to use my ExtendedFieldAccessingSolutionCloner as solution cloner.
If the generic solution cloner decided to clone that List, there is probably a good reason for it do so: one of the the elements in that list probably has a reference to a planning entity or the planning solution - and therefore the entire list needs to be planning cloned.
If that's not the case, this is a bug in OptaPlanner. Please provide the classes source code of the class with that field and the CustomListImpl class too, so we can reproduce and fix it.
To supply a custom SolutionCloner, follow the docs which will show something like this (but this is a simple case without chained variables, so it's easy to get right, but solution cloning is notoriously difficult!).
#PlanningSolution(solutionCloner = VaccinationSolutionCloner.class)
public class VaccinationSolution {...}
public class VaccinationSolutionCloner implements SolutionCloner<VaccinationSolution> {
#Override
public VaccinationSolution cloneSolution(VaccinationSolution solution) {
List<PersonAssignment> personAssignmentList = solution.getPersonAssignmentList();
List<PersonAssignment> clonedPersonAssignmentList = new ArrayList<>(personAssignmentList.size());
for (PersonAssignment personAssignment : personAssignmentList) {
PersonAssignment clonedPersonAssignment = new PersonAssignment(personAssignment);
clonedPersonAssignmentList.add(clonedPersonAssignment);
}
return new VaccinationSolution(solution.getVaccineTypeList(), solution.getVaccinationCenterList(), solution.getAppointmentList(),
solution.getVaccinationSlotList(), clonedPersonAssignmentList, solution.getScore());
}
}
I saw a tutorial where an extra class is created just to be able to serialize a list of objects, instead of a single object:
I'm using json_serializable to generate some serialization code for my class Preference, but now I want to save a list of preferences using shared_preferences and I get an error obviously.
var sSavedPrefs = json.encode(PreferenceRepo.getSavedPrefs());
prefs.setString(saved_prefs_key, sSavedPrefs );
I used
#JsonSerializable()
class Preference{...}
to make it serializable, but I don't want to create an extra class like
#JsonSerializable()
class Preferences{...}
just to make it work - is there a better way?
I found a way:
Using the setStringList method I could create a List where I added each serialized object one by one without needing an extra list class. I also noticed that json.encode might not have been the right method to use, I saw jsonEncode in another tutorial and used it instead:
List<String> savedPrefsJson = [];
for (Preference savedPref in PreferenceRepo.savedPrefs) {
String savedPrefJson = jsonEncode(savedPref);
savedPrefsJson.add(savedPrefJson);
}
prefs.setStringList(saved_prefs_key, savedPrefsJson);
I have an antlr4 grammar file that parses a BASIC language. Is there a way to insert more code in my extended baseListener class?
For example, if I am parsing this code:
10 print "hello world"
%include "moreCode.bas"
print "after include"
moreCode.bas could be something like:
for t% = 1% to 10%
print t%
next t%
I need to detect the include command and include the contents into the file being walked and continue walking it as a whole.
So I was thinking that in my enterIncludeCommand method in my listener class I would start a new parser for moreCode.bas and then somehow insert the tokens/contexts into my current one.
What is the correct way of doing this?
There is no one right pattern. That said, one effective way is to have your main initiate the parser by always calling through a constructor that takes a state object and a source path as parameters
public class BasicParser {
public static void main(String[] args) {
...
StateModel state = new StateModel()
RecurseParser rp = new RecurseParser(state, pathname);
...
}
}
public class RecurseParser {
public RecurseParser(StateModel state, String pathname) {
this.state = state;
this.pathname = pathname; // source text to parse
...
}
public StateModel getResults() {
return this.state
}
In your enterIncludeStatement method, create and run a new RecurseParser instance directly. In your exitIncludeStatement, retrieve the new current state and, as appropriate, validate/check for errors.
Since the state model encapsulates your symbol table, etc., you maintain continuity as you walk through the forest -- recursion is effectively free.
Should mention that, relative to the symbol table, treat executing an include essentially the same as calling a subroutine.
Related: Symbol Table
I have two solutions for this and I took the last one I am going to mention. Also GRosenBerg has a great idea too.
1) use the TokenStreamRewriter and in the enterIncludeStatement use the rewriter insertBefore, insertAfter and/or replace methods. At the end of the walk of that particular listener object, call the rewriter getText() and that will give you the combined string. You will have to reparse that text to go the next listener pass.
2) In the enterIncludeStatement method of the listener class, get the include file name, run the lexer/parser on it and then take the first StatementContext(in my case) and inject it into the current tree using the IncludeContext.AddChile(myStatement). Looping for each statement line in that include file. The tricky part is to include the statements in the correct place but you will end up with a complete tree that you can walk with the next listener class phase.
I used option 2 and its working for me so far however I'm not sure using the addChild method is the best way since I am really inserting siblings not children. Given this siblings/childrens issue then maybe grosenberg's recursive idea would be the best.
In my Google Web Toolkit project, I got the following error:
com.google.gwt.user.client.rpc.SerializationException: Type ‘your.class.Type’ was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.
What are the possible causes of this error?
GWT keeps track of a set of types which can be serialized and sent to the client. your.class.Type apparently was not on this list. Lists like this are stored in .gwt.rpc files. These lists are generated, so editing these lists is probably useless. How these lists are generated is a bit unclear, but you can try the following things:
Make sure your.class.Type implements java.io.Serializable
Make sure your.class.Type has a public no-args constructor
Make sure the members of your.class.Type do the same
Check if your program does not contain collections of a non-serializable type, e.g. ArrayList<Object>. If such a collection contains your.class.Type and is serialized, this error will occur.
Make your.class.Type implement IsSerializable. This marker interface was specifically meant for classes that should be sent to the client. This didn't work for me, but my class also implemented Serializable, so maybe both interfaces don't work well together.
Another option is to create a dummy class with your.class.Type as a member, and add a method to your RPC interface that gets and returns the dummy. This forces the GWT compiler to add the dummy class and its members to the serialization whitelist.
I'll also add that if you want to use a nested class, use a static member class.
I.e.,
public class Pojo {
public static class Insider {
}
}
Nonstatic member classes get the SerializationException in GWT 2.4
I had the same issue in a RemoteService like this
public List<X> getX(...);
where X is an interface. The only implementation did conform to the rules, i.e. implements Serializable or IsSerializable, has a default constructor, and all its (non-transient and non-final) fields follow those rules as well.
But I kept getting that SerializationException until I changed the result type from List to X[], so
public X[] getX(...);
worked. Interestingly, the only argument being a List, Y being an interface, was no problem at all...
I have run into this problem, and if you per chance are using JPA or Hibernate, this can be a result of trying to return the query object and not creating a new object and copying your relavant fields into that new object. Check the following out, which I saw in a google group.
#SuppressWarnings("unchecked")
public static List<Article> getForUser(User user)
{
List<Article> articles = null;
PersistenceManager pm = PMF.get().getPersistenceManager();
try
{
Query query = pm.newQuery(Article.class);
query.setFilter("email == emailParam");
query.setOrdering("timeStamp desc");
query.declareParameters("String emailParam");
List<Article> results = (List<Article>) query.execute(user.getEmail
());
articles = new ArrayList<Article>();
for (Article a : results)
{
a.getEmail();
articles.add(a);
}
}
finally
{
pm.close();
}
return articles;
}
this helped me out a lot, hopefully it points others in the right direction.
Looks like this question is very similar to what IsSerializable or not in GWT?, see more links to related documentation there.
When your class has JDO annotations, then this fixed it for me (in addition to the points in bspoel's answer) : https://stackoverflow.com/a/4826778/1099376
Resolving a class that has multiple constructors with NInject doesn't seem to work.
public class Class1 : IClass
{
public Class1(int param) {...}
public Class1(int param2, string param3) { .. }
}
the following doesn’t seem to work:
IClass1 instance =
IocContainer.Get<IClass>(With.Parameters.ConstructorArgument(“param”, 1));
The hook in the module is simple, and worked before I added the extra constructor:
Bind().To();
The reason that it doesn't work is that manually supplied .ctor arguments are not considered in the .ctor selection process. The .ctors are scored according to how many parameters they have of which there is a binding on the parameter type. During activation, the manually supplied .ctor arguments are applied. Since you don't have bindings on int or string, they are not scored. You can force a scoring by adding the [Inject] attribute to the .ctor you wish to use.
The problem you're having is that Ninject selects .ctors based on the number of bound parameters available to it. That means that Ninject fundamentally doesn't understand overloading.
You can work around this problem by using the .ToConstructor() function in your bindings and combining it with the .Named() function. That lets you create multiple bindings for the same class to different constructors with different names. It's a little kludgy, but it works.
I maintain my own software development blog so this ended up being a post on it. If you want some example code and a little more explanation you should check it out.
http://www.nephandus.com/2013/05/10/overloading-ninject/