2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com
.intellij
.codeInspection
.defaultFileTemplateUsage
;
18 import com
.intellij
.codeInsight
.PsiEquivalenceUtil
;
19 import com
.intellij
.codeInspection
.*;
20 import com
.intellij
.ide
.fileTemplates
.FileTemplate
;
21 import com
.intellij
.ide
.fileTemplates
.FileTemplateManager
;
22 import com
.intellij
.ide
.fileTemplates
.JavaTemplateUtil
;
23 import com
.intellij
.openapi
.diagnostic
.Logger
;
24 import com
.intellij
.openapi
.progress
.ProcessCanceledException
;
25 import com
.intellij
.openapi
.project
.Project
;
26 import com
.intellij
.openapi
.util
.Pair
;
27 import com
.intellij
.psi
.*;
28 import com
.intellij
.util
.IncorrectOperationException
;
29 import org
.jetbrains
.annotations
.NotNull
;
31 import java
.io
.IOException
;
32 import java
.util
.Collection
;
33 import java
.util
.Comparator
;
34 import java
.util
.Properties
;
39 class CatchBodyVisitor
extends JavaRecursiveElementWalkingVisitor
{
40 private static final Logger LOG
= Logger
.getInstance("#com.intellij.codeInspection.defaultFileTemplateUsage.CatchBodyVisitor");
42 Collection
<ProblemDescriptor
> myProblemDescriptors
;
43 private final InspectionManager myManager
;
45 public CatchBodyVisitor(InspectionManager manager
, Collection
<ProblemDescriptor
> descriptors
) {
47 myProblemDescriptors
= descriptors
;
50 @Override public void visitCatchSection(PsiCatchSection section
) {
51 checkSection(section
);
52 super.visitCatchSection(section
);
55 @Override public void visitClass(PsiClass aClass
) {
59 private void checkSection(final PsiCatchSection section
) {
60 final PsiParameter parameter
= section
.getParameter();
61 if (parameter
== null) return;
62 PsiCodeBlock catchBlock
= section
.getCatchBlock();
63 if (catchBlock
== null) return;
64 PsiType type
= parameter
.getType();
65 if (!(type
instanceof PsiClassType
)) return;
66 PsiCodeBlock templateCatchBlock
;
67 final PsiParameter templateParameter
;
69 final PsiJavaParserFacade elementFactory
= JavaPsiFacade
.getInstance(section
.getProject()).getParserFacade();
70 PsiCatchSection sectionTemplate
= elementFactory
.createCatchSection((PsiClassType
)type
, parameter
.getName(), parameter
);
71 templateCatchBlock
= sectionTemplate
.getCatchBlock();
73 // replace with default template text
74 FileTemplate catchBodyTemplate
= FileTemplateManager
.getInstance().getDefaultTemplate(JavaTemplateUtil
.TEMPLATE_CATCH_BODY
);
76 Properties props
= new Properties();
77 props
.setProperty(FileTemplate
.ATTRIBUTE_EXCEPTION
, parameter
.getName());
78 String catchBody
= catchBodyTemplate
.getText(props
);
79 PsiCodeBlock codeBlockFromText
= elementFactory
.createCodeBlockFromText("{\n" + catchBody
+ "\n}", null);
80 templateCatchBlock
= (PsiCodeBlock
)templateCatchBlock
.replace(codeBlockFromText
);
82 templateParameter
= sectionTemplate
.getParameter();
84 catch (ProcessCanceledException e
) {
88 catch (IncorrectOperationException e
) {
92 catch (IOException e
) {
96 // should be equal except parameter names which should resolve to corresponding parameters
97 if (!PsiEquivalenceUtil
.areElementsEquivalent(catchBlock
, templateCatchBlock
, new Comparator
<PsiElement
>() {
98 public int compare(final PsiElement o1
, final PsiElement o2
) {
99 if (o1
== parameter
&& o2
== templateParameter
) return 0;
105 Pair
<?
extends PsiElement
, ?
extends PsiElement
> range
= DefaultFileTemplateUsageInspection
.getInteriorRange(catchBlock
);
106 final String description
= InspectionsBundle
.message("default.file.template.description");
107 ProblemDescriptor descriptor
= myManager
.createProblemDescriptor(range
.first
, range
.second
, description
, ProblemHighlightType
.GENERIC_ERROR_OR_WARNING
, createQuickFix(section
));
108 myProblemDescriptors
.add(descriptor
);
111 private static LocalQuickFix
[] createQuickFix(final PsiCatchSection section
) {
112 FileTemplate template
= FileTemplateManager
.getInstance().getCodeTemplate(JavaTemplateUtil
.TEMPLATE_CATCH_BODY
);
113 ReplaceWithFileTemplateFix replaceWithFileTemplateFix
= new ReplaceWithFileTemplateFix() {
114 public void applyFix(@NotNull Project project
, @NotNull ProblemDescriptor descriptor
) {
115 final PsiParameter parameter
= section
.getParameter();
116 if (parameter
== null) return;
117 PsiCodeBlock catchBlock
= section
.getCatchBlock();
118 if (catchBlock
== null) return;
119 PsiType type
= parameter
.getType();
120 if (!(type
instanceof PsiClassType
)) return;
121 final PsiJavaParserFacade elementFactory
= JavaPsiFacade
.getInstance(section
.getProject()).getParserFacade();
123 PsiCatchSection sectionTemplate
= elementFactory
.createCatchSection((PsiClassType
)type
, parameter
.getName(), parameter
);
124 section
.replace(sectionTemplate
);
126 catch (IncorrectOperationException e
) {
132 LocalQuickFix editFileTemplateFix
= DefaultFileTemplateUsageInspection
.createEditFileTemplateFix(template
, replaceWithFileTemplateFix
);
133 if (template
.isDefault()) {
134 return new LocalQuickFix
[]{editFileTemplateFix
};
136 return new LocalQuickFix
[]{replaceWithFileTemplateFix
, editFileTemplateFix
};