eclipse CDT Plugin development : How to get the class name which has a declaration - eclipse-plugin

I'm developing an eclipse plugin based on CDT API.
Suppose I've following C++ code
class EventEnum
{
public:
enum e {
E_CompleteDisconnectSuccess = 1,
E_CreateBtAdapterNoSuccess = 2,
E_CreateBtAdapterSuccess = 3,
};
};
Using following ASTVisitor visitor method I can find the enum declaration
public int visit(IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration) {
IASTDeclSpecifier specifier = ((IASTSimpleDeclaration)declaration).getDeclSpecifier();
if (specifier instanceof IASTEnumerationSpecifier) {
IASTEnumerationSpecifier enumSpecifier = (IASTEnumerationSpecifier)specifier;
// Get the current enumeration name
String enumerationName = enumSpecifier.getName().toString();
System.out.println("Found enum : " + enumerationName);
}
}
return PROCESS_CONTINUE;
}
Question : How can I get the class name which contains the found enum declaration, in my case it will be EventEnum ?

Found the answer on my own, probably for someone it will be usefull, so I'm posting it here
if (enumSpecifier.getParent() instanceof CPPASTSimpleDeclaration)
{
if (enumSpecifier.getParent().getParent() instanceof CPPASTCompositeTypeSpecifier)
{
CPPASTCompositeTypeSpecifier firstLevelClass = (CPPASTCompositeTypeSpecifier)enumSpecifier.getParent().getParent();
return firstLevelClass.getName().toString();
}
}

Related

HTTP end point property string starts with "is" will get omit [duplicate]

This might be a duplicate. But I cannot find a solution to my Problem.
I have a class
public class MyResponse implements Serializable {
private boolean isSuccess;
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Getters and setters are generated by Eclipse.
In another class, I set the value to true, and write it as a JSON string.
System.out.println(new ObjectMapper().writeValueAsString(myResponse));
In JSON, the key is coming as {"success": true}.
I want the key as isSuccess itself. Is Jackson using the setter method while serializing? How do I make the key the field name itself?
This is a slightly late answer, but may be useful for anyone else coming to this page.
A simple solution to changing the name that Jackson will use for when serializing to JSON is to use the #JsonProperty annotation, so your example would become:
public class MyResponse implements Serializable {
private boolean isSuccess;
#JsonProperty(value="isSuccess")
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
This would then be serialised to JSON as {"isSuccess":true}, but has the advantage of not having to modify your getter method name.
Note that in this case you could also write the annotation as #JsonProperty("isSuccess") as it only has the single value element
I recently ran into this issue and this is what I found. Jackson will inspect any class that you pass to it for getters and setters, and use those methods for serialization and deserialization. What follows "get", "is" and "set" in those methods will be used as the key for the JSON field ("isValid" for getIsValid and setIsValid).
public class JacksonExample {
private boolean isValid = false;
public boolean getIsValid() {
return isValid;
}
public void setIsValid(boolean isValid) {
this.isValid = isValid;
}
}
Similarly "isSuccess" will become "success", unless renamed to "isIsSuccess" or "getIsSuccess"
Read more here: http://www.citrine.io/blog/2015/5/20/jackson-json-processor
Using both annotations below, forces the output JSON to include is_xxx:
#get:JsonProperty("is_something")
#param:JsonProperty("is_something")
When you are using Kotlin and data classes:
data class Dto(
#get:JsonProperty("isSuccess") val isSuccess: Boolean
)
You might need to add #param:JsonProperty("isSuccess") if you are going to deserialize JSON as well.
EDIT: If you are using swagger-annotations to generate documentation, the property will be marked as readOnly when using #get:JsonProperty. In order to solve this, you can do:
#JsonAutoDetect(isGetterVisibility = JsonAutoDetect.Visibility.NONE)
data class Dto(
#field:JsonProperty(value = "isSuccess") val isSuccess: Boolean
)
You can configure your ObjectMapper as follows:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
&& method.getName().startsWith("is")) {
return method.getName();
}
return super.nameForGetterMethod(config, method, defaultName);
}
});
I didn't want to mess with some custom naming strategies, nor re-creating some accessors.
The less code, the happier I am.
This did the trick for us :
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
#JsonIgnoreProperties({"success", "deleted"}) // <- Prevents serialization duplicates
public class MyResponse {
private String id;
private #JsonProperty("isSuccess") boolean isSuccess; // <- Forces field name
private #JsonProperty("isDeleted") boolean isDeleted;
}
Building upon Utkarsh's answer..
Getter names minus get/is is used as the JSON name.
public class Example{
private String radcliffe;
public getHarryPotter(){
return radcliffe;
}
}
is stored as { "harryPotter" : "whateverYouGaveHere" }
For Deserialization, Jackson checks against both the setter and the field name.
For the Json String { "word1" : "example" }, both the below are valid.
public class Example{
private String word1;
public setword2( String pqr){
this.word1 = pqr;
}
}
public class Example2{
private String word2;
public setWord1(String pqr){
this.word2 = pqr ;
}
}
A more interesting question is which order Jackson considers for deserialization. If i try to deserialize { "word1" : "myName" } with
public class Example3{
private String word1;
private String word2;
public setWord1( String parameter){
this.word2 = parameter ;
}
}
I did not test the above case, but it would be interesting to see the values of word1 & word2 ...
Note: I used drastically different names to emphasize which fields are required to be same.
You can change primitive boolean to java.lang.Boolean (+ use #JsonPropery)
#JsonProperty("isA")
private Boolean isA = false;
public Boolean getA() {
return this.isA;
}
public void setA(Boolean a) {
this.isA = a;
}
Worked excellent for me.
If you are interested in handling 3rd party classes not under your control (like #edmundpie mentioned in a comment) then you add Mixin classes to your ObjectMapper where the property/field names should match the ones from your 3rd party class:
public class MyStack32270422 {
public static void main(String[] args) {
ObjectMapper om3rdParty = new ObjectMapper();
om3rdParty .addMixIn(My3rdPartyResponse.class, MixinMyResponse.class);
// add further mixins if required
String jsonString = om3rdParty.writeValueAsString(new My3rdPartyResponse());
System.out.println(jsonString);
}
}
class MixinMyResponse {
// add all jackson annotations here you want to be used when handling My3rdPartyResponse classes
#JsonProperty("isSuccess")
private boolean isSuccess;
}
class My3rdPartyResponse{
private boolean isSuccess = true;
// getter and setter here if desired
}
Basically you add all your Jackson annotations to your Mixin classes as if you would own the class. In my opinion quite a nice solution as you don't have to mess around with checking method names starting with "is.." and so on.
there is another method for this problem.
just define a new sub-class extends PropertyNamingStrategy and pass it to ObjectMapper instance.
here is a code snippet may be help more:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
String input = defaultName;
if(method.getName().startsWith("is")){
input = method.getName();
}
//copy from LowerCaseWithUnderscoresStrategy
if (input == null) return input; // garbage in, garbage out
int length = input.length();
StringBuilder result = new StringBuilder(length * 2);
int resultLength = 0;
boolean wasPrevTranslated = false;
for (int i = 0; i < length; i++)
{
char c = input.charAt(i);
if (i > 0 || c != '_') // skip first starting underscore
{
if (Character.isUpperCase(c))
{
if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_')
{
result.append('_');
resultLength++;
}
c = Character.toLowerCase(c);
wasPrevTranslated = true;
}
else
{
wasPrevTranslated = false;
}
result.append(c);
resultLength++;
}
}
return resultLength > 0 ? result.toString() : input;
}
});
The accepted answer won't work for my case.
In my case, the class is not owned by me. The problematic class comes from 3rd party dependencies, so I can't just add #JsonProperty annotation in it.
To solve it, inspired by #burak answer above, I created a custom PropertyNamingStrategy as follow:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if (method.getParameterCount() == 1 &&
(method.getRawParameterType(0) == Boolean.class || method.getRawParameterType(0) == boolean.class) &&
method.getName().startsWith("set")) {
Class<?> containingClass = method.getDeclaringClass();
String potentialFieldName = "is" + method.getName().substring(3);
try {
containingClass.getDeclaredField(potentialFieldName);
return potentialFieldName;
} catch (NoSuchFieldException e) {
// do nothing and fall through
}
}
return super.nameForSetterMethod(config, method, defaultName);
}
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
&& method.getName().startsWith("is")) {
Class<?> containingClass = method.getDeclaringClass();
String potentialFieldName = method.getName();
try {
containingClass.getDeclaredField(potentialFieldName);
return potentialFieldName;
} catch (NoSuchFieldException e) {
// do nothing and fall through
}
}
return super.nameForGetterMethod(config, method, defaultName);
}
});
Basically what this does is, before serializing and deserializing, it checks in the target/source class which property name is present in the class, whether it is isEnabled or enabled property.
Based on that, the mapper will serialize and deserialize to the property name that is exist.

How to reference Composite ID in Gorm 6 or 7 to prevent IllegalArgumentException: Unable to locate Attribute with the the given name

I have this model which works with Gorm3
class UserDataPoint implements Serializable {
User user
DataPoint dataPoint
static mapping = {
id composite: ['user', 'dataPoint']
}
static List<Long> getReadDataPointIds(User user, List<Long> locationIds = null) {
createCriteria().list {
eq('user', user)
dataPoint {
listing {
location {
inList('id', locationIds)
}
}
}
projections {
property('dataPoint.id')
}
} as List
}
}
but now it runs this exception :
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given
name [dataPoint] on this ManagedType [user.UserDataPoint]
Some debug allows me to understand what is happening, it seems that GORM remove the user and dataPoint properties from HibernateProperties because the are a part of the Composite ID
public abstract class AbstractPersistentEntity<T extends Entity> implements PersistentEntity {
.......
IdentityMapping identifier = mapping != null ? mapping.getIdentifier() : null;
if(identity == null && identifier != null) {
final String[] identifierName = identifier.getIdentifierName();
final MappingContext mappingContext = getMappingContext();
if(identifierName.length > 1) {
compositeIdentity = mappingContext.getMappingSyntaxStrategy().getCompositeIdentity(javaClass, mappingContext);
}
for (String in : identifierName) {
final PersistentProperty p = propertiesByName.get(in);
if(p != null) {
persistentProperties.remove(p);
}
persistentPropertyNames.remove(in);
}
disableDefaultId();
}
......
}
So I understand the problem, but I don't know how to fix it ?
how to reference the composite ID and it fields in the projection ?
It seems to be fixed with this recent version https://github.com/grails/gorm-hibernate5/releases/tag/v7.2.1

Using both Microsoft.Web.RedisSessionStateProvider and Microsoft.Web.RedisOutputCacheProvider

I have installed and used Microsoft.Web.RedisSessionStateProvider for a while and after looking at OutputCaching I thought of installing Microsoft.Web.RedisOutputCacheProvider as well but they both have Microsoft.Web.Redis.ISerializer interface which breaks my JsonCacheSerializer as it uses the ISerializer interface.
I am getting an error in VS 2017, which reads ...
"The type 'ISerializer' exists in both Microsoft.Web.RedisOutputCacheProvider and Microsoft.Web.RedisSessionStateProvider"
The JsonCacheSerializer code I use for SessionState is :
public class JsonCacheSerializer : Microsoft.Web.Redis.ISerializer
{
private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.All,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
Error = (serializer, err) => {
err.ErrorContext.Handled = true;
}
};
public byte[] Serialize(object data)
{
return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data, Settings));
}
public object Deserialize(byte[] data)
{
return data == null ? null : JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), Settings);
}
}
Does this mean one has to use one or the other, not both?
You may use extern alias feature of C#
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/extern-alias
Visual Studio example:
1) right click Microsoft.Web.RedisOutputCacheProvider and put following into Aliases field:
global,redisoutputcacheprovider
2) right click Microsoft.Web.RedisSessionStateProvider and put following into Aliases field:
global,redissessionstateprovider
then on top of your code file add:
extern alias redissessionstateprovider;
extern alias redisoutputcacheprovider;
and finally declare your class as:
public class JsonCacheSessionStateSerializer : redissessionstateprovider::Microsoft.Web.Redis.ISerializer

Why is this subclass' parent method call not polymorphic?

I've been dabbling in Dlang recently as C++ just wasn't quite sitting right with me after having used Python for so long. While dabbling, I came across what I thought would be a very simple exercise in polymorphism. I suppose how you would expect something to work and what it actually does are two entirely different things for reasons an end user probably can't comprehend. That being said, here is the source code of my "sandbox.D":
import std.stdio;
class Animal {
string voice = "--silence--";
void speak() {
writeln(this.voice);
}
}
class Dog : Animal {
string voice = "Whoof!";
}
int main() {
auto a = new Animal();
auto d = new Dog();
writeln(a.voice); // Prints "--silence--"
writeln(d.voice); // Prints "Whoof!"
a.speak(); // Prints "--silence--"
d.speak(); // Prints "--silence--" NOT "Whoof!"
return 0;
}
I guess my issue is why the "this" keyword just doesn't seem to be functioning how you would expect it to in the C++ successor language.
Methods are polymorphic, variables aren't. So instead of making the voice a variable, you want to override speak in the child.
Also, the auto return type doesn't work with polymorphism, you need to actually specify the types. (The reason is that auto return makes a function template in the compiler, which in theory could have multiple overridable slots in the function table, so it just doesn't try to put it in.)
So try this out:
import std.stdio;
class Animal {
void speak() { // changed to void instead of auto
writeln("--silence--");
}
}
class Dog : Animal {
override void speak() { // the override tells it to override the base method
writeln("woof");
}
}
int main() {
auto d = new Dog();
d.speak();
return 0;
}
If you have a lot of shared functionality and want to reuse one function with slight changes in child classes, you might make a method instead of a variable that just returns something.
Like string voice() { return "woof"; }, then it can be overridden in children.
Another way is to use template this parameter:
import std.stdio;
class Animal {
string voice;
void speak(this C)() {
writeln((cast(C)this).voice);
}
}
class Dog : Animal {
string voice = "Whoof!";
}
int main() {
auto a = new Animal();
auto d = new Dog();
a.speak(); // Prints ""
d.speak(); // Prints "Whoof!"
return 0;
}
Or when you do not need to have voice as a member:
import std.stdio;
class Animal {
static immutable voice = "";
void speak(this C)() {
writeln(C.voice);
}
}
class Dog : Animal {
static immutable voice = "Whoof!";
}
int main() {
auto a = new Animal();
auto d = new Dog();
a.speak(); // Prints ""
d.speak(); // Prints "Whoof!"
return 0;
}

Duck type testing with C# 4 for dynamic objects

I'm wanting to have a simple duck typing example in C# using dynamic objects. It would seem to me, that a dynamic object should have HasValue/HasProperty/HasMethod methods with a single string parameter for the name of the value, property, or method you are looking for before trying to run against it. I'm trying to avoid try/catch blocks, and deeper reflection if possible. It just seems to be a common practice for duck typing in dynamic languages (JS, Ruby, Python etc.) that is to test for a property/method before trying to use it, then falling back to a default, or throwing a controlled exception. The example below is basically what I want to accomplish.
If the methods described above don't exist, does anyone have premade extension methods for dynamic that will do this?
Example: In JavaScript I can test for a method on an object fairly easily.
//JavaScript
function quack(duck) {
if (duck && typeof duck.quack === "function") {
return duck.quack();
}
return null; //nothing to return, not a duck
}
How would I do the same in C#?
//C# 4
dynamic Quack(dynamic duck)
{
//how do I test that the duck is not null,
//and has a quack method?
//if it doesn't quack, return null
}
If you have control over all of the object types that you will be using dynamically, another option would be to force them to inherit from a subclass of the DynamicObject class that is tailored to not fail when a method that does not exist is invoked:
A quick and dirty version would look like this:
public class DynamicAnimal : DynamicObject
{
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
bool success = base.TryInvokeMember(binder, args, out result);
// If the method didn't exist, ensure the result is null
if (!success) result = null;
// Always return true to avoid Exceptions being raised
return true;
}
}
You could then do the following:
public class Duck : DynamicAnimal
{
public string Quack()
{
return "QUACK!";
}
}
public class Cow : DynamicAnimal
{
public string Moo()
{
return "Mooooo!";
}
}
class Program
{
static void Main(string[] args)
{
var duck = new Duck();
var cow = new Cow();
Console.WriteLine("Can a duck quack?");
Console.WriteLine(DoQuack(duck));
Console.WriteLine("Can a cow quack?");
Console.WriteLine(DoQuack(cow));
Console.ReadKey();
}
public static string DoQuack(dynamic animal)
{
string result = animal.Quack();
return result ?? "... silence ...";
}
}
And your output would be:
Can a duck quack?
QUACK!
Can a cow quack?
... silence ...
Edit: I should note that this is the tip of the iceberg if you are able to use this approach and build on DynamicObject. You could write methods like bool HasMember(string memberName) if you so desired.
Try this:
using System.Linq;
using System.Reflection;
//...
public dynamic Quack(dynamic duck, int i)
{
Object obj = duck as Object;
if (duck != null)
{
//check if object has method Quack()
MethodInfo method = obj.GetType().GetMethods().
FirstOrDefault(x => x.Name == "Quack");
//if yes
if (method != null)
{
//invoke and return value
return method.Invoke((object)duck, null);
}
}
return null;
}
Or this (uses only dynamic):
public static dynamic Quack(dynamic duck)
{
try
{
//invoke and return value
return duck.Quack();
}
//thrown if method call failed
catch (RuntimeBinderException)
{
return null;
}
}
Implementation of the HasProperty method for every IDynamicMetaObjectProvider WITHOUT throwing RuntimeBinderException.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using Microsoft.CSharp.RuntimeBinder;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
namespace DynamicCheckPropertyExistence
{
class Program
{
static void Main(string[] args)
{
dynamic testDynamicObject = new ExpandoObject();
testDynamicObject.Name = "Testovaci vlastnost";
Console.WriteLine(HasProperty(testDynamicObject, "Name"));
Console.WriteLine(HasProperty(testDynamicObject, "Id"));
Console.ReadLine();
}
private static bool HasProperty(IDynamicMetaObjectProvider dynamicProvider, string name)
{
var defaultBinder = Binder.GetMember(CSharpBinderFlags.None, name, typeof(Program),
new[]
{
CSharpArgumentInfo.Create(
CSharpArgumentInfoFlags.None, null)
}) as GetMemberBinder;
var callSite = CallSite<Func<CallSite, object, object>>.Create(new NoThrowGetBinderMember(name, false, defaultBinder));
var result = callSite.Target(callSite, dynamicProvider);
if (Object.ReferenceEquals(result, NoThrowExpressionVisitor.DUMMY_RESULT))
{
return false;
}
return true;
}
}
class NoThrowGetBinderMember : GetMemberBinder
{
private GetMemberBinder m_innerBinder;
public NoThrowGetBinderMember(string name, bool ignoreCase, GetMemberBinder innerBinder) : base(name, ignoreCase)
{
m_innerBinder = innerBinder;
}
public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
var retMetaObject = m_innerBinder.Bind(target, new DynamicMetaObject[] {});
var noThrowVisitor = new NoThrowExpressionVisitor();
var resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
var finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions);
return finalMetaObject;
}
}
class NoThrowExpressionVisitor : ExpressionVisitor
{
public static readonly object DUMMY_RESULT = new DummyBindingResult();
public NoThrowExpressionVisitor()
{
}
protected override Expression VisitConditional(ConditionalExpression node)
{
if (node.IfFalse.NodeType != ExpressionType.Throw)
{
return base.VisitConditional(node);
}
Expression<Func<Object>> dummyFalseResult = () => DUMMY_RESULT;
var invokeDummyFalseResult = Expression.Invoke(dummyFalseResult, null);
return Expression.Condition(node.Test, node.IfTrue, invokeDummyFalseResult);
}
private class DummyBindingResult {}
}
}
impromptu-interface seems to be a nice Interface mapper for dynamic objects... It's a bit more work than I was hoping for, but seems to be the cleanest implementation of the examples presented... Keeping Simon's answer as correct, since it is still the closest to what I wanted, but the Impromptu interface methods are really nice.
The shortest path would be to invoke it, and handle the exception if the method does not exist. I come from Python where such method is common in duck-typing, but I don't know if it is widely used in C#4...
I haven't tested myself since I don't have VC 2010 on my machine
dynamic Quack(dynamic duck)
{
try
{
return duck.Quack();
}
catch (RuntimeBinderException)
{ return null; }
}
Have not see a correct answer here, MS provides an example now with casting to a dictionary
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
foreach (var property in (IDictionary<String, Object>)employee)
{
Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33