diff --git a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java index 9835c6864ad5..150cbe05b980 100644 --- a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +18,15 @@ package com.intellij.codeInspection.defaultFileTemplateUsage; import com.intellij.codeInspection.*; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Pair; -import com.intellij.psi.*; +import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; - /** * @author cdr */ @@ -60,26 +58,6 @@ public class DefaultFileTemplateUsageInspection extends BaseJavaLocalInspectionT return "DefaultFileTemplate"; } - static Pair getInteriorRange(PsiCodeBlock codeBlock) { - PsiElement[] children = codeBlock.getChildren(); - if (children.length == 0) return Pair.create(codeBlock, codeBlock); - int start; - for (start=0; start start;end--) { - PsiElement child = children[end]; - if (child instanceof PsiWhiteSpace) continue; - if (child instanceof PsiJavaToken && ((PsiJavaToken)child).getTokenType() == JavaTokenType.RBRACE) continue; - break; - } - return Pair.create(children[start], children[end]); - } - @Override @Nullable public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) { @@ -92,15 +70,15 @@ public class DefaultFileTemplateUsageInspection extends BaseJavaLocalInspectionT return true; } - public static LocalQuickFix createEditFileTemplateFix(final FileTemplate templateToEdit, final ReplaceWithFileTemplateFix replaceTemplateFix) { - return new MyLocalQuickFix(templateToEdit, replaceTemplateFix); + public static LocalQuickFix createEditFileTemplateFix(FileTemplate templateToEdit, ReplaceWithFileTemplateFix replaceTemplateFix) { + return new EditFileTemplateFix(templateToEdit, replaceTemplateFix); } - private static class MyLocalQuickFix implements LocalQuickFix { + private static class EditFileTemplateFix implements LocalQuickFix { private final FileTemplate myTemplateToEdit; private final ReplaceWithFileTemplateFix myReplaceTemplateFix; - public MyLocalQuickFix(FileTemplate templateToEdit, ReplaceWithFileTemplateFix replaceTemplateFix) { + public EditFileTemplateFix(FileTemplate templateToEdit, ReplaceWithFileTemplateFix replaceTemplateFix) { myTemplateToEdit = templateToEdit; myReplaceTemplateFix = replaceTemplateFix; } @@ -120,11 +98,10 @@ public class DefaultFileTemplateUsageInspection extends BaseJavaLocalInspectionT @Override public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) { final FileTemplateConfigurable configurable = new FileTemplateConfigurable(); - SwingUtilities.invokeLater(new Runnable(){ + ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { configurable.setTemplate(myTemplateToEdit, null); - boolean ok = ShowSettingsUtil.getInstance().editConfigurable(project, configurable); if (ok) { WriteCommandAction.runWriteCommandAction(project, new Runnable() { diff --git a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java index a3db2c3d31f8..86cd33ba5434 100644 --- a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java +++ b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java @@ -20,97 +20,97 @@ import com.intellij.codeInspection.*; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.JavaRecursiveElementWalkingVisitor; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; -import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.TIntObjectHashMap; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; +import java.util.List; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * @author Alexey + * @author cdr */ public class FileHeaderChecker { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defaultFileTemplateUsage.FileHeaderChecker"); - static ProblemDescriptor checkFileHeader(@NotNull final PsiFile file, @NotNull InspectionManager manager, boolean onTheFly) { + static ProblemDescriptor checkFileHeader(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean onTheFly) { TIntObjectHashMap offsetToProperty = new TIntObjectHashMap(); FileTemplate defaultTemplate = FileTemplateManager.getInstance().getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME); Pattern pattern = getTemplatePattern(defaultTemplate, file.getProject(), offsetToProperty); Matcher matcher = pattern.matcher(file.getViewProvider().getContents()); - if (matcher.matches()) { - final int startOffset = matcher.start(1); - final int endOffset = matcher.end(1); - final Ref docComment = new Ref(); - file.accept(new JavaRecursiveElementWalkingVisitor(){ - @Override public void visitElement(PsiElement element) { - if (docComment.get() != null) return; - TextRange range = element.getTextRange(); - if (!range.contains(startOffset) && !range.contains(endOffset)) return; - super.visitElement(element); - } - @Override public void visitDocComment(PsiDocComment comment) { - docComment.set(comment); - } - }); - PsiDocComment element = docComment.get(); - if (element == null) return null; - LocalQuickFix[] quickFix = createQuickFix(matcher, offsetToProperty); - final String description = InspectionsBundle.message("default.file.template.description"); - return manager.createProblemDescriptor(element, description, onTheFly, quickFix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - } - return null; + if (!matcher.matches()) return null; + + final int startOffset = matcher.start(1); + final int endOffset = matcher.end(1); + final Ref docComment = new Ref(); + file.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitElement(PsiElement element) { + if (docComment.get() != null) return; + TextRange range = element.getTextRange(); + if (!range.contains(startOffset) && !range.contains(endOffset)) return; + super.visitElement(element); + } + + @Override + public void visitDocComment(PsiDocComment comment) { + docComment.set(comment); + } + }); + PsiDocComment element = docComment.get(); + if (element == null) return null; + + LocalQuickFix[] fixes = createQuickFix(matcher, offsetToProperty); + String description = InspectionsBundle.message("default.file.template.description"); + return manager.createProblemDescriptor(element, description, onTheFly, fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } - public static Pattern getTemplatePattern(@NotNull FileTemplate template, @NotNull Project project, @NotNull TIntObjectHashMap offsetToProperty) { + public static Pattern getTemplatePattern(@NotNull FileTemplate template, + @NotNull Project project, + @NotNull TIntObjectHashMap offsetToProperty) { String templateText = template.getText().trim(); String regex = templateToRegex(templateText, offsetToProperty, project); regex = StringUtil.replace(regex, "with", "(?:with|by)"); - regex = ".*("+regex+").*"; + regex = ".*(" + regex + ").*"; return Pattern.compile(regex, Pattern.DOTALL); } private static Properties computeProperties(final Matcher matcher, final TIntObjectHashMap offsetToProperty) { Properties properties = new Properties(FileTemplateManager.getInstance().getDefaultProperties()); + int[] offsets = offsetToProperty.keys(); Arrays.sort(offsets); - for (int i = 0; i < offsets.length; i++) { final int offset = offsets[i]; String propName = offsetToProperty.get(offset); int groupNum = i + 2; // first group is whole doc comment String propValue = matcher.group(groupNum); - properties.put(propName, propValue); + properties.setProperty(propName, propValue); } + return properties; } - private static LocalQuickFix[] createQuickFix(final Matcher matcher, - final TIntObjectHashMap offsetToProperty) { + private static LocalQuickFix[] createQuickFix(final Matcher matcher, final TIntObjectHashMap offsetToProperty) { final FileTemplate template = FileTemplateManager.getInstance().getPattern(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME); - final ReplaceWithFileTemplateFix replaceTemplateFix = new ReplaceWithFileTemplateFix() { + ReplaceWithFileTemplateFix replaceTemplateFix = new ReplaceWithFileTemplateFix() { @Override - public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) { + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PsiElement element = descriptor.getPsiElement(); if (element == null || !element.isValid()) return; if (!CodeInsightUtil.preparePsiElementsForWrite(element)) return; + String newText; try { newText = template.getText(computeProperties(matcher, offsetToProperty)); @@ -119,49 +119,30 @@ public class FileHeaderChecker { LOG.error(e); return; } - try { - int offset = element.getTextRange().getStartOffset(); - PsiFile psiFile = element.getContainingFile(); - if (psiFile == null) return; - PsiDocumentManager documentManager = PsiDocumentManager.getInstance(psiFile.getProject()); - Document document = documentManager.getDocument(psiFile); - if (document == null) return; - element.delete(); - documentManager.doPostponedOperationsAndUnblockDocument(document); - documentManager.commitDocument(document); - - document.insertString(offset, newText); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - catch (IllegalStateException e) { - LOG.error("Cannot create doc comment from text: '" + newText + "'", e); - } + PsiDocComment newComment = JavaPsiFacade.getElementFactory(project).createDocCommentFromText(newText); + element.replace(newComment); } }; - final LocalQuickFix editFileTemplateFix = DefaultFileTemplateUsageInspection.createEditFileTemplateFix(template, replaceTemplateFix); - if (template.isDefault()) { - return new LocalQuickFix[]{editFileTemplateFix}; - } - return new LocalQuickFix[]{replaceTemplateFix,editFileTemplateFix}; + + LocalQuickFix editFileTemplateFix = DefaultFileTemplateUsageInspection.createEditFileTemplateFix(template, replaceTemplateFix); + return template.isDefault() ? new LocalQuickFix[]{editFileTemplateFix} : new LocalQuickFix[]{replaceTemplateFix, editFileTemplateFix}; } - private static String templateToRegex(@NotNull String text, @NotNull TIntObjectHashMap offsetToProperty, @NotNull Project project) { - String regex = text; - @NonNls Collection properties = new ArrayList((Collection)FileTemplateManager.getInstance().getDefaultProperties(project).keySet()); + private static String templateToRegex(String text, TIntObjectHashMap offsetToProperty, Project project) { + List properties = ContainerUtil.newArrayList(FileTemplateManager.getInstance().getDefaultProperties(project).keySet()); properties.add("PACKAGE_NAME"); - regex = escapeRegexChars(regex); + String regex = escapeRegexChars(text); // first group is a whole file header int groupNumber = 1; - for (String name : properties) { - String escaped = escapeRegexChars("${"+name+"}"); + for (Object property : properties) { + String name = property.toString(); + String escaped = escapeRegexChars("${" + name + "}"); boolean first = true; - for (int i = regex.indexOf(escaped); i!=-1 && i i) { @@ -170,7 +151,7 @@ public class FileHeaderChecker { } } offsetToProperty.put(i, name); - regex = regex.substring(0,i) + replacement + regex.substring(i+escaped.length()); + regex = regex.substring(0, i) + replacement + regex.substring(i + escaped.length()); if (first) { groupNumber++; first = false; @@ -181,18 +162,18 @@ public class FileHeaderChecker { } private static String escapeRegexChars(String regex) { - regex = StringUtil.replace(regex,"|", "\\|"); - regex = StringUtil.replace(regex,".", "\\."); - regex = StringUtil.replace(regex,"*", "\\*"); - regex = StringUtil.replace(regex,"+", "\\+"); - regex = StringUtil.replace(regex,"?", "\\?"); - regex = StringUtil.replace(regex,"$", "\\$"); - regex = StringUtil.replace(regex,"(", "\\("); - regex = StringUtil.replace(regex,")", "\\)"); - regex = StringUtil.replace(regex,"[", "\\["); - regex = StringUtil.replace(regex,"]", "\\]"); - regex = StringUtil.replace(regex,"{", "\\{"); - regex = StringUtil.replace(regex,"}", "\\}"); + regex = StringUtil.replace(regex, "|", "\\|"); + regex = StringUtil.replace(regex, ".", "\\."); + regex = StringUtil.replace(regex, "*", "\\*"); + regex = StringUtil.replace(regex, "+", "\\+"); + regex = StringUtil.replace(regex, "?", "\\?"); + regex = StringUtil.replace(regex, "$", "\\$"); + regex = StringUtil.replace(regex, "(", "\\("); + regex = StringUtil.replace(regex, ")", "\\)"); + regex = StringUtil.replace(regex, "[", "\\["); + regex = StringUtil.replace(regex, "]", "\\]"); + regex = StringUtil.replace(regex, "{", "\\{"); + regex = StringUtil.replace(regex, "}", "\\}"); return regex; } }