Cleanup (warnings; formatting)
[idea/community.git] / java / java-impl / src / com / intellij / codeInsight / daemon / impl / quickfix / DefaultQuickFixProvider.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.codeInsight.daemon.impl.quickfix;
17
18 import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
19 import com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil;
20 import com.intellij.codeInsight.intention.IntentionAction;
21 import com.intellij.codeInsight.intention.QuickFixFactory;
22 import com.intellij.codeInsight.intention.impl.PriorityIntentionActionWrapper;
23 import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
24 import com.intellij.openapi.util.TextRange;
25 import com.intellij.openapi.util.text.StringUtil;
26 import com.intellij.psi.*;
27 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
28 import com.intellij.psi.codeStyle.VariableKind;
29 import com.intellij.psi.util.PsiTreeUtil;
30 import com.intellij.psi.util.PsiUtil;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
33
34 import java.util.EnumMap;
35 import java.util.Map;
36
37 public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider<PsiJavaCodeReferenceElement> {
38   @Override
39   public void registerFixes(@NotNull PsiJavaCodeReferenceElement ref, @NotNull QuickFixActionRegistrar registrar) {
40     registrar.register(new ImportClassFix(ref));
41     registrar.register(new StaticImportConstantFix(ref));
42     registrar.register(QuickFixFactory.getInstance().createSetupJDKFix());
43
44     OrderEntryFix.registerFixes(registrar, ref);
45
46     MoveClassToModuleFix.registerFixes(registrar, ref);
47
48     if (ref instanceof PsiReferenceExpression) {
49       TextRange fixRange = HighlightMethodUtil.getFixRange(ref);
50       PsiReferenceExpression refExpr = (PsiReferenceExpression)ref;
51
52       registrar.register(fixRange, new CreateEnumConstantFromUsageFix(refExpr), null);
53       registrar.register(new RenameWrongRefFix(refExpr));
54
55       if (!ref.isQualified()) {
56         registrar.register(fixRange, new BringVariableIntoScopeFix(refExpr), null);
57       }
58
59       registerPriorityActions(registrar, fixRange, refExpr);
60     }
61
62     registrar.register(new CreateClassFromUsageFix(ref, CreateClassKind.INTERFACE));
63     if (PsiUtil.isLanguageLevel5OrHigher(ref)) {
64       registrar.register(new CreateClassFromUsageFix(ref, CreateClassKind.ENUM));
65       registrar.register(new CreateClassFromUsageFix(ref, CreateClassKind.ANNOTATION));
66     }
67
68     PsiElement parent = PsiTreeUtil.getParentOfType(ref, PsiNewExpression.class, PsiMethod.class);
69     PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(ref, PsiExpressionList.class);
70     if (parent instanceof PsiNewExpression &&
71         !(ref.getParent() instanceof PsiTypeElement) &&
72         (expressionList == null || !PsiTreeUtil.isAncestor(parent, expressionList, false))) {
73       registrar.register(new CreateClassFromNewFix((PsiNewExpression)parent));
74       registrar.register(new CreateInnerClassFromNewFix((PsiNewExpression)parent));
75     }
76     else {
77       registrar.register(new CreateClassFromUsageFix(ref, CreateClassKind.CLASS));
78       registrar.register(new CreateInnerClassFromUsageFix(ref, CreateClassKind.CLASS));
79     }
80   }
81
82   private static void registerPriorityActions(@NotNull QuickFixActionRegistrar registrar,
83                                               @NotNull TextRange fixRange,
84                                               @NotNull PsiReferenceExpression refExpr) {
85     final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(refExpr.getProject());
86
87     final Map<VariableKind, IntentionAction> map = new EnumMap<>(VariableKind.class);
88     map.put(VariableKind.FIELD, new CreateFieldFromUsageFix(refExpr));
89     map.put(VariableKind.STATIC_FINAL_FIELD, new CreateConstantFieldFromUsageFix(refExpr));
90     if (!refExpr.isQualified()) {
91       map.put(VariableKind.LOCAL_VARIABLE, new CreateLocalFromUsageFix(refExpr));
92       map.put(VariableKind.PARAMETER, new CreateParameterFromUsageFix(refExpr));
93     }
94
95     final VariableKind kind = getKind(styleManager, refExpr);
96     if (map.containsKey(kind)) {
97       map.put(kind, PriorityIntentionActionWrapper.highPriority(map.get(kind)));
98     }
99
100     for (IntentionAction action : map.values()) {
101       registrar.register(fixRange, action, null);
102     }
103   }
104
105   @Nullable
106   private static VariableKind getKind(@NotNull JavaCodeStyleManager styleManager, @NotNull PsiReferenceExpression refExpr) {
107     final String reference = refExpr.getText();
108
109     boolean upperCase = true;
110     for (int i = 0; i < reference.length(); i++) {
111       if (!Character.isUpperCase(reference.charAt(i))) { upperCase = false; break; }
112     }
113     if (upperCase) {
114       return VariableKind.STATIC_FINAL_FIELD;
115     }
116
117     for (VariableKind kind : VariableKind.values()) {
118       final String prefix = styleManager.getPrefixByVariableKind(kind);
119       final String suffix = styleManager.getSuffixByVariableKind(kind);
120
121       if (prefix.isEmpty() && suffix.isEmpty()) {
122         continue;
123       }
124
125       if (reference.startsWith(prefix) && reference.endsWith(suffix)) {
126         return kind;
127       }
128     }
129
130     if (StringUtil.isCapitalized(reference)) {
131       return null;
132     }
133
134     return VariableKind.LOCAL_VARIABLE;
135   }
136
137   @Override
138   @NotNull
139   public Class<PsiJavaCodeReferenceElement> getReferenceClass() {
140     return PsiJavaCodeReferenceElement.class;
141   }
142 }