/*
- * 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.
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
*/
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) {
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;
}
@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() {
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));
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) {
}
}
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;
}
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;
}
}