Is it possible to NATVIS a recursive tuple (variadic template)? - natvis

I implemented the tuple from here: https://voidnish.wordpress.com/2013/07/13/tuple-implementation-via-variadic-templates/
Is it possible to visualize it with NATVIS? I got as far as
<Type Name="tuple">
<DisplayString>()</DisplayString>
</Type>
<Type Name="tuple<*>">
<DisplayString>({_Myfirst})</DisplayString>
</Type>
How can I get the _Myfirst value for more than one type, to get
<Type Name="tuple<*,*>">
<DisplayString>({_Myfirst}, {???})</DisplayString>
</Type>
<Type Name="tuple<*,*,*>">
<DisplayString>({_Myfirst}, {???}, {???})</DisplayString>
</Type>
etc?

You'll have to modify the type a little to get this to work. What's required is a base_type typedef.
i.e.
// tuple
template<class... _Types> class tuple;
// empty tuple
template<> class tuple<> {};
// recursive tuple definition
template<class _This,
class... _Rest>
class tuple<_This, _Rest...>
: private tuple<_Rest...>
{
public:
typedef tuple<_Rest...> base_type; // ***** Added this line
_This _Myfirst;
};
Now we can recursively evaluate the base types with the natvis declarations:
<!-- Handle empty tuples -->
<Type Name="tuple<>">
<DisplayString>()</DisplayString>
<Expand/>
</Type>
<!-- Handle a single parameter (this is also our terminator for recursion) -->
<Type Name="tuple<*>">
<DisplayString IncludeView="noparens">{_Myfirst}</DisplayString>
<DisplayString ExcludeView="noparens">({_Myfirst})</DisplayString>
<Expand>
<Item Name="Value">_Myfirst</Item>
</Expand>
</Type>
<!-- Handle 2 or more items -->
<Type Name="tuple<*,*>">
<!-- show the first item and then recurse by casting this to 'base_type' -->
<DisplayString IncludeView="noparens">{_Myfirst}, {*(base_type *)this,view(noparens)}</DisplayString>
<!-- Wrap our display string that doesn't a have any parentheses, this will be only done for the top level tuple -->
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
<Expand>
<!-- Show the top level item -->
<Item Name="Value">_Myfirst</Item>
<!-- Recursively expand our base types -->
<ExpandedItem>*(base_type *)this</ExpandedItem>
</Expand>
</Type>
And this is the result:

Related

How to write dynamic attributes

I need to write a dynamic Attribute name instead of hardcode of Name attribute in dataweave 2.0 mulesoft 4 in anypointstudio
<?xml version="1.0" encoding="UTF-8"?>
<iGoApplicationData>
<UserData>
<Data Name="UpdateUserProfile">True</Data>
<Data Name="Action">??</Data>
</iGoApplicationData>
So in order to generate an XML like yours the DW structure will look like
{
iGoApplicationData: {
UserData: {
Data #(Name: payload.foo): "True",
Data #((var.attributeName): "Action"): "??"
}
}
}
So in this example I show how to specify a value in the attribute or a dynamic attribute name. For the dynamic attribute value just type the expression on the value side of the attribute (the part that goes after the :)
For dynamic attribute name you need to wrap the expression between parenthesis. When the name is wrapped between parenthesis it is considered dynamic. This applies to object keys and attributes names

Kotlin Extension Functions Databinding

Is there any possibility to use extension function with a databinding?
XML:
<data>
<import type="my.package.domain.country.model.City.streetName" />
<variable
name="city"
type="my.package.domain.country.model.City" />
</data>
<TextView
android:id="#+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{city.street.streetName()}" />
my.package.domain.country.model.city
data class City(
val id: String,
val street: Street
)
fun City.streetName(): String = street.houseNumber
Error
[kapt] An exception occurred:
android.databinding.tool.util.LoggedErrorException: Found data binding
errors.
****/ data binding error ****msg:cannot find method streetName() in class my.package.domain.country.model.City
Thanks ;)
You have to import CityKt firstly into xml
<import type="my.package.domain.country.model.CityKt" />
int the data section
then you can use it like this
<TextView
android:id="#+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{CityKt.streetName(city)}" />
If you review CityKt you will see that there is static Java method with City as first argument
While #skiff2011 is correct, one could also use alias to prevent the Kt postfix.
For example, a certain extension function is located in ExtensionFunctionsKt can be aliased by ExtensionFunctions
<import
alias="ExtensionFunctions"
type="com.helloworld.app.util.ExtensionFunctionsKt" />
<variable
name="someData"
type="com.helloworld.app.model.SomeData" />
The ExtensionFunction alias can now be used to call the extension function. The first argument still needs to be the extended class variable.
<TextView
android:id="#+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{ExtensionFunctions.doStuff(someData)}" />
Extension function
Ex:
fun Context.isDarkMode(): Boolean {
}
Now we have Extenstion function for dark mode which can be accessed using context.
Usually in Kotlin class we can access using context obj like below.
context.isDarkMode()
But in Xml,we can't access like above.
We need to import Extension function by appending KT to class.
Ex) If your file name is Extensions,then import should be ExtensionsKt.
Import like below in xml.
<import type="com.example.extensions.ExtensionsKt" />
And then we can access Extension function like below i.e we need to pass object for which we are creating Extension i.e in our case it is context.
app:context='#{(ExtensionsKt.isDarkMode(context)}'
If using Utils class you can to this:
object Utils(){
fun streetName(): String {}
}
<import
type="com.helloworld.app.util.Utils" />
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{Utils.INSTANCE.streetName()}"
/>
Use view model for to call extension functions.

mybatis use input param as argument in constructor

In mybatis, can i use an input #Param object in the resultMap constructor?
int test(#Param("param1") someObj obj, #Param("str") String str);
<resultMap id="testResultMap" type="com.test.someOtherObject">
<constructor>
<idArg column="id" javaType="String"/>
<arg column="<use the input param obj of type someObj>" javaType="com.test.someObj"/>
No: Parameters and result maps are 2 distinct things. You cannot feed the result map directly from parameter.
If you want the input parameter to be in the result Map, then it must be in the result set, so you must either select the corresponding column if you filter on that column: SELECT col FROM t WHERE col = #{param}or add it as pseudo column: SELECT '${param}' AS "colName" FROM t and map it as usual with parameterized constructor if you like.
If the constructor argument is a complex type then use <arg resultMap="anotherResultMap" /> instead of <arg column="col" />.

How to remove all XML children nodes but not attributes in Powershell

From this :
<products id="col">
<product code="id1" />
<product code="id2" />
</products>
I want to get this :
<products id="col">
</products>
If I use RemoveAll() it will remove products id attribute also so I will get this
<products>
</products>
That's not what I want. What method could I use to keep my id attribute in products node ?
Instead of calling RemoveAll(), you need to find the nodes you want to remove and then remove each of them manually, with RemoveChild():
$XmlDocument = [xml]#'
<products id="col">
<product code="id1" />
<product code="id2" />
</products>
'#
$ChildNodes = $XmlDocument.SelectNodes('//product')
foreach($Child in $ChildNodes){
[void]$Child.ParentNode.RemoveChild($Child)
}
$XmlDocument.Save("C:\path\to\doc.xml")
If you don't know the name of the immediate child nodes, but only the parent node name, you can use XPath to select them anyways: '//ParentNodeName/child::*'
$ChildNodes = $XmlDocument.SelectNodes('//products/child::*')
My answer doesn't rely on XPath to accomplish this. The script assumes $XmlDocument is a variable containing an XmlDocument instance. The script also assumes that only <product> elements live inside <products>.
if ($XmlDocument.products -is [Xml.XmlElement]) {
$XmlDocument.products.product | %{ $_.ParentNode.RemoveChild($_) | Out-Null }
}
This code also works if <products> does not contain any child elements (i.e., it is a text element).

dynamic MenuContribution - Get a warning

I am using dynamic MenuContribution and get a warning that two of my referenced identifiers "cannot be found". Even though the contribution works. These warnings bug me.
I have a CompoundContributionItem implementation defined in one of my plugins. Basically it looks like this:
public class ViewerHistoryMenuItems extends CompoundContributionItem
implements IExecutableExtension {
private static final String PARAM_TYPE = "type";
private static final String PARAM_COMMAND = "command";
// some fields
public void setInitializationData(final IConfigurationElement config,
final String propertyName, final Object data) {
/* set fields */
}
protected final IContributionItem[] getContributionItems() {
/* create Items */
}
}
In other plugins I use this ContributionItem implementation by declaring the following:
<menuContribution locationURI="menu:mylocationUri">
<dynamic id="myId">
<class class="ViewerHistoryMenuItems">
<parameter
name="type"
value="someValue">
</parameter>
<parameter
name="command"
value="someCommandId">
</parameter>
</class>
</dynamic>
<command
commandId="someCommandId"
icon="anIcon.png">
</command>
</menuContribution>
When looking at the Problems-View I get two entries there (for each plug-in, which uses this contribution):
**Referenced identifier 'type' in attribute 'name' cannot be found**
**Referenced identifier 'command' in attribute 'name' cannot be found**
What am I missing here? Any ideas, why I get this warning?
PS: It doesn't help, to make the two fields PARAM_TYPE & PARAM_COMMAND public
I do not think this is related to the presence of internal fields within a class.
If you look at a similar error (not the same since it includes annotationType), the correction involved the definition of said Referenced identifier:
Referenced identifier 'com.atlassian.connector.eclipse.cruicible.ui.comment.annotation'
in attribute 'annotationType' cannot be found
Fixed with:
+ <extension
+ point="org.eclipse.ui.editors.annotationTypes">
+ <type
+ markerType="com.atlassian.connector.eclipse.crucible.ui.com.atlassian.connector.eclipse.cruicible.ui.comment.marker"
+ name="com.atlassian.connector.eclipse.cruicible.ui.comment.annotation">
+ </type>
+ </extension>
+ <extension
+ id="com.atlassian.connector.eclipse.cruicible.ui.comment.marker"
+ point="org.eclipse.core.resources.markers">
+ </extension>
Considering the extension point org.eclipse.ui.menus help page:
<!ELEMENT parameter EMPTY>
<!ATTLIST parameter
name IDREF #REQUIRED
value CDATA #REQUIRED
>
A parameter to either an executable extension or a command -- depending on where it appears in the extension.
name - The name is either the name of the parameter to pass to the executable extension, or the identifier of the parameter for the command.
value - The value to pass for this parameter.
You need to reference in the name attribute an id present somewhere else in your plugin.xml.
Sure thing, VonC. Here we go:
Within the dynamic declaration (see above) there are two parameter references
<parameter
name="type"
value="someValue">
</parameter>
<parameter
name="command"
value="someCommandId">
</parameter>
These two parameter are meant to be passed to the command itself. The command declaration is within the same plugin.xml but wasn't declaring these two commandParameters.
What I did was adding these missing commandParameters, resolving the missing reference, which was clearly stated by the warning.
<command
categoryId="aCategory"
id="someCommandId"
name="%theName">
<commandParameter
id="type"
name="type"/>
<commandParameter
id="command"
name="command">
</commandParameter>
</command>
So, you were absolutely right by saying "the correction involved the definition of said reference identifier". The question just was where and what I had to define.
I think, I wasn't thinking about the most obvious in this case.