mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-132440 (quick fix corrected; cleanup)
This commit is contained in:
+8
-31
@@ -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<? extends PsiElement, ? extends PsiElement> getInteriorRange(PsiCodeBlock codeBlock) {
|
||||
PsiElement[] children = codeBlock.getChildren();
|
||||
if (children.length == 0) return Pair.create(codeBlock, codeBlock);
|
||||
int start;
|
||||
for (start=0; start<children.length;start++) {
|
||||
PsiElement child = children[start];
|
||||
if (child instanceof PsiWhiteSpace) continue;
|
||||
if (child instanceof PsiJavaToken && ((PsiJavaToken)child).getTokenType() == JavaTokenType.LBRACE) continue;
|
||||
break;
|
||||
}
|
||||
int end;
|
||||
for (end=children.length-1; end > 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() {
|
||||
|
||||
+67
-86
@@ -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<String> offsetToProperty = new TIntObjectHashMap<String>();
|
||||
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<PsiDocComment> docComment = new Ref<PsiDocComment>();
|
||||
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<PsiDocComment> docComment = new Ref<PsiDocComment>();
|
||||
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<String> offsetToProperty) {
|
||||
public static Pattern getTemplatePattern(@NotNull FileTemplate template,
|
||||
@NotNull Project project,
|
||||
@NotNull TIntObjectHashMap<String> 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<String> 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<String> offsetToProperty) {
|
||||
private static LocalQuickFix[] createQuickFix(final Matcher matcher, final TIntObjectHashMap<String> 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<String> offsetToProperty, @NotNull Project project) {
|
||||
String regex = text;
|
||||
@NonNls Collection<String> properties = new ArrayList<String>((Collection)FileTemplateManager.getInstance().getDefaultProperties(project).keySet());
|
||||
private static String templateToRegex(String text, TIntObjectHashMap<String> offsetToProperty, Project project) {
|
||||
List<Object> 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<regex.length(); i = regex.indexOf(escaped,i+1)) {
|
||||
for (int i = regex.indexOf(escaped); i != -1 && i < regex.length(); i = regex.indexOf(escaped, i + 1)) {
|
||||
String replacement = first ? "([^\\n]*)" : "\\" + groupNumber;
|
||||
final int delta = escaped.length() - replacement.length();
|
||||
int delta = escaped.length() - replacement.length();
|
||||
int[] offs = offsetToProperty.keys();
|
||||
for (int off : offs) {
|
||||
if (off > 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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user