get rid of intellij.build.toolbox.litegen parameter and use BuildOptions.TOOLBOX_LITE...
[idea/community.git] / java / java-impl / src / com / intellij / codeInspection / duplicateExpressions / DuplicateExpressionsContext.java
1 // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.codeInspection.duplicateExpressions;
3
4 import com.intellij.openapi.util.Key;
5 import com.intellij.openapi.util.UserDataHolder;
6 import com.intellij.psi.PsiCodeBlock;
7 import com.intellij.psi.PsiExpression;
8 import com.intellij.psi.controlFlow.ControlFlowUtil;
9 import com.intellij.util.ObjectUtils;
10 import gnu.trove.THashMap;
11 import org.jetbrains.annotations.NotNull;
12 import org.jetbrains.annotations.Nullable;
13
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.function.BiConsumer;
18
19 /**
20  * @author Pavel.Dolgov
21  */
22 class DuplicateExpressionsContext {
23   private static final Key<Map<PsiCodeBlock, DuplicateExpressionsContext>> CONTEXTS_KEY = Key.create("DuplicateExpressionsContext");
24
25   private final Map<PsiExpression, List<PsiExpression>> myOccurrences = new THashMap<>(new ExpressionHashingStrategy());
26   private final ComplexityCalculator myComplexityCalculator = new ComplexityCalculator();
27   private final SideEffectCalculator mySideEffectCalculator = new SideEffectCalculator();
28
29   void addOccurrence(PsiExpression expression) {
30     List<PsiExpression> list = myOccurrences.computeIfAbsent(expression, unused -> new ArrayList<>());
31     list.add(expression);
32   }
33
34   void forEach(BiConsumer<? super PsiExpression, ? super List<PsiExpression>> consumer) {
35     myOccurrences.forEach(consumer);
36   }
37
38   int getComplexity(PsiExpression expression) {
39     return myComplexityCalculator.getComplexity(expression);
40   }
41
42   boolean mayHaveSideEffect(PsiExpression expression) {
43     return mySideEffectCalculator.mayHaveSideEffect(expression);
44   }
45
46   @Nullable
47   static DuplicateExpressionsContext getOrCreateContext(@NotNull PsiExpression expression, @NotNull UserDataHolder session) {
48     PsiCodeBlock nearestBody = findNearestBody(expression);
49     if (nearestBody != null) {
50       Map<PsiCodeBlock, DuplicateExpressionsContext> contexts = session.getUserData(CONTEXTS_KEY);
51       if (contexts == null) {
52         session.putUserData(CONTEXTS_KEY, contexts = new THashMap<>());
53       }
54       return contexts.computeIfAbsent(nearestBody, unused -> new DuplicateExpressionsContext());
55     }
56     return null;
57   }
58
59   @Nullable
60   static DuplicateExpressionsContext getContext(@Nullable PsiCodeBlock body, @NotNull UserDataHolder session) {
61     Map<PsiCodeBlock, DuplicateExpressionsContext> contexts = session.getUserData(CONTEXTS_KEY);
62     return contexts != null ? contexts.get(body) : null;
63   }
64
65   static PsiCodeBlock findNearestBody(@NotNull PsiExpression expression) {
66     return ObjectUtils.tryCast(ControlFlowUtil.findCodeFragment(expression), PsiCodeBlock.class);
67   }
68 }