• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.uber.nullaway.dataflow;
2 
3 import com.google.common.base.Preconditions;
4 import com.google.errorprone.util.ASTHelpers;
5 import com.sun.source.tree.ClassTree;
6 import com.sun.source.tree.LambdaExpressionTree;
7 import com.sun.source.tree.Tree;
8 import com.sun.tools.javac.util.Context;
9 import java.util.LinkedHashMap;
10 import java.util.Map;
11 import javax.annotation.Nullable;
12 import javax.lang.model.element.NestingKind;
13 
14 /**
15  * Stores info on nullness of local variables in enclosing environments, used when performing
16  * dataflow analysis on lambdas or methods in anonymous classes that may access these locals
17  */
18 public class EnclosingEnvironmentNullness {
19 
20   public static final Context.Key<EnclosingEnvironmentNullness>
21       ENCLOSING_ENVIRONMENT_NULLNESS_ANALYSIS_KEY = new Context.Key<>();
22 
23   private final Map<Tree, NullnessStore> environmentNullness = new LinkedHashMap<>();
24 
instance(Context context)25   public static EnclosingEnvironmentNullness instance(Context context) {
26     EnclosingEnvironmentNullness instance =
27         context.get(ENCLOSING_ENVIRONMENT_NULLNESS_ANALYSIS_KEY);
28     if (instance == null) {
29       instance = new EnclosingEnvironmentNullness();
30       context.put(ENCLOSING_ENVIRONMENT_NULLNESS_ANALYSIS_KEY, instance);
31     }
32     return instance;
33   }
34 
addEnvironmentMapping(Tree t, NullnessStore s)35   public void addEnvironmentMapping(Tree t, NullnessStore s) {
36     Preconditions.checkArgument(isValidTreeType(t), "cannot store environment for node " + t);
37     environmentNullness.put(t, s);
38   }
39 
40   @Nullable
getEnvironmentMapping(Tree t)41   public NullnessStore getEnvironmentMapping(Tree t) {
42     Preconditions.checkArgument(isValidTreeType(t));
43     return environmentNullness.get(t);
44   }
45 
clear()46   public void clear() {
47     environmentNullness.clear();
48   }
49 
50   /** Is t an anonymous inner class or a lambda? */
isValidTreeType(Tree t)51   private boolean isValidTreeType(Tree t) {
52     if (t instanceof LambdaExpressionTree) {
53       return true;
54     }
55     if (t instanceof ClassTree) {
56       NestingKind nestingKind = ASTHelpers.getSymbol((ClassTree) t).getNestingKind();
57       return nestingKind.equals(NestingKind.ANONYMOUS) || nestingKind.equals(NestingKind.LOCAL);
58     }
59     return false;
60   }
61 }
62