Visitar URL original
Templates in maps loaded via STGroupFile do not use registered ObjectModelAdaptors · Issue #223 · antlr/stringtemplate4 · GitHub
Skip to content

Templates in maps loaded via STGroupFile do not use registered ObjectModelAdaptors #223

Open

Description

@Aethon

Given ST4 4.1 on the JVM and the following code, I would expect that the View would be dumped out identically both times. However, the following is produced:

before template = View(regularName=HIP! HIP!,special_name=HUZZAH!) and after map template = View(regularName=HIP! HIP!,special_name=)

It seems that the templates in the map create a new group based on the file they appear in but this new group does not inherit the model adaptor registrations from the original group. Much confusion ensues.

import org.stringtemplate.v4.*
import org.stringtemplate.v4.misc.*
import java.nio.charset.StandardCharsets

class Adaptor : ObjectModelAdaptor() {
    override fun getProperty(interp: Interpreter, self: ST, o: Any, property: Any?, propertyName: String): Any? =
        if (propertyName == "special_name")
            "HUZZAH!"
        else
            super.getProperty(interp, self, o, property, propertyName)
}

class View(val regularName: String)

fun main(args: Array<String>) {
    val group = STGroupFile(View::class.java.getResource("/strepl/main.stg"), StandardCharsets.UTF_8.name(), '$', '$')
    group.registerModelAdaptor(Object::class.java, Adaptor())
    val st = group.getInstanceOf("main")
    st.add("view", View("HIP! HIP!"))
    println(st.render())
}

/strepl/main:

import "other.stg"

main(view) ::= "$other_main(view)$"

/strepl/other:

delimiters "$", "$"

other_main(view) ::= "before template = $dump(view)$ and after $map.(\"simple\")$"
map ::= [
    "simple": <%map template = $dump(view)$%>
]
dump(view) ::= "View(regularName=$view.regularName$,special_name=$view.special_name$)"

Activity

  1. Aethon commented on Oct 2, 2019

    @Aethon
    Author

    For anyone that finds this, the workaround I am using is to just store template names in the map and use double indirection to invoke them:

    ... $(map.(\"simple\"))()$ ...
    

    and

    map ::= [
        "simple": "simple_template"
    ]
    
    simple_template() ::= "map template = $dump(view)$"
    

    It is slightly more verbose, but not so terrible as workarounds go :)

  2. parrt commented on Oct 5, 2019

    @parrt
    Member

    hi. is this Kotlin? Might matter. E.g., what if an object gets wrapped and no longer a java object? Maybe the registration no longer works?

  3. Aethon commented on Oct 5, 2019

    @Aethon
    Author

    It is Kotlin. The registrations work, just not after "passing through" a mapped template in a loaded group file.

    I will provide a Java repro after the weekend.

    Thanks.

  4. parrt commented on Oct 5, 2019

    @parrt
    Member

    ok, yeah, Maybe there's something about parameter handoff or dynamic scoping that is screwing something up here.

  5. Aethon commented on Oct 6, 2019

    @Aethon
    Author

    Here is the Java 11 repro (using the same template files above):

    package test;
    
    import org.stringtemplate.v4.Interpreter;
    import org.stringtemplate.v4.ST;
    import org.stringtemplate.v4.STGroupFile;
    import org.stringtemplate.v4.misc.ObjectModelAdaptor;
    
    import java.nio.charset.StandardCharsets;
    
    public class ST4BugReplJava {
        static class Adaptor extends ObjectModelAdaptor {
            @Override
            public Object getProperty(Interpreter interp, ST self, Object o, Object property, String propertyName) {
                if (propertyName.equals("special_name"))
                    return "HUZZAH!";
                return super.getProperty(interp, self, o, property, propertyName);
            }
        }
    
        static class View {
            public String regularName;
    
            public View(String regularName) {
                this.regularName = regularName;
            }
        }
    
        static public void main(String[] args) {
            var group = new STGroupFile(View.class.getResource("/strepl/main.stg"), StandardCharsets.UTF_8.name(), '$', '$');
            group.registerModelAdaptor(Object.class, new Adaptor());
            var st = group.getInstanceOf("main");
            st.add("view", new View("HIP! HIP!"));
            System.out.println(st.render());
        }
    }
  6. deleted a comment from on Apr 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions