From faaea767e563e18452621b2aa33842db87edbe9d Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 6 Oct 2013 21:35:54 +0200 Subject: [PATCH 1/3] do not unnecessarily write inspection settings --- .../javaDoc/JavaDocLocalInspection.java | 16 ++++++++++++---- .../codeInspection/JavaDocInspectionTest.java | 3 +-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspection.java index fc3cdd0b6fc7..146bf0c72e75 100644 --- a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspection.java @@ -75,8 +75,7 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool { @NonNls public String ACCESS_JAVADOC_REQUIRED_FOR = NONE; @NonNls public String REQUIRED_TAGS = ""; - public Options() { - } + public Options() {} public Options(String ACCESS_JAVADOC_REQUIRED_FOR, String REQUIRED_TAGS) { this.ACCESS_JAVADOC_REQUIRED_FOR = ACCESS_JAVADOC_REQUIRED_FOR; @@ -94,7 +93,7 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool { } } - @NonNls public Options PACKAGE_OPTIONS = new Options("none", ""); + @NonNls private Options PACKAGE_OPTIONS = new Options("none", ""); @NonNls public Options TOP_LEVEL_CLASS_OPTIONS = new Options("none", ""); @NonNls public Options INNER_CLASS_OPTIONS = new Options("none", ""); @NonNls public Options METHOD_OPTIONS = new Options("none", "@return@param@throws or @exception"); @@ -112,6 +111,11 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool { myIgnoreSimpleAccessors = ignoreSimpleAccessors; } + public void setPackageOption(@NonNls String modifier, @NonNls String tags) { + PACKAGE_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR = modifier; + PACKAGE_OPTIONS.REQUIRED_TAGS = tags; + } + private static final Logger LOG = Logger.getInstance("com.intellij.codeInspection.javaDoc.JavaDocLocalInspection"); private class OptionsPanel extends JPanel { @@ -331,6 +335,9 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool { option.setAttribute("value", String.valueOf(true)); node.addContent(option); } + if (!PACKAGE_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR.equals("none") || !PACKAGE_OPTIONS.REQUIRED_TAGS.isEmpty()) { + PACKAGE_OPTIONS.writeExternal(node); + } } @Override @@ -340,11 +347,12 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool { if (ignoreAccessorsTag != null) { myIgnoreSimpleAccessors = Boolean.parseBoolean(ignoreAccessorsTag.getAttributeValue("value")); } + PACKAGE_OPTIONS.readExternal(node); } private static ProblemDescriptor createDescriptor(@NotNull PsiElement element, String template, InspectionManager manager, boolean onTheFly) { - return manager.createProblemDescriptor(element, template, onTheFly, (LocalQuickFix [])null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + return manager.createProblemDescriptor(element, template, onTheFly, null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } private static ProblemDescriptor createDescriptor(@NotNull PsiElement element, String template, @NotNull LocalQuickFix fix, diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/JavaDocInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/JavaDocInspectionTest.java index 0e5e20e3212f..a8330887731e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/JavaDocInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/JavaDocInspectionTest.java @@ -74,8 +74,7 @@ public class JavaDocInspectionTest extends InspectionTestCase { public void testPackageInfo() throws Exception { final JavaDocLocalInspection inspection = new JavaDocLocalInspection(); inspection.IGNORE_DEPRECATED = true; - inspection.PACKAGE_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR = "public"; - inspection.PACKAGE_OPTIONS.REQUIRED_TAGS = "@author"; + inspection.setPackageOption("public", "@author"); doTest("javaDocInspection/" + getTestName(true), inspection); } } From c674398043320313200c6d834da74591dfe5189a Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 6 Oct 2013 20:14:41 +0200 Subject: [PATCH 2/3] IDEA-74901 Fold simple property accessors inline --- .../impl/JavaCodeFoldingSettingsBase.java | 2 +- .../folding/impl/JavaFoldingBuilderBase.java | 59 +++++++++++++++++-- .../folding/JavaFoldingTest.groovy | 38 ++++++++++++ 3 files changed, 94 insertions(+), 5 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaCodeFoldingSettingsBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaCodeFoldingSettingsBase.java index ebbf55e2eee6..c092b5398a81 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaCodeFoldingSettingsBase.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaCodeFoldingSettingsBase.java @@ -4,7 +4,7 @@ import com.intellij.codeInsight.folding.CodeFoldingSettings; import com.intellij.codeInsight.folding.JavaCodeFoldingSettings; public class JavaCodeFoldingSettingsBase extends JavaCodeFoldingSettings { - @SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_ACCESSORS = false; + @SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_ACCESSORS = true; @SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_INNER_CLASSES = false; @SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_ANONYMOUS_CLASSES = false; @SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_ANNOTATIONS = false; diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java index cbaedbeb93d4..d29436834d4e 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java @@ -71,7 +71,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem private static boolean isSimplePropertyAccessor(PsiMethod method) { PsiCodeBlock body = method.getBody(); - if (body == null) return false; + if (body == null || body.getLBrace() == null || body.getRBrace() == null) return false; PsiStatement[] statements = body.getStatements(); if (statements.length == 0) return false; PsiStatement statement = statements[0]; @@ -515,7 +515,10 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem if (child instanceof PsiMethod) { PsiMethod method = (PsiMethod)child; - addToFold(list, method, document, true); + boolean accessor = isSimplePropertyAccessor(method) && addInlineAccessorFolding(list, method); + if (!accessor) { + addToFold(list, method, document, true); + } addAnnotationsToFold(method.getModifierList(), list, document); if (foldJavaDocs) { @@ -526,7 +529,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem } PsiCodeBlock body = method.getBody(); - if (body != null) { + if (body != null && !accessor) { addCodeBlockFolds(body, list, processedComments, document, quick); } } @@ -560,6 +563,48 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem } } + private static boolean addInlineAccessorFolding(List descriptorList, PsiMethod accessor) { + if (!JavaCodeFoldingSettings.getInstance().isCollapseAccessors()) { + return false; + } + + PsiCodeBlock body = accessor.getBody(); + assert body != null; + if (body.getStatements().length > 1) { + return false; + } + + PsiStatement statement = body.getStatements()[0]; + if (statement.textContains('\n')) { + return false; + } + + FoldingGroup group = FoldingGroup.newGroup("simple property accessor"); + int paramListEnd = accessor.getParameterList().getTextRange().getEndOffset(); + int statementStart = statement.getTextRange().getStartOffset(); + PsiJavaToken lBrace = body.getLBrace(); + assert lBrace != null; + descriptorList.add(new FoldingDescriptor(lBrace.getNode(), new TextRange(paramListEnd, statementStart), group) { + @Nullable + @Override + public String getPlaceholderText() { + return " { "; + } + }); + + int statementEnd = statement.getTextRange().getEndOffset(); + PsiJavaToken rBrace = body.getRBrace(); + assert rBrace != null; + descriptorList.add(new FoldingDescriptor(rBrace.getNode(), new TextRange(statementEnd, body.getTextRange().getEndOffset()), group) { + @Nullable + @Override + public String getPlaceholderText() { + return " }"; + } + }); + return true; + } + @Override protected String getLanguagePlaceholderText(@NotNull ASTNode node, @NotNull TextRange range) { return getPlaceholderText(SourceTreeToPsiMap.treeElementToPsi(node)); @@ -569,9 +614,15 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem protected boolean isRegionCollapsedByDefault(@NotNull ASTNode node) { final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(node); JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance(); - if (element instanceof PsiNewExpression || element instanceof PsiJavaToken) { + if (element instanceof PsiNewExpression || element instanceof PsiJavaToken && + element.getParent() instanceof PsiAnonymousClass) { return settings.isCollapseLambdas(); } + if (element instanceof PsiJavaToken && + element.getParent() instanceof PsiCodeBlock && + element.getParent().getParent() instanceof PsiMethod) { + return settings.isCollapseAccessors(); + } if (element instanceof PsiReferenceParameterList) { return settings.isCollapseConstructorGenericParameters(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index 76e465e6952e..1e03eeb15b66 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -24,6 +24,10 @@ import com.intellij.openapi.editor.FoldRegion import com.intellij.openapi.editor.ex.FoldingModelEx import com.intellij.openapi.editor.impl.FoldingModelImpl import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider +import com.intellij.psi.JavaPsiFacade +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiMethod +import com.intellij.psi.search.GlobalSearchScope import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase /** @@ -427,6 +431,40 @@ class Test { myFixture.doHighlighting() } + public void "test simple property accessors in one line"() { + configure """class Foo { + int field; + + int getField() + { + return field; + } + + void setField(int f) { + field = f; + } + +}""" + PsiClass fooClass = JavaPsiFacade.getInstance(project).findClass('Foo', GlobalSearchScope.allScope(project)) + def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset } + assert regions.size() == 4 + + Closure checkAccessorFolding = { FoldRegion region1, FoldRegion region2, PsiMethod method -> + assert region1.startOffset == method.parameterList.textRange.endOffset + assert region1.endOffset == method.body.statements[0].textRange.startOffset + assert region1.placeholderText == ' { ' + + assert region2.startOffset == method.body.statements[0].textRange.endOffset + assert region2.endOffset == method.textRange.endOffset + assert region2.placeholderText == ' }' + assert region1.group == region2.group + } + + checkAccessorFolding(regions[0], regions[1], fooClass.methods[0]) + checkAccessorFolding(regions[2], regions[3], fooClass.methods[1]) + + } + private def changeFoldRegions(Closure op) { myFixture.editor.foldingModel.runBatchFoldingOperationDoNotCollapseCaret(op) } From 46a5f0e96b7abbdbd237c8c415ff2c6c98ddd2f0 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 6 Oct 2013 22:03:45 +0200 Subject: [PATCH 3/3] IDEA-113546 Suggest to create a plain file when creating a Java class with a suspicious name --- .../CreateDirectoryOrPackageHandler.java | 10 ++++- .../ide/actions/CreateFromTemplateAction.java | 40 ++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java b/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java index 3ccd80c3c4ac..e95196cecd54 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java @@ -105,8 +105,8 @@ public class CreateDirectoryOrPackageHandler implements InputValidatorEx { boolean createFile = false; if (StringUtil.countChars(subDirName, '.') == 1) { - FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(subDirName); - if (!(fileType instanceof UnknownFileType)) { + FileType fileType = findFileTypeBoundToName(subDirName); + if (fileType != null) { String message = "The name you entered looks like a file name. Do you want to create a file named " + subDirName + " instead?"; int ec = Messages.showYesNoDialog(myProject, message, "File Name Detected", "Yes, create file", @@ -123,6 +123,12 @@ public class CreateDirectoryOrPackageHandler implements InputValidatorEx { return myCreatedElement != null; } + @Nullable + public static FileType findFileTypeBoundToName(String name) { + FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(name); + return fileType instanceof UnknownFileType ? null : fileType; + } + private void doCreateElement(final String subDirName, final boolean createFile) { Runnable command = new Runnable() { @Override diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CreateFromTemplateAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CreateFromTemplateAction.java index 26ecb5616972..69ef5f92eba2 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CreateFromTemplateAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CreateFromTemplateAction.java @@ -23,11 +23,15 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiNameIdentifierOwner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,14 +66,35 @@ public abstract class CreateFromTemplateAction extends AnA final CreateFileFromTemplateDialog.Builder builder = CreateFileFromTemplateDialog.createDialog(project); buildDialog(project, dir, builder); + final Ref createdElement = Ref.create(null); + final Ref createdFile = Ref.create(null); final Ref selectedTemplateName = Ref.create(null); - final T createdElement = - builder.show(getErrorTitle(), getDefaultTemplateName(dir), new CreateFileFromTemplateDialog.FileCreator() { + builder.show(getErrorTitle(), getDefaultTemplateName(dir), new CreateFileFromTemplateDialog.FileCreator() { @Override public T createFile(@NotNull String name, @NotNull String templateName) { + if (StringUtil.countChars(name, '.') == 1) { + FileType fileType = CreateDirectoryOrPackageHandler.findFileTypeBoundToName(name); + if (fileType != null) { + String message = "The name you entered looks like a file name. Do you want to create a file named " + name + " instead?"; + int ec = Messages.showYesNoDialog(project, message, + "File Name Detected", + "Yes, create " + name, + "No, create " + e.getPresentation().getText(), + fileType.getIcon()); + if (ec == Messages.OK) { + PsiFile newFile = dir.createFile(name); + createdFile.set(newFile); + //noinspection unchecked + return (T)newFile; + } + } + } + selectedTemplateName.set(templateName); - return CreateFromTemplateAction.this.createFile(name, templateName, dir); + T created = CreateFromTemplateAction.this.createFile(name, templateName, dir); + createdElement.set(created); + return created; } @Override @@ -78,9 +103,12 @@ public abstract class CreateFromTemplateAction extends AnA return CreateFromTemplateAction.this.getActionName(dir, name, templateName); } }); - if (createdElement != null) { - view.selectElement(createdElement); - postProcess(createdElement, selectedTemplateName.get(), builder.getCustomProperties()); + if (!createdFile.isNull()) { + view.selectElement(createdFile.get()); + } + else if (!createdElement.isNull()) { + view.selectElement(createdElement.get()); + postProcess(createdElement.get(), selectedTemplateName.get(), builder.getCustomProperties()); } }