|
1 | 1 | package checkers.inference; |
2 | 2 |
|
3 | 3 | import checkers.inference.util.SlotDefaultTypeResolver; |
| 4 | +import com.sun.source.tree.ClassTree; |
4 | 5 | import com.sun.source.tree.CompilationUnitTree; |
5 | 6 | import com.sun.source.tree.Tree; |
| 7 | +import com.sun.source.util.TreePath; |
6 | 8 | import com.sun.tools.javac.code.Symbol; |
7 | 9 | import org.checkerframework.checker.nullness.qual.Nullable; |
8 | 10 | import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory; |
|
11 | 13 | import org.checkerframework.javacutil.AnnotationBuilder; |
12 | 14 | import org.checkerframework.javacutil.AnnotationUtils; |
13 | 15 | import org.checkerframework.javacutil.BugInCF; |
| 16 | +import org.checkerframework.javacutil.TreeUtils; |
14 | 17 | import org.checkerframework.javacutil.TypeKindUtils; |
15 | 18 | import org.checkerframework.javacutil.TypesUtils; |
16 | 19 |
|
@@ -202,6 +205,25 @@ public int compare(Class<? extends Annotation> o1, Class<? extends Annotation> o |
202 | 205 | return set; |
203 | 206 | } |
204 | 207 |
|
| 208 | + @Override |
| 209 | + public void setTopLevelClass(ClassTree classTree) { |
| 210 | + // If the top level has changed, we refresh our cache with the new scope. |
| 211 | + defaultAnnotationsCache.clear(); |
| 212 | + |
| 213 | + Map<Tree, AnnotatedTypeMirror> defaultTypes = SlotDefaultTypeResolver.resolve( |
| 214 | + classTree, |
| 215 | + InferenceMain.getInstance().getRealTypeFactory() |
| 216 | + ); |
| 217 | + |
| 218 | + // find default types in the current hierarchy and save them to the cache |
| 219 | + for (Map.Entry<Tree, AnnotatedTypeMirror> entry : defaultTypes.entrySet()) { |
| 220 | + defaultAnnotationsCache.put( |
| 221 | + entry.getKey(), |
| 222 | + entry.getValue().getAnnotationInHierarchy(this.realTop) |
| 223 | + ); |
| 224 | + } |
| 225 | + } |
| 226 | + |
205 | 227 | /** |
206 | 228 | * Returns the next unique variable id. These id's are monotonically increasing. |
207 | 229 | * @return the next variable id to be used in VariableCreation |
@@ -347,25 +369,6 @@ public int getNumberOfSlots() { |
347 | 369 | return nextId - 1; |
348 | 370 | } |
349 | 371 |
|
350 | | - @Override |
351 | | - public void setRoot(CompilationUnitTree compilationUnit) { |
352 | | - this.defaultAnnotationsCache.clear(); |
353 | | - |
354 | | - BaseAnnotatedTypeFactory realTypeFactory = InferenceMain.getInstance().getRealTypeFactory(); |
355 | | - Map<Tree, AnnotatedTypeMirror> defaultTypes = SlotDefaultTypeResolver.resolve( |
356 | | - compilationUnit, |
357 | | - realTypeFactory |
358 | | - ); |
359 | | - |
360 | | - for (Map.Entry<Tree, AnnotatedTypeMirror> entry : defaultTypes.entrySet()) { |
361 | | - // find default types in the current hierarchy and save them to the cache |
362 | | - this.defaultAnnotationsCache.put( |
363 | | - entry.getKey(), |
364 | | - entry.getValue().getAnnotationInHierarchy(this.realTop) |
365 | | - ); |
366 | | - } |
367 | | - } |
368 | | - |
369 | 372 | @Override |
370 | 373 | public SourceVariableSlot createSourceVariableSlot(AnnotationLocation location, TypeMirror type) { |
371 | 374 | AnnotationMirror defaultAnnotation = null; |
@@ -424,13 +427,20 @@ public SourceVariableSlot createSourceVariableSlot(AnnotationLocation location, |
424 | 427 | throw new BugInCF("Unable to find default annotation for location " + location); |
425 | 428 | } |
426 | 429 |
|
427 | | - AnnotationMirror realAnnotation = null; |
428 | | - if (tree != null) { |
429 | | - realAnnotation = this.defaultAnnotationsCache.get(tree); |
430 | | - if (realAnnotation == null) { |
431 | | - // If its default type can't be found in the cache, we can |
432 | | - // fallback to the simplest method. |
433 | | - realAnnotation = realTypeFactory.getAnnotatedType(tree).getAnnotationInHierarchy(this.realTop); |
| 430 | + AnnotationMirror realAnnotation = defaultAnnotationsCache.get(tree); |
| 431 | + if (tree != null && realAnnotation == null) { |
| 432 | + // If its default type can't be found in the cache, we can |
| 433 | + // fallback to the simplest method. |
| 434 | + // TODO: If the tree is not under the current top-level tree |
| 435 | + // that's being processed, the type factory may crash due |
| 436 | + // to lack of information. We may want to investigate if |
| 437 | + // this issue ever happens. |
| 438 | + if (TreeUtils.isTypeTree(tree)) { |
| 439 | + realAnnotation = realTypeFactory.getAnnotatedTypeFromTypeTree(tree) |
| 440 | + .getAnnotationInHierarchy(this.realTop); |
| 441 | + } else { |
| 442 | + realAnnotation = realTypeFactory.getAnnotatedType(tree) |
| 443 | + .getAnnotationInHierarchy(this.realTop); |
434 | 444 | } |
435 | 445 | } |
436 | 446 | return realAnnotation; |
|
0 commit comments