From dc4b01f875abbd8989f9ae921334383c4e5e1c8c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 15 Aug 2017 16:05:16 +0300 Subject: [PATCH 01/15] DB tests fix --- .../openapi/fileEditor/impl/LoadTextUtil.java | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java index 1cb44204be41..94b5fec2d631 100644 --- a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java +++ b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java @@ -332,7 +332,6 @@ public final class LoadTextUtil { toolkit.setEnforce8Bit(true); Charset charset = toolkit.guessFromBOM(); if (charset != null) { - byte[] bom = ObjectUtils.notNull(CharsetToolkit.getMandatoryBom(charset), CharsetToolkit.UTF8_BOM); return Trinity.create(charset, null, bom); } @@ -340,29 +339,39 @@ public final class LoadTextUtil { if (guessed == CharsetToolkit.GuessedEncoding.VALID_UTF8) { return Trinity.create(CharsetToolkit.UTF8_CHARSET, CharsetToolkit.GuessedEncoding.VALID_UTF8, null); //UTF detected, ignore all directives } - if (guessed == CharsetToolkit.GuessedEncoding.SEVEN_BIT) { - return Trinity.create(null, CharsetToolkit.GuessedEncoding.SEVEN_BIT, null); - } return Trinity.create(null, guessed, null); } /** * Tries to detect text in the {@code bytes} and call the {@code fileTextProcessor} with the text (if detected) or with null if not */ - public static String getTextFromBytesOrNull(@NotNull byte[] bytes, - int startOffset, int endOffset) { - Trinity info = guessFromBytes(bytes, startOffset, endOffset, CharsetToolkit.UTF8_CHARSET); - Charset internalCharset = info.getFirst(); - CharsetToolkit.GuessedEncoding guessed = info.getSecond(); - if (internalCharset == null || guessed == CharsetToolkit.GuessedEncoding.BINARY || guessed == CharsetToolkit.GuessedEncoding.INVALID_UTF8) { - // the charset was not detected so the file is likely binary - return null; + public static String getTextFromBytesOrNull(@NotNull byte[] bytes, int startOffset, int endOffset) { + Charset defaultCharset = EncodingManager.getInstance().getDefaultCharset(); + Trinity info = guessFromBytes(bytes, startOffset, endOffset, defaultCharset); + Charset charset; + if (info.getFirst() != null) { + charset = info.getFirst(); // hardcoded charset } else { - byte[] bom = info.getThird(); - Pair result = convertBytes(bytes, Math.min(startOffset+(bom==null?0:bom.length), endOffset), endOffset, internalCharset); - return result.getFirst().toString(); + CharsetToolkit.GuessedEncoding guessed = info.getSecond(); + switch (guessed) { + case SEVEN_BIT: + charset = CharsetToolkit.US_ASCII_CHARSET; + break; + case VALID_UTF8: + charset = CharsetToolkit.UTF8_CHARSET; + break; + case INVALID_UTF8: + case BINARY: + // the charset was not detected so the file is likely binary + return null; + default: + throw new IllegalStateException(String.valueOf(guessed)); + } } + byte[] bom = info.getThird(); + Pair result = convertBytes(bytes, Math.min(startOffset+(bom==null?0:bom.length), endOffset), endOffset, charset); + return result.getFirst().toString(); } @NotNull From 3f39d833d16cff829ad0550404796f7220c2b34c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 15 Aug 2017 16:05:31 +0300 Subject: [PATCH 02/15] do not insert @SuppressWarning("xxx") suppression into java literal, it will imbalance quotes --- .../codeInsight/daemon/impl/actions/SuppressFix.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java index a6f2737b5afe..b657b8093b19 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java @@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.impl.storage.ClassPathStorageUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.JavaResolveUtil; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.util.PsiTreeUtil; @@ -159,7 +160,12 @@ public class SuppressFix extends AbstractBatchSuppressByNoInspectionCommentFix { protected boolean use15Suppressions(@NotNull PsiJavaDocumentedElement container) { return JavaSuppressionUtil.canHave15Suppressions(container) && - !JavaSuppressionUtil.alreadyHas14Suppressions(container); + !JavaSuppressionUtil.alreadyHas14Suppressions(container) && + !isInjectedToStringLiteral(container); // quotes will be imbalanced when insert annotation value in quotes into literal expression + } + + private static boolean isInjectedToStringLiteral(@NotNull PsiJavaDocumentedElement container) { + return JavaResolveUtil.findParentContextOfClass(container, PsiLiteralExpression.class, true) != null; } private String getID(@NotNull PsiElement place) { From aee9e0a22cd5fed0c8dc95ce21c3fbddc846fc3f Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 15 Aug 2017 16:03:24 +0300 Subject: [PATCH 03/15] show value popup below the line, not over it --- .../impl/evaluate/quick/common/AbstractValueHint.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/AbstractValueHint.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/AbstractValueHint.java index c3c479605e15..7b3a793a0f99 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/AbstractValueHint.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/AbstractValueHint.java @@ -327,7 +327,8 @@ public abstract class AbstractValueHint { } protected void showTreePopup(@NotNull DebuggerTreeCreator creator, @NotNull D descriptor) { - DebuggerTreeWithHistoryPopup.showTreePopup(creator, descriptor, getEditor(), myPoint, getProject(), myHideRunnable); + Point point = new Point(myPoint.x, myPoint.y + myEditor.getLineHeight()); + DebuggerTreeWithHistoryPopup.showTreePopup(creator, descriptor, myEditor, point, getProject(), myHideRunnable); } @Override From 1bae670acfef3fd1cee349ea3b16b10bfd254189 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 10 Aug 2017 16:02:21 +0300 Subject: [PATCH 04/15] vcs-log: use FontFallbackIterator for details view rendering `getFontAbleToDisplay(char, ...)` can return wrong font for symbols, that consist of multiple characters. follow-up: f9e87096304a9ccee8e98e35a795e685b455e73e --- .../com/intellij/openapi/vcs/ui/FontUtil.java | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/FontUtil.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/FontUtil.java index dc7cacf2244c..41d6f783ac30 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/FontUtil.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/FontUtil.java @@ -15,20 +15,13 @@ */ package com.intellij.openapi.vcs.ui; -import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry; +import com.intellij.openapi.editor.impl.FontFallbackIterator; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.awt.*; public class FontUtil { - @Nullable - public static Font getFontAbleToDisplay(char c, int size, int style, @NotNull String family) { - Font font = ComplementaryFontsRegistry.getFontAbleToDisplay(c, size, style, family, null).getFont(); - return font.canDisplay(c) ? font : null; - } - @NotNull public static String getHtmlWithFonts(@NotNull String input) { Font font = UIUtil.getLabelFont(); @@ -40,26 +33,29 @@ public class FontUtil { int start = baseFont.canDisplayUpTo(input); if (start == -1) return input; - Font font = null; - StringBuilder result = new StringBuilder(input.substring(0, start)); - for (int i = start; i < input.length(); i++) { - char c = input.charAt(i); - if (baseFont.canDisplay(c)) { - if (font != null) result.append(""); - result.append(c); - font = null; + StringBuilder result = new StringBuilder(); + + FontFallbackIterator it = new FontFallbackIterator(); + it.setPreferredFont(baseFont.getFamily(), baseFont.getSize()); + it.setFontStyle(style); + + it.start(input, 0, input.length()); + while (!it.atEnd()) { + Font font = it.getFont(); + + boolean insideFallbackBlock = !font.getFamily().equals(baseFont.getFamily()); + if (insideFallbackBlock) { + result.append(""); } - else if (font != null && font.canDisplay(c)) { - result.append(c); - } - else { - if (font != null) result.append(""); - font = getFontAbleToDisplay(c, baseFont.getSize(), style, baseFont.getFamily()); - if (font != null) result.append(""); - result.append(c); + + result.append(input, it.getStart(), it.getEnd()); + + if (insideFallbackBlock) { + result.append(""); } + + it.advance(); } - if (font != null) result.append(""); return result.toString(); } From 375f882a51f5de21883fe3172ad616877a288467 Mon Sep 17 00:00:00 2001 From: "alexey.afanasiev" Date: Tue, 15 Aug 2017 16:26:07 +0300 Subject: [PATCH 05/15] IDEA-177330 @CompileStatic multiple assignment in variable definition should be red --- .../codeInspection/GroovyQuickFixFactory.java | 4 +++- .../type/GroovyStaticTypeCheckVisitor.java | 4 ++-- .../type/GroovyTypeCheckVisitor.java | 2 +- .../lang/EmptyGroovyQuickFixFactory.java | 7 +++++- .../GroovyQuickFixFactoryImpl.java | 8 ++++++- .../cs}/GrReplaceMultiAssignmentFix.kt | 17 ++++++++++---- .../highlighting/GrAssignabilityTest.groovy | 23 +++++++++++++++++++ 7 files changed, 55 insertions(+), 10 deletions(-) rename plugins/groovy/{groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment => src/org/jetbrains/plugins/groovy/codeInspection/cs}/GrReplaceMultiAssignmentFix.kt (76%) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/GroovyQuickFixFactory.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/GroovyQuickFixFactory.java index edb0ebb4aff5..6479a9491d96 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/GroovyQuickFixFactory.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/GroovyQuickFixFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -79,4 +79,6 @@ public abstract class GroovyQuickFixFactory { public abstract IntentionAction createRemoveUnusedGrParameterFix(GrParameter parameter); public abstract IntentionAction createInvestigateFix(String reason); + + public abstract GroovyFix createMultipleAssignmentFix(int size); } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/type/GroovyStaticTypeCheckVisitor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/type/GroovyStaticTypeCheckVisitor.java index 2c9bd92fea4d..9cf457fdbb2d 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/type/GroovyStaticTypeCheckVisitor.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/type/GroovyStaticTypeCheckVisitor.java @@ -32,7 +32,7 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyBundle; -import org.jetbrains.plugins.groovy.codeInspection.assignment.GrReplaceMultiAssignmentFix; +import org.jetbrains.plugins.groovy.codeInspection.GroovyQuickFixFactory; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; @@ -92,7 +92,7 @@ public class GroovyStaticTypeCheckVisitor extends GroovyTypeCheckVisitor { registerError( initializer, GroovyBundle.message("multiple.assignments.without.list.expr"), - new LocalQuickFix[]{new GrReplaceMultiAssignmentFix(types.length)}, + new LocalQuickFix[]{GroovyQuickFixFactory.getInstance().createMultipleAssignmentFix(types.length)}, ProblemHighlightType.GENERIC_ERROR ); } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/type/GroovyTypeCheckVisitor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/type/GroovyTypeCheckVisitor.java index 45d2c5c20abc..6c2a97f6b894 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/type/GroovyTypeCheckVisitor.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/type/GroovyTypeCheckVisitor.java @@ -999,7 +999,7 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor { final GrVariableDeclaration tuple = (GrVariableDeclaration)parent; final GrExpression initializer = tuple.getTupleInitializer(); if (initializer == null) return; - if (!(initializer instanceof GrListOrMap)) { + if (!(initializer instanceof GrListOrMap) && !PsiUtil.isCompileStatic(variable)) { PsiType type = initializer.getType(); if (type == null) return; PsiType valueType = extractIterableTypeParameter(type, false); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/EmptyGroovyQuickFixFactory.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/EmptyGroovyQuickFixFactory.java index 343b76b92ecc..eeb8b5424683 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/EmptyGroovyQuickFixFactory.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/EmptyGroovyQuickFixFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -142,4 +142,9 @@ public class EmptyGroovyQuickFixFactory extends GroovyQuickFixFactory { public IntentionAction createInvestigateFix(String reason) { return QuickFixes.EMPTY_ACTION; } + + @Override + public GroovyFix createMultipleAssignmentFix(int size) { + return GroovyFix.EMPTY_FIX; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyQuickFixFactoryImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyQuickFixFactoryImpl.java index 1e1789fa1c54..58e3ea6ac1e2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyQuickFixFactoryImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyQuickFixFactoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -25,6 +25,7 @@ import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicProperty import org.jetbrains.plugins.groovy.codeInspection.bugs.AddClassToExtendsFix; import org.jetbrains.plugins.groovy.codeInspection.bugs.AddMethodFix; import org.jetbrains.plugins.groovy.codeInspection.confusing.ReplaceWithImportFix; +import org.jetbrains.plugins.groovy.codeInspection.cs.GrReplaceMultiAssignmentFix; import org.jetbrains.plugins.groovy.codeInspection.local.RemoveUnusedGrParameterFix; import org.jetbrains.plugins.groovy.codeInspection.naming.RenameFix; import org.jetbrains.plugins.groovy.dsl.InvestigateFix; @@ -150,4 +151,9 @@ public class GroovyQuickFixFactoryImpl extends GroovyQuickFixFactory { public IntentionAction createInvestigateFix(String reason) { return new InvestigateFix(reason); } + + @Override + public GroovyFix createMultipleAssignmentFix(int size) { + return new GrReplaceMultiAssignmentFix(size); + } } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GrReplaceMultiAssignmentFix.kt b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/cs/GrReplaceMultiAssignmentFix.kt similarity index 76% rename from plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GrReplaceMultiAssignmentFix.kt rename to plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/cs/GrReplaceMultiAssignmentFix.kt index 1e55f92cf1e5..2b782e9a18f2 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GrReplaceMultiAssignmentFix.kt +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/cs/GrReplaceMultiAssignmentFix.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.groovy.codeInspection.assignment +package org.jetbrains.plugins.groovy.codeInspection.cs import com.intellij.codeInspection.ProblemDescriptor import com.intellij.openapi.project.Project @@ -27,8 +27,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner +import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidator +import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil -internal val fixVariableName = "storedList" +internal val defaultFixVariableName = "storedList" class GrReplaceMultiAssignmentFix(val size: Int) : GroovyFix() { override fun doFix(project: Project, descriptor: ProblemDescriptor) { @@ -39,7 +41,8 @@ class GrReplaceMultiAssignmentFix(val size: Int) : GroovyFix() { var initializer = element.text if (element !is GrReferenceExpression || element.resolve() !is GrVariable) { val factory = GroovyPsiElementFactory.getInstance(element.project) - val varDefinition = factory.createStatementFromText("def $fixVariableName = ${initializer}") + val fixVariableName = generateVariableName(element) + val varDefinition = factory.createStatementFromText("def ${fixVariableName} = ${initializer}") grStatementOwner.addStatementBefore(varDefinition, grStatement) initializer = fixVariableName } @@ -47,7 +50,13 @@ class GrReplaceMultiAssignmentFix(val size: Int) : GroovyFix() { GrInspectionUtil.replaceExpression(element, generateListLiteral(initializer)) } - fun generateListLiteral(varName: String): String { + private fun generateVariableName(expression: GrExpression): String { + val validator = DefaultGroovyVariableNameValidator(expression) + val suggestedNames = GroovyNameSuggestionUtil.suggestVariableNameByType(expression.type, validator) + return if (suggestedNames.isNotEmpty()) suggestedNames[0] else defaultFixVariableName + } + + private fun generateListLiteral(varName: String): String { return (0..(size - 1)).joinToString(", ", "[", "]") { "$varName[$it]" } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignabilityTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignabilityTest.groovy index ddc94c2e9f17..73458fbd6cf2 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignabilityTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrAssignabilityTest.groovy @@ -833,6 +833,29 @@ def foo() { ''' } + void testMultiAssignmentWithTypeError() { + testHighlighting''' +import groovy.transform.CompileStatic + +@CompileStatic +def foo() { + def list = ["", ""] + def (Integer a, b) = list +} +''' + } + + void testMultiAssignmentLiteralWithTypeError() { + testHighlighting''' +import groovy.transform.CompileStatic + +@CompileStatic +def foo() { + def (Integer a, b) = ["", ""] +} +''' + } + void testMultiAssignment() { testHighlighting''' import groovy.transform.CompileStatic From 2f92fb6e96eae487107bd1f8db6ff3c6b94de876 Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Tue, 15 Aug 2017 16:38:53 +0300 Subject: [PATCH 06/15] IDEA-177568 Weird mouse selection --- .../ui/laf/darcula/ui/DarculaTextAreaUI.java | 11 ++++--- .../ui/TextFieldWithPopupHandlerUI.java | 30 ++++++++++++++++--- .../util/resources/misc/registry.properties | 2 ++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextAreaUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextAreaUI.java index 294df86da147..de00a8e00bb7 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextAreaUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextAreaUI.java @@ -17,14 +17,12 @@ package com.intellij.ide.ui.laf.darcula.ui; import com.intellij.ide.ui.laf.darcula.DarculaUIUtil; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.registry.Registry; import javax.swing.*; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicTextAreaUI; -import javax.swing.text.BadLocationException; -import javax.swing.text.DefaultEditorKit; -import javax.swing.text.JTextComponent; -import javax.swing.text.Position; +import javax.swing.text.*; import java.awt.event.KeyEvent; public class DarculaTextAreaUI extends BasicTextAreaUI{ @@ -51,4 +49,9 @@ public class DarculaTextAreaUI extends BasicTextAreaUI{ int position = DarculaUIUtil.getPatchedNextVisualPositionFrom(t, pos, direction); return position != -1 ? position : super.getNextVisualPositionFrom(t, pos, b, direction, biasRet); } + + @Override + protected Caret createCaret() { + return Registry.is("ide.text.mouse.selection.new") ? new TextFieldWithPopupHandlerUI.MyCaret(getComponent()) : super.createCaret(); + } } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/TextFieldWithPopupHandlerUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/TextFieldWithPopupHandlerUI.java index e42dd5f3349d..94ea6706f6d4 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/TextFieldWithPopupHandlerUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/TextFieldWithPopupHandlerUI.java @@ -36,10 +36,7 @@ import javax.swing.event.DocumentListener; import javax.swing.plaf.FontUIResource; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicTextFieldUI; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.JTextComponent; -import javax.swing.text.Position; +import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; @@ -201,6 +198,11 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple return position != -1 ? position : super.getNextVisualPositionFrom(t, pos, b, direction, biasRet); } + @Override + protected Caret createCaret() { + return Registry.is("ide.text.mouse.selection.new") ? new MyCaret(getComponent()) : super.createCaret(); + } + @Override public boolean value(Object o) { if (o instanceof MouseEvent) { @@ -632,4 +634,24 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple return "clear"; } } + + static class MyCaret extends BasicCaret { + private final JTextComponent myComponent; + + public MyCaret(JTextComponent component) { + myComponent = component; + } + + @Override + public void mouseDragged(MouseEvent e) { + if (e.getID() == MouseEvent.MOUSE_DRAGGED && !myComponent.getText().contains("\n")) { + boolean consumed = e.isConsumed(); + e = new MouseEvent(e.getComponent(), e.getID(), e.getWhen(), e.getModifiers() | e.getModifiersEx(), e.getX(), + myComponent.getHeight() / 2, + e.getClickCount(), e.isPopupTrigger(), e.getButton()); + if (consumed) e.consume(); + } + super.mouseDragged(e); + } + } } diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 5d4ff8a59a01..8d2cec5a3301 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -1079,6 +1079,8 @@ ide.text.effect.new.scale=true ide.text.effect.new.scale.description=Enables scalable effect painter for text ide.text.effect.new.metrics=true ide.text.effect.new.metrics.description=Use line metrics to calculate text offset in the effect painter +ide.text.mouse.selection.new=true +ide.text.mouse.selection.description=Use improved mouse-drag processing in single-line text components when mouse pointer is out of area ide.intellij.laf.win10.ui=true ide.intellij.laf.win10.restartRequired=true From fc3fc3210a70101e05bbf9a43e54c966e7c6f62f Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 15 Aug 2017 17:21:06 +0300 Subject: [PATCH 07/15] fixed tests on jdk9 --- .../src/com/intellij/debugger/impl/OutputChecker.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/java/testFramework/src/com/intellij/debugger/impl/OutputChecker.java b/java/testFramework/src/com/intellij/debugger/impl/OutputChecker.java index 7f1a78121f1a..825160e0cedd 100644 --- a/java/testFramework/src/com/intellij/debugger/impl/OutputChecker.java +++ b/java/testFramework/src/com/intellij/debugger/impl/OutputChecker.java @@ -21,6 +21,7 @@ import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.ex.JavaSdkUtil; import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl; @@ -113,6 +114,12 @@ public class OutputChecker { assert outs.exists() || outs.mkdirs() : outs; File outFile = new File(outs, myTestName + ".out"); + if (JavaSdkUtil.isJdkAtLeast(jdk, JavaSdkVersion.JDK_1_9)) { + File jdk9Out = new File(outs, myTestName + ".jdk9.out"); + if (jdk9Out.exists()) { + outFile = jdk9Out; + } + } if (!outFile.exists()) { if (SystemInfo.isWindows) { final File winOut = new File(outs, myTestName + ".win.out"); From f4136fc7219d79ee25f8b3e88027df804aa73f5a Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 15 Aug 2017 17:48:27 +0300 Subject: [PATCH 08/15] one more correction for a folding model fix (IDEA-177458) also make EditorStressTest validate folding model's internal state --- .../openapi/editor/impl/FoldRegionsTree.java | 5 +- .../openapi/editor/impl/FoldingModelImpl.java | 58 +++++++++++++++++-- .../openapi/editor/impl/FoldingTest.java | 7 +++ 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java index 42f72b4db4d1..04dea9d5c2da 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java @@ -37,7 +37,7 @@ abstract class FoldRegionsTree { private static final Comparator BY_END_OFFSET = Comparator.comparingInt(RangeMarker::getEndOffset); private static final Comparator BY_END_OFFSET_REVERSE = Collections.reverseOrder(BY_END_OFFSET); - private static final TObjectHashingStrategy OFFSET_BASED_HASHING_STRATEGY = new TObjectHashingStrategy() { + static final TObjectHashingStrategy OFFSET_BASED_HASHING_STRATEGY = new TObjectHashingStrategy() { @Override public int computeHashCode(FoldRegion o) { return o.getStartOffset() * 31 + o.getEndOffset(); @@ -77,13 +77,14 @@ abstract class FoldRegionsTree { public boolean process(int offset, @NotNull FoldRegionImpl region, boolean atStart, @NotNull Collection overlapping) { if (atStart) { if (sameRange(region, lastRegion)) { - if (region.getUserData(VISIBLE) == null) { + if (region.getUserData(VISIBLE) == null || lastRegion.getUserData(VISIBLE) != null && region.isExpanded()) { duplicatesToKill.add(region); return true; } else { duplicatesToKill.add(lastRegion); if (!visible.isEmpty() && lastRegion == visible.get(visible.size() - 1)) removeFromVisible(visible.size() - 1); + if (lastRegion == lastCollapsedRegion) lastCollapsedRegion = null; } } lastRegion = region; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java index 159768c5cbec..f9f73570d28e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java @@ -34,12 +34,13 @@ import com.intellij.openapi.util.ModificationTracker; import com.intellij.util.DocumentUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import java.awt.*; -import java.util.Arrays; +import java.util.*; import java.util.List; import java.util.concurrent.atomic.AtomicLong; @@ -622,10 +623,57 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedInternalDocu @TestOnly void validateState() { - for (FoldRegion region : getAllFoldRegions()) { - LOG.assertTrue (!region.isValid() || - !DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), region.getStartOffset()) && - !DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), region.getEndOffset())); + if (myEditor.getDocument().isInBulkUpdate()) return; + + FoldRegion[] allFoldRegions = getAllFoldRegions(); + boolean[] invisibleRegions = new boolean[allFoldRegions.length]; + for (int i = 0; i < allFoldRegions.length; i++) { + FoldRegion r1 = allFoldRegions[i]; + LOG.assertTrue(r1.isValid() && + !DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), r1.getStartOffset()) && + !DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), r1.getEndOffset()), + "Invalid region"); + for (int j = i + 1; j < allFoldRegions.length; j++) { + FoldRegion r2 = allFoldRegions[j]; + int r1s = r1.getStartOffset(); + int r1e = r1.getEndOffset(); + int r2s = r2.getStartOffset(); + int r2e = r2.getEndOffset(); + LOG.assertTrue(r1s < r2s && (r1e <= r2s || r1e >= r2e) || + r1s == r2s && r1e != r2e || + r1s > r2s && r1s < r2e && r1e <= r2e || + r1s >= r2e, + "Disallowed relative position of regions"); + if (!r1.isExpanded() && r1s <= r2s && r1e >= r2e) invisibleRegions[j] = true; + if (!r2.isExpanded() && r2s <= r1s && r2e >= r1e) invisibleRegions[i] = true; + } + } + Set visibleRegions = new THashSet<>(FoldRegionsTree.OFFSET_BASED_HASHING_STRATEGY); + List topLevelRegions = new ArrayList<>(); + for (int i = 0; i < allFoldRegions.length; i++) { + if (!invisibleRegions[i]) { + FoldRegion region = allFoldRegions[i]; + LOG.assertTrue(visibleRegions.add(region), "Duplicate visible regions"); + if (!region.isExpanded()) topLevelRegions.add(region); + } + } + Collections.sort(topLevelRegions, Comparator.comparingInt(r -> r.getStartOffset())); + + FoldRegion[] actualVisibles = fetchVisible(); + if (actualVisibles != null) { + for (FoldRegion r : actualVisibles) { + LOG.assertTrue(visibleRegions.remove(r), "Unexpected visible region"); + } + LOG.assertTrue(visibleRegions.isEmpty(), "Missing visible region"); + } + + FoldRegion[] actualTopLevels = fetchTopLevel(); + if (actualTopLevels != null) { + LOG.assertTrue(actualTopLevels.length == topLevelRegions.size(), "Wrong number of top-level regions"); + for (int i = 0; i < actualTopLevels.length; i++) { + LOG.assertTrue(FoldRegionsTree.OFFSET_BASED_HASHING_STRATEGY.equals(actualTopLevels[i], topLevelRegions.get(i)), + "Unexpected top-level region"); + } } } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/FoldingTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/FoldingTest.java index 7f6f530fecd0..2e5d03a46a1c 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/FoldingTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/FoldingTest.java @@ -350,4 +350,11 @@ public class FoldingTest extends AbstractEditorTest { addCollapsedFoldRegion(11, 12, "innermost"); Assert.assertArrayEquals(new FoldRegion[]{inner}, myModel.fetchTopLevel()); } + + public void testIdenticalRegionsOtherCase() { + FoldRegion inner = addCollapsedFoldRegion(10, 15, "inner"); + addFoldRegion(10, 20, "outer"); + WriteCommandAction.runWriteCommandAction(ourProject, () -> myEditor.getDocument().deleteString(15, 20)); + Assert.assertArrayEquals(new FoldRegion[]{inner}, myModel.fetchTopLevel()); + } } From 143d2030946da9d03f4896bf8d47d9ec9a74e979 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 15 Aug 2017 18:18:03 +0300 Subject: [PATCH 09/15] get rid of static var in DefaultInspectionToolPresentation --- .../ex/GlobalInspectionContextImpl.java | 9 ++++++-- .../ui/DefaultInspectionToolPresentation.java | 23 ++++++------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java index 6790a9f3cf9a..022fe4a1e9ee 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -104,6 +104,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp private final NotNullLazyValue myContentManager; private volatile InspectionResultsView myView; + private volatile String myOutputPath; private Content myContent; private volatile boolean myViewClosed = true; private long myInspectionStartedTimestamp; @@ -193,13 +194,13 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp setCurrentScope(scope); final Runnable action = () -> { - DefaultInspectionToolPresentation.setOutputPath(outputPath); + myOutputPath = outputPath; try { performInspectionsWithProgress(scope, runGlobalToolsOnly, isOfflineInspections); exportResults(inspectionsResults, outputPath); } finally { - DefaultInspectionToolPresentation.setOutputPath(null); + myOutputPath = null; } }; if (isOfflineInspections) { @@ -305,6 +306,10 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp return myView; } + public String getOutputPath() { + return myOutputPath; + } + private void ignoreElementRecursively(@NotNull InspectionToolWrapper toolWrapper, final RefEntity refElement) { if (refElement != null) { InspectionToolPresentation presentation = getPresentation(toolWrapper); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java index 366cbb80fed0..fae3e66d8529 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java @@ -31,6 +31,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.FileStatus; import com.intellij.openapi.vfs.CharsetToolkit; @@ -57,11 +58,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class DefaultInspectionToolPresentation implements ProblemDescriptionsProcessor, InspectionToolPresentation { - @NotNull private final InspectionToolWrapper myToolWrapper; + protected static final Logger LOG = Logger.getInstance(DefaultInspectionToolPresentation.class); - @NotNull - private final GlobalInspectionContextImpl myContext; - private static String ourOutputPath; + @NotNull private final InspectionToolWrapper myToolWrapper; + @NotNull private final GlobalInspectionContextImpl myContext; protected InspectionNode myToolNode; private static final Object lock = new Object(); @@ -74,7 +74,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro private final Map> myQuickFixActions = Collections.synchronizedMap(ContainerUtil.newIdentityTroveMap()); private final Map myIgnoredElements = Collections.synchronizedMap(ContainerUtil.newIdentityTroveMap()); - protected static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.DescriptorProviderInspection"); private volatile boolean isDisposed; public DefaultInspectionToolPresentation(@NotNull InspectionToolWrapper toolWrapper, @NotNull GlobalInspectionContextImpl context) { @@ -183,7 +182,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro if (refElement == null) return; if (descriptors.length == 0) return; if (filterSuppressed) { - if (!isOutputPathSet() || !(myToolWrapper instanceof LocalInspectionToolWrapper)) { + if (myContext.getOutputPath() == null || !(myToolWrapper instanceof LocalInspectionToolWrapper)) { synchronized (lock) { Map problemElements = getProblemElements(); CommonProblemDescriptor[] problems = problemElements.get(refElement); @@ -259,11 +258,11 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro final List list = parentNode.getChildren(); @NonNls final String ext = ".xml"; - final String fileName = ourOutputPath + File.separator + myToolWrapper.getShortName() + ext; + final String fileName = myContext.getOutputPath() + File.separator + myToolWrapper.getShortName() + ext; final PathMacroManager pathMacroManager = PathMacroManager.getInstance(getContext().getProject()); PrintWriter printWriter = null; try { - new File(ourOutputPath).mkdirs(); + FileUtil.createDirectory(new File(myContext.getOutputPath())); final File file = new File(fileName); final StringWriter writer = new StringWriter(); if (!file.exists()) { @@ -770,12 +769,4 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro } }; } - - public static synchronized void setOutputPath(final String output) { - ourOutputPath = output; - } - - private static synchronized boolean isOutputPathSet() { - return ourOutputPath != null; - } } From fc6955efc5161a9bd9510382fe3812fd2056c6f2 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 15 Aug 2017 18:25:57 +0300 Subject: [PATCH 10/15] move stripUIRefsFromInspectionDescription --- .../impl/DaemonTooltipRendererProvider.java | 6 +++--- .../ui/DefaultInspectionToolPresentation.java | 17 --------------- .../codeInspection/ui/InspectionNodeInfo.java | 21 ++++++++++++++++++- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java index 96c1ab40c3c8..04a2637c5b0e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonTooltipRendererProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -24,7 +24,7 @@ import com.intellij.codeInsight.daemon.impl.actions.ShowErrorDescriptionAction; import com.intellij.codeInsight.hint.LineTooltipRenderer; import com.intellij.codeInsight.hint.TooltipLinkHandlerEP; import com.intellij.codeInsight.hint.TooltipRenderer; -import com.intellij.codeInspection.ui.DefaultInspectionToolPresentation; +import com.intellij.codeInspection.ui.InspectionNodeInfo; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.ErrorStripTooltipRendererProvider; import com.intellij.openapi.editor.impl.TrafficTooltipRenderer; @@ -141,7 +141,7 @@ public class DaemonTooltipRendererProvider implements ErrorStripTooltipRendererP if (ref != null) { String description = TooltipLinkHandlerEP.getDescription(ref, editor); if (description != null) { - description = DefaultInspectionToolPresentation.stripUIRefsFromInspectionDescription(UIUtil.getHtmlBody(new Html(description).setKeepFont(true))); + description = InspectionNodeInfo.stripUIRefsFromInspectionDescription(UIUtil.getHtmlBody(new Html(description).setKeepFont(true))); text += UIUtil.getHtmlBody(new Html(problem).setKeepFont(true)).replace(DaemonBundle.message("inspection.extended.description"), DaemonBundle.message("inspection.collapse.description")) + END_MARKER + "

" + description + UIUtil.BORDER_LINE; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java index fae3e66d8529..bac99ceaaba8 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java @@ -81,23 +81,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro myContext = context; } - public static String stripUIRefsFromInspectionDescription(@NotNull String description) { - final int descriptionEnd = description.indexOf(""); - if (descriptionEnd < 0) { - final Pattern pattern = Pattern.compile(".*Use.*(the (panel|checkbox|checkboxes|field|button|controls).*below).*", Pattern.DOTALL); - final Matcher matcher = pattern.matcher(description); - int startFindIdx = 0; - while (matcher.find(startFindIdx)) { - final int end = matcher.end(1); - startFindIdx = end; - description = description.substring(0, matcher.start(1)) + " inspection settings " + description.substring(end); - } - } else { - description = description.substring(0, descriptionEnd); - } - return description; - } - @Override public HighlightSeverity getSeverity(@NotNull RefElement element) { final PsiElement psiElement = element.getPointer().getContainingFile(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java index e4a29f30b86a..737f486e645b 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java @@ -40,6 +40,8 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author Dmitry Batkovich @@ -82,7 +84,7 @@ public class InspectionNodeInfo extends JPanel { String descriptionText = toolWrapper.loadDescription(); LOG.assertTrue(descriptionText != null, "Inspection '" + toolWrapper.getShortName() + "' has no description"); final String toolDescription = - DefaultInspectionToolPresentation.stripUIRefsFromInspectionDescription(StringUtil.notNullize(descriptionText)); + stripUIRefsFromInspectionDescription(StringUtil.notNullize(descriptionText)); SingleInspectionProfilePanel.readHTML(description, SingleInspectionProfilePanel.toHTML(description, toolDescription == null ? "" : toolDescription, false)); JScrollPane pane = ScrollPaneFactory.createScrollPane(description, true); int maxWidth = getFontMetrics(UIUtil.getLabelFont()).charWidth('f') * 110 - pane.getMinimumSize().width; @@ -122,4 +124,21 @@ public class InspectionNodeInfo extends JPanel { new JBInsets(15, 9, 9, 0), 0, 0)); } + + public static String stripUIRefsFromInspectionDescription(@NotNull String description) { + final int descriptionEnd = description.indexOf(""); + if (descriptionEnd < 0) { + final Pattern pattern = Pattern.compile(".*Use.*(the (panel|checkbox|checkboxes|field|button|controls).*below).*", Pattern.DOTALL); + final Matcher matcher = pattern.matcher(description); + int startFindIdx = 0; + while (matcher.find(startFindIdx)) { + final int end = matcher.end(1); + startFindIdx = end; + description = description.substring(0, matcher.start(1)) + " inspection settings " + description.substring(end); + } + } else { + description = description.substring(0, descriptionEnd); + } + return description; + } } From c712e459228a2e6abebe8b5a658bbd6363cc2354 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 15 Aug 2017 18:51:04 +0300 Subject: [PATCH 11/15] inspection view: remove unused code (node status) --- .../deadCode/UnusedDeclarationPresentation.java | 9 +-------- .../OfflineProblemDescriptorNode.java | 8 +------- .../ui/DefaultInspectionToolPresentation.java | 16 +--------------- .../ui/InspectionToolPresentation.java | 6 +----- .../ui/InspectionTreeCellRenderer.java | 7 +------ .../codeInspection/ui/InspectionTreeNode.java | 6 +----- .../ui/ProblemDescriptionNode.java | 12 +----------- .../codeInspection/ui/RefElementNode.java | 7 +------ 8 files changed, 8 insertions(+), 63 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java index f3835da5b318..ea055e5b8345 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -589,13 +589,6 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta return myIgnoreElements.contains(element); } - - @NotNull - @Override - public FileStatus getElementStatus(final RefEntity element) { - return FileStatus.NOT_CHANGED; - } - @Override @NotNull public Set getIgnoredRefElements() { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java index de7b222cda3b..cdbb2d548c54 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -24,7 +24,6 @@ import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.InspectionToolPresentation; import com.intellij.codeInspection.ui.ProblemDescriptionNode; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.FileStatus; import org.jetbrains.annotations.NotNull; public class OfflineProblemDescriptorNode extends ProblemDescriptionNode { @@ -48,11 +47,6 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode { offlineDescriptor); } - @Override - public FileStatus getNodeStatus() { - return FileStatus.NOT_CHANGED; - } - @NotNull @Override protected String calculatePresentableName() { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java index bac99ceaaba8..f0dd05343278 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java @@ -23,6 +23,7 @@ import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.*; import com.intellij.codeInspection.reference.*; +import com.intellij.concurrency.ConcurrentCollectionFactory; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.PathMacroManager; @@ -41,7 +42,6 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; -import com.intellij.concurrency.ConcurrentCollectionFactory; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import gnu.trove.Equality; @@ -54,8 +54,6 @@ import org.jetbrains.annotations.Nullable; import java.io.*; import java.util.*; import java.util.function.Predicate; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class DefaultInspectionToolPresentation implements ProblemDescriptionsProcessor, InspectionToolPresentation { protected static final Logger LOG = Logger.getInstance(DefaultInspectionToolPresentation.class); @@ -656,18 +654,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro return descriptors != null && ArrayUtil.contains(descriptor, descriptors); } - @Override - @NotNull - public FileStatus getProblemStatus(@NotNull final CommonProblemDescriptor descriptor) { - return FileStatus.NOT_CHANGED; - } - - @NotNull - @Override - public FileStatus getElementStatus(final RefEntity element) { - return FileStatus.NOT_CHANGED; - } - @NotNull @Override public Set getIgnoredRefElements() { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java index fefa3fb1574f..482adaff4cf1 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -73,8 +73,6 @@ public interface InspectionToolPresentation extends ProblemDescriptionsProcessor boolean isGraphNeeded(); boolean isElementIgnored(final RefEntity element); @NotNull - FileStatus getElementStatus(final RefEntity element); - @NotNull Set getIgnoredRefElements(); @Nullable IntentionAction findQuickFixes(@NotNull CommonProblemDescriptor descriptor, final String hint); @@ -89,8 +87,6 @@ public interface InspectionToolPresentation extends ProblemDescriptionsProcessor Map getProblemElements(); @NotNull Collection getProblemDescriptors(); - @NotNull - FileStatus getProblemStatus(@NotNull CommonProblemDescriptor descriptor); boolean isProblemResolved(RefEntity refEntity, CommonProblemDescriptor descriptor); void ignoreCurrentElementProblem(RefEntity refEntity, CommonProblemDescriptor descriptor); void addProblemElement(RefEntity refElement, boolean filterSuppressed, @NotNull CommonProblemDescriptor... descriptions); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeCellRenderer.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeCellRenderer.java index 040f413da079..8320b3b0124c 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeCellRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -91,11 +91,6 @@ class InspectionTreeCellRenderer extends ColoredTreeCellRenderer { } } } - final FileStatus nodeStatus = node.getNodeStatus(); - if (nodeStatus != FileStatus.NOT_CHANGED) { - foreground = - new SimpleTextAttributes(foreground.getBgColor(), nodeStatus.getColor(), foreground.getWaveColor(), foreground.getStyle()); - } return foreground; } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java index 29fddb38979f..ce45e1dd29ba 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -79,10 +79,6 @@ public abstract class InspectionTreeNode extends DefaultMutableTreeNode { return null; } - public FileStatus getNodeStatus() { - return FileStatus.NOT_CHANGED; - } - public void excludeElement(ExcludedInspectionTreeNodesManager excludedManager) { excludedManager.exclude(this); Enumeration enumeration = children(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java index 160e0ab42a35..c4061b2f5396 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -23,10 +23,8 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.codeInspection.ProblemDescriptorUtil; import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.codeInspection.ex.InspectionToolWrapper; -import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vcs.FileStatus; import com.intellij.psi.PsiElement; import com.intellij.xml.util.XmlStringUtil; import gnu.trove.TObjectIntHashMap; @@ -134,14 +132,6 @@ public class ProblemDescriptionNode extends SuppressableInspectionTreeNode { super.amnestyElement(manager); } - @Override - public FileStatus getNodeStatus() { - if (myElement instanceof RefElement) { - return getPresentation().getProblemStatus(myDescriptor); - } - return FileStatus.NOT_CHANGED; - } - @Override protected void dropCache(Project project) { if (!isQuickFixAppliedFromView()) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java index 6995f67424d4..195f37395c12 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -85,11 +85,6 @@ public class RefElementNode extends SuppressableInspectionTreeNode { super.amnestyElement(excludedManager); } - @Override - public FileStatus getNodeStatus() { - return getPresentation().getElementStatus(getElement()); - } - @Override public void add(MutableTreeNode newChild) { checkHasDescriptorUnder(newChild); From 794a1c4bfb7253966b976495c4eb6be36cb16878 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 15 Aug 2017 18:54:04 +0300 Subject: [PATCH 12/15] inspection view: remove dead code --- .../deadCode/UnusedDeclarationPresentation.java | 11 ----------- .../ui/DefaultInspectionToolPresentation.java | 10 ---------- .../codeInspection/ui/InspectionToolPresentation.java | 3 --- 3 files changed, 24 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java index ea055e5b8345..ff0a3608c09a 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java @@ -562,28 +562,17 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta super.ignoreElement(refEntity); } - @Override - public void amnesty(RefEntity refEntity) { - myIgnoreElements.remove(refEntity); - } - @Override public void cleanup() { super.cleanup(); myIgnoreElements.clear(); } - @Override public void finalCleanup() { super.finalCleanup(); } - @Override - public boolean isGraphNeeded() { - return true; - } - @Override public boolean isElementIgnored(final RefEntity element) { return myIgnoreElements.contains(element); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java index f0dd05343278..f27d01686b7f 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java @@ -300,11 +300,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro getProblemElements().getOrDefault(refEntity, CommonProblemDescriptor.EMPTY_ARRAY))); } - @Override - public void amnesty(RefEntity refEntity) { - getIgnoredElements().remove(refEntity); - } - @Override public void amnesty(RefEntity refEntity, CommonProblemDescriptor descriptor) { final CommonProblemDescriptor[] ignoredDescriptors = getIgnoredElements().get(refEntity); @@ -507,11 +502,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro } } - @Override - public boolean isGraphNeeded() { - return false; - } - @Override public boolean hasReportedProblems() { return !myProblemToElements.isEmpty(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java index 482adaff4cf1..0c138f2b3e03 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java @@ -24,7 +24,6 @@ import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.reference.RefModule; import com.intellij.lang.annotation.HighlightSeverity; -import com.intellij.openapi.vcs.FileStatus; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -66,11 +65,9 @@ public interface InspectionToolPresentation extends ProblemDescriptionsProcessor Map> getContent(); void ignoreCurrentElement(RefEntity refEntity); - void amnesty(RefEntity refEntity); void amnesty(RefEntity refEntity, CommonProblemDescriptor descriptor); void cleanup(); void finalCleanup(); - boolean isGraphNeeded(); boolean isElementIgnored(final RefEntity element); @NotNull Set getIgnoredRefElements(); From 5d99c6b7dc2896587c41ea20e6648a3758f18345 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 15 Aug 2017 19:33:10 +0300 Subject: [PATCH 13/15] fix the bug with showing empty parameter info popups on completion --- .../completion/CompletionHintsTest.java | 17 ++++++++++++++++- .../hint/ParameterInfoComponent.java | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java index 6c793c8aebca..a5e95a2be894 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java @@ -528,7 +528,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { checkResultWithInlays("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); } - public void testHintPopupContents() throws Exception { + public void testHintPopupContentsForMethodWithOverloads() throws Exception { configureJava("class C { void m() { System.getPro } }"); complete("getProperty(String key, String def)"); waitForAllAsyncStuff(); @@ -544,6 +544,21 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { "@NotNull String key, String def"); } + public void testHintPopupContentsForMethodWithoutOverloads() throws Exception { + configureJava("class C { void m() { System.setPro } }"); + complete("setProperty"); + waitForAllAsyncStuff(); + checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); + checkHintContents("@NotNull String"); + next(); + waitForAllAsyncStuff(); + checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); + checkHintContents("String"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_SHOW_PARAMETER_INFO); + waitForAllAsyncStuff(); + checkHintContents("@NotNull String key, String value"); + } + private void checkResult(String text) { myFixture.checkResult(text); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java index 29edb3032d4e..41ddd37ff79a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java @@ -234,7 +234,7 @@ public class ParameterInfoComponent extends JPanel { context.i = i; final Object o = myObjects[i]; - if (singleParameterInfo && !context.isHighlighted()) { + if (singleParameterInfo && myObjects.length > 1 && !context.isHighlighted()) { setVisible(i, false); } else { From 707826d3ecb8c9df78a530a58712fdef7a7b179a Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 15 Aug 2017 20:13:31 +0300 Subject: [PATCH 14/15] IDEA-177087 No space between label and text field in breakpoint properties dialog --- .../impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java index 2ea18555d1e9..41b453f48282 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java @@ -139,7 +139,7 @@ public class XLightBreakpointPropertiesPanel implements XSuspendPolicyPanel.Dele myConditionEnabledCheckbox = new JBCheckBox(XDebuggerBundle.message("xbreakpoints.condition.checkbox")); myConditionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, CONDITION_HISTORY_ID, myBreakpoint.getSourcePosition(), true); JComponent conditionComponent = myConditionComboBox.getComponent(); - conditionComponent.setBorder(JBUI.Borders.emptyRight(3)); + conditionComponent.setBorder(JBUI.Borders.empty(0, 4)); myConditionExpressionPanel.add(conditionComponent, BorderLayout.CENTER); myConditionEnabledCheckbox.addActionListener(e -> onCheckboxChanged()); DebuggerUIUtil.focusEditorOnCheck(myConditionEnabledCheckbox, myConditionComboBox.getEditorComponent()); @@ -244,7 +244,7 @@ public class XLightBreakpointPropertiesPanel implements XSuspendPolicyPanel.Dele myConditionEnabledPanel.removeAll(); if (hideCheckbox) { JBLabel label = new JBLabel(XDebuggerBundle.message("xbreakpoints.condition.checkbox")); - label.setBorder(JBUI.Borders.empty(0, 4)); + label.setBorder(JBUI.Borders.emptyLeft(4)); label.setLabelFor(myConditionComboBox.getComboBox()); myConditionEnabledPanel.add(label); } From c3100ec702d498f9f79833aa953d95f146558072 Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Tue, 15 Aug 2017 20:35:29 +0300 Subject: [PATCH 15/15] [groovy] don't load AST in GrMethod.getDocComment() Store flag meaning there is something to search. Use it to not to load AST in GeMethod.getDocComment() when there is definitely no doc comment. --- .../typedef/members/GrMethodBaseImpl.java | 2 ++ .../groovy/lang/psi/stubs/GrMethodStub.java | 18 +++++++----- .../stubs/elements/GrStubFileElementType.java | 2 +- .../lang/psi/GrStubAstSwitchTest.groovy | 29 +++++++++++++++++++ 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java index 99050670f2b3..4c3f627b6ba4 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java @@ -504,6 +504,8 @@ public abstract class GrMethodBaseImpl extends GrStubElementBase i @Override @Nullable public GrDocComment getDocComment() { + final GrMethodStub stub = getStub(); + if (stub != null && !stub.hasComment()) return null; return GrDocCommentUtil.findDocComment(this); } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/GrMethodStub.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/GrMethodStub.java index 5c4f77dd7d6d..37e04bb50d7f 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/GrMethodStub.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/GrMethodStub.java @@ -31,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.psi.stubs.elements.GrMethodElementType; public class GrMethodStub extends StubBase implements NamedStub { public static final byte IS_DEPRECATED_BY_DOC_TAG = 0b1; public static final byte HAS_BLOCK = 0b10; + public static final byte HAS_COMMENT = 0b100; private final StringRef myName; private final String[] myAnnotations; @@ -54,7 +55,8 @@ public class GrMethodStub extends StubBase implements NamedStub implements NamedStub { - public static final int STUB_VERSION = 36; + public static final int STUB_VERSION = 37; public GrStubFileElementType(Language language) { super(language); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/psi/GrStubAstSwitchTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/psi/GrStubAstSwitchTest.groovy index 5097ce949791..89c5c434b24d 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/psi/GrStubAstSwitchTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/psi/GrStubAstSwitchTest.groovy @@ -295,4 +295,33 @@ class C { fixture.configureByText '_.groovy', 'C.staticVoidMethod()' fixture.checkHighlighting() } + + void 'test do not load AST when method has no comment'() { + def file = fixture.tempDirFixture.createFile('classes.groovy', '''\ +class C { + static void someMethod() {} + /** + * + */ + static void someMethodWithDocs() {} +} +''') + def psiFile = psiManager.findFile(file) as GroovyFileImpl + assert !psiFile.contentsLoaded + + def typeDefinition = psiFile.typeDefinitions.first() + assert !psiFile.contentsLoaded + + def method = typeDefinition.findMethodsByName('someMethod', false).first() + assert !psiFile.contentsLoaded + + assert method.docComment == null + assert !psiFile.contentsLoaded + + def methodWithDocs = typeDefinition.findMethodsByName('someMethodWithDocs', false).first() + assert !psiFile.contentsLoaded + + assert methodWithDocs.docComment != null + assert psiFile.contentsLoaded + } }