Skip to content

Commit ed48d6b

Browse files
author
jeloguy15
committed
Fixed bugs with varargs in the parser & added the rebuild-parser command to the ant script that will take care of the javacc and uncomment all generics and clean compile.
git-svn-id: file:///tmp/test-svn/trunk@2630 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent 4d3fa64 commit ed48d6b

File tree

10 files changed

+1748
-1313
lines changed

10 files changed

+1748
-1313
lines changed

dynamicjava/src/koala/Version.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
* This file is copied to Version.java by the build process, which also
5454
* fills in the right values of the date and time.
5555
*
56-
* This javadoc corresponds to build drjava-20040808-2204;
56+
* This javadoc corresponds to build drjava-20040812-1723;
5757
*
5858
* @version $Id$
5959
*/
@@ -62,7 +62,7 @@ public abstract class Version {
6262
* This string will be automatically expanded upon "ant commit".
6363
* Do not edit it by hand!
6464
*/
65-
private static final String BUILD_TIME_STRING = "20040808-2204";
65+
private static final String BUILD_TIME_STRING = "20040812-1723";
6666

6767
/** A {@link Date} version of the build time. */
6868
private static final Date BUILD_TIME = _getBuildDate();

dynamicjava/src/koala/build.xml

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939
<property name="manifest" value="manifest" />
4040

4141

42+
<!-- properties for the parser generation -->
43+
<property environment="env" />
44+
<property name="parser_path" value="dynamicjava/parser" />
45+
<property name="javacc_home" value="${env.JAVACC_HOME}" />
46+
<!-- end properties for autocomplete parser generation -->
47+
4248
<!-- Sets a flag indicating that code dealing with new features since the
4349
last stable release should be enabled and testable.
4450
Takes effect only after a clean compile -->
@@ -115,6 +121,124 @@
115121
</antcall>
116122
</target>
117123

124+
125+
126+
127+
<!-- targets used to generate the parser for autocompletion -->
128+
<target name="clean-parser">
129+
<delete file="${parser_path}/Parser.java" />
130+
<delete file="${parser_path}/ParserConstants.java" />
131+
<delete file="${parser_path}/ParserTokenManager.java" />
132+
</target>
133+
134+
<!-- based off of fixparser script in parser folder -->
135+
<target name="generate-parser" depends="init">
136+
<javacc target="${parser_path}/grammar.jj" javacchome="${javacc_home}" outputdirectory="${parser_path}" />
137+
<echo message="Uncommenting the generics in the Parser.java file" />
138+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
139+
<arg line="&quot;s/\/\*&lt;/&lt;/g&quot;" />
140+
<arg line="Parser.java" />
141+
</exec>
142+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
143+
<arg line="&quot;s/&gt;\*\//&gt;/g&quot;" />
144+
<arg line="tmpParser1.java" />
145+
</exec>
146+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
147+
<arg line="&quot;s/List name[(]/List&lt;IdentifierToken&gt; name(/&quot;" />
148+
<arg line="tmpParser2.java" />
149+
</exec>
150+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
151+
<arg line="&quot;s/List TypeArguments[(]/List&lt;Type&gt; TypeArguments(/&quot;" />
152+
<arg line="tmpParser1.java" />
153+
</exec>
154+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
155+
<arg line="&quot;s/List ReferenceTypeNameList[(]/List&lt;? extends ReferenceType&gt; ReferenceTypeNameList(/&quot;" />
156+
<arg line="tmpParser2.java" />
157+
</exec>
158+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
159+
<arg line="&quot;s/List localVariableDeclaration[(]/List&lt;Node&gt; localVariableDeclaration(/&quot;" />
160+
<arg line="tmpParser1.java" />
161+
</exec>
162+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
163+
<arg line="&quot;s/List nameList[(]/List&lt;List&lt;IdentifierToken&gt;&gt; nameList(/&quot;" />
164+
<arg line="tmpParser2.java" />
165+
</exec>
166+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
167+
<arg line="&quot;s/List enumConstants[(]/List&lt;EnumDeclaration.EnumConstant&gt; enumConstants(/&quot;" />
168+
<arg line="tmpParser1.java" />
169+
</exec>
170+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
171+
<arg line="&quot;s/List enumBodyDeclarations[(]/List&lt;Node&gt; enumBodyDeclarations(/&quot;" />
172+
<arg line="tmpParser2.java" />
173+
</exec>
174+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
175+
<arg line="&quot;s/List topLevelStatement[(]/List&lt;Node&gt; topLevelStatement(/&quot;" />
176+
<arg line="tmpParser1.java" />
177+
</exec>
178+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
179+
<arg line="&quot;s/List classBodyDeclaration[(]/List&lt;Node&gt; classBodyDeclaration(/&quot;" />
180+
<arg line="tmpParser2.java" />
181+
</exec>
182+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
183+
<arg line="&quot;s/List fieldDeclaration[(]/List&lt;Node&gt; fieldDeclaration(/&quot;" />
184+
<arg line="tmpParser1.java" />
185+
</exec>
186+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
187+
<arg line="&quot;s/List formalParameters[(]/List&lt;FormalParameter&gt; formalParameters(/&quot;" />
188+
<arg line="tmpParser2.java" />
189+
</exec>
190+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
191+
<arg line="&quot;s/List argumentList[(]/List&lt;Expression&gt; argumentList(/&quot;" />
192+
<arg line="tmpParser1.java" />
193+
</exec>
194+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
195+
<arg line="&quot;s/List parseStream[(]/List&lt;Node&gt; parseStream(/&quot;" />
196+
<arg line="tmpParser2.java" />
197+
</exec>
198+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
199+
<arg line="&quot;s/List parseCompilationUnit[(]/List&lt;Node&gt; parseCompilationUnit(/&quot;" />
200+
<arg line="tmpParser1.java" />
201+
</exec>
202+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
203+
<arg line="&quot;s/List interfaceMemberDeclaration[(]/List&lt;Node&gt; interfaceMemberDeclaration(/&quot;" />
204+
<arg line="tmpParser2.java" />
205+
</exec>
206+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
207+
<arg line="&quot;s/List blockStatement[(]/List&lt;Node&gt; blockStatement(/&quot;" />
208+
<arg line="tmpParser1.java" />
209+
</exec>
210+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
211+
<arg line="&quot;s/List forInit[(]/List&lt;Node&gt; forInit(/&quot;" />
212+
<arg line="tmpParser2.java" />
213+
</exec>
214+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser2.java">
215+
<arg line="&quot;s/List statementExpressionList[(]/List&lt;Node&gt; statementExpressionList(/&quot;" />
216+
<arg line="tmpParser1.java" />
217+
</exec>
218+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser1.java">
219+
<arg line="&quot;s/Vector/Vector&lt;Object&gt;/g&quot;" />
220+
<arg line="tmpParser2.java" />
221+
</exec>
222+
223+
<!-- This is a template for the above calls to sed. Replace the #s with the correct values. follow the
224+
pattern used for the numbering of tmpParser and make sure the output of the last one is the one
225+
moved and the input of the last one is the one deleted.
226+
227+
<exec executable="sed" dir="${parser_path}" failonerror="true" output="${parser_path}/tmpParser#.java">
228+
<arg line="&quot;#&quot;" />
229+
<arg line="tmpParser#.java" />
230+
</exec>
231+
-->
232+
233+
<move file="${parser_path}/tmpParser1.java" tofile="${parser_path}/Parser.java" />
234+
<delete file="${parser_path}/tmpParser2.java" />
235+
</target>
236+
237+
<target name="rebuild-parser" depends="clean, clean-parser, generate-parser, compile" />
238+
239+
240+
241+
118242
<target name="compile" depends="do-compile">
119243

120244
<copy todir="${built}">

dynamicjava/src/koala/dynamicjava/interpreter/EvaluationVisitor.java

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,44 @@ private Object buildArrayOfRemainingArgs(Class[] typs, int larg_size, Iterator<E
805805
Object argArray = Array.newInstance(componentType,new int[]{(larg_size-typs.length+1)});
806806
for(int j = 0; j < larg_size-typs.length+1; j++){
807807
Object p = it.next().acceptVisitor(this);
808-
Array.set(argArray, j, performCast(componentType, p));
808+
Object casted = performCast(componentType, p);
809+
if (componentType.isPrimitive()) {
810+
if (componentType == boolean.class && casted instanceof Boolean) {
811+
Array.setBoolean(argArray, j, ((Boolean)casted).booleanValue());
812+
}
813+
else if (componentType == char.class && casted instanceof Character) {
814+
Array.setChar(argArray, j, ((Character)casted).charValue());
815+
}
816+
else if (casted instanceof Number) {
817+
if (componentType == char.class) { // just in case
818+
Array.setChar(argArray, j, (char)((Number)casted).intValue());
819+
}
820+
else if (componentType == byte.class) {
821+
Array.setByte(argArray, j, ((Number)casted).byteValue());
822+
}
823+
else if (componentType == short.class) {
824+
Array.setShort(argArray, j, ((Number)casted).shortValue());
825+
}
826+
else if (componentType == int.class) {
827+
Array.setInt(argArray, j, ((Number)casted).intValue());
828+
}
829+
else if (componentType == long.class) {
830+
Array.setLong(argArray, j, ((Number)casted).longValue());
831+
}
832+
else if (componentType == float.class) {
833+
Array.setFloat(argArray, j, ((Number)casted).floatValue());
834+
}
835+
else { // double
836+
Array.setDouble(argArray, j, ((Number)casted).doubleValue());
837+
}
838+
}
839+
else {
840+
throw new ClassCastException("Cannot insert object of type " + casted.getClass() + " into primitive array");
841+
}
842+
}
843+
else {
844+
Array.set(argArray, j, casted);
845+
}
809846
}
810847
return argArray;
811848
}
@@ -972,17 +1009,19 @@ public Object visit(StaticMethodCall node) {
9721009
// Fill the arguments
9731010
if (larg != null) {
9741011
args = new Object[typs.length];
975-
Iterator<Expression> it = larg.iterator();
1012+
ListIterator<Expression> it = larg.listIterator();
9761013
int i = 0;
9771014
while (i < typs.length-1) {
9781015
args[i] = it.next().acceptVisitor(this);
9791016
i++;
9801017
}
9811018
if(typs.length > 0){
982-
if(!TigerUtilities.isVarArgs(m)){
983-
args[i] = it.next().acceptVisitor(this);
984-
i++;
1019+
Object last = it.next().acceptVisitor(this);
1020+
if(!TigerUtilities.isVarArgs(m) ||
1021+
(last != null && typs[i].isAssignableFrom(last.getClass()))){
1022+
args[i] = last;
9851023
} else {
1024+
it.previous(); // back up since we pulled the expression out a few lines above
9861025
args[i] = buildArrayOfRemainingArgs(typs, larg.size(), it);
9871026
}
9881027
}
@@ -2117,7 +2156,7 @@ protected static Object performCast(Class<?> tc, Object o) {
21172156

21182157
if (tc != ec && tc.isPrimitive() && ec != null) {
21192158
if (tc != char.class && ec == Character.class) {
2120-
o = new Integer(((Character)o).charValue());
2159+
o = new Character(((Character)o).charValue());
21212160
}
21222161
else if (tc == byte.class) {
21232162
o = new Byte(((Number)o).byteValue());

dynamicjava/src/koala/dynamicjava/interpreter/EvaluationVisitorTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,4 +313,48 @@ public void testUnaryArrayOps() throws InterpreterException {
313313
res = interpret("--c[0]");
314314
assertEquals("char value should be \'`\'","`",res.toString());
315315
}
316+
317+
/**
318+
* At one point passing in an int array for the in varargs would cause
319+
* djava to throw an unexpected ClassCastException inside performCast(EvaluationVisitor.java:2129)
320+
* Also, if the class was defined to have an Integer varargs signature, passing in the classic
321+
* array form would cause an IllegalArgumentException with Array.set inside
322+
* buildArrayOfRemainingArgs(EvaluationVisitor.java:808)
323+
*/
324+
public void testVarArgsWithMethodInvocation() throws InterpreterException {
325+
String text = "public class ClassA { public static void x(int... y) { } }; ClassA.x(new int[]{1,2,3});";
326+
Object res = interpret(text);
327+
text = "public class ClassB { public static Object x(Integer... y) { return y; } };";
328+
interpret(text);
329+
330+
text = "ClassB.x(new Integer[]{1,2,3})";
331+
res = interpret(text);
332+
assertFalse("Result shouldn't be null", res == null);
333+
assertEquals("Should be an array of Integers", Integer[].class, res.getClass());
334+
335+
text =
336+
"import java.util.*;" +
337+
"public class ClassC {" +
338+
" public static List<Integer> asList(Integer... a) {" +
339+
" ArrayList<Integer> list = new ArrayList<Integer>(a.length);"+
340+
" for(Integer i : a) {" +
341+
" list.add(i);" +
342+
" }" +
343+
" return list;" +
344+
" }" +
345+
"}";
346+
interpret(text);
347+
348+
text = "ClassC.asList(new Integer[]{1,2,3})";
349+
res = interpret(text);
350+
assertTrue("res should be an instance of a List", res instanceof java.util.List);
351+
assertEquals("first element should be 1", new Integer(1), ((java.util.List)res).get(0));
352+
353+
text = "Arrays.asList(new Integer[]{1,2,3})";
354+
res = interpret(text);
355+
assertTrue("res should be an instance of a List", res instanceof java.util.List);
356+
assertEquals("first element should be 1", new Integer(1), ((java.util.List)res).get(0));
357+
}
358+
359+
316360
}

0 commit comments

Comments
 (0)