Is there a concise way to reference a property of a property in StringTemplate - stringtemplate-4

I find myself wanting to write <prop1.subprop1:sometemplate> to apply a template to a list in a property of a property. To do this, I have to make two levels of template: I have to invoke the outer one on prop1 and and then have it process the next property down.
Data model:
class Clazz {
String name;
Class parent;
}
Goal:
class(c) ::= <<
<c.parent.name> <! oops, not allowed !>
>>
So I end up with
<c.parent:{ p | <p.name> }>
which is a little clumsy.
Then I got to this:
class Attr {
List<String> requiredParameters;
Attr baseObject;
}
and I want to generate:
def __init__(self, reqparam1, ... rewqparamN)
where the first 'reqparam' is from the deepest item. I tried to write the following, but ST gives me syntax errors in the second template where I try to recurse to build a list.
self_and_list(list) ::= << self<if(first(list))>, <endif><list;separator=", "> >>
recurse_req(attr) ::= "<[<attr.baseObject:recurse_req()>, <attr.requiredParameters>]>"
self_and_req_params(attribute) ::= "<self_and_list(<attribute:recurse_req()>)>"

Related

how to use template "inheritance" to avoid boilerplate code when binding C++ to python with pybind11

I managed to bind template definitions doing
py::class_<T<a>>(m, "Ta")
py::class_<T<b>>(m, "Tb")
...
where T is the template class and a and b typenames defining the template. But the problem I have tells me that this is not the really good way to expose these template definitions, because now I am forced to duplicate code for all the functions and parameters of the template class T:
py::class_<T<a>>(m, "Ta")
.def(py::init<string, string>())
.def("do_smthg", &T<a>::do_sthg)
...;
py::class_<T<b>>(m, "Tb")
.def(py::init<string, string>())
.def("do_smthg", &T<b>::do_sthg)
...;
when class T itself for instance has do_smthg, that I would then expect to have to define only once. I tried to browse the doc and the web, but I failed to find the right pointer.
You may just create a simple helper function that instantiates a list of templates, like following:
template <typename x, typename ... Tail, typename ModT>
void ApplyTemplate(ModT & m, std::vector<std::string> names) {
py::class_<T<x>>(m, names.at(0))
.def(py::init<string, string>())
.def("do_smthg", &T<x>::do_sthg)
;
names.erase(names.begin());
if constexpr(sizeof...(Tail) > 0)
ApplyTemplate<Tail...>(m, names);
}
Now call this function within module context with all possible arguments to template:
PYBIND11_MODULE(example, m) {
ApplyTemplate<a, b>(m, {"Ta", "Tb"});
}
If for some reason your T template is not available within ApplyTemplate context then you may pass it as a template <typename> typename argument:
template <template <typename> typename T, typename x, typename ... Tail, typename ModT>
void ApplyTemplate(.....
Instead of function you can also use a simple macro:
PYBIND11_MODULE(example, m) {
// Define macro
#define MY_CLASS(param, name) \
py::class_<T<param>>(m, name) \
.def(py::init<string, string>()) \
.def("do_smthg", &T<param>::do_sthg) \
;
// Use macro
MY_CLASS(a, "Ta");
MY_CLASS(b, "Tb");
// Remove macro
#undef MY_CLASS
}

init block position in class in Kotlin

I recently came across a situation where my standard variable's values are replaced by the default one even if I have assigned a value with the constructor using init block.
What I tried was:
class Example(function: Example.() -> Unit) {
init {
function()
}
var name = "default name"
}
// assigning it like this:
val example = Example { name = "new name" }
// print value
print(example.name) // prints "default name"
After struggling a bit, I have found that the position of the init block matters. If I put the init block at the last in the class, It initializes the name with default one first and then calls the function() which replaces the value with the "new name".
And If I put it first, it doesn't found the name and it is replaced by the "default name" when properties are initialized.
This is strange to me. Can anyone explain why this has happened?
The reason is kotlin follows top-to-bottom approach
From the documents (An in-depth look at Kotlin’s initializers) Initializers (property initializers and init blocks) are executed in the order that they are defined in the class, top-to-bottom.
You can define multiple secondary constructors, but only one will be called when you create a class instance unless the constructor explicitly calls another one.
Constructors can also have default argument values which are evaluated each time the constructor is called. Like property initializers, these can be function calls or other expressions that will run arbitrary code.
initializers are run top to bottom at the beginning of a class’ primary constructor.
This is correct way
class Example(function: Example.() -> Unit) {
var name = "default name"
init {
function()
}
}
Java constructor is just a method that run after object creation. Before running the constructor, all the class fields get initialized.
In Kotlin there are two types of constructors namely primary constructor and the secondary constructor. I see primary constructor as a regular java constructor that supports field encapsulation built-in. After compilation, primary constructor fields are put on the top of the class if they have declared visible to the whole class.
In java or kotlin, constructor is invoked after initializing class fields. But in primary constructor we cannot write any statements. If we want to write statements that need to be executed after object creation, we have to put them in the initialization blocks. But init blocks are executed as they appear in the class body. We can define multiple init blocks in the class. They will be executed from top to the bottom.
Lets do some experiment with init blocks..
Test.kt
fun main() {
Subject("a1")
}
class Element {
init {
println("Element init block 1")
}
constructor(message: String) {
println(message)
}
init {
println("Element init block 2")
}
}
class Subject(private val name: String, e: Element = Element("$name: first element")) {
private val field1: Int = 1
init {
println("$name: first init")
}
val e2 = Element("$name: second element")
init {
println("$name: second init")
}
val e3 = Element("$name: third element")
}
Lets compile the above and run it.
kotlinc Test.kt -include-runtime -d Test.jar
java -jar Test.jar
The output of the above program is
Element init block 1
Element init block 2
a1: first element
a1: first init
Element init block 1
Element init block 2
a1: second element
a1: second init
Element init block 1
Element init block 2
a1: third element
As you can see, first primary constructor was called, before secondary constructor, all the init blocks were executed. This is because init blocks become a part of the constructor in the order they appear in the class body.
Lets compile the kotlin code to java byte code and decompile it back to java. I used jd-gui to decompile java classes. You can install it with yay -S jd-gui-bin in arch linux based distributions.
Here is the output I got after decompiling Subject.class file
import kotlin.Metadata;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
#Metadata(mv = {1, 6, 0}, k = 1, xi = 48, d1 = {"\000\034\n\002\030\002\n\002\020\000\n\000\n\002\020\016\n\000\n\002\030\002\n\002\b\007\n\002\020\b\030\0002\0020\001B\027\022\006\020\002\032\0020\003\022\b\b\002\020\004\032\0020\005\006\002\020\006R\021\020\007\032\0020\005\006\b\n\000\032\004\b\b\020\tR\021\020\n\032\0020\005\006\b\n\000\032\004\b\013\020\tR\016\020\f\032\0020\rX\006\002\n\000R\016\020\002\032\0020\003X\004\006\002\n\000"}, d2 = {"LSubject;", "", "name", "", "e", "LElement;", "(Ljava/lang/String;LElement;)V", "e2", "getE2", "()LElement;", "e3", "getE3", "field1", ""})
public final class Subject {
#NotNull
private final String name;
private final int field1;
#NotNull
private final Element e2;
#NotNull
private final Element e3;
public Subject(#NotNull String name, #NotNull Element e) {
this.name = name;
this.field1 = 1;
System.out
.println(Intrinsics.stringPlus(this.name, ": first init"));
this.e2 = new Element(Intrinsics.stringPlus(this.name, ": second element"));
System.out
.println(Intrinsics.stringPlus(this.name, ": second init"));
this.e3 = new Element(Intrinsics.stringPlus(this.name, ": third element"));
}
#NotNull
public final Element getE2() {
return this.e2;
}
#NotNull
public final Element getE3() {
return this.e3;
}
}
As you can see all the init blocks have become a part of the constructor in the order they appear in the class body. I noticed one thing different from java. Class fields were initialized in the constructor. Class fields and init blocks were initialized in the order they appear in the class body. It seems order is so important in kotlin.
As stated in the Kotlin docs:
During an instance initialization, the initializer blocks are executed in the same order as they appear in the class body, interleaved with the property initializers: ...
https://kotlinlang.org/docs/classes.html#constructors

How to write a macro to generate list item

I have a list of structs, the struct has a field which defines it's type (assume it's name).
I would to have a macro as follows:
MYKEEP <name>.<field> <ANY KEEP>;
which would be translated to:
keep value(mylist.has(it.name == <name>)) => mylist.first(it.name == <name>).<field> <ANY KEEP>
Is it possible to do it without an "as computed" macro?
it looks like you want to get a list of structs as an input, check the value of some of the
struct's fields, and then assign a constant value to a different struct field
according to that value.
taking performance into account,this kind of 'Injective' relationship between the two fields should
be in proceedural code rather than generative. (most likely in post_generate()).
consider using a define as macro that looks like this:
define <name_induced_field'struct_member> "MYKEEP <name'exp> <field'exp> <ANY_KEEP'exp>" as{
post_generate() is also{
for each in l{
if (it.t==<name'exp>){
it.<field'exp> = <ANY_KEEP'exp>;
};
};
};
};
and then use it in the code like so:
type mytype: [AA,BB];
struct s {
t:mytype;
!i:int;
};
extend sys{
MYKEEP AA i 1;
MYKEEP BB i 2;
l:list of s;
keep l.size()==5;
};
note: if the struct field has the same relationship to it's name in other cases ,consider
maybe constraining the field from within the struct, for example:
define <name_induced_field'struct_member> "MYKEEP <name'exp> <field'exp> <ANY_KEEP'exp>" as{
keep value(t==<name'exp>) => (<field'exp>==<ANY_KEEP'exp>);
};
type mytype: [AA,BB];
struct s {
MYKEEP AA i 1;
MYKEEP BB i 2;
t:mytype;
i:int;
post_generate() is also{
print me;
};
};
proceedural code doesn't help me, because these fields may effect others in generation time.
I manged to find a macro that seems to work:
define <ana_packet_gen_con_keep1'exp> "KEEP_CON [(<WORD>soft) ]<type'exp>\.<field'any> <exp>" as {
keep for each (con) in it.containers {
<WORD> (con.con_type==<type'exp>) => con.as_a(<type'exp>'con_type ana_container).<field'any> <exp>;
};
};
Does having several "keep for each" effect the performance too much?

Working with Classes in vb6 with user selected fields

I found out how to create the properties of the class, like this:
private m_Name as string
public property get Name() as string
Name = m_Name
end sub
public property let Name(sval as string)
m_name = sval
end sub
The user will create a document and choose some fields (Name, Birthday, Phone....) inside this document, as I can't know exactly which fields will be chosen by the user, I thought create a class would be the best option.
After I create the class like above, how may I make a loop through this class to check which fields has been chosen by the user?
Any better option for my situation, please, let me know...
If I understood you correctly, you want to know which fields (out of a number of existing fields) user used/initialized?
I see several ways to do it:
1) If your variables do not have default values and must have a non-empty/non-zero values, then you can simply check if a variable is empty or zero. If it is, it hasn't been initialized.
If m_name = "" Then MsgBox "Variable is not initialized"
2) for each field you have, create a boolean fieldName_Initialized so for each field, you would have something like this:
private m_Name as string
private m_name_Initialized as Boolean
public property get Name() as string
Name = m_Name
end sub
public property let Name(sval as string)
m_name = sval
m_name_Initialized = True
end sub
3) you could have a list and add variable names to the list as they become initialized:
Make sure to add Microsoft Scripting Runtime to your References for Dictionary to work.
Dim initialized As Dictionary
Set initialized = New Dictionary
private m_Name as string
private m_name_Initialized as Boolean
public property get Name() as string
Name = m_Name
end sub
public property let Name(sval as string)
m_name = sval
initialized.Add "m_name", True
end sub
Then, to check if the var has been initialized:
If initialized.Exists("m_name") Then
' Var is initialized
4) similar to #3, except use an array of booleans. Tie specific var to a specific index, like m_name is index 0. This way you skip the hassle of controlling variable names (adds to maintenance cause as far as I know you can't get the name of the variable)
Personally, #1 is the most simple, but may not be possible in a certain situations. If #1 does not apply, I would personally pick #2, unless someone can figure out how to get a string representation of a variable name from the variable itself, then #3 is preferred.
I guess what you need is a kind of Nullable-behaviour. Yes you can do this ins VB6 with the datatype Variant. Then you can use the function "IsEmpty()" to check if a property was already set or not.
a little code-example:
Option Explicit
Private m_Vars()
'0 : Name
'1 : Birthday
'2 : Phone
Private Sub Class_Initialize()
ReDim m_Vars(0 To 2)
End Sub
Public Property Get Name() As String
Name = m_Vars(0)
End Property
Public Property Let Name(RHS As String)
m_Vars(0) = RHS
End Property
Public Property Get Birthday() As Date
Birthday = m_Vars(1)
End Property
Public Property Let Birthday(RHS As Date)
m_Vars(1) = RHS
End Property
Public Sub DoSomething()
Dim i As Integer
For i = 0 To UBound(m_Vars)
Dim v: v = m_Vars(i)
If IsEmpty(v) Then
MsgBox "is empty"
Else
MsgBox v
End If
Next
End Sub
If I understand correctly, the user will add tags or something to something like a document (e.g. [Name]) and you want to know how to map your class members to these tags. To do this, you dont really want to loop thru the class members, but the document tags to find out what is needed. When you find a "tag", submit it to your class to fill in the blank.
Part 1 is a parser to find the tags...my VB6 is very rusty, so pseudocode for this:
Const TagStart = "[" ' "$[" is better as it is not likely to appear
Const TagStop = "]" ' "]$" " " "
' make this a loop looking for tags
i = Instr(docScript, TagStart)
j = Instr(docScript, TagStop)
thisTag = Mid(docScript, TagStart, TagEnd )
' not correct, but the idea is to get the text WITH the Start and Stop markers
' like [Name] or [Address]
' get the translation...see below
docText = MyClass.Vocab(thisTag)
' put it back
Mid(docScript, TagStart, TagEnd) = docText
It is actually better to look for each possible legal tag (ie Instr(docScript, "[Name]")) which are stored in an array but you may have to do that in 2 loops to allow that a given tag could be requested more than once.
Part 2 supply the replacement text from MyClass:
Friend Function Vocab(tag as string) As String
Dim Ret as string
Select Case tag
Case "$[NAME]$"
ret = "Name: " & m_Name
' if the caption is part of the "script" then just:
'ret = m_Name
Case "$[ADDRESS]$"
ret = "Address: " & m_Addr
' if not found, return the tag so you can add new Vocab items
' or user can fix typos like '[NMAR]'
Case Else
ret = tag
...
End Select
Return Ret
End Function
The parsing routines in Part 1 could also be a method in your class to process the document "script" which calls a private Vocab.
Edit
a fraction of a 'script' might look like this:
Customer's Name:| $[CUST_FNAME]$ $[CUST_LNAME]$ (ignore the pipe (|) it was a table cell marker)
The parser looks thru the string to find "$[", when it does, it isolates the related tag $[CUST_FNAME]$. If you have a large number, the first part (CUST) can be used as a router to send it to the correct class. Next, call the method to get the translation:
newText = Cust.Vocab(thisTag)
Cust Class just looks at the tag and returns "Bob" or whatever and the parsing loop replaces the tag with the data:
Customer's Name:| Bob $[CUST_LNAME]$
Then just continue until all the tags have been replaced.
With "just" 22 vocab items, you could create a dedicated class for it:
Vocab.Translate(tag ...) as string
Case "$[CUST_FNAME]$"
return Cust.FirstName
...or
Are you trying to work out a way to do this via a DOC object from office? The above is more of from the ground up document composition type thing. For office I'd think you just need some sort of collection of replacement text.
HTH
If the user has a form that they do something to create their document, why not use simple checkbox controls, one for each possible field? If you want to use a loop to check for selected fields make the checkboxes a control array and loop though the array. You can assign the field name to the Tag property, then if the checkbox is checked add the field to an array.

Can I generate fields automatically in eclipse from a constructor?

When I'm coding in eclipse, I like to be as lazy as possible. So I frequently type something like:
myObject = new MyClass(myParam1, myParam2, myParam3);
Even though MyClass doesn't exist and neither does it's constructor. A few clicks later and eclipse has created MyClass with a constructor inferred from what I typed. My question is, is it possible to also get eclipse to generate fields in the class which correspond to what I passed to the constructor? I realize it's super lazy, but that's the whole joy of eclipse!
If you have a class A.
class A{
A(int a |){}
}
| is the cursor. Crtl + 1 "assign parameter to new field"
Result:
class A{
private final int a;
A(int a){
this.a = a;
}
}
This works also for methods:
void method(int b){}
Will result in:
private int b;
void method(int b){
this.b = b;
}
I know you can do the other way round. Define the fields and let Eclipse generate a constructor using these fields for you: Source | Generate Constructor using Fields
Since Eclipse Neon it is possible to assign all parameters to fields.
Using the quick assist Ctrl + 1 it suggest Assign all parameters to new fields. You can call for the quick assist if the cursor is anywhere between the parenthesis of the constructor.
This option is available for methods as well.
source