[stringtemplate-interest] Group Syntax extension for ModelAdapter and Renderer

Terence Parr parrt at cs.usfca.edu
Sat Jun 25 11:08:45 PDT 2011


hiya.  Inheritance will work on this.  it's the only way polymorphism works with template instantiation; same for adaptors/renderers.  If A imports B we created templates relative to A even if defined in B.  Therefore, a renderer for A works for B.  A's renderer overrides any you set in B as well.  No need to think about propagation or whatever.

I'll go look at inheritance mech. i see on my list "should adaptors get imported from super group?"

http://www.antlr.org/wiki/display/ST4/ST+v4+TODO+list

Ter
On Jun 24, 2011, at 7:20 AM, Sam Barnett-Cormack wrote:

> On 24/06/2011 14:59, Sam Harwell wrote:
>> The VM-wide setting approach seems like a possibility, but only if the "VM"
>> is an instance object. There are a number of cases where I run several
>> independent ST "sessions" within a single process, so I'm trying hard to
>> remove every last mutable static variable from the entire [C# port of the]
>> library. Perhaps an Interpreter object could be stored in an STGroup at the
>> time when the group is constructed, and that interpreter used for all
>> rendering of templates accessed through that group's getInstanceOf() method.
>> That way, we have a "VM" which is a single interpreter used for that group's
>> operations. I'd even go so far as to declare the Interpreter field of
>> STGroup final, giving a fixed view of the VM.
> 
> I used the term VM based on my understanding of the Java version. I 
> would agree that it would be best not to have such things truly static - 
> I would support a (for example) STInterpreter class, an instance of 
> which can be used when creating a group, or it be specified with a 
> boolean parameter that a new one should be created (otherwise a truly 
> VM-wide default shared one would be used). I imagine implementation 
> would be awkward if you could import groups that use a different 
> STInterpreter from the one doing the important (depending on what 
> actually gets stored in the instance), but otherwise it's a good way to 
> share details of such things between multiple groups under control. 
> Perhaps allow STInterpreters to be defined as 'children' of another 
> STInterpreter, with any properties not specifically set in that child 
> being proxied to the parent (implementation details could vary, but I 
> can see that being easiest with a specialised subclass).
> 
> And yes, it would make sense for the interpreter of any given STGroup to 
> be final, to whatever extent is possible in any given implementation 
> language. You don't want to be changing back and forth all of those 
> things after a group is created, though you may want to manipulate the 
> interpreter itself.
> 
> This would also fit with the usual patterns used for such things in Java 
> these days, particularly EE, allowing it to fit better with Dependency 
> Injection and Contexts. It's definitely more common in my experience to 
> have some sort of context class to hold such things than it is to have 
> anything global/static.
> 
> Sam
> 
>> -----Original Message-----
>> From: Sam Barnett-Cormack [mailto:s.barnett-cormack at lancaster.ac.uk]
>> Sent: Friday, June 24, 2011 5:17 AM
>> To: Udo Borkowski
>> Cc: Sam Harwell; 'stringtemplate-interest Template'; 'Terence Parr'
>> Subject: Re: [stringtemplate-interest] Group Syntax extension for
>> ModelAdapter and Renderer
>> 
>> Sorry to top-post, but this is a very general statement/opinion...
>> 
>> Renderers and ModelAdapters need to be entirely in the programming side,
>> surely, to keep the complete language-agnostic value of template code.
>> Unlike Antlr grammars, for instance, there's nothing in a StringTemplate
>> that is ever language-specific (in terms of implementation), that I'm aware
>> of, and I devoutly hope it will remain so.
>> 
>> Furthermore, whether it happens at the programming level or in the group
>> file (and what about people not using group files, but group dirs or a
>> custom group type), whatever is chosen in terms of when to propagate and in
>> which direction, there will always be situations where what happens isn't
>> what makes sense for that use-case. Thus, what would really be ideal is a
>> way of controlling it more finely, as to when it propagates or doesn't, some
>> sort of configuration. This would, however, likely be a huge burden on the
>> ST developers, and a pretty big burden on those using it.
>> 
>> One alternative that occurs to me as probably working in most cases, is to
>> allow a VM-wide setting of model adapters and renderers, and then allow
>> group-specific overriding of this. Whether the group-specific ones then
>> propagate or not, and in which direction, I'm not sure. You obviously can't
>> have them propagating in both directions without every change always
>> affecting the whole constellation of groups involved, which would seem
>> suboptimal to me.
>> 
>> Anyway, that's just some software engineering thoughts. To get a better
>> decision, it would really make sense to drill down to some competing
>> use-cases and see if there's a common denominator that would work in all
>> cases that anyone can think of.
>> 
>> Sam
>> 
>> On 24/06/2011 10:41, Udo Borkowski wrote:
>>> The "propagation" approach solves one half of the problem: with this
>>> approach one could use renderers and adapters in groups that are
>>> imported through the "import" statement (and not programmatically).
>>> This is currently not possible.
>>> 
>>> But the other half of the problem still exists: assume I change a
>>> group G and use some special renderer in the new version. The group G
>>> is imported by many other groups (maybe indirectly). I now need to
>>> find all the "roots" of imports to G and add the new renderer there.
>>> This can really become a maintenance nightmare. Providing the
>>> "renderer" syntax extension and defining the renderer in the group
>>> text would solve this issue.
>>> 
>>> Regarding the implementation of the "propagation" approach:
>>> registering a renderer will require to visit all directly and
>>> indirectly imported groups and add the renderer to all of them,
>>> possibly creating new maps etc.. Most of the times this will be extra
>>> work as the imported groups don't reference that renderer. Propagating
>>> a renderer to all imported groups may lead to a performance issue when
>> using large systems.
>>> 
>>> I would also hesitate to use the "propagation" approach as it adds a
>>> new concept to StringTemplate ("propagation of renderers") that in
>>> addition seems to "reverse" an already existing concept
>>> ("inheritance"). I guess this may to misunderstandings.
>>> 
>>> In contrast to this the "renderer" syntax extension does not use a new
>>> concept but rather makes an existing feature ("registerRenderer")
>>> accessible to those users who prefer to work on the group text than
>>> coding in Java.
>>> 
>>> As the "propagation" approach does not solve the whole problem I still
>>> think we should add the "renderer"/"adapter" feature I suggested.
>>> 
>>> Udo
>>> 
>>> P.S.: all stuff mentioned regarding "renderer" also applied "adapter".
>>> 
>>> 
>>> 
>>> On 23.06.2011, at 23:38, Sam Harwell wrote:
>>> 
>>>> This is an interesting problem. Normally when things are inherited,
>>>> they start at the imported group and propagate to the group that
>>>> imported them. In this case, it sounds like you want to propagate it
>>>> from the topmost group to all the groups it imports.
>>>> Perhaps the thing to do here is propagate renderers to groups
>>>> imported with STGroup.importTemplates(Token) (those are the ones
>>>> imported via the group file), but don't propagate them to groups
>>>> imported with a direct call to importTemplates(STGroup)?
>>>> If you look at the diff of TemplateGroup.cs in CL8734 (it's a small
>>>> diff), you can see how I adjusted the import code to handle the
>>>> unload() method in everyone's cases. If the java code is adjusted in
>>>> the same way (I can make the change if you want), then it's easy to
>>>> propagate renderers by the following two rules:
>>>> 1.When STGroup.importTemplates(Token) is called, the current group's
>>>> renderers are added to the group that just got imported. This handles
>>>> the case where the renderer is registered before the group is
>>>> imported (especially relevant in reloading a group file after calling
>> unload()).
>>>> 2.When a renderer is added to a group, it is automatically added (by
>>>> calling registerRenderer) to all groups in the importsToClearOnUnload
>>>> list. This handles the case where the group is imported before the
>>>> renderer is registered.
>>>> Sam
>>>> *From:*stringtemplate-interest-bounces at antlr.org
>>>> <mailto:stringtemplate-interest-bounces at antlr.org>[mailto:stringtempl
>>>> ate-interest-bounces at antlr.org]*On
>>>> Behalf Of*Terence Parr
>>>> *Sent:*Thursday, June 23, 2011 1:44 PM *To:*Udo Borkowski
>>>> *Cc:*stringtemplate-interest Template
>>>> *Subject:*Re: [stringtemplate-interest] Group Syntax extension for
>>>> ModelAdapter and Renderer I think that we should probably keep this
>>>> at the programming level.
>>>> should we make renderers inherited instead to solve your problem?
>>>> Ter
>>>> On Jun 21, 2011, at 1:17 AM, Udo Borkowski wrote:
>>>> 
>>>> 
>>>> Hi,
>>>> currently we programmatically register ModelAdapters and Renderers to
>>>> an STGroup.
>>>> What about providing an extension to the syntax of Group to also
>>>> define these in a Group file?
>>>> E.g. I could imagine to use something like
>>>> 
>>>>     adapter "org.w3c.dom.Node"
>>>>     "com.collinfagan.strum.adapters.xml.NodeModelAdapter"
>>>>     renderer "org.w3c.dom.Node"
>>>>     "com.collinfagan.strum.adapters.xml.NodeRenderer"
>>>> 
>>>> at the top of an Group file. This would mean the same as running this
>>>> Java code for the group:
>>>> 
>>>>     group.registerRenderer(org.w3c.dom.Node.class, new
>>>>     com.collinfagan.strum.adapters.xml.NodeRenderer());
>>>> 
>>>>     group.registerModelAdaptor(org.w3c.dom.Node.class, new
>>>>     com.collinfagan.strum.adapters.xml.NodeModelAdapter());
>>>> 
>>>> Especially when importing groups this feature comes in handy as I
>>>> cannot register adapters/renderers when importing. In these cases I
>>>> must rely on the root group. For this group R we must register ALL
>>>> adapters/renders used in ANY group R imports. This make things hard
>>>> to maintain as using a "new" renderer in some template T requires me
>>>> to add the "registerRenderer" in EVERY code using T, maybe indirectly
>>>> through imports.
>>>> Similar to features discussed earlier this feature is easy to
>>>> implement for the STGroupFile, but the STGroupDir currently has no
>>>> proper place to hold this information. So we may also need to tackle
>>>> this re-appearing topic, too.
>>>> What do others think?
>>>> Udo
>>>> _______________________________________________
>>>> stringtemplate-interest mailing list
>>>> stringtemplate-interest at antlr.org
>>>> <mailto:stringtemplate-interest at antlr.org>
>>>> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> stringtemplate-interest mailing list
>>> stringtemplate-interest at antlr.org
>>> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
>> 
>> 
> 
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org/mailman/listinfo/stringtemplate-interest



More information about the stringtemplate-interest mailing list