When trying to inspect a main template of this group:
main(doit = true) ::= "<if(doit || other)><t(...)><endif>\"
t2() ::= "Hello"
t(x={<(t2())>}) ::= "<x>"
ST4 throws an ArrayIndexOutOfBoundsException
in STRuntimeMessage.getSourceLocation
.
Interestingly removing the "|| other" let you inspect the template.
Also making the default for x = {<t2()>}
(i.e. use lazy evaluation) and keeping the "|| other" also works fine.
I added a test case to TestEarlyEvaluation
and checked it in into Perforce.
Udo
P.S.: here the stack track
java.lang.ArrayIndexOutOfBoundsException: 17
at org.stringtemplate.v4.misc.STRuntimeMessage.getSourceLocation(STRuntimeMessage.java:70)
at org.stringtemplate.v4.misc.STRuntimeMessage.toString(STRuntimeMessage.java:81)
at javax.swing.DefaultListCellRenderer.getListCellRendererComponent(DefaultListCellRenderer.java:134)
at javax.swing.plaf.basic.BasicListUI.updateLayoutState(BasicListUI.java:1344)
at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.java:1294)
at javax.swing.plaf.basic.BasicListUI.getPreferredSize(BasicListUI.java:561)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1634)
at javax.swing.JList.getPreferredScrollableViewportSize(JList.java:2412)
at javax.swing.ViewportLayout.preferredLayoutSize(ViewportLayout.java:75)
at java.awt.Container.preferredSize(Container.java:1599)
at java.awt.Container.getPreferredSize(Container.java:1584)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1636)
at javax.swing.ScrollPaneLayout.preferredLayoutSize(ScrollPaneLayout.java:475)
at java.awt.Container.preferredSize(Container.java:1599)
at java.awt.Container.getPreferredSize(Container.java:1584)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1636)
at java.awt.GridBagLayout.GetLayoutInfo(GridBagLayout.java:1092)
at java.awt.GridBagLayout.getLayoutInfo(GridBagLayout.java:893)
at java.awt.GridBagLayout.preferredLayoutSize(GridBagLayout.java:713)
at java.awt.Container.preferredSize(Container.java:1599)
at java.awt.Container.getPreferredSize(Container.java:1584)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1636)
at javax.swing.JRootPane$RootLayout.preferredLayoutSize(JRootPane.java:907)
at java.awt.Container.preferredSize(Container.java:1599)
at java.awt.Container.getPreferredSize(Container.java:1584)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1636)
at java.awt.BorderLayout.preferredLayoutSize(BorderLayout.java:702)
at java.awt.Container.preferredSize(Container.java:1599)
at java.awt.Container.getPreferredSize(Container.java:1584)
at java.awt.Window.pack(Window.java:706)
at org.stringtemplate.v4.gui.STViz.open(STViz.java:212)
at org.stringtemplate.v4.ST.inspect(ST.java:471)
at org.stringtemplate.v4.ST.inspect(ST.java:454)
at org.stringtemplate.v4.ST.inspect(ST.java:447)
at org.stringtemplate.v4.test.TestEarlyEvaluation.testBugArrayIndexOutOfBoundsExceptionInSTRuntimeMessage_getSourceLocation(TestEarlyEvaluation.java:138)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
stringtemplate-interest mailing list
[email protected]
http://www.antlr.org/mailman/listinfo/stringtemplate-interest
Also: to avoid confusion with the Java null maybe call the constant 'undefined'?
I was kind of thinking that it should be null because it has the same semantics as passing all in to add().
Actually this is not the case as you can see in the following test case. That's why I thought mixing "null" und "undefined" isn't such a good idea.
BTW: in the implementation the "undefined" literal should probably get the value ST.EMPTY_ATTR rather than null.
public class UndefinedOrNullTest extends BaseTest {
@Test
public void testUndefinedParameter() throws Exception {
writeFile(tmpdir, "t.stg", "t(s=\"world\") ::= <<\nHello <s>\n>>");
String path = tmpdir + "t.stg";
STGroup group = new STGroupFile(tmpdir + "/t.stg");
ST st = group.getInstanceOf("t");
String s = st.render();
Assert.assertEquals("Hello world", s);
}
@Test
public void testNullParameter() throws Exception {
writeFile(tmpdir, "t.stg", "t(s=\"world\") ::= <<\nHello <s>\n>>");
String path = tmpdir + "t.stg";
STGroup group = new STGroupFile(tmpdir + "/t.stg");
ST st = group.getInstanceOf("t");
st.add("s", null);
String s = st.render();
Assert.assertEquals("Hello ", s);
}
}
Udo
On 01.08.2011, at 21:33, Terence Parr wrote:
On Aug 1, 2011, at 7:10 AM, Udo Borkowski wrote:
Not sure about the semantic of null.
E.g. assume you have this template
t(s="world") ::= "Hello <s>"
What will
render?
a) "Hello " (i.e. same as <t("")>
)
b) "Hello world" (i.e. same as <t()>
)
I would assume it would render this one since the parameters missing.
c) "Hello null"
d) something else?
Also: to avoid confusion with the Java null maybe call the constant 'undefined'?
I was kind of thinking that it should be null because it has the same semantics as passing all in to add().
Ter
stringtemplate-interest mailing list
[email protected]
http://www.antlr.org/mailman/listinfo/stringtemplate-interest
stringtemplate-interest mailing list
[email protected]
http://www.antlr.org/mailman/listinfo/stringtemplate-interest
Begin forwarded message:
From: Udo Borkowski
Subject: [stringtemplate-interest] ST4: Pass Thru (...) support for indirect includes
Date: August 7, 2011 12:42:43 AM PDT
To: stringtemplate-interest List [email protected]
Is there a reason why indirect includes don't support Pass Thru (…
)?
E.g.
t1(x) ::= "<x>"
main(x="hello",t="t1") ::= "<(t)(...)>"
will emit the following error:
t.stg 2:34: mismatched input '...' expecting RPAREN
However explicitly passing the parameter (x) with the indirect include, like in this example:
t1(x) ::= "<x>"
main(x="hello",t="t1") ::= "<(t)(x)>"
works fine.
If there is no real reason for this restriction I suggest to add "Pass Thru" support for indirect calls into the next release of ST4.
Udo
P.S.: Possibly the same applies for "named arguments" and indirect includes.
P.P.S.: here the test case:
@Test
public void testIndirectCallWithPassThru() throws Exception {
String path = tmpdir + "t.stg";
// indirectly call t1, with explicit parameter passing
writeFile(tmpdir, "t.stg",
"t1(x) ::= \"<x>\"\nmain(x=\"hello\",t=\"t1\") ::= <<\n<(t)(x)>\n>>");
STGroup group = new STGroupFile(tmpdir + "/t.stg");
ST st = group.getInstanceOf("main");
String s = st.render();
Assert.assertEquals("hello", s);
// indirectly call t1, with "pass thru" (...) parameter passing
// (used to fail with:
// "t.stg 2:21: mismatched input '...' expecting RPAREN")
writeFile(tmpdir, "t.stg",
"t1(x) ::= \"<x>\"\nmain(x=\"hello\",t=\"t1\") ::= <<\n<(t)(...)>\n>>");
group = new STGroupFile(tmpdir + "/t.stg");
st = group.getInstanceOf("main");
s = st.render();
Assert.assertEquals("hello", s);
}