| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent a240824 commit b2a145d
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -719,8 +719,7 @@ private DJClass resolveThis(Option<String> outerName, Node node) { | |||
| 719 | 719 | ||
| 720 | 720 | private void addRuntimeCheck(Node node, Type expectedType, Type declaredActualType) { | |
| 721 | 721 | 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)); | ||
| 724 | 723 | } | |
| 725 | 724 | } | |
| 726 | 725 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -111,31 +111,66 @@ public TypeNameChecker(TypeContext ctx, Options options) { | |||
| 111 | 111 | visitor = new TypeNameVisitor(); | |
| 112 | 112 | } | |
| 113 | 113 | ||
| 114 | + /** Get the type corresponding to {@code t}; verify that it is well-formed. */ | ||
| 114 | 115 | 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) { | ||
| 115 | 126 | return t.acceptVisitor(visitor); | |
| 116 | 127 | } | |
| 117 | 128 | ||
| 129 | + /** Invoke {@link #check} on each element of a list. */ | ||
| 118 | 130 | 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; | ||
| 120 | 140 | } | |
| 121 | 141 | ||
| 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 | + | ||
| 122 | 158 | /** Tag the given type parameters with a new VariableType, and set the bounds appropriately. */ | |
| 123 | 159 | public void checkTypeParameters(TypeParameter[] tparams) { | |
| 124 | 160 | for (TypeParameter tparam : tparams) { | |
| 125 | 161 | setTypeVariable(tparam, new VariableType(new BoundedSymbol(tparam, tparam.getRepresentation()))); | |
| 126 | 162 | } | |
| 127 | 163 | TypeNameVisitor v = new TypeNameVisitor(); | |
| 128 | 164 | 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); | ||
| 135 | 168 | } | |
| 169 | + BoundedSymbol bounds = getTypeVariable(param).symbol(); | ||
| 170 | + bounds.initializeUpperBound(upperBound); | ||
| 136 | 171 | bounds.initializeLowerBound(TypeSystem.NULL); | |
| 137 | 172 | } | |
| 138 | - } | ||
| 173 | + } | ||
| 139 | 174 | ||
| 140 | 175 | private class TypeNameVisitor extends AbstractVisitor<Type> implements Lambda<TypeName, Type> { | |
| 141 | 176 | ||
@@ -282,7 +317,7 @@ private class TypeNameVisitor extends AbstractVisitor<Type> implements Lambda<Ty | |||
| 282 | 317 | } | |
| 283 | 318 | catch (AmbiguousNameException e) { throw new ExecutionError("ambiguous.name", node); } | |
| 284 | 319 | 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); } | ||
| 286 | 321 | catch (UnmatchedLookupException e) { | |
| 287 | 322 | if (e.matches() == 0) { throw new ExecutionError("undefined.name.noinfo", node); } | |
| 288 | 323 | else { throw new ExecutionError("ambiguous.name", node); } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -75,7 +75,9 @@ private Iterable<CompilationUnit> parse(Iterable<? extends File> sources) throws | |||
| 75 | 75 | private void typeCheck(Iterable<CompilationUnit> sources, Iterable<? extends File> cp) throws InterpreterException { | |
| 76 | 76 | ClassLoader loader = new PathClassLoader(null, cp); | |
| 77 | 77 | Library classLib = SymbolUtil.classLibrary(loader); | |
| 78 | + debug.logStart("creating TreeLibrary"); | ||
| 78 | 79 | Library sourceLib = new TreeLibrary(sources, loader, _opt); | |
| 80 | + debug.logEnd("creating TreeLibrary"); | ||
| 79 | 81 | TypeContext context = new TopLevelContext(new LibraryContext(new LibraryContext(classLib), sourceLib), loader); | |
| 80 | 82 | CompilationUnitChecker checker = new CompilationUnitChecker(context, _opt); | |
| 81 | 83 | List<InterpreterException> errors = new ArrayList<InterpreterException>(); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments