|
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