Clang tooling. Type name without keyword - clang

I'm working on some clang tool, and I need to generate source code with types, that aren't specified explicitly.
The strings with types I get from clang::QualType is something like: class std::initializer_list<int>. The issue is to get type without keyword.
I've tried to dyn_cast<> types (clang::Type) to all heirs of TypeWithKeyword but the result is always null.
Of course I can delete all occurrence of "class", "struct", etc. from the string with type name, but I would like to solve this in "clang way".

The answer was simple.
Instead of using QualType::getAsString(), just needed QualType::getAsString (const PrintingPolicy &Policy).
So the code:
PrintingPolicy pp(f_context->getLangOpts());
string typeName = qualType.getAsString(pp);
Works well without changing fields of PrintingPolicy.

Related

If a set literal is of type set then what is its class in dart?

So the following code snippet
Set mySet = {1,2,3};
is an instance of type Set which is permissible, however what would the class of the set literal be. I have tried to search for this, however I have found no answer in the dart documentation.
A literal exists only in your source code. Asking for its "class" doesn't make a lot of sense.
Using a Set, Map, or List literal is just syntactic sugar for invoking a corresponding constructor. The Set factory constructor constructs a LinkedHashSet.
However, you'll see that LinkedHashSet is also abstract. Its factory constructor returns an instance of a private, internal class. You can see its typename via print(Set().runtimeType); the actual type might be different for different platforms and is unlikely to be useful to you.

What does the "as" keyword do in Dart language?

I'm confused as to the uses of "as" keyword.
Is it a cast operator or alias operator?
I encountered the following code on the internet which looked like a cast operator:
var list = json['images'] as List;
What does this mean?
as means different things in different contexts.
It's primarily used as a type cast operator. From the Dart Language Tour:
as: Typecast (also used to specify library prefixes)
It links to an explanation of how as is also used to add a prefix to an imported library to avoid name collisions. (as was reused to do different things to avoid needing extra keywords.)
just to add the as keyword is now flagged by the linter and they prefer you to use a check like is
if (pm is Person)
pm.firstName = 'Seth';
you can read more here https://github.com/dart-lang/linter/issues/145
As the language tour says:
Use the as operator to cast an object to a particular type if and only if you are sure that the object is of that type.
Following with your example:
var list = json['images'] as List;
You would use as here to cast or convert json['images'] into a <List> object.
From another SO post (talking about explicit cast vs. as):
as ... is more like an assertion, if the values type doesn't match as causes a runtime exception.
You can also use it when importing packages. A common example is the dart:convert as JSON which then can be reached final foo = JSON.jsonDecode(baz)
It's casting, your code is similar as:
List list = json['images'];

Type name as identifier in F#

I just started to study F# and accidentally wrote this binding
let List = 1
Now when I try to obtain List methods such as 'filter' I get this error
error FS0039: The field, constructor or member 'filter' is not defined.
Of course using method with full type name like Microsoft.FSharp.Collections.List.filter is still working.
I'm wondering why it is possible to use type name as identifier in F# and how I can set back name List to type List from Microsoft.FSharp.Collections.
When I tried to reassign like this
type List = Microsoft.FSharp.Collections.List<'T>
I get
Error FS0039: The type parameter 'T is not defined.
Thank you!
In F# you can redefine almost everything and shadow existing definitions. This applies to both types (well actually types have a different behavior regarding shadowing, they shadow their values as you open the namespaces) and values but not interchangeably since values and type (and also modules) can somehow coexist at the same time in the scope. The compiler will do his best to find out which one is.
You are not forced to, but it's a common good practice in F# not to use let bindings in uppercase.
Regarding your second question, you are using a type parameter in the right side which doesn't exist in the left side of the assignment, it should be:
type List<'T> = Microsoft.FSharp.Collections.List<'T>
But notice that filter doesn't belong to the type. It's rather defined in the List module.
You should just rename your let binding from List to something sensible - as Gustavo mentioned, your definition is shadowing the core List module from F# and there is no way to use List to refer both to your integer and to the module. Shadowing core functions will make your code pretty confusing. It's also a good idea to use camelCase for let bindings, but that's a matter of taste.
If you insist on shadowing List, then you won't be able to call List.filter using List.filter. If you wanted something shorter, you could define module alias:
module FsList = Microsoft.FSharp.Collections.List
Note that your attempt to do something similar with List<'T> does not do the same thing, because functions such as filter are in a module named List rather than being static members of the type. With this, you can call filter using FsList.filter.

How does Orika decide when to use converter

I am trying to understand when does Orika use converters to do the mapping versus direct casting.
I have the following mapping:
Class A {
Map<String, Object> props;
}
Class B {
String bStr;
int bInt;
}
My mapping is defined as props['aStr'] => bStr and props['aInt'] => bInt
When I look at the generated code, I see that for the String case, it uses a converter and calls its convert method for the transformation:
destination.setBStr("" + ((ma.glasnost.orika.Converter)usedConverters[0]).convert(
((java.lang.Object) ((java.util.Map) source.getProps().get("aStr"),
(ma.glasnost.orika.metadata.Type) usedTypes[0]))
But, for the integer case it directly casts it like this:
destination.setBInt((java.lang.Integer)(java.lang.Object) ((java.util.Map)
source.getProps().get("aInt")))
The above line of code ends up giving class cast exception.
For fixing this issue, I was thinking along the lines of using a custom converter but if the above line of code doesn't use the converter then that wont work.
Of course, I can always do this is in my custom mapper but just trying to understand how the code is generated for type conversion.
Thanks!!
In Orika there is two stages: config-time and runtime, as optimization Orika resolve all used converter in the config-time and cache them into each generated mapper so it will be accessible directly O(1) but in the config time it will try to find in a list O(n) of registered converters which one "canConvert" between two given types, canConvert is a method in Converter interface .
So this solution offer the best of the two worlds:
A very flexible way to register a converter with arbitrary conditions
An efficient resolution and conversion operation in the runtime.
Orika by default, leverage the existence of .toString in every object to offer implicit coercion to String for every Object. The problem here is that there is no Converter from Object to Integer.
Maybe this can be an issue of error reporting. Ideally Orika should report that an Object have to be converted to Integer and there is no appropriate converter registered.

Global constants in F# - how to

I need to set a version number to be used in the AssemblyVersion attribute by several related projects.
In C# I use the following
public class Constants {
public const string Version = "1.2.3.4";
}
then it can be used as follows:
[assembly:AssemblyVersion(Constants.Version)]
What would be the equivalent construct in F#. All my attempts to come up with a binding which can be accepted as an attribute argument did not work.
Use the attribute Literal:
[<Literal>]
let version = "1.2.3.4"
[<assembly:AssemblyVersion(version)>]
Since I stepped into this trap myself I thought I'd share for anyone following.
A 'Literal' requires that the letter starts with a capital letter. This will hit you when you try to use the literal in a pattern matching construct.
Reference:
Literal attribute not working

Resources