Skip to content

Commit b2a145d

Browse files
author
dlsmith
committed
DynamicJava: Refactored ExtendedTypeSystem by separating customizeable subtyping and inference functions from the standard conversion, lookup, etc. code. Standard code was lifted into an abstract parent, StandardTypeSystem. Also eliminated the bounds check from makeClassType(), allowing bounds checking to occur at a later stage.
git-svn-id: file:///tmp/test-svn/trunk@4843 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent a240824 commit b2a145d

File tree

9 files changed

+3395
-3376
lines changed

9 files changed

+3395
-3376
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -719,8 +719,7 @@ private DJClass resolveThis(Option<String> outerName, Node node) {
719719

720720
private void addRuntimeCheck(Node node, Type expectedType, Type declaredActualType) {
721721
if (!ts.isSubtype(ts.erase(declaredActualType), ts.erase(expectedType))) {
722-
Thunk<Class<?>> erasedExpectedType = ts.erasedClass(expectedType);
723-
if (erasedExpectedType != null) { setCheckedType(node, erasedExpectedType); }
722+
setCheckedType(node, ts.erasedClass(expectedType));
724723
}
725724
}
726725

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

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,31 +111,66 @@ public TypeNameChecker(TypeContext ctx, Options options) {
111111
visitor = new TypeNameVisitor();
112112
}
113113

114+
/** Get the type corresponding to {@code t}; verify that it is well-formed. */
114115
public Type check(TypeName t) {
116+
Type result = t.acceptVisitor(visitor);
117+
ensureWellFormed(t);
118+
return result;
119+
}
120+
121+
/**
122+
* Get the type corresponding to {@code t}; verify that it is structurally well-formed, but
123+
* delay full well-formedness checking until a later {@link #ensureWellFormed} call.
124+
*/
125+
public Type checkStructure(TypeName t) {
115126
return t.acceptVisitor(visitor);
116127
}
117128

129+
/** Invoke {@link #check} on each element of a list. */
118130
public Iterable<Type> checkList(Iterable<? extends TypeName> l) {
119-
return IterUtil.mapSnapshot(l, visitor);
131+
Iterable<Type> result = IterUtil.mapSnapshot(l, visitor);
132+
ensureWellFormedList(l);
133+
return result;
134+
}
135+
136+
/** Invoke {@link #checkStructure} on each element of a list. */
137+
public Iterable<Type> checkStructureForList(Iterable<? extends TypeName> l) {
138+
Iterable<Type> result = IterUtil.mapSnapshot(l, visitor);
139+
return result;
120140
}
121141

142+
/**
143+
* Verify that a TypeName that has already been checked is well-formed (according to
144+
* {@link TypeSystem#isWellFormed}).
145+
*/
146+
public void ensureWellFormed(TypeName t) {
147+
if (!ts.isWellFormed(getType(t))) {
148+
throw new ExecutionError("malformed.type", t);
149+
}
150+
}
151+
152+
/** Invoke {@link #ensureWellFormed} on each element of a list. */
153+
public void ensureWellFormedList(Iterable<? extends TypeName> l) {
154+
for (TypeName t : l) { ensureWellFormed(t); }
155+
}
156+
157+
122158
/** Tag the given type parameters with a new VariableType, and set the bounds appropriately. */
123159
public void checkTypeParameters(TypeParameter[] tparams) {
124160
for (TypeParameter tparam : tparams) {
125161
setTypeVariable(tparam, new VariableType(new BoundedSymbol(tparam, tparam.getRepresentation())));
126162
}
127163
TypeNameVisitor v = new TypeNameVisitor();
128164
for (TypeParameter param : tparams) {
129-
Type firstBound = param.getBound().acceptVisitor(v);
130-
Iterable<Type> restBounds = checkList(param.getInterfaceBounds());
131-
BoundedSymbol bounds = getTypeVariable(param).symbol();
132-
if (IterUtil.isEmpty(restBounds)) { bounds.initializeUpperBound(firstBound); }
133-
else {
134-
bounds.initializeUpperBound(new IntersectionType(IterUtil.compose(firstBound, restBounds)));
165+
Type upperBound = param.getBound().acceptVisitor(v);
166+
for (Type t : checkList(param.getInterfaceBounds())) {
167+
upperBound = ts.meet(upperBound, t);
135168
}
169+
BoundedSymbol bounds = getTypeVariable(param).symbol();
170+
bounds.initializeUpperBound(upperBound);
136171
bounds.initializeLowerBound(TypeSystem.NULL);
137172
}
138-
}
173+
}
139174

140175
private class TypeNameVisitor extends AbstractVisitor<Type> implements Lambda<TypeName, Type> {
141176

@@ -282,7 +317,7 @@ private class TypeNameVisitor extends AbstractVisitor<Type> implements Lambda<Ty
282317
}
283318
catch (AmbiguousNameException e) { throw new ExecutionError("ambiguous.name", node); }
284319
catch (InvalidTargetException e) { throw new RuntimeException("context produced bad type"); }
285-
catch (InvalidTypeArgumentException e) { throw new ExecutionError("type.argument", node); }
320+
catch (InvalidTypeArgumentException e) { throw new ExecutionError("type.argument.arity", node); }
286321
catch (UnmatchedLookupException e) {
287322
if (e.matches() == 0) { throw new ExecutionError("undefined.name.noinfo", node); }
288323
else { throw new ExecutionError("ambiguous.name", node); }

dynamicjava/src/edu/rice/cs/dynamicjava/sourcechecker/SourceChecker.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ private Iterable<CompilationUnit> parse(Iterable<? extends File> sources) throws
7575
private void typeCheck(Iterable<CompilationUnit> sources, Iterable<? extends File> cp) throws InterpreterException {
7676
ClassLoader loader = new PathClassLoader(null, cp);
7777
Library classLib = SymbolUtil.classLibrary(loader);
78+
debug.logStart("creating TreeLibrary");
7879
Library sourceLib = new TreeLibrary(sources, loader, _opt);
80+
debug.logEnd("creating TreeLibrary");
7981
TypeContext context = new TopLevelContext(new LibraryContext(new LibraryContext(classLib), sourceLib), loader);
8082
CompilationUnitChecker checker = new CompilationUnitChecker(context, _opt);
8183
List<InterpreterException> errors = new ArrayList<InterpreterException>();

0 commit comments

Comments
 (0)