Skip to content

Commit f85f20b

Browse files
author
dlsmith
committed
DynamicJava: Raw types are subtypes of their wildcard-parameterized equivalents. Bug fixes for RecursionStack uses (should be defined using equals() rather than ==) and userRepresentation (now correctly handles varargs and parameterized inner class names).
git-svn-id: file:///tmp/test-svn/trunk@5041 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent da8b202 commit f85f20b

File tree

4 files changed

+93
-77
lines changed

4 files changed

+93
-77
lines changed

dynamicjava/lib/plt.jar

0 Bytes
Binary file not shown.

dynamicjava/src/edu/rice/cs/dynamicjava/symbol/ExtendedTypeSystem.java

Lines changed: 74 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import edu.rice.cs.plt.tuple.Pair;
55
import edu.rice.cs.plt.tuple.Triple;
66
import edu.rice.cs.plt.tuple.Option;
7+
import edu.rice.cs.plt.tuple.Wrapper;
78
import edu.rice.cs.plt.recur.*;
89
import edu.rice.cs.plt.lambda.*;
910
import edu.rice.cs.plt.iter.IterUtil;
@@ -38,7 +39,7 @@ public boolean isWellFormed(Type t) {
3839
* invocations should use distinct instances.
3940
*/
4041
private class WellFormedChecker extends TypeAbstractVisitor<Boolean> implements Predicate<Type> {
41-
RecursionStack<Type> _stack = new RecursionStack<Type>();
42+
RecursionStack<Type> _stack = new RecursionStack<Type>(Wrapper.<Type>factory());
4243
public boolean contains(Type t) { return t.apply(this); }
4344

4445
@Override public Boolean defaultCase(Type t) { return true; }
@@ -113,7 +114,7 @@ public boolean isSubtype(Type subT, Type superT) {
113114
* invocations should use distinct instances.
114115
*/
115116
private class NormSubtyper implements Order<Type>, Lambda2<Type, Type, Boolean> {
116-
RecursionStack2<Type, Type> _stack = new RecursionStack2<Type, Type>();
117+
RecursionStack2<Type, Type> _stack = new RecursionStack2<Type, Type>(Pair.<Type, Type>factory());
117118

118119
public Boolean value(Type subT, Type superT) { return contains(subT, superT); }
119120

@@ -178,9 +179,9 @@ public Boolean value() {
178179
// Handle subT-based cases:
179180
return subT.apply(new TypeAbstractVisitor<Boolean>() {
180181

181-
public Boolean defaultCase(Type t) { return false; }
182+
@Override public Boolean defaultCase(Type t) { return false; }
182183

183-
public Boolean forCharType(CharType subT) {
184+
@Override public Boolean forCharType(CharType subT) {
184185
return superT.apply(new TypeAbstractVisitor<Boolean>() {
185186
public Boolean defaultCase(Type superT) { return false; }
186187
@Override public Boolean forCharType(CharType superT) { return true; }
@@ -190,15 +191,15 @@ public Boolean forCharType(CharType subT) {
190191
});
191192
}
192193

193-
public Boolean forByteType(ByteType subT) {
194+
@Override public Boolean forByteType(ByteType subT) {
194195
return superT.apply(new TypeAbstractVisitor<Boolean>() {
195196
public Boolean defaultCase(Type superT) { return false; }
196197
@Override public Boolean forIntegerType(IntegerType superT) { return true; }
197198
@Override public Boolean forFloatingPointType(FloatingPointType superT) { return true; }
198199
});
199200
}
200201

201-
public Boolean forShortType(ShortType subT) {
202+
@Override public Boolean forShortType(ShortType subT) {
202203
return superT.apply(new TypeAbstractVisitor<Boolean>() {
203204
public Boolean defaultCase(Type superT) { return false; }
204205
@Override public Boolean forShortType(ShortType superT) { return true; }
@@ -208,7 +209,7 @@ public Boolean forShortType(ShortType subT) {
208209
});
209210
}
210211

211-
public Boolean forIntType(IntType subT) {
212+
@Override public Boolean forIntType(IntType subT) {
212213
return superT.apply(new TypeAbstractVisitor<Boolean>() {
213214
public Boolean defaultCase(Type superT) { return false; }
214215
@Override public Boolean forIntType(IntType superT) { return true; }
@@ -217,21 +218,21 @@ public Boolean forIntType(IntType subT) {
217218
});
218219
}
219220

220-
public Boolean forLongType(LongType subT) {
221+
@Override public Boolean forLongType(LongType subT) {
221222
return superT.apply(new TypeAbstractVisitor<Boolean>() {
222223
public Boolean defaultCase(Type superT) { return false; }
223224
@Override public Boolean forLongType(LongType superT) { return true; }
224225
@Override public Boolean forFloatingPointType(FloatingPointType superT) { return true; }
225226
});
226227
}
227228

228-
public Boolean forFloatType(FloatType subT) { return superT instanceof FloatingPointType; }
229+
@Override public Boolean forFloatType(FloatType subT) { return superT instanceof FloatingPointType; }
229230

230-
public Boolean forNullType(NullType subT) { return isReference(superT); }
231+
@Override public Boolean forNullType(NullType subT) { return isReference(superT); }
231232

232-
public Boolean forSimpleArrayType(SimpleArrayType subT) { return handleArrayType(subT); }
233+
@Override public Boolean forSimpleArrayType(SimpleArrayType subT) { return handleArrayType(subT); }
233234

234-
public Boolean forVarargArrayType(VarargArrayType subT) { return handleArrayType(subT); }
235+
@Override public Boolean forVarargArrayType(VarargArrayType subT) { return handleArrayType(subT); }
235236

236237
private Boolean handleArrayType(final ArrayType subT) {
237238
return superT.apply(new TypeAbstractVisitor<Boolean>() {
@@ -252,74 +253,81 @@ private Boolean handleArrayType(final ArrayType subT) {
252253
});
253254
}
254255

255-
public Boolean forClassType(final ClassType subT) {
256+
/**
257+
* Recur on {@code newSub}, a class's parent type. {@code newSub} may be null, as in
258+
* {@code immediateSupertype()}.
259+
*/
260+
private Boolean recurOnClassParent(final Type newSub) {
261+
if (newSub == null) { return false; }
262+
else {
263+
Thunk<Boolean> recurOnParent = new Thunk<Boolean>() {
264+
public Boolean value() {
265+
Type newSubNorm = new Normalizer(NormSubtyper.this).value(newSub);
266+
return NormSubtyper.this.contains(newSubNorm, superT);
267+
}
268+
};
269+
return _stack.apply(recurOnParent, false, newSub, superT);
270+
}
271+
}
272+
273+
@Override public Boolean forSimpleClassType(final SimpleClassType subT) {
256274
return superT.apply(new TypeAbstractVisitor<Boolean>() {
257275
public Boolean defaultCase(Type superT) { return false; }
258276
@Override public Boolean forClassType(final ClassType superT) {
259-
final Type newSub = immediateSupertype(subT);
260-
if (newSub == null) { return false; }
261-
else {
262-
Thunk<Boolean> recurOnParent = new Thunk<Boolean>() {
263-
public Boolean value() {
264-
Type newSubNorm = new Normalizer(NormSubtyper.this).value(newSub);
265-
return NormSubtyper.this.contains(newSubNorm, superT);
266-
}
267-
};
268-
return _stack.apply(recurOnParent, false, subT, superT);
269-
}
277+
return recurOnClassParent(immediateSupertype(subT));
270278
}
271279
});
272280
}
273281

274-
public Boolean forParameterizedClassType(final ParameterizedClassType subT) {
282+
@Override public Boolean forRawClassType(final RawClassType subT) {
275283
return superT.apply(new TypeAbstractVisitor<Boolean>() {
276284
public Boolean defaultCase(Type superT) { return false; }
277-
285+
@Override public Boolean forClassType(final ClassType superT) {
286+
return recurOnClassParent(immediateSupertype(subT));
287+
}
278288
@Override public Boolean forParameterizedClassType(final ParameterizedClassType superT) {
279289
if (subT.ofClass().equals(superT.ofClass())) {
280-
281-
Thunk<Boolean> containedArgs = new Thunk<Boolean>() {
282-
public Boolean value() {
283-
boolean result = true;
284-
ParameterizedClassType subCapT = capture(subT);
285-
for (final Pair<Type, Type> args : IterUtil.zip(subCapT.typeArguments(),
286-
superT.typeArguments())) {
287-
result &= args.second().apply(new TypeAbstractVisitor<Boolean>() {
288-
public Boolean defaultCase(Type superArg) {
289-
Type subArg = args.first();
290-
return NormSubtyper.this.contains(subArg, superArg) &&
291-
NormSubtyper.this.contains(superArg, subArg);
292-
}
293-
@Override public Boolean forWildcard(Wildcard superArg) {
294-
Type subArg = args.first();
295-
return NormSubtyper.this.contains(superArg.symbol().lowerBound(), subArg) &&
296-
NormSubtyper.this.contains(subArg, superArg.symbol().upperBound());
297-
}
298-
});
299-
if (!result) { break; }
300-
}
301-
return result;
302-
}
303-
};
304-
305-
return _stack.apply(containedArgs, false, subT, superT) || forClassType(superT);
290+
return recurOnClassParent(parameterize(subT)) || forClassType(superT);
306291
}
307292
else { return forClassType(superT); }
308293
}
309-
294+
});
295+
}
296+
297+
@Override public Boolean forParameterizedClassType(final ParameterizedClassType subT) {
298+
return superT.apply(new TypeAbstractVisitor<Boolean>() {
299+
public Boolean defaultCase(Type superT) { return false; }
310300
@Override public Boolean forClassType(ClassType superT) {
311-
Type newSub = immediateSupertype(subT);
312-
if (newSub == null) { return false; }
313-
else {
314-
// results of immediateSupertype() and erase() are always normalized
315-
return NormSubtyper.this.contains(newSub, superT) || NormSubtyper.this.contains(erase(subT), superT);
301+
return recurOnClassParent(immediateSupertype(subT)) || recurOnClassParent(erase(subT));
302+
}
303+
@Override public Boolean forParameterizedClassType(final ParameterizedClassType superT) {
304+
if (subT.ofClass().equals(superT.ofClass())) {
305+
boolean containedArgs = true;
306+
ParameterizedClassType subCapT = capture(subT);
307+
for (final Pair<Type, Type> args : IterUtil.zip(subCapT.typeArguments(),
308+
superT.typeArguments())) {
309+
containedArgs &= args.second().apply(new TypeAbstractVisitor<Boolean>() {
310+
public Boolean defaultCase(Type superArg) {
311+
Type subArg = args.first();
312+
return NormSubtyper.this.contains(subArg, superArg) &&
313+
NormSubtyper.this.contains(superArg, subArg);
314+
}
315+
@Override public Boolean forWildcard(Wildcard superArg) {
316+
Type subArg = args.first();
317+
return NormSubtyper.this.contains(superArg.symbol().lowerBound(), subArg) &&
318+
NormSubtyper.this.contains(subArg, superArg.symbol().upperBound());
319+
}
320+
});
321+
if (!containedArgs) { break; }
322+
}
323+
return containedArgs || forClassType(superT);
316324
}
325+
else { return forClassType(superT); }
317326
}
318-
319327
});
320328
}
321329

322-
public Boolean forVariableType(final VariableType subT) {
330+
@Override public Boolean forVariableType(final VariableType subT) {
323331
Thunk<Boolean> checkUpperBound = new Thunk<Boolean>() {
324332
public Boolean value() {
325333
Type bound = new Normalizer(NormSubtyper.this).value(subT.symbol().upperBound());
@@ -332,16 +340,17 @@ public Boolean value() {
332340
return _stack.apply(checkUpperBound, checkInfinite, subT, superT);
333341
}
334342

335-
public Boolean forIntersectionType(IntersectionType subT) {
343+
@Override public Boolean forIntersectionType(IntersectionType subT) {
336344
return IterUtil.or(subT.ofTypes(), subtypes(superT));
337345
}
338346

339-
public Boolean forUnionType(UnionType subT) {
347+
@Override public Boolean forUnionType(UnionType subT) {
340348
return IterUtil.and(subT.ofTypes(), subtypes(superT));
341349
}
342350

343351
public Boolean forBottomType(BottomType subT) { return true; }
344352
});
353+
345354
//} finally { debug.logEnd(); }
346355
}
347356
};
@@ -785,8 +794,8 @@ private class Inferencer {
785794

786795
public Inferencer(Set<? extends VariableType> vars) {
787796
_vars = vars;
788-
_subStack = new RecursionStack2<Type, Type>();
789-
_supStack = new RecursionStack2<Type, Type>();
797+
_subStack = new RecursionStack2<Type, Type>(Pair.<Type, Type>factory());
798+
_supStack = new RecursionStack2<Type, Type>(Pair.<Type, Type>factory());
790799
_subtyper = new NormSubtyper();
791800
}
792801

@@ -1143,7 +1152,7 @@ public ConstraintFormula equivalentNorm(final Type arg, final Type param) {
11431152
}
11441153

11451154
private final TypeVisitorLambda<Boolean> _containsVar = new TypeAbstractVisitor<Boolean>() {
1146-
private final RecursionStack<Type> _stack = new RecursionStack<Type>();
1155+
private final RecursionStack<Type> _stack = new RecursionStack<Type>(Wrapper.<Type>factory());
11471156
public Boolean defaultCase(Type t) { return false; }
11481157
@Override public Boolean forArrayType(ArrayType t) { return t.ofType().apply(this); }
11491158
@Override public Boolean forParameterizedClassType(ParameterizedClassType t) {

dynamicjava/src/edu/rice/cs/dynamicjava/symbol/StandardTypeSystem.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -287,24 +287,17 @@ public boolean isReferenceConvertible(Type t) {
287287
}
288288

289289

290-
/**
291-
* Determine the type bound to {@code super} in the body of the given type's declaration, or
292-
* {@code null} if no such type exists.
293-
*/
294290
public Type immediateSuperclass(Type t) {
295291
if (t instanceof ClassType) { return ((ClassType) t).ofClass().immediateSuperclass(); }
296292
else { return null; }
297293
}
298294

299-
/**
300-
* @return The capture {@code t}. Capture eliminates wildcards in a
301-
* {@link ParameterizedClassType}.
302-
*/
303295
public Type capture(Type t) { return t.apply(CAPTURE); }
304296

305297
// cannot be defined statically, because it relies on the definition of non-static "capture"
306298
private final TypeVisitorLambda<Type> CAPTURE = new TypeAbstractVisitor<Type>() {
307299
public Type defaultCase(Type t) { return t; }
300+
public Type forVarargArrayType(VarargArrayType t) { return new SimpleArrayType(t.ofType()); }
308301
@Override public Type forParameterizedClassType(ParameterizedClassType t) { return capture(t); }
309302
};
310303

@@ -425,6 +418,17 @@ private Thunk<Class<?>> wrapDJClass(final DJClass c) {
425418

426419
};
427420

421+
/** Convert a raw class type to its wildcard-parameterized equivalent. */
422+
protected ParameterizedClassType parameterize(final RawClassType t) {
423+
Iterable<VariableType> tparams = SymbolUtil.allTypeParameters(t.ofClass());
424+
return new ParameterizedClassType(t.ofClass(), IterUtil.mapSnapshot(tparams, new Lambda<VariableType, Type>() {
425+
public Type value(VariableType param) {
426+
// identity is determined by t and param -- result should be identical when repeatedly invoked
427+
return new Wildcard(new BoundedSymbol(Pair.make(t, param), OBJECT, NULL));
428+
}
429+
}));
430+
}
431+
428432
/**
429433
* @return The type of the Class object associated with t (for example, (informally)
430434
* {@code reflectionClassOf(java.lang.Integer) = Class<Integer>}).
@@ -667,7 +671,7 @@ public void forSimpleArrayType(SimpleArrayType t) {
667671

668672
public void forVarargArrayType(VarargArrayType t) {
669673
run(t.ofType());
670-
_result.append("[]");
674+
_result.append("...");
671675
}
672676

673677
public void forSimpleClassType(SimpleClassType t) {
@@ -700,7 +704,7 @@ public void forParameterizedClassType(ParameterizedClassType t) {
700704
_result.append(">");
701705
}
702706
}
703-
if (inner != null) { _result.append("."); _result.append(c.declaredName()); }
707+
if (inner != null) { _result.append("."); _result.append(inner.declaredName()); }
704708
c = inner;
705709
}
706710
}
@@ -1649,7 +1653,7 @@ private class MethodFinder extends MemberFinder<DJMethod> {
16491653
public FunctionInvocationCandidate<DJMethod>
16501654
findSingleMethod(Type t, Iterable<? extends Type> targs, Iterable<? extends Expression> args,
16511655
Option<Type> expected) throws UnmatchedLookupException {
1652-
debug.logStart(new String[]{"t","name"}, wrap(t)); try {
1656+
debug.logStart(new String[]{"t","name","onlyStatic"}, wrap(t), _name, _onlyStatic); try {
16531657

16541658
PredicateSet<DJMethod> candidates = findAll(t);
16551659
Iterable<FunctionInvocationCandidate<DJMethod>> best = bestInvocations(candidates, targs, args, expected);

dynamicjava/src/edu/rice/cs/dynamicjava/symbol/TypeSystem.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ public boolean equals(Object o) {
178178

179179
/* Unary Operations on Types */
180180

181-
/** Compute the capture of {@code t}. Capture eliminates wildcards in a {@link ParameterizedClassType}. */
181+
/**
182+
* Compute the capture of {@code t}. Capture eliminates wildcards in a {@link ParameterizedClassType}
183+
* and converts VarargArrayTypes to StandardArrayTypes.
184+
*/
182185
public abstract Type capture(Type t);
183186

184187
/**

0 commit comments

Comments
 (0)