Skip to content

Commit 30059ed

Browse files
author
dlsmith
committed
DynamicJava: Added support for interval-bounded wildcards (also fixed a bug in which lower bounds were incorrectly parsed). Added both 1.5 and 1.4 versions of jlbench, because each is required for running the corresponding version of tests (the JLBench interface includes Iterable, which gets changed by Retroweaver).
git-svn-id: file:///tmp/test-svn/trunk@4631 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent d29db16 commit 30059ed

File tree

8 files changed

+169
-63
lines changed

8 files changed

+169
-63
lines changed

dynamicjava/build.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@
189189
<classpath>
190190
<fileset refid="libs" />
191191
<pathelement location="lib/buildlib/junit.jar" />
192-
<pathelement location="lib/buildlib/jlbench-base-14.jar" />
192+
<pathelement location="lib/buildlib/jlbench-base-15.jar" />
193193
<pathelement location="classes/base" />
194194
</classpath>
195195
<compilerarg value="-Xlint" />
@@ -371,7 +371,7 @@
371371
<junit haltonfailure="yes" fork="yes" forkmode="perTest" maxmemory="256M" dir="${basedir}">
372372
<classpath>
373373
<pathelement location="lib/buildlib/junit.jar" />
374-
<pathelement location="lib/buildlib/jlbench-base-14.jar" />
374+
<pathelement location="lib/buildlib/jlbench-base-15.jar" />
375375
<pathelement location="${clover-jar}" />
376376
<pathelement location="classes/test" />
377377
<pathelement location="classes/base" />
@@ -505,7 +505,7 @@
505505
<classpath>
506506
<fileset refid="libs" />
507507
<pathelement location="lib/buildlib/junit.jar" />
508-
<pathelement location="lib/buildlib/jlbench-base-14.jar" />
508+
<pathelement location="lib/buildlib/jlbench-base-15.jar" />
509509
</classpath>
510510
<link href="http://java.sun.com/j2se/1.5/docs/api" />
511511
<link href="http://junit.org/junit/javadoc/3.8.1" />
2.26 KB
Binary file not shown.
83.2 KB
Binary file not shown.

dynamicjava/src/edu/rice/cs/dynamicjava/interpreter/TypeNameChecker.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,30 @@ private class TypeNameVisitor extends AbstractVisitor<Type> implements Lambda<Ty
314314
* @return The type of the TypeName
315315
*/
316316
@Override public Type visit(HookTypeName node) {
317-
Type bound = check(node.getHookedType());
318-
if (node.isSupered()) {
319-
return setType(node, new Wildcard(new BoundedSymbol(node, TypeSystem.OBJECT, bound)));
317+
Type upper = TypeSystem.OBJECT;
318+
if (node.getUpperBound().isSome()) {
319+
upper = check(node.getUpperBound().unwrap());
320+
if (!ts.isReference(upper)) {
321+
setErrorStrings(node, ts.userRepresentation(upper));
322+
throw new ExecutionError("wildcard.bound", node);
323+
}
324+
}
325+
326+
Type lower = TypeSystem.NULL;
327+
if (node.getLowerBound().isSome()) {
328+
lower = check(node.getLowerBound().unwrap());
329+
if (!ts.isReference(lower)) {
330+
setErrorStrings(node, ts.userRepresentation(lower));
331+
throw new ExecutionError("wildcard.bound", node);
332+
}
320333
}
321-
else { return setType(node, new Wildcard(new BoundedSymbol(node, bound, TypeSystem.NULL))); }
334+
335+
if (!ts.isSubtype(lower, upper)) {
336+
setErrorStrings(node, ts.userRepresentation(upper), ts.userRepresentation(lower));
337+
throw new ExecutionError("wildcard.bounds", node);
338+
}
339+
340+
return setType(node, new Wildcard(new BoundedSymbol(node, upper, lower)));
322341
}
323342

324343
/**

dynamicjava/src/koala/dynamicjava/interpreter/resources/messages.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,7 @@ uninitialized.variable = Variable '%0' uninitialized
203203

204204
# Used by NameVisitor
205205
variable.redefinition = Redefinition of '%0'
206+
207+
wildcard.bound = Invalid wildcard bound, %0
208+
wildcard.bounds = Invalid wildcard bounds, %0 and %1
209+

dynamicjava/src/koala/dynamicjava/parser/grammar.jj

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ PARSER_BEGIN(Parser)
1313
import java.lang.reflect.Modifier;
1414
import java.util.*;
1515
import java.io.File;
16+
import edu.rice.cs.plt.tuple.Option;
1617

1718
import koala.dynamicjava.SourceInfo;
1819
import koala.dynamicjava.parser.wrapper.*;
@@ -4853,45 +4854,30 @@ PARSER_END(Parser)
48534854
List<TypeName> TypeArguments() :
48544855
{
48554856
List<TypeName> typeArgs = new LinkedList<TypeName>();
4856-
ReferenceTypeName hookedType = new ReferenceTypeName("java.lang.Object");
4857-
TypeName temp = new HookTypeName(hookedType, false);
4858-
Token hook = null;
4859-
Token supered = null;
4857+
TypeName arg;
48604858
}
48614859
{
48624860
<LESS>
4863-
(LOOKAHEAD("?") hook="?"
4864-
[("extends"|"super") hookedType = ReferenceTypeName()]
4865-
// added to support wildcards
4866-
|
4867-
( temp = type()) // should be modified to not allow primitives
4868-
)
4869-
{
4870-
if(hook!= null)
4871-
temp = new HookTypeName(hookedType, (supered!=null));
4872-
typeArgs.add(temp);
4873-
4874-
}
4875-
4861+
arg = TypeArgument() { typeArgs.add(arg); }
4862+
( <COMMA> arg = TypeArgument() { typeArgs.add(arg); } )*
4863+
RightAngledBracket() { return typeArgs; }
4864+
}
4865+
4866+
TypeName TypeArgument() :
4867+
{ Token hook; TypeName upper = null; TypeName lower = null; }
4868+
{
48764869
(
4877-
<COMMA>
4878-
(LOOKAHEAD("?") hook="?"
4879-
[("extends"|"super") hookedType = ReferenceTypeName()]
4880-
|
4881-
(temp = type() ) // should be modified to not allow primitives
4882-
)
4883-
{
4884-
if(hook!= null)
4885-
temp = new HookTypeName(hookedType, (supered!=null));
4886-
typeArgs.add(temp);
4887-
}
4888-
)*
4889-
4890-
RightAngledBracket()
4891-
4892-
{
4893-
return typeArgs;
4894-
}
4870+
hook="?" ( "extends" upper = type() )? ( "super" lower = type() )?
4871+
{
4872+
int endLine = hook.endLine;
4873+
int endColumn = hook.endColumn;
4874+
if (upper != null) { endLine = upper.getEndLine(); endColumn = upper.getEndColumn(); }
4875+
if (lower != null) { endLine = lower.getEndLine(); endColumn = lower.getEndColumn(); }
4876+
return new HookTypeName(Option.wrap(upper), Option.wrap(lower), filename,
4877+
hook.beginLine, hook.beginColumn, endLine, endColumn);
4878+
}
4879+
| upper = type() { return upper; }
4880+
)
48954881
}
48964882

48974883
Token RightAngledBracket() :

dynamicjava/src/koala/dynamicjava/tree/tiger/HookTypeName.java

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
package koala.dynamicjava.tree.tiger;
3838

3939
import java.util.*;
40+
import edu.rice.cs.plt.tuple.Option;
4041

4142
import koala.dynamicjava.tree.*;
4243
import koala.dynamicjava.tree.visitor.Visitor;
@@ -48,16 +49,16 @@
4849

4950
public class HookTypeName extends ReferenceTypeName {
5051

51-
ReferenceTypeName hookedType;
52-
boolean supered;
52+
private final Option<TypeName> upperBound;
53+
private final Option<TypeName> lowerBound;
5354

5455
/**
5556
* Initializes the type
5657
* @param type the hooked type
5758
* @exception IllegalArgumentException if type is null
5859
*/
59-
public HookTypeName(ReferenceTypeName type, boolean supered) {
60-
this(type, supered, null, 0, 0, 0, 0);
60+
public HookTypeName(Option<TypeName> up, Option<TypeName> low) {
61+
this(up, low, null, 0, 0, 0, 0);
6162
}
6263

6364
/**
@@ -70,26 +71,19 @@ public HookTypeName(ReferenceTypeName type, boolean supered) {
7071
* @param ec the end column
7172
* @exception IllegalArgumentException if type is null
7273
*/
73-
public HookTypeName(ReferenceTypeName type, boolean _supered, String fn, int bl, int bc, int el, int ec) {
74-
super(Arrays.asList(new Identifier("?")), fn, bl, bc, el, ec);
74+
public HookTypeName(Option<TypeName> up, Option<TypeName> low,
75+
String fn, int bl, int bc, int el, int ec) {
76+
super("?");
7577

76-
if (type == null) throw new IllegalArgumentException("type == null");
77-
hookedType = type;
78-
supered = _supered;
78+
if (up == null) throw new IllegalArgumentException("up == null");
79+
if (low == null) throw new IllegalArgumentException("low == null");
80+
upperBound = up;
81+
lowerBound = low;
7982
}
8083

81-
/**
82-
* Returns the representation of this type
83-
*/
84-
public String getRepresentation() {
85-
if(supered) return "java.lang.Object";
86-
return hookedType.getRepresentation();
87-
}
84+
public Option<TypeName> getUpperBound() { return upperBound; }
85+
public Option<TypeName> getLowerBound() { return lowerBound; }
8886

89-
public ReferenceTypeName getHookedType() { return hookedType; }
90-
91-
public boolean isSupered() { return supered; }
92-
9387
/**
9488
* Allows a visitor to traverse the tree
9589
* @param visitor the visitor to accept
@@ -105,6 +99,6 @@ public String toString() {
10599
}
106100

107101
protected String toStringHelper() {
108-
return getRepresentation();
102+
return upperBound + " " + lowerBound;
109103
}
110104
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
class Box<T> {
2+
private T _val;
3+
public Box(T arg) { _val = arg; }
4+
public T get() { return _val; }
5+
public void set(T arg) { _val = arg; }
6+
}
7+
8+
declaration {
9+
Box<Object> o = new Box<Object>("xyz");
10+
Box<String> s = new Box<String>("hi");
11+
Box<Number> n = new Box<Number>(new Integer(12));
12+
Box<Integer> i = new Box<Integer>(new Integer(3));
13+
Box<Double> d = new Box<Double>(new Double(2.0));
14+
}
15+
16+
/** Valid assignments to an interval wildcard. */
17+
test {
18+
Box<? extends Number super Integer> b;
19+
b = n;
20+
b = i;
21+
}
22+
23+
/** Invalid assignments to an interval wildcard. */
24+
static error {
25+
Box<? extends Number super Integer> b;
26+
b = s;
27+
}
28+
29+
/** Invalid assignments to an interval wildcard. */
30+
static error {
31+
Box<? extends Number super Integer> b;
32+
b = o;
33+
}
34+
35+
/** Invalid assignments to an interval wildcard. */
36+
static error {
37+
Box<? extends Number super Integer> b;
38+
b = d;
39+
}
40+
41+
/** Invalid interval */
42+
static error {
43+
Box<? extends Number super String> b;
44+
}
45+
46+
/** Invalid interval */
47+
static error {
48+
Box<? extends Box<Number> super Box<Integer>> b;
49+
}
50+
51+
/** Subtyping with an interval wildcard */
52+
test {
53+
Box<? extends Integer super Integer> b1 = i;
54+
Box<? extends Number super Integer> b2 = b1;
55+
Box<? extends Number> b3;
56+
b3 = b1;
57+
b3 = b2;
58+
Box<? super Integer> b4;
59+
b4 = b1;
60+
b4 = b2;
61+
Box<?> b5;
62+
b5 = b1;
63+
b5 = b2;
64+
b5 = b3;
65+
b5 = b4;
66+
Box<? extends Object super Integer> b6;
67+
b6 = b1;
68+
b6 = b2;
69+
b6 = b4;
70+
}
71+
72+
/** Invalid interval-wildcard subtyping */
73+
static error {
74+
Box<? extends Number> b1 = i;
75+
Box<? extends Object super Integer> b2 = b1;
76+
}
77+
78+
/** Invalid interval-wildcard subtyping */
79+
static error {
80+
Box<? extends Integer super Integer> b1 = i;
81+
Box<? extends Number super Integer> b2 = b1;
82+
Box<? super Number> b3 = b2;
83+
}
84+
85+
/** Capture for interval-bounded wildcards. */
86+
test {
87+
Box<? extends Number super Integer> b = i;
88+
Number num = b.get();
89+
b.set(new Integer(23));
90+
b.set(null);
91+
}
92+
93+
/** Invalid use of interval-bounded wildcards. */
94+
static error {
95+
Box<? extends Number super Integer> b = i;
96+
Integer intgr = b.get();
97+
}
98+
99+
/** Invalid use of interval-bounded wildcards. */
100+
static error {
101+
Box<? extends Number super Integer> b = i;
102+
b.set(new Double(2.0));
103+
}

0 commit comments

Comments
 (0)