From d1a20543c2fa7adcb6ff71933b47602983d96ce2 Mon Sep 17 00:00:00 2001 From: Ingo Kegel Date: Tue, 27 Dec 2016 17:07:19 +0100 Subject: [PATCH 001/629] IDEA-165963 Gradle run configurations cannot be profiled Provide a way for executors other than the debugging executor to set VM parameters that are patched into the gradle Java task. This is solved with a special key that can be set in the user data of the ExecutionEnvironment. --- .../execution/ExternalSystemTaskExecutionSettings.java | 3 +++ .../service/execution/ExternalSystemRunConfiguration.java | 6 ++++++ .../service/project/BaseGradleProjectResolverExtension.java | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java index fb7d8e1c0b0e..4301d7bcc7b8 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java @@ -15,7 +15,9 @@ */ package com.intellij.openapi.externalSystem.model.execution; +import com.intellij.execution.configurations.ParametersList; import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.xmlb.annotations.Tag; @@ -36,6 +38,7 @@ import java.util.List; public class ExternalSystemTaskExecutionSettings implements Cloneable { @NotNull @NonNls public static final String TAG_NAME = "ExternalSystemSettings"; + @NotNull @NonNls public static final Key DEBUGGER_SETUP_KEY = Key.create("debuggerSetup"); private List myTaskNames = ContainerUtilRt.newArrayList(); private List myTaskDescriptions = ContainerUtilRt.newArrayList(); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java index 0a15a9e3663d..154e75e88ea6 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java @@ -4,6 +4,7 @@ import com.intellij.diagnostic.logging.LogConfigurationPanel; import com.intellij.execution.*; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.LocatableConfigurationBase; +import com.intellij.execution.configurations.ParametersList; import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.console.DuplexConsoleView; import com.intellij.execution.executors.DefaultDebugExecutor; @@ -169,6 +170,11 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase { String debuggerSetup = null; if (myDebugPort > 0) { debuggerSetup = "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=" + myDebugPort; + } else { + ParametersList parametersList = myEnv.getUserData(ExternalSystemTaskExecutionSettings.DEBUGGER_SETUP_KEY); + if (parametersList != null) { + debuggerSetup = parametersList.getParametersString(); + } } ApplicationManager.getApplication().assertIsDispatchThread(); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java index e05b0a9dcad0..cbea21b74b28 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java @@ -671,7 +671,7 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver "gradle.taskGraph.beforeTask { Task task ->", " if (task instanceof JavaForkOptions && (" + names + ".contains(task.name) || " + names + ".contains(task.path))) {", " def jvmArgs = task.jvmArgs.findAll{!it?.startsWith('-agentlib') && !it?.startsWith('-Xrunjdwp')}", - " jvmArgs << '" + debuggerSetup.trim() + '\'', + " jvmArgs << '" + debuggerSetup.trim().replace("\\", "\\\\") + '\'', " task.jvmArgs jvmArgs", " }" + "}", From 20a5396e3780c05f80b6ce49b0d07c9e4a210481 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 8 Mar 2017 14:14:18 +0100 Subject: [PATCH 002/629] no cached value leak checks in performance tests --- .../src/com/intellij/util/CachedValueLeakChecker.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/core-impl/src/com/intellij/util/CachedValueLeakChecker.java b/platform/core-impl/src/com/intellij/util/CachedValueLeakChecker.java index e963816c4d07..71f7447ae1e3 100644 --- a/platform/core-impl/src/com/intellij/util/CachedValueLeakChecker.java +++ b/platform/core-impl/src/com/intellij/util/CachedValueLeakChecker.java @@ -17,6 +17,7 @@ package com.intellij.util; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; @@ -45,7 +46,7 @@ class CachedValueLeakChecker { static void checkProvider(@NotNull final CachedValueProvider provider, @NotNull final Key key, @NotNull final UserDataHolder userDataHolder) { - if (!DO_CHECKS) return; + if (!DO_CHECKS || ApplicationInfoImpl.isInStressTest()) return; if (!ourCheckedKeys.add(key.toString())) return; // store strings because keys are created afresh in each (test) project findReferencedPsi(provider, userDataHolder, 5); From 486bd9398f1fddb4d092ee2368388016a1197580 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 8 Mar 2017 14:16:26 +0100 Subject: [PATCH 003/629] [java] highlights non-static implementations in 'provides' (IDEA-169205) --- .../daemon/impl/analysis/ModuleHighlightUtil.java | 5 +++++ java/java-psi-impl/src/messages/JavaErrorMessages.properties | 1 + .../intellij/codeInsight/daemon/ModuleHighlightingTest.kt | 2 ++ 3 files changed, 8 insertions(+) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java index 15b441741786..f1b92e358a04 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java @@ -34,6 +34,7 @@ import com.intellij.psi.*; import com.intellij.psi.PsiPackageAccessibilityStatement.Role; import com.intellij.psi.impl.light.LightJavaModule; import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.util.ClassUtil; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -363,6 +364,10 @@ public class ModuleHighlightUtil { String message = JavaErrorMessages.message("module.service.abstract", implClass.getName()); results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).description(message).create()); } + else if (!(ClassUtil.isTopLevelClass(implClass) || implClass.hasModifierProperty(PsiModifier.STATIC))) { + String message = JavaErrorMessages.message("module.service.inner", implClass.getName()); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).description(message).create()); + } else if (!PsiUtil.hasDefaultConstructor(implClass)) { String message = JavaErrorMessages.message("module.service.no.ctor", implClass.getName()); results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).description(message).create()); diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index e2bd1360d070..14529a5a8f25 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -412,6 +412,7 @@ package.is.empty=Package is empty: {0} module.service.enum=The service definition is an enum: {0} module.service.impl=The service implementation type must be a subtype of the service interface type, or have a public static no-args 'provider' method module.service.abstract=The service implementation is an abstract class: {0} +module.service.inner=The service implementation is an inner class: {0} module.service.no.ctor=The service implementation does not have a public default constructor: {0} module.service.provider.type=The ''provider'' method return type must be a subtype of the service interface type: {0} module.service.unused=Service interface provided but not exported or used diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt index c5383af285c3..ab5bb2857f18 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt @@ -150,6 +150,7 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() { addFile("pkg/main/Impl6.java", "package pkg.main;\npublic class Impl6 implements C { }") addFile("pkg/main/Impl7.java", "package pkg.main;\npublic class Impl7 {\n public static void provider();\n}") addFile("pkg/main/Impl8.java", "package pkg.main;\npublic class Impl8 {\n public static C provider();\n}") + addFile("pkg/main/Impl9.java", "package pkg.main;\npublic class Impl9 {\n public class Inner implements C { }\n}") highlight(""" module M { provides pkg.main.C with pkg.main.NoImpl; @@ -161,6 +162,7 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() { provides pkg.main.C with pkg.main.Impl6, pkg.main.Impl6; provides pkg.main.C with pkg.main.Impl7; provides pkg.main.C with pkg.main.Impl8; + provides pkg.main.C with pkg.main.Impl9.Inner; }""".trimIndent()) } From dcac209600d9d538a24aa41fbe86ea7177ccceaf Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 8 Mar 2017 14:07:00 +0100 Subject: [PATCH 004/629] no in-place rename in dumb mode (EA-98518 - INRE: FileBasedIndexImpl.handleDumbMode) --- .../refactoring/rename/inplace/MemberInplaceRenamer.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java index a95ab1de7008..5d0855f8915d 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java @@ -29,6 +29,7 @@ import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.impl.EditorImpl; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; @@ -219,6 +220,11 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer { } Runnable performRunnable = () -> { + if (DumbService.isDumb(myProject)) { + DumbService.getInstance(myProject).showDumbModeNotification("Refactorings cannot be performed while indexing is in progress"); + return; + } + final String commandName = RefactoringBundle.message("renaming.0.1.to.2", UsageViewUtil.getType(variable), DescriptiveNameUtil.getDescriptiveName(variable), newName); From 166a500fdef9c508f55f05ffce7a93e3888b43b4 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 8 Mar 2017 14:27:49 +0100 Subject: [PATCH 005/629] [java] minor parser optimization (IDEA-CR-19063) --- .../src/com/intellij/lang/java/parser/FileParser.java | 6 ++++-- .../src/com/intellij/lang/java/parser/ModuleParser.java | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/FileParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/FileParser.java index b322a971b69a..f007e3c93248 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/FileParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/FileParser.java @@ -106,9 +106,11 @@ public class FileParser { private static boolean stopImportListParsing(PsiBuilder b) { IElementType type = b.getTokenType(); - String text = b.getTokenText(); if (IMPORT_LIST_STOPPER_SET.contains(type)) return true; - if (type == JavaTokenType.IDENTIFIER && (PsiKeyword.OPEN.equals(text) || PsiKeyword.MODULE.equals(text))) return true; + if (type == JavaTokenType.IDENTIFIER) { + String text = b.getTokenText(); + if (PsiKeyword.OPEN.equals(text) || PsiKeyword.MODULE.equals(text)) return true; + } return false; } diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ModuleParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ModuleParser.java index 873679f9c05c..535db3f68eb6 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ModuleParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ModuleParser.java @@ -49,8 +49,8 @@ public class ModuleParser { PsiBuilder.Marker firstAnnotation = myParser.getDeclarationParser().parseAnnotations(builder); IElementType type = builder.getTokenType(); - String text = builder.getTokenText(); - if (type != JavaTokenType.IDENTIFIER || !(PsiKeyword.OPEN.equals(text) || PsiKeyword.MODULE.equals(text))) { + String text = type == JavaTokenType.IDENTIFIER ? builder.getTokenText() : null; + if (!(PsiKeyword.OPEN.equals(text) || PsiKeyword.MODULE.equals(text))) { module.rollbackTo(); return null; } From a08786331d56e0bd5bba05dbea34eede1b3217fc Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 8 Mar 2017 14:38:11 +0100 Subject: [PATCH 006/629] [java] tooltips for module-info error messages (IDEA-169101) --- .../impl/analysis/ModuleHighlightUtil.java | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java index f1b92e358a04..1a88b089b664 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java @@ -97,7 +97,7 @@ public class ModuleHighlightUtil { static HighlightInfo checkPackageStatement(@NotNull PsiPackageStatement statement, @NotNull PsiFile file) { if (PsiUtil.isModuleFile(file)) { String message = JavaErrorMessages.message("module.no.package"); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).description(message).create(); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(message).create(); QuickFixAction.registerQuickFixAction(info, factory().createDeleteFix(statement)); return info; } @@ -109,7 +109,7 @@ public class ModuleHighlightUtil { static HighlightInfo checkFileName(@NotNull PsiJavaModule element, @NotNull PsiFile file) { if (!MODULE_INFO_FILE.equals(file.getName())) { String message = JavaErrorMessages.message("module.file.wrong.name"); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).description(message).create(); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).descriptionAndTooltip(message).create(); QuickFixAction.registerQuickFixAction(info, factory().createRenameFileFix(MODULE_INFO_FILE)); return info; } @@ -125,7 +125,7 @@ public class ModuleHighlightUtil { Collection others = FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, module.getModuleScope(false)); if (others.size() > 1) { String message = JavaErrorMessages.message("module.file.duplicate"); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).description(message).create(); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).descriptionAndTooltip(message).create(); others.stream().map(f -> PsiManager.getInstance(project).findFile(f)).filter(f -> f != file).findFirst().ifPresent( duplicate -> QuickFixAction.registerQuickFixAction(info, new GoToSymbolFix(duplicate, JavaErrorMessages.message("module.open.duplicate.text"))) ); @@ -176,7 +176,7 @@ public class ModuleHighlightUtil { String refText = ref.apply(statement).orElse(null); if (refText != null && !filter.add(refText)) { String message = JavaErrorMessages.message(key, refText); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).description(message).create(); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(message).create(); QuickFixAction.registerQuickFixAction(info, factory().createDeleteFix(statement)); results.add(info); } @@ -199,7 +199,7 @@ public class ModuleHighlightUtil { String className = refText(ref), packageName = StringUtil.getPackageName(className); if (!exports.contains(packageName) && !uses.contains(className)) { String message = JavaErrorMessages.message("module.service.unused"); - results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(range(ref)).description(message).create()); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(range(ref)).descriptionAndTooltip(message).create()); } } } @@ -219,7 +219,7 @@ public class ModuleHighlightUtil { VirtualFile root = ProjectFileIndex.SERVICE.getInstance(file.getProject()).getSourceRootForFile(vFile); if (root != null && !root.equals(vFile.getParent())) { String message = JavaErrorMessages.message("module.file.wrong.location"); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(range(element)).description(message).create(); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(range(element)).descriptionAndTooltip(message).create(); QuickFixAction.registerQuickFixAction(info, new MoveFileFix(vFile, root, QuickFixBundle.message("move.file.to.source.root.text"))); return info; } @@ -239,7 +239,7 @@ public class ModuleHighlightUtil { } else if (target == container) { String message = JavaErrorMessages.message("module.cyclic.dependence", container.getName()); - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).description(message).create(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).descriptionAndTooltip(message).create(); } else { Collection cycle = JavaModuleGraphUtil.findCycle((PsiJavaModule)target); @@ -247,7 +247,7 @@ public class ModuleHighlightUtil { Stream stream = cycle.stream().map(PsiJavaModule::getName); if (ApplicationManager.getApplication().isUnitTestMode()) stream = stream.sorted(); String message = JavaErrorMessages.message("module.cyclic.dependence", stream.collect(Collectors.joining(", "))); - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).description(message).create(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).descriptionAndTooltip(message).create(); } } } @@ -262,7 +262,7 @@ public class ModuleHighlightUtil { (parent = statement.getParent()) instanceof PsiJavaModule && ((PsiJavaModule)parent).hasModifierProperty(PsiModifier.OPEN)) { String message = JavaErrorMessages.message("module.opens.in.weak.module"); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).description(message).create(); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(message).create(); QuickFixAction.registerQuickFixAction(info, factory().createModifierListFix((PsiModifierListOwner)parent, PsiModifier.OPEN, false, false)); return info; } @@ -282,11 +282,11 @@ public class ModuleHighlightUtil { HighlightInfoType type = statement.getRole() == Role.OPENS ? HighlightInfoType.WARNING : HighlightInfoType.ERROR; if (directories == null || directories.length == 0) { String message = JavaErrorMessages.message("package.not.found", packageName); - return HighlightInfo.newHighlightInfo(type).range(refElement).description(message).create(); + return HighlightInfo.newHighlightInfo(type).range(refElement).descriptionAndTooltip(message).create(); } if (PsiUtil.isPackageEmpty(directories, packageName)) { String message = JavaErrorMessages.message("package.is.empty", packageName); - return HighlightInfo.newHighlightInfo(type).range(refElement).description(message).create(); + return HighlightInfo.newHighlightInfo(type).range(refElement).descriptionAndTooltip(message).create(); } } @@ -304,11 +304,11 @@ public class ModuleHighlightUtil { assert ref != null : statement; if (!targets.add(refText)) { String message = JavaErrorMessages.message("module.duplicate.export", refText); - results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).description(message).create()); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).descriptionAndTooltip(message).create()); } else if (ref.multiResolve(true).length == 0) { String message = JavaErrorMessages.message("module.not.found", refElement.getReferenceText()); - results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(refElement).description(message).create()); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(refElement).descriptionAndTooltip(message).create()); } } @@ -321,11 +321,11 @@ public class ModuleHighlightUtil { PsiElement target = refElement.resolve(); if (target == null) { String message = JavaErrorMessages.message("cannot.resolve.symbol", refElement.getReferenceName()); - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(refElement)).description(message).create(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(refElement)).descriptionAndTooltip(message).create(); } else if (target instanceof PsiClass && ((PsiClass)target).isEnum()) { String message = JavaErrorMessages.message("module.service.enum", ((PsiClass)target).getName()); - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(refElement)).description(message).create(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(refElement)).descriptionAndTooltip(message).create(); } } @@ -346,7 +346,7 @@ public class ModuleHighlightUtil { String refText = refText(implRef); if (!filter.add(refText)) { String message = JavaErrorMessages.message("module.duplicate.impl", refText); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(implRef).description(message).create(); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(implRef).descriptionAndTooltip(message).create(); QuickFixAction.registerQuickFixAction(info, factory().createDeleteFix(implRef, QuickFixBundle.message("delete.reference.fix.text"))); results.add(info); continue; @@ -362,15 +362,15 @@ public class ModuleHighlightUtil { if (InheritanceUtil.isInheritorOrSelf(implClass, (PsiClass)intTarget, true)) { if (implClass.hasModifierProperty(PsiModifier.ABSTRACT)) { String message = JavaErrorMessages.message("module.service.abstract", implClass.getName()); - results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).description(message).create()); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message).create()); } else if (!(ClassUtil.isTopLevelClass(implClass) || implClass.hasModifierProperty(PsiModifier.STATIC))) { String message = JavaErrorMessages.message("module.service.inner", implClass.getName()); - results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).description(message).create()); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message).create()); } else if (!PsiUtil.hasDefaultConstructor(implClass)) { String message = JavaErrorMessages.message("module.service.no.ctor", implClass.getName()); - results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).description(message).create()); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message).create()); } } else if ((provider = findProvider(implClass)) != null) { @@ -378,12 +378,12 @@ public class ModuleHighlightUtil { PsiClass typeClass = type instanceof PsiClassType ? ((PsiClassType)type).resolve() : null; if (!InheritanceUtil.isInheritorOrSelf(typeClass, (PsiClass)intTarget, true)) { String message = JavaErrorMessages.message("module.service.provider.type", implClass.getName()); - results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).description(message).create()); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message).create()); } } else { String message = JavaErrorMessages.message("module.service.impl"); - results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).description(message).create()); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message).create()); } } } @@ -433,19 +433,19 @@ public class ModuleHighlightUtil { if (!refModule.equals(targetModule)) { if (targetModule == null) { String message = JavaErrorMessages.message("module.package.on.classpath"); - return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).description(message).create(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).descriptionAndTooltip(message).create(); } String refModuleName = refModule.getName(); String requiredName = targetModule.getName(); if (!(targetModule instanceof LightJavaModule || JavaModuleGraphUtil.exports(targetModule, packageName, refModule))) { String message = JavaErrorMessages.message("module.package.not.exported", requiredName, packageName, refModuleName); - return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).description(message).create(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).descriptionAndTooltip(message).create(); } if (!(PsiJavaModule.JAVA_BASE.equals(requiredName) || JavaModuleGraphUtil.reads(refModule, targetModule))) { String message = JavaErrorMessages.message("module.not.in.requirements", refModuleName, requiredName); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).description(message).create(); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).descriptionAndTooltip(message).create(); QuickFixAction.registerQuickFixAction(info, new AddRequiredModuleFix(refModule, requiredName)); return info; } @@ -464,15 +464,15 @@ public class ModuleHighlightUtil { private static HighlightInfo moduleResolveError(PsiJavaModuleReferenceElement refElement, PsiPolyVariantReference ref) { if (ref.multiResolve(true).length == 0) { String message = JavaErrorMessages.message("module.not.found", refElement.getReferenceText()); - return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(refElement).description(message).create(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(refElement).descriptionAndTooltip(message).create(); } else if (ref.multiResolve(false).length > 1) { String message = JavaErrorMessages.message("module.ambiguous", refElement.getReferenceText()); - return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(refElement).description(message).create(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(refElement).descriptionAndTooltip(message).create(); } else { String message = JavaErrorMessages.message("module.not.on.path", refElement.getReferenceText()); - HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(refElement).description(message).create(); + HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(refElement).descriptionAndTooltip(message).create(); factory().registerOrderEntryFixes(new QuickFixActionRegistrarImpl(info), ref); return info; } From 812941b126015ba1e73576811b5f2b967ab7c68b Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 8 Mar 2017 14:55:52 +0100 Subject: [PATCH 007/629] [java] corrects 'opens' error message (IDEA-169009) --- java/java-psi-impl/src/messages/JavaErrorMessages.properties | 2 +- .../com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index 14529a5a8f25..d7b2f6cbe5e5 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -406,7 +406,7 @@ module.not.found=Module not found: {0} module.ambiguous=Ambiguous module reference: {0} module.not.on.path=Module is not in dependencies: {0} module.cyclic.dependence=Cyclic dependence: {0} -module.opens.in.weak.module='opens' only allowed in strong modules +module.opens.in.weak.module='opens' is not allowed in an open module package.not.found=Package not found: {0} package.is.empty=Package is empty: {0} module.service.enum=The service definition is an enum: {0} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt index ab5bb2857f18..ce7ffce24ba0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt @@ -122,7 +122,7 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() { } fun testWeakModule() { - highlight("""open module M { opens pkg.missing; }""") + highlight("""open module M { opens pkg.missing; }""") } fun testUses() { From da77d7d1d8b9ff3703a6d8aa4e592e72503f8410 Mon Sep 17 00:00:00 2001 From: Brendan Douglas Date: Mon, 27 Feb 2017 16:22:20 -0500 Subject: [PATCH 008/629] Python import resolution: support multiple import source directories with the same qualified name (PY-22522) --- .../python/psi/resolve/PyResolveImportUtil.kt | 11 +++-- .../a.py | 5 ++ .../ext/m1.py | 1 + .../root/m1.py | 1 + .../CustomPackageIdentifier.py | 2 + .../mypackage/myfile.py | 0 .../python/PyMultiFileResolveTest.java | 48 +++++++++++++++++++ 7 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/a.py create mode 100644 python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/ext/m1.py create mode 100644 python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/root/m1.py create mode 100644 python/testData/resolve/multiFile/customPackageIdentifier/CustomPackageIdentifier.py create mode 100644 python/testData/resolve/multiFile/customPackageIdentifier/mypackage/myfile.py diff --git a/python/src/com/jetbrains/python/psi/resolve/PyResolveImportUtil.kt b/python/src/com/jetbrains/python/psi/resolve/PyResolveImportUtil.kt index 302b8d3a121a..5ac231bb3e5d 100644 --- a/python/src/com/jetbrains/python/psi/resolve/PyResolveImportUtil.kt +++ b/python/src/com/jetbrains/python/psi/resolve/PyResolveImportUtil.kt @@ -78,11 +78,12 @@ fun resolveQualifiedName(name: QualifiedName, context: PyQualifiedNameResolveCon } } - val allResults = listOf(relativeResults, - resultsFromRoots(name, context), - relativeResultsFromSkeletons(name, context), - foreignResults(name, context)).flatten() - val results = if (name.componentCount > 0) findFirstResults(allResults) else allResults + val foreignResults = foreignResults(name, context) + val pythonResults = listOf(relativeResults, + resultsFromRoots(name, context), + relativeResultsFromSkeletons(name, context)).flatten() + val allResults = foreignResults + pythonResults + val results = if (name.componentCount > 0) foreignResults + findFirstResults(pythonResults) else allResults if (mayCache) { cache?.put(key, results) diff --git a/python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/a.py b/python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/a.py new file mode 100644 index 000000000000..8b56d2040e86 --- /dev/null +++ b/python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/a.py @@ -0,0 +1,5 @@ +import m1 + + +print(m1) +# diff --git a/python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/ext/m1.py b/python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/ext/m1.py new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/ext/m1.py @@ -0,0 +1 @@ + diff --git a/python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/root/m1.py b/python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/root/m1.py new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/python/testData/resolve/multiFile/bothForeignAndSourceRootImportResultsReturned/root/m1.py @@ -0,0 +1 @@ + diff --git a/python/testData/resolve/multiFile/customPackageIdentifier/CustomPackageIdentifier.py b/python/testData/resolve/multiFile/customPackageIdentifier/CustomPackageIdentifier.py new file mode 100644 index 000000000000..faafe5f7d809 --- /dev/null +++ b/python/testData/resolve/multiFile/customPackageIdentifier/CustomPackageIdentifier.py @@ -0,0 +1,2 @@ +from mypackage import myfile +# \ No newline at end of file diff --git a/python/testData/resolve/multiFile/customPackageIdentifier/mypackage/myfile.py b/python/testData/resolve/multiFile/customPackageIdentifier/mypackage/myfile.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java index 13a1f32bf97f..341e3c54d9a9 100644 --- a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java +++ b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java @@ -16,24 +16,33 @@ package com.jetbrains.python; import com.google.common.collect.Lists; +import com.intellij.openapi.extensions.ExtensionPoint; +import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.GeneratedSourcesFilter; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.psi.util.QualifiedName; +import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.PsiTestUtil; import com.jetbrains.python.fixtures.PyMultiFileResolveTestCase; import com.jetbrains.python.fixtures.PyResolveTestCase; import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.impl.PyImportResolver; import com.jetbrains.python.psi.impl.PyPsiUtils; +import com.jetbrains.python.psi.resolve.PyQualifiedNameResolveContext; import com.jetbrains.python.sdk.PythonSdkType; import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -98,6 +107,23 @@ public class PyMultiFileResolveTest extends PyMultiFileResolveTestCase { assertEquals("mypackage", ((PsiFile)element).getContainingDirectory().getName()); } + public void testCustomPackageIdentifier() { + PlatformTestUtil.registerExtension(PyCustomPackageIdentifier.EP_NAME, new PyCustomPackageIdentifier() { + @Override + public boolean isPackage(PsiDirectory directory) { + return true; + } + + @Override + public boolean isPackageFile(PsiFile file) { + return false; + } + }, getTestRootDisposable()); + PsiElement element = doResolve(); + assertTrue(element instanceof PsiFile); + assertEquals("myfile.py", ((PyFile)element).getName()); + } + public void testImportAs() { PsiElement element = doResolve(); assertTrue(element instanceof PyFunction); @@ -451,6 +477,28 @@ public class PyMultiFileResolveTest extends PyMultiFileResolveTestCase { }); } + // PY-22522 + public void testBothForeignAndSourceRootImportResultsReturned() { + myFixture.copyDirectoryToProject("bothForeignAndSourceRootImportResultsReturned", ""); + + VirtualFile vf = myFixture.findFileInTempDir("ext/m1.py"); + final PsiFile extSource = myFixture.getPsiManager().findFile(vf); + PyImportResolver foreignResolver = (name, context, withRoots) -> name.toString().equals("m1") ? extSource : null; + PlatformTestUtil.registerExtension(PyImportResolver.EP_NAME, foreignResolver, getTestRootDisposable()); + + withSourceRoots(Lists.newArrayList(myFixture.findFileInTempDir("root")), () -> { + final PsiFile psiFile = myFixture.configureByFile("a.py"); + final PsiReference ref = PyResolveTestCase.findReferenceByMarker(psiFile); + assertInstanceOf(ref, PsiPolyVariantReference.class); + final List elements = PyUtil.multiResolveTopPriority((PsiPolyVariantReference)ref); + assertEquals(2, elements.size()); + final Set parentNames = elements.stream() + .filter(e -> e instanceof PyFile) + .map(e -> ((PyFile)e).getVirtualFile().getParent().getName()).collect(Collectors.toSet()); + assertContainsElements(parentNames, "root", "ext"); + }); + } + private void withSourceRoots(@NotNull List sourceRoots, @NotNull Runnable f) { final Module module = myFixture.getModule(); for (VirtualFile root : sourceRoots) { From b06d94febd45f5f22265007dbff491b8a2e6ff9e Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 8 Mar 2017 15:24:03 +0100 Subject: [PATCH 009/629] [^ann] on exception during move, show error dialog outside write action (EA-98512 - assert: NoSwingUnderWriteAction.lambda$watchForEvents$) --- .../MoveDirectoryWithClassesProcessor.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java index 18cdd6d2c077..432981665cc6 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java @@ -20,10 +20,8 @@ */ package com.intellij.refactoring.move.moveClassesOrPackages; -import com.intellij.CommonBundle; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.psi.PsiDirectory; @@ -152,13 +150,9 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor for (PsiFile psiFile : myFilesToMove.keySet()) { myFilesToMove.get(psiFile).findOrCreateTargetDirectory(); } - } - catch (IncorrectOperationException e) { - Messages.showErrorDialog(myProject, e.getMessage(), CommonBundle.getErrorTitle()); - return; - } - DumbService.getInstance(myProject).completeJustSubmittedTasks(); - try { + + DumbService.getInstance(myProject).completeJustSubmittedTasks(); + final List movedFiles = new ArrayList<>(); final Map oldToNewElementsMapping = new HashMap<>(); for (PsiFile psiFile : myFilesToMove.keySet()) { From 60b937e7c3cecaf4200929f19552456c89ad4980 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Wed, 8 Mar 2017 23:24:20 +0900 Subject: [PATCH 010/629] remove yellow code --- .../src/com/intellij/GroupBasedTestClassFilter.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java b/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java index ad0da481e816..6ffb2a4e2dbd 100644 --- a/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java +++ b/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 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. @@ -21,7 +21,9 @@ import org.jetbrains.annotations.NotNull; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.regex.Pattern; /** @@ -40,7 +42,7 @@ import java.util.regex.Pattern; * {@link PatternListTestClassFilter#PatternListTestClassFilter(List) PatternListTestClassFilter}; * *
  • - * Read class name filters (at regexp format) from the given stream - see {@link #createOn(java.io.Reader, java.util.List)}; + * Read class name filters (at regexp format) from the given stream - see {@link #createOn(Reader, List)}; *
  • * */ From 3849e3c228f2cce2b5ea6ac541044094fe5a3c99 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 8 Mar 2017 15:58:33 +0100 Subject: [PATCH 011/629] dfa: fix false positive when throwing parameter remove complicated code that the tests pass without --- .../codeInspection/dataFlow/ControlFlowAnalyzer.java | 11 ----------- .../inspection/dataFlow/fixture/ThrowNullable.java | 4 ++++ 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index 66e300dc0b3f..cbb59ab67237 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -52,7 +52,6 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { private FList myTrapStack = FList.emptyList(); private final ExceptionTransfer myRuntimeException; private final ExceptionTransfer myError; - private final PsiType myNpe; private final PsiType myAssertionError; ControlFlowAnalyzer(final DfaValueFactory valueFactory, @NotNull PsiElement codeFragment, boolean ignoreAssertions) { @@ -63,7 +62,6 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { GlobalSearchScope scope = codeFragment.getResolveScope(); myRuntimeException = new ExceptionTransfer(myFactory.createTypeValue(createClassType(scope, JAVA_LANG_RUNTIME_EXCEPTION), Nullness.NOT_NULL)); myError = new ExceptionTransfer(myFactory.createTypeValue(createClassType(scope, JAVA_LANG_ERROR), Nullness.NOT_NULL)); - myNpe = createClassType(scope, JAVA_LANG_NULL_POINTER_EXCEPTION); myAssertionError = createClassType(scope, JAVA_LANG_ASSERTION_ERROR); } @@ -708,16 +706,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { exception.accept(this); addConditionalRuntimeThrow(); - addInstruction(new DupInstruction()); - addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null)); - addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, myProject)); - ConditionalGotoInstruction gotoInstruction = new ConditionalGotoInstruction(null, true, null); - addInstruction(gotoInstruction); - addInstruction(new FieldReferenceInstruction(exception, "thrown exception")); - throwException(myNpe, statement); - - gotoInstruction.setOffset(myCurrentFlow.getInstructionCount()); throwException(exception.getType(), statement); } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ThrowNullable.java b/java/java-tests/testData/inspection/dataFlow/fixture/ThrowNullable.java index 4c9c3986c834..568b193ad217 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/ThrowNullable.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ThrowNullable.java @@ -15,4 +15,8 @@ class DataFlowBug { } } + void foo(RuntimeException tt) { + throw tt; + } + } \ No newline at end of file From f815aa1b1e85af1cec5c4a26809a6d3cd8e3a843 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Wed, 8 Mar 2017 23:59:52 +0900 Subject: [PATCH 012/629] git tests -> vcs tests --- community-tests/src/tests/testGroups.properties | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/community-tests/src/tests/testGroups.properties b/community-tests/src/tests/testGroups.properties index 8d0bc68bf3e4..e0aea2ee01fb 100644 --- a/community-tests/src/tests/testGroups.properties +++ b/community-tests/src/tests/testGroups.properties @@ -5,9 +5,14 @@ org.jetbrains.idea.svn16.* com.intellij.util.net.ssl.* com.intellij.tasks.live.* -[GIT_TESTS] +[VCS_TESTS] git4idea.* +hg4idea.* org.jetbrains.plugins.github.* +com.intellij.openapi.vcs.* +com.intellij.testFramework.vcs.* +com.intellij.tasks.vcs.* +com.intellij.vcs.* [ANDROID_SDK_TOOLS_TESTS] com.android.dvlib.* From c36f6616b046f078f607257bd027c4d8e0c79b32 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 8 Mar 2017 16:33:35 +0100 Subject: [PATCH 013/629] more stable expected times across Performance Tests builds recalculate timings until they don't vary too much --- .../intellij/testFramework/CpuTimings.java | 85 +++++++++++++++++++ .../com/intellij/testFramework/Timings.java | 26 +----- 2 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 platform/testFramework/src/com/intellij/testFramework/CpuTimings.java diff --git a/platform/testFramework/src/com/intellij/testFramework/CpuTimings.java b/platform/testFramework/src/com/intellij/testFramework/CpuTimings.java new file mode 100644 index 000000000000..f4ae11a6709e --- /dev/null +++ b/platform/testFramework/src/com/intellij/testFramework/CpuTimings.java @@ -0,0 +1,85 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.testFramework; + +import com.intellij.util.ArrayUtil; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.stream.LongStream; + +/** + * @author peter + */ +class CpuTimings { + final long[] rawData; + long average; + private double myStandardDeviation; + + private CpuTimings(long[] rawData) { + this.rawData = rawData; + average = ArrayUtil.averageAmongMedians(rawData, 2); + myStandardDeviation = standardDeviation(rawData); + } + + private static double standardDeviation(long[] elapsed) { + //noinspection ConstantConditions + double average = LongStream.of(elapsed).mapToDouble(value -> (double)value).average().getAsDouble(); + double variance = 0; + for (long l : elapsed) { + variance += Math.pow(average - l, 2); + } + return Math.sqrt(variance / average); + } + + @Override + public String toString() { + return "CpuTimings{" + average + ", raw=" + Arrays.toString(rawData) + ", sd=" + myStandardDeviation + '}'; + } + + static CpuTimings calcStableCpuTiming() { + for (int i = 0; i < 200; i++) { + CpuTimings timings = calcCpuTiming(); + if (timings.myStandardDeviation < 1.8) { + return timings; + } + //noinspection UseOfSystemOutOrSystemErr + System.out.println("Unstable timings: " + timings); + } + throw new IllegalStateException("Cannot calculate timings that are stable enough"); + } + + static CpuTimings calcCpuTiming() { + int n = 20; + long[] elapsed = new long[n]; + for (int i = 0; i < n; i++) { + elapsed[i] = measureCPU(); + } + return new CpuTimings(elapsed); + } + + private static long measureCPU() { + long start = System.currentTimeMillis(); + + BigInteger k = new BigInteger("1"); + for (int i = 0; i < 1000000; i++) { + k = k.add(new BigInteger("1")); + } + + return System.currentTimeMillis() - start; + } + +} diff --git a/platform/testFramework/src/com/intellij/testFramework/Timings.java b/platform/testFramework/src/com/intellij/testFramework/Timings.java index 77bd8648a6ea..c6c1f80890dd 100644 --- a/platform/testFramework/src/com/intellij/testFramework/Timings.java +++ b/platform/testFramework/src/com/intellij/testFramework/Timings.java @@ -17,10 +17,8 @@ package com.intellij.testFramework; import com.intellij.concurrency.JobSchedulerImpl; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.util.ArrayUtil; import java.io.*; -import java.math.BigInteger; import java.util.Arrays; /** @@ -44,16 +42,9 @@ public class Timings { private static final long[] CPU_TIMING_DATA; static { - int N = 20; - for (int i=0; i Date: Wed, 8 Mar 2017 16:41:29 +0100 Subject: [PATCH 014/629] more diagnostics for EA-92996 - assert: SmartPointerTracker.removeReference --- .../smartPointers/SmartPointerManagerImpl.java | 5 ++++- .../impl/smartPointers/SmartPointerTracker.java | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java index a8e09ee9e57e..a3a66fd15f33 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java @@ -155,11 +155,14 @@ public class SmartPointerManagerImpl extends SmartPointerManager { info.cleanup(); if (containingFile == null) return; + + assert containingFile.getProject() == myProject : "Project mismatch: expected " + myProject + ", got " + containingFile.getProject(); + VirtualFile vFile = containingFile.getViewProvider().getVirtualFile(); SmartPointerTracker pointers = getTracker(vFile); SmartPointerTracker.PointerReference reference = ((SmartPsiElementPointerImpl)pointer).pointerReference; if (pointers != null && reference != null) { - pointers.removeReference(reference); + pointers.removeReference(reference, POINTERS_KEY); } } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerTracker.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerTracker.java index 3d02360392e3..027a5b7d76ad 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerTracker.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerTracker.java @@ -68,7 +68,7 @@ class SmartPointerTracker { return true; } - private boolean isActual(VirtualFile file, Key key) { + boolean isActual(VirtualFile file, Key key) { return file.getUserData(key) == this; } @@ -94,11 +94,11 @@ class SmartPointerTracker { nextAvailableIndex = index; } - synchronized void removeReference(@NotNull PointerReference reference) { + synchronized void removeReference(@NotNull PointerReference reference, @NotNull Key expectedKey) { int index = reference.index; if (index < 0) return; - assert isActual(reference.file, reference.key); + assertActual(expectedKey, reference.file, reference.key); assert references[index] == reference : "At " + index + " expected " + reference + ", found " + references[index]; references[index].index = -1; references[index] = null; @@ -107,6 +107,13 @@ class SmartPointerTracker { } } + private void assertActual(Key expectedKey, VirtualFile file, Key refKey) { + assert isActual(file, refKey) : "Smart pointer list mismatch mismatch:" + + " ref.key=" + expectedKey + + ", manager.key=" + refKey + + (file.getUserData(refKey) != null ? "; has another pointer list" : ""); + } + private void processAlivePointers(@NotNull Processor processor) { for (int i = 0; i < nextAvailableIndex; i++) { PointerReference ref = references[i]; @@ -115,7 +122,7 @@ class SmartPointerTracker { assert isActual(ref.file, ref.key); SmartPsiElementPointerImpl pointer = ref.get(); if (pointer == null) { - removeReference(ref); + removeReference(ref, ref.key); continue; } @@ -235,7 +242,7 @@ class SmartPointerTracker { SmartPointerTracker pointers = reference.file.getUserData(reference.key); if (pointers != null) { - pointers.removeReference(reference); + pointers.removeReference(reference, reference.key); } } } From 3ad54795d456df4624eec0ab4c3c699d21ed9001 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 8 Mar 2017 17:42:41 +0100 Subject: [PATCH 015/629] more diagnostics for invalid file returned from PsiDocumentManager (EA-89617 - PIEAE: PsiUtilCore.ensureValid) and don't return psi for invalidated injections --- .../psi/impl/PsiDocumentManagerBase.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java index e0378f1cd8e0..6efa2046f346 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java @@ -104,11 +104,19 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen @Override @Nullable public PsiFile getPsiFile(@NotNull Document document) { + if (document instanceof DocumentWindow && !((DocumentWindow)document).isValid()) { + return null; + } + final PsiFile userData = document.getUserData(HARD_REF_TO_PSI); - if (userData != null) return userData; + if (userData != null) { + return ensureValidFile(userData, "From hard ref"); + } PsiFile psiFile = getCachedPsiFile(document); - if (psiFile != null) return psiFile; + if (psiFile != null) { + return ensureValidFile(psiFile, "Cached PSI"); + } final VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); if (virtualFile == null || !virtualFile.isValid()) return null; @@ -121,6 +129,12 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen return psiFile; } + @NotNull + private static PsiFile ensureValidFile(@NotNull PsiFile psiFile, @NotNull String debugInfo) { + if (!psiFile.isValid()) throw new PsiInvalidElementAccessException(psiFile, debugInfo); + return psiFile; + } + @Deprecated // todo remove when Database Navigator plugin doesn't need that anymore // todo to be removed in idea 17 From c0b227f467f78527f92aaa94a342628091571b0c Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 8 Mar 2017 18:18:40 +0100 Subject: [PATCH 016/629] WEB-25806 Don't provide completion from Webpack 2 schema when using Webpack 1 --- platform/util/src/com/intellij/util/text/SemVer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/util/src/com/intellij/util/text/SemVer.java b/platform/util/src/com/intellij/util/text/SemVer.java index e5b829ff5101..075c48a60cf1 100644 --- a/platform/util/src/com/intellij/util/text/SemVer.java +++ b/platform/util/src/com/intellij/util/text/SemVer.java @@ -90,12 +90,14 @@ public class SemVer implements Comparable { public static SemVer parseFromText(@NotNull String text) { int majorEndInd = text.indexOf('.'); if (majorEndInd < 0) { - return null; + final int major = StringUtil.parseInt(text, -1); + return major < 0 ? null : new SemVer(text, major, 0, 0); } int major = StringUtil.parseInt(text.substring(0, majorEndInd), -1); int minorEndInd = text.indexOf('.', majorEndInd + 1); if (minorEndInd < 0) { - return null; + final int minor = StringUtil.parseInt(text.substring(majorEndInd + 1), -1); + return new SemVer(text, major, minor < 0 ? 0 : minor, 0); } int minor = StringUtil.parseInt(text.substring(majorEndInd + 1, minorEndInd), -1); final String patchStr; From 9d2446b8861e5c15db2d5bad12293d7f95c6a338 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Fri, 24 Feb 2017 02:35:17 +0300 Subject: [PATCH 017/629] [vcs-log] enable columns drag, explicitly prohibit drag for root column This commit exposes a big problem in the code: columns a referred by index everywhere. This is fixed in subsequent commits. --- .../vcs/log/ui/table/VcsLogGraphTable.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java index 0acad0186ecb..cd83ad839aed 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java @@ -804,9 +804,9 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, public InvisibleResizableHeader() { myHeaderUI = new MyBasicTableHeaderUI(this); - // need a header to resize columns, so use header that is not visible + // need a header to resize/drag columns, so use header that is not visible setDefaultRenderer(new EmptyTableCellRenderer()); - setReorderingAllowed(false); + setReorderingAllowed(true); } @Override @@ -890,13 +890,13 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, @Override public void mousePressed(@NotNull MouseEvent e) { - if (isOnBorder(e)) return; + if (isOnBorder(e) || isOnRootColumn(e)) return; mouseInputListener.mousePressed(convertMouseEvent(e)); } @Override public void mouseReleased(@NotNull MouseEvent e) { - if (isOnBorder(e)) return; + if (isOnBorder(e) || isOnRootColumn(e)) return; mouseInputListener.mouseReleased(convertMouseEvent(e)); } @@ -910,7 +910,7 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, @Override public void mouseDragged(@NotNull MouseEvent e) { - if (isOnBorder(e)) return; + if (isOnBorder(e) || isOnRootColumn(e)) return; mouseInputListener.mouseDragged(convertMouseEvent(e)); } @@ -923,6 +923,10 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, public boolean isOnBorder(@NotNull MouseEvent e) { return Math.abs(header.getTable().getWidth() - e.getPoint().x) <= JBUI.scale(3); } + + public boolean isOnRootColumn(@NotNull MouseEvent e) { + return header.getTable().getColumnModel().getColumnIndexAtX(e.getX()) == ROOT_COLUMN; + } } private class MyListSelectionListener implements ListSelectionListener { @@ -973,5 +977,11 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, } super.propertyChange(evt); } + + @Override + public void moveColumn(int columnIndex, int newIndex) { + if (columnIndex == ROOT_COLUMN || newIndex == ROOT_COLUMN) return; + super.moveColumn(columnIndex, newIndex); + } } } From d38e427c387131307f583fd6d4fcebf2502bdcdd Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Fri, 24 Feb 2017 05:14:07 +0300 Subject: [PATCH 018/629] [vcs-log] convert column indexes from view to model when needed Model receives model column indexes. But renderer and column model receive view indexes. Previously, model indexes were used everywhere, now they are converted to view indexes where needed. --- .../ui/render/GraphCommitCellRenderer.java | 2 +- .../log/ui/table/GraphTableController.java | 13 ++++--- .../vcs/log/ui/table/VcsLogGraphTable.java | 35 +++++++++++-------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java index 5a36e5bdb232..5aa4b999e7c8 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java @@ -116,7 +116,7 @@ public class GraphCommitCellRenderer extends TypeSafeTableCellRenderer 0 && width != getColumnModel().getColumn(i).getPreferredWidth()) { - getColumnModel().getColumn(i).setPreferredWidth(width); + if (width > 0 && width != getColumnByModelIndex(i).getPreferredWidth()) { + getColumnByModelIndex(i).setPreferredWidth(width); } } @@ -231,7 +231,7 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, private int getColumnWidthFromData(int i) { Font tableFont = getTableFont(); if (i == AUTHOR_COLUMN) { - int width = getColumnModel().getColumn(AUTHOR_COLUMN).getPreferredWidth(); + int width = getColumnByModelIndex(i).getPreferredWidth(); // detect author with the longest name if (getModel().getRowCount() > 0) { @@ -245,7 +245,7 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, continue; } Font font = tableFont; - VcsLogHighlighter.TextStyle style = getStyle(row, AUTHOR_COLUMN, false, false).getTextStyle(); + VcsLogHighlighter.TextStyle style = getStyle(row, convertColumnIndexToView(AUTHOR_COLUMN), false, false).getTextStyle(); if (BOLD.equals(style)) { font = tableFont.deriveFont(Font.BOLD); } @@ -268,6 +268,11 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, throw new IllegalArgumentException("Can only calculate author or date columns width from data, yet given column " + i); } + @NotNull + public TableColumn getColumnByModelIndex(int index) { + return getColumnModel().getColumn(convertColumnIndexToView(index)); + } + private static Font getTableFont() { return UIManager.getFont("Table.font"); } @@ -276,16 +281,16 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, int size = getWidth(); for (int i = 0; i < getColumnCount(); i++) { if (i == COMMIT_COLUMN) continue; - TableColumn column = getColumnModel().getColumn(i); + TableColumn column = getColumnByModelIndex(i); size -= column.getPreferredWidth(); } - TableColumn commitColumn = getColumnModel().getColumn(COMMIT_COLUMN); + TableColumn commitColumn = getColumnByModelIndex(COMMIT_COLUMN); commitColumn.setPreferredWidth(size); } private void setRootColumnSize() { - TableColumn column = getColumnModel().getColumn(ROOT_COLUMN); + TableColumn column = getColumnByModelIndex(ROOT_COLUMN); int rootWidth; if (!myUi.isMultipleRoots()) { rootWidth = 0; @@ -317,7 +322,7 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, @Override public String getToolTipText(@NotNull MouseEvent event) { int row = rowAtPoint(event.getPoint()); - int column = columnAtPoint(event.getPoint()); + int column = convertColumnIndexToModel(columnAtPoint(event.getPoint())); if (column < 0 || row < 0) { return null; } @@ -636,19 +641,19 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, protected void paintFooter(@NotNull Graphics g, int x, int y, int width, int height) { int lastRow = getRowCount() - 1; if (lastRow >= 0) { - g.setColor(getStyle(lastRow, COMMIT_COLUMN, hasFocus(), false).getBackground()); + g.setColor(getStyle(lastRow, convertColumnIndexToView(COMMIT_COLUMN), hasFocus(), false).getBackground()); g.fillRect(x, y, width, height); if (myUi.isMultipleRoots()) { g.setColor(getRootBackgroundColor(getModel().getRoot(lastRow), myUi.getColorManager())); - int rootWidth = getColumnModel().getColumn(ROOT_COLUMN).getWidth(); + int rootWidth = getColumnByModelIndex(ROOT_COLUMN).getWidth(); if (!myUi.isShowRootNames()) rootWidth -= JBUI.scale(ROOT_INDICATOR_WHITE_WIDTH); g.fillRect(x, y, rootWidth, height); } } else { - g.setColor(getBaseStyle(lastRow, COMMIT_COLUMN, hasFocus(), false).getBackground()); + g.setColor(getBaseStyle(lastRow, convertColumnIndexToView(COMMIT_COLUMN), hasFocus(), false).getBackground()); g.fillRect(x, y, width, height); } } @@ -964,12 +969,12 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, // and TableColumnModelListener.columnMarginChanged does not provide any information which column was changed if (getTableHeader().getResizingColumn() == null) return; if ("width".equals(evt.getPropertyName())) { - TableColumn authorColumn = getColumn(AUTHOR_COLUMN); + TableColumn authorColumn = getColumnByModelIndex(AUTHOR_COLUMN); if (authorColumn.equals(evt.getSource())) { CommonUiProperties.saveColumnWidth(myProperties, AUTHOR_COLUMN, authorColumn.getWidth()); } else { - TableColumn dateColumn = getColumn(DATE_COLUMN); + TableColumn dateColumn = getColumnByModelIndex(DATE_COLUMN); if (dateColumn.equals(evt.getSource())) { CommonUiProperties.saveColumnWidth(myProperties, DATE_COLUMN, dateColumn.getWidth()); } @@ -980,7 +985,7 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, @Override public void moveColumn(int columnIndex, int newIndex) { - if (columnIndex == ROOT_COLUMN || newIndex == ROOT_COLUMN) return; + if (convertColumnIndexToModel(columnIndex) == ROOT_COLUMN || convertColumnIndexToModel(newIndex) == ROOT_COLUMN) return; super.moveColumn(columnIndex, newIndex); } } From 8d93866940883bb08a55bcaf5430c0263647a491 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Fri, 24 Feb 2017 06:48:28 +0300 Subject: [PATCH 019/629] [vcs-log] save and restore column order in properties IDEA-168629 --- .../vcs/log/impl/CommonUiProperties.java | 2 + .../vcs/log/impl/VcsLogUiPropertiesImpl.java | 18 ++++- .../com/intellij/vcs/log/ui/VcsLogUiImpl.java | 5 ++ .../vcs/log/ui/history/FileHistoryUi.java | 7 +- .../ui/history/FileHistoryUiProperties.java | 12 ++++ .../vcs/log/ui/table/VcsLogGraphTable.java | 66 +++++++++++++++++++ 6 files changed, 107 insertions(+), 3 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/CommonUiProperties.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/CommonUiProperties.java index 0dbe7aed74df..37128fdd65d7 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/CommonUiProperties.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/CommonUiProperties.java @@ -20,11 +20,13 @@ import com.intellij.vcs.log.impl.VcsLogUiProperties.VcsLogUiProperty; import com.intellij.vcs.log.ui.table.GraphTableModel; import org.jetbrains.annotations.NotNull; +import java.util.List; import java.util.Map; public class CommonUiProperties { public static final VcsLogUiProperty SHOW_DETAILS = new VcsLogUiProperty<>("Window.ShowDetails"); public static final Map> COLUMN_WIDTH = ContainerUtil.newHashMap(); + public static final VcsLogUiProperty> COLUMN_ORDER = new VcsLogUiProperty<>("Table.ColumnOrder"); static { COLUMN_WIDTH.put(GraphTableModel.AUTHOR_COLUMN, new TableColumnProperty("Author", GraphTableModel.AUTHOR_COLUMN)); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogUiPropertiesImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogUiPropertiesImpl.java index f8962e32d3e8..f82530d861b7 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogUiPropertiesImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogUiPropertiesImpl.java @@ -36,7 +36,8 @@ public abstract class VcsLogUiPropertiesImpl implements PersistentStateComponent MainVcsLogUiProperties.COMPACT_REFERENCES_VIEW, MainVcsLogUiProperties.SHOW_TAG_NAMES, MainVcsLogUiProperties.TEXT_FILTER_MATCH_CASE, - MainVcsLogUiProperties.TEXT_FILTER_REGEX); + MainVcsLogUiProperties.TEXT_FILTER_REGEX, + CommonUiProperties.COLUMN_ORDER); private final Set myListeners = ContainerUtil.newLinkedHashSet(); public static class State { @@ -52,6 +53,7 @@ public abstract class VcsLogUiPropertiesImpl implements PersistentStateComponent public boolean SHOW_TAG_NAMES = false; public TextFilterSettings TEXT_FILTER_SETTINGS = new TextFilterSettings(); public Map COLUMN_WIDTH = ContainerUtil.newHashMap(); + public List COLUMN_ORDER = ContainerUtil.newArrayList(); } @NotNull @@ -86,6 +88,11 @@ public abstract class VcsLogUiPropertiesImpl implements PersistentStateComponent else if (TEXT_FILTER_REGEX.equals(property)) { return (T)Boolean.valueOf(getTextFilterSettings().REGEX); } + else if (CommonUiProperties.COLUMN_ORDER.equals(property)) { + List order = getState().COLUMN_ORDER; + if (order == null) order = ContainerUtil.newArrayList(); + return (T)order; + } else if (property instanceof VcsLogHighlighterProperty) { Boolean result = getState().HIGHLIGHTERS.get(((VcsLogHighlighterProperty)property).getId()); if (result == null) return (T)Boolean.TRUE; @@ -99,6 +106,7 @@ public abstract class VcsLogUiPropertiesImpl implements PersistentStateComponent throw new UnsupportedOperationException("Property " + property + " does not exist"); } + @SuppressWarnings("unchecked") @Override public void set(@NotNull VcsLogUiProperties.VcsLogUiProperty property, @NotNull T value) { if (CommonUiProperties.SHOW_DETAILS.equals(property)) { @@ -125,6 +133,9 @@ public abstract class VcsLogUiPropertiesImpl implements PersistentStateComponent else if (TEXT_FILTER_MATCH_CASE.equals(property)) { getTextFilterSettings().MATCH_CASE = (boolean)(Boolean)value; } + else if (CommonUiProperties.COLUMN_ORDER.equals(property)) { + getState().COLUMN_ORDER = (List)value; + } else if (property instanceof VcsLogHighlighterProperty) { getState().HIGHLIGHTERS.put(((VcsLogHighlighterProperty)property).getId(), (Boolean)value); } @@ -264,6 +275,8 @@ public abstract class VcsLogUiPropertiesImpl implements PersistentStateComponent public abstract void onColumnWidthChanged(int column); + public abstract void onColumnOrderChanged(); + @Override public void onPropertyChanged(@NotNull VcsLogUiProperties.VcsLogUiProperty property) { if (CommonUiProperties.SHOW_DETAILS.equals(property)) { @@ -287,6 +300,9 @@ public abstract class VcsLogUiPropertiesImpl implements PersistentStateComponent else if (TEXT_FILTER_REGEX.equals(property) || TEXT_FILTER_MATCH_CASE.equals(property)) { onTextFilterSettingsChanged(); } + else if (CommonUiProperties.COLUMN_ORDER.equals(property)) { + onColumnOrderChanged(); + } else if (property instanceof VcsLogHighlighterProperty) { onHighlighterChanged(); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java index 17417f706bdb..bec262398e73 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java @@ -189,6 +189,11 @@ public class VcsLogUiImpl extends AbstractVcsLogUi { myMainFrame.getGraphTable().forceReLayout(column); } + @Override + public void onColumnOrderChanged() { + myMainFrame.getGraphTable().onColumnOrderSettingChanged(); + } + @Override public void onTextFilterSettingsChanged() { applyFiltersAndUpdateUi(myMainFrame.getFilterUi().getFilters()); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUi.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUi.java index 33d40170566d..794191d8078f 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUi.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUi.java @@ -248,12 +248,15 @@ public class FileHistoryUi extends AbstractVcsLogUi { private class MyPropertiesChangeListener implements VcsLogUiProperties.PropertiesChangeListener { @Override public void onPropertyChanged(@NotNull VcsLogUiProperties.VcsLogUiProperty property) { - if (property == CommonUiProperties.SHOW_DETAILS) { + if (CommonUiProperties.SHOW_DETAILS.equals(property)) { myFileHistoryPanel.showDetails(myUiProperties.get(CommonUiProperties.SHOW_DETAILS)); } - else if (property == FileHistoryUiProperties.SHOW_ALL_BRANCHES) { + else if (FileHistoryUiProperties.SHOW_ALL_BRANCHES.equals(property)) { updateFilter(); } + else if (CommonUiProperties.COLUMN_ORDER.equals(property)) { + getTable().onColumnOrderSettingChanged(); + } else if (property instanceof CommonUiProperties.TableColumnProperty) { getTable().forceReLayout(((CommonUiProperties.TableColumnProperty)property).getColumn()); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUiProperties.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUiProperties.java index 2bbcf55f13b8..b9c9865430ca 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUiProperties.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUiProperties.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; +import java.util.List; import java.util.Map; @State(name = "Vcs.Log.History.Properties", storages = {@Storage(file = StoragePathMacros.WORKSPACE_FILE)}) @@ -40,6 +41,7 @@ public class FileHistoryUiProperties implements VcsLogUiProperties, PersistentSt public boolean SHOW_DETAILS = false; public boolean SHOW_OTHER_BRANCHES = false; public Map COLUMN_WIDTH = ContainerUtil.newHashMap(); + public List COLUMN_ORDER = ContainerUtil.newArrayList(); } @SuppressWarnings("unchecked") @@ -52,6 +54,11 @@ public class FileHistoryUiProperties implements VcsLogUiProperties, PersistentSt else if (SHOW_ALL_BRANCHES.equals(property)) { return (T)Boolean.valueOf(myState.SHOW_OTHER_BRANCHES); } + else if (CommonUiProperties.COLUMN_ORDER.equals(property)) { + List order = myState.COLUMN_ORDER; + if (order == null) order = ContainerUtil.newArrayList(); + return (T)order; + } else if (property instanceof TableColumnProperty) { Integer savedWidth = myState.COLUMN_WIDTH.get(((TableColumnProperty)property).getColumn()); if (savedWidth == null) return (T)Integer.valueOf(-1); @@ -60,6 +67,7 @@ public class FileHistoryUiProperties implements VcsLogUiProperties, PersistentSt throw new UnsupportedOperationException("Unknown property " + property); } + @SuppressWarnings("unchecked") @Override public void set(@NotNull VcsLogUiProperty property, @NotNull T value) { if (CommonUiProperties.SHOW_DETAILS.equals(property)) { @@ -68,6 +76,9 @@ public class FileHistoryUiProperties implements VcsLogUiProperties, PersistentSt else if (SHOW_ALL_BRANCHES.equals(property)) { myState.SHOW_OTHER_BRANCHES = (Boolean)value; } + else if (CommonUiProperties.COLUMN_ORDER.equals(property)) { + myState.COLUMN_ORDER = (List)value; + } else if (property instanceof TableColumnProperty) { myState.COLUMN_WIDTH.put(((TableColumnProperty)property).getColumn(), (Integer)value); } @@ -81,6 +92,7 @@ public class FileHistoryUiProperties implements VcsLogUiProperties, PersistentSt public boolean exists(@NotNull VcsLogUiProperty property) { return CommonUiProperties.SHOW_DETAILS.equals(property) || SHOW_ALL_BRANCHES.equals(property) || + CommonUiProperties.COLUMN_ORDER.equals(property) || property instanceof TableColumnProperty; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java index d7b9d7837031..30e1d8e3b331 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java @@ -151,6 +151,7 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, setColumnModel(new MyTableColumnModel(myUi.getProperties())); createDefaultColumnsFromModel(); setAutoCreateColumnsFromModel(false); // otherwise sizes are recalculated after each TableColumn re-initialization + onColumnOrderSettingChanged(); setRootColumnSize(); @@ -178,6 +179,66 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, reLayout(); } + public void onColumnOrderSettingChanged() { + if (myUi.getProperties().exists(CommonUiProperties.COLUMN_ORDER)) { + List columnOrder = myUi.getProperties().get(CommonUiProperties.COLUMN_ORDER); + + int columnCount = getColumnModel().getColumnCount(); + boolean dataCorrect = true; + if (columnOrder.size() != columnCount) { + dataCorrect = false; + } + else { + for (int i = 0; i < columnCount; i++) { + Integer expectedColumnIndex = columnOrder.get(i); + if (expectedColumnIndex < 0 || expectedColumnIndex >= columnCount) { + dataCorrect = false; + break; + } + if (expectedColumnIndex != getColumnModel().getColumn(i).getModelIndex()) { + // need to put column with model index columnOrder.get(i) into position i + // let's find it + // since we are going from left to right, we know that columns on the left are already placed correctly + // so only need to check columns on the right + int foundColumnIndex = -1; + for (int j = i + 1; j < columnCount; j++) { + if (getColumnModel().getColumn(j).getModelIndex() == expectedColumnIndex) { + foundColumnIndex = j; + break; + } + } + if (foundColumnIndex < 0) { + dataCorrect = false; + break; + } + else { + ((MyTableColumnModel)getColumnModel()).moveWithoutChecks(foundColumnIndex, i); + } + } + } + } + + if (!dataCorrect) { + if (!columnOrder.isEmpty()) { + LOG.debug("Incorrect column order was saved in properties " + columnOrder + ", replacing it with current order."); + } + saveColumnOrderToSettings(); + } + } + } + + private void saveColumnOrderToSettings() { + if (myUi.getProperties().exists(CommonUiProperties.COLUMN_ORDER)) { + List columnOrder = ContainerUtil.newArrayList(); + + for (int i = 0; i < getColumnModel().getColumnCount(); i++) { + columnOrder.add(getColumnModel().getColumn(i).getModelIndex()); + } + + myUi.getProperties().set(CommonUiProperties.COLUMN_ORDER, columnOrder); + } + } + public void reLayout() { if (getTableHeader().getResizingColumn() == null) { updateAuthorAndDataWidth(); @@ -986,6 +1047,11 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, @Override public void moveColumn(int columnIndex, int newIndex) { if (convertColumnIndexToModel(columnIndex) == ROOT_COLUMN || convertColumnIndexToModel(newIndex) == ROOT_COLUMN) return; + moveWithoutChecks(columnIndex, newIndex); + saveColumnOrderToSettings(); + } + + public void moveWithoutChecks(int columnIndex, int newIndex) { super.moveColumn(columnIndex, newIndex); } } From fecffd36df7a01740d6ef7193887ce373d7e72f0 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Fri, 24 Feb 2017 07:50:47 +0300 Subject: [PATCH 020/629] [vcs-log] set hand cursor when column is dragged --- .../com/intellij/vcs/log/ui/table/VcsLogGraphTable.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java index 30e1d8e3b331..c97679a1fbf5 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/VcsLogGraphTable.java @@ -964,6 +964,9 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, public void mouseReleased(@NotNull MouseEvent e) { if (isOnBorder(e) || isOnRootColumn(e)) return; mouseInputListener.mouseReleased(convertMouseEvent(e)); + if (header.getCursor() == Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)) { + header.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } } @Override @@ -978,6 +981,11 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider, public void mouseDragged(@NotNull MouseEvent e) { if (isOnBorder(e) || isOnRootColumn(e)) return; mouseInputListener.mouseDragged(convertMouseEvent(e)); + // if I change cursor on mouse pressed, it will change on double-click as well + // and I do not want that + if (header.getDraggedColumn() != null && header.getCursor() == Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)) { + header.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + } } @Override From 89e1e23ba962143c5fd982d7664011078d346311 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Thu, 2 Mar 2017 19:30:59 +0300 Subject: [PATCH 021/629] [file-history] author and date columns go before commit in file history --- .../vcs/log/ui/history/FileHistoryUiProperties.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUiProperties.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUiProperties.java index b9c9865430ca..960045375a70 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUiProperties.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/history/FileHistoryUiProperties.java @@ -21,6 +21,7 @@ import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.components.StoragePathMacros; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.ContainerUtilRt; import com.intellij.vcs.log.impl.CommonUiProperties; import com.intellij.vcs.log.impl.CommonUiProperties.TableColumnProperty; import com.intellij.vcs.log.impl.VcsLogUiProperties; @@ -31,6 +32,8 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import static com.intellij.vcs.log.ui.table.GraphTableModel.*; + @State(name = "Vcs.Log.History.Properties", storages = {@Storage(file = StoragePathMacros.WORKSPACE_FILE)}) public class FileHistoryUiProperties implements VcsLogUiProperties, PersistentStateComponent { public static final VcsLogUiProperty SHOW_ALL_BRANCHES = new VcsLogUiProperty<>("Table.ShowOtherBranches"); @@ -56,7 +59,9 @@ public class FileHistoryUiProperties implements VcsLogUiProperties, PersistentSt } else if (CommonUiProperties.COLUMN_ORDER.equals(property)) { List order = myState.COLUMN_ORDER; - if (order == null) order = ContainerUtil.newArrayList(); + if (order == null || order.isEmpty()) { + order = ContainerUtilRt.newArrayList(ROOT_COLUMN, AUTHOR_COLUMN, DATE_COLUMN, COMMIT_COLUMN); + } return (T)order; } else if (property instanceof TableColumnProperty) { From 1871e09d72479f0e62b66cc97049638ef174c04c Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Sat, 4 Mar 2017 23:31:32 +0300 Subject: [PATCH 022/629] [vcs-log] adjust auto-resize by double-click mechanism for changed column order Since it is the commit column that provides the extra space when auto-resizing (or absorbs extra space), columns are resized by the border that is closest to the commit column. --- .../log/ui/table/GraphTableController.java | 54 ++++++++++++------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/GraphTableController.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/GraphTableController.java index 5a86110a85e6..ba4cfef4f66e 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/GraphTableController.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/table/GraphTableController.java @@ -53,6 +53,8 @@ import java.awt.event.MouseEvent; import java.util.Collection; import java.util.Collections; +import static com.intellij.vcs.log.ui.table.GraphTableModel.*; + /** * Processes mouse clicks and moves on the table */ @@ -146,7 +148,7 @@ public class GraphTableController { int width = 0; for (int i = 0; i < myTable.getColumnModel().getColumnCount(); i++) { TableColumn column = myTable.getColumnModel().getColumn(i); - if (column.getModelIndex() == GraphTableModel.COMMIT_COLUMN) break; + if (column.getModelIndex() == COMMIT_COLUMN) break; width += column.getWidth(); } return new Point(clickPoint.x - width, PositionUtil.getYInsideRow(clickPoint, myTable.getRowHeight())); @@ -217,7 +219,7 @@ public class GraphTableController { TableColumn rootColumn = myTable.getColumnModel().getColumn(GraphTableModel.ROOT_COLUMN); Point point = new Point(rootColumn.getWidth() + myCommitRenderer.getTooltipXCoordinate(row), row * myTable.getRowHeight() + myTable.getRowHeight() / 2); - showTooltip(row, GraphTableModel.COMMIT_COLUMN, point, true); + showTooltip(row, COMMIT_COLUMN, point, true); } private void performRootColumnAction() { @@ -251,25 +253,34 @@ public class GraphTableController { int c = myTable.columnAtPoint(e.getPoint()); int column = myTable.convertColumnIndexToModel(c); - // if clicked on the left of column border, c2 is the column to the right of the border - // we resize it first - int c2 = myTable.columnAtPoint(new Point(e.getPoint().x + BORDER_THICKNESS, e.getPoint().y)); - int column2 = myTable.convertColumnIndexToModel(c2); - if (e.getClickCount() == 2 && isOnBorder(e, c)) { - if (isOnBorder(e, c2) && (column2 == GraphTableModel.AUTHOR_COLUMN || column2 == GraphTableModel.DATE_COLUMN)) { - myTable.resetColumnWidth(column2); - } - else if (column == GraphTableModel.AUTHOR_COLUMN || column == GraphTableModel.DATE_COLUMN) { + if (e.getClickCount() == 2) { + // when we reset column width, commit column eats all the remaining space + // (or gives the required space) + // so it is logical that we reset column width by right border if it is on the left of the commit column + // and by the left border otherwise + int commitColumnIndex = myTable.convertColumnIndexToView(COMMIT_COLUMN); + boolean useLeftBorder = c > commitColumnIndex; + if ((useLeftBorder ? isOnLeftBorder(e, c) : isOnRightBorder(e, c)) && (column == AUTHOR_COLUMN || column == DATE_COLUMN)) { myTable.resetColumnWidth(column); } + else { + // user may have clicked just outside of the border + // in that case, c is not the column we are looking for + int c2 = + myTable.columnAtPoint(new Point(e.getPoint().x + (useLeftBorder ? 1 : -1) * JBUI.scale(BORDER_THICKNESS), e.getPoint().y)); + int column2 = myTable.convertColumnIndexToModel(c2); + if ((useLeftBorder ? isOnLeftBorder(e, c2) : isOnRightBorder(e, c2)) && (column2 == AUTHOR_COLUMN || column2 == DATE_COLUMN)) { + myTable.resetColumnWidth(column2); + } + } } int row = myTable.rowAtPoint(e.getPoint()); if ((row >= 0 && row < myTable.getRowCount()) && e.getClickCount() == 1) { - if (column == GraphTableModel.ROOT_COLUMN) { + if (column == ROOT_COLUMN) { performRootColumnAction(); } - else if (column == GraphTableModel.COMMIT_COLUMN) { + else if (column == COMMIT_COLUMN) { PrintElement printElement = findPrintElement(row, e); if (printElement != null) { performGraphAction(printElement, e, GraphAction.Type.MOUSE_CLICK); @@ -278,13 +289,20 @@ public class GraphTableController { } } - public boolean isOnBorder(@NotNull MouseEvent e, int column) { + public boolean isOnLeftBorder(@NotNull MouseEvent e, int column) { int x = 0; for (int i = 0; i < column; i++) { x += myTable.getColumnModel().getColumn(i).getWidth(); } - return Math.abs(x - e.getPoint().x) <= JBUI.scale(BORDER_THICKNESS) || - Math.abs(x + myTable.getColumnModel().getColumn(column).getWidth() - e.getPoint().x) <= JBUI.scale(BORDER_THICKNESS); + return Math.abs(x - e.getPoint().x) <= JBUI.scale(BORDER_THICKNESS); + } + + public boolean isOnRightBorder(@NotNull MouseEvent e, int column) { + int x = 0; + for (int i = 0; i < column; i++) { + x += myTable.getColumnModel().getColumn(i).getWidth(); + } + return Math.abs(x + myTable.getColumnModel().getColumn(column).getWidth() - e.getPoint().x) <= JBUI.scale(BORDER_THICKNESS); } @Override @@ -300,11 +318,11 @@ public class GraphTableController { int row = myTable.rowAtPoint(e.getPoint()); if (row >= 0 && row < myTable.getRowCount()) { int column = myTable.convertColumnIndexToModel(myTable.columnAtPoint(e.getPoint())); - if (column == GraphTableModel.ROOT_COLUMN) { + if (column == ROOT_COLUMN) { myTable.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); return; } - else if (column == GraphTableModel.COMMIT_COLUMN) { + else if (column == COMMIT_COLUMN) { PrintElement printElement = findPrintElement(row, e); performGraphAction(printElement, e, GraphAction.Type.MOUSE_OVER); // if printElement is null, still need to unselect whatever was selected in a graph From 472660a3b0c1f804096c4022ad431f343c5f3604 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 8 Mar 2017 14:08:15 +0100 Subject: [PATCH 023/629] junit rt: don't eat exceptions from user's code --- .../junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java index a497222ecc22..5a80ab583022 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java @@ -69,6 +69,7 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner { return result.wasSuccessful() ? 0 : -1; } catch (Exception e) { + e.printStackTrace(System.err); return -2; } } From 92d60ede85d5b79b099ae59b3f987052cacafd84 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 8 Mar 2017 19:14:00 +0100 Subject: [PATCH 024/629] enclosing instance check: don't check the inheritance for the class with extends/implements itself --- .../daemon/impl/analysis/HighlightClassUtil.java | 2 +- .../com/intellij/psi/util/InheritanceUtil.java | 12 ++++++++++-- ...lClassExtendingInnerWhichExtendsItsOuter.java | 16 +++++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java index 6552e5aa2c7c..00ca113a49de 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java @@ -784,7 +784,7 @@ public class HighlightClassUtil { if (!PsiUtil.isInnerClass(base)) return; if (resolve == resolved && baseClass != null && (!PsiTreeUtil.isAncestor(baseClass, extendRef, true) || aClass.hasModifierProperty(PsiModifier.STATIC)) && - !InheritanceUtil.hasEnclosingInstanceInScope(baseClass, extendRef, PsiUtil.isInnerClass(aClass) && !aClass.hasModifierProperty(PsiModifier.STATIC), true) && + !InheritanceUtil.hasEnclosingInstanceInScope(baseClass, extendRef, psiClass -> psiClass != aClass, true) && !qualifiedNewCalledInConstructors(aClass)) { String description = JavaErrorMessages.message("no.enclosing.instance.in.scope", HighlightUtil.formatClass(baseClass)); infos[0] = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(extendRef).descriptionAndTooltip(description).create(); diff --git a/java/java-psi-api/src/com/intellij/psi/util/InheritanceUtil.java b/java/java-psi-api/src/com/intellij/psi/util/InheritanceUtil.java index cdc464c621e8..c273e6433e35 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/InheritanceUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/InheritanceUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.util; +import com.intellij.openapi.util.Condition; import com.intellij.psi.*; import com.intellij.util.Processor; import gnu.trove.THashSet; @@ -131,13 +132,20 @@ public class InheritanceUtil { public static boolean hasEnclosingInstanceInScope(PsiClass aClass, PsiElement scope, - final boolean isSuperClassAccepted, + boolean isSuperClassAccepted, + boolean isTypeParamsAccepted) { + return hasEnclosingInstanceInScope(aClass, scope, psiClass -> isSuperClassAccepted, isTypeParamsAccepted); + } + + public static boolean hasEnclosingInstanceInScope(PsiClass aClass, + PsiElement scope, + Condition isSuperClassAccepted, boolean isTypeParamsAccepted) { PsiManager manager = aClass.getManager(); PsiElement place = scope; while (place != null && place != aClass && !(place instanceof PsiFile)) { if (place instanceof PsiClass) { - if (isSuperClassAccepted) { + if (isSuperClassAccepted.value((PsiClass)place)) { if (isInheritorOrSelf((PsiClass)place, aClass, true)) return true; } else { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/EnclosingRefInTopLevelClassExtendingInnerWhichExtendsItsOuter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/EnclosingRefInTopLevelClassExtendingInnerWhichExtendsItsOuter.java index 27cfe3cb7f1f..422f47c829d9 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/EnclosingRefInTopLevelClassExtendingInnerWhichExtendsItsOuter.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/EnclosingRefInTopLevelClassExtendingInnerWhichExtendsItsOuter.java @@ -2,4 +2,18 @@ class Outer { class Inner extends Outer {} } -class Impl extends Outer.Inner {} \ No newline at end of file +class Impl extends Outer.Inner {} + +class Impl1 { + class InnerImpl extends Outer.Inner {} +} + +class Impl2 extends Outer { + { + class L extends Outer.Inner {} + } + + class In extends Outer.Inner {} + + static class In1 extends Outer.Inner {} +} \ No newline at end of file From eb708890e591dca7c4f1865a53ac57f1e605d439 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Tue, 7 Mar 2017 21:53:00 +0300 Subject: [PATCH 025/629] [file-history] intern file path sets in the names data for file history --- .../vcs/log/data/index/IndexDataGetter.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/IndexDataGetter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/IndexDataGetter.java index e67922709be5..745051eec489 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/IndexDataGetter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/IndexDataGetter.java @@ -21,11 +21,13 @@ import com.intellij.openapi.util.UnorderedPair; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.SmartHashSet; import com.intellij.util.indexing.StorageException; import com.intellij.vcs.log.impl.FatalErrorHandler; import com.intellij.vcsUtil.VcsUtil; import gnu.trove.TIntObjectHashMap; +import gnu.trove.TIntObjectIterator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -83,6 +85,7 @@ public class IndexDataGetter { if (myRoots.contains(root)) { try { myIndexStorage.paths.iterateCommits(Collections.singleton(path), (paths, commit) -> result.add(commit, paths)); + result.pack(); } catch (IOException | StorageException e) { myFatalErrorsConsumer.consume(this, e); @@ -93,6 +96,7 @@ public class IndexDataGetter { } public static class FileNamesData { + @NotNull private final Interner> myPathsInterner = new Interner<>(); @NotNull private final TIntObjectHashMap> myCommitsToPaths; @NotNull private final TIntObjectHashMap>> myCommitsToRenames; @@ -117,13 +121,13 @@ public class IndexDataGetter { private void addRename(int commit, @NotNull Couple path) { Set> paths = myCommitsToRenames.get(commit); if (paths == null) { - paths = new SmartHashSet<>(); + paths = ContainerUtil.newHashSet(); myCommitsToRenames.put(commit, paths); } paths.add(new UnorderedPair<>(path.first, path.second)); } - public void add(int commit, @NotNull Couple paths) { + private void add(int commit, @NotNull Couple paths) { if (paths.second == null) { addPath(commit, paths.first); } @@ -164,7 +168,7 @@ public class IndexDataGetter { public void retain(int commit, @NotNull FilePath path, @NotNull FilePath previousPath) { if (path.equals(previousPath)) { - myCommitsToPaths.put(commit, ContainerUtil.set(path)); + myCommitsToPaths.put(commit, myPathsInterner.intern(ContainerUtil.set(path))); myCommitsToRenames.remove(commit); } else { @@ -190,5 +194,13 @@ public class IndexDataGetter { return result; } + + void pack() { + TIntObjectIterator> iterator = myCommitsToPaths.iterator(); + while (iterator.hasNext()) { + iterator.advance(); + iterator.setValue(myPathsInterner.intern(iterator.value())); + } + } } } From 4d5f1ce3be2ebe4d1b534068dadb65b01ba4cb45 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 8 Mar 2017 21:41:28 +0100 Subject: [PATCH 026/629] multithreaded completion in tests --- .../completion/CodeCompletionHandlerBase.java | 26 ++++++++----------- .../CompletionProgressIndicator.java | 20 +++++++++++--- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 15d6833ab4e7..880aa5179371 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -303,10 +303,8 @@ public class CodeCompletionHandlerBase { CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass()); } - final Semaphore freezeSemaphore = new Semaphore(); - freezeSemaphore.down(); final CompletionProgressIndicator indicator = new CompletionProgressIndicator(editor, initContext.getCaret(), - parameters, this, freezeSemaphore, + parameters, this, initContext.getOffsetMap(), hostOffsets, hasModifiers, lookup); Disposer.register(indicator, hostCopyOffsets.getOffsets()); Disposer.register(indicator, context.getOffsetMap()); @@ -320,20 +318,18 @@ public class CodeCompletionHandlerBase { return; } - if (freezeSemaphore.waitFor(ourAutoInsertItemTimeout)) { - if (!indicator.isRunning() && !indicator.isCanceled()) { // the completion is really finished, now we may auto-insert or show lookup - try { - indicator.getLookup().refreshUi(true, false); - } - catch (Exception e) { - CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion); - LOG.error(e); - return; - } - - completionFinished(indicator, hasModifiers); + if (indicator.blockingWaitForFinish(ourAutoInsertItemTimeout)) { + try { + indicator.getLookup().refreshUi(true, false); + } + catch (Exception e) { + CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion); + LOG.error(e); return; } + + completionFinished(indicator, hasModifiers); + return; } CompletionServiceImpl.setCompletionPhase(new CompletionPhase.BgCalculation(indicator)); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 63903e022e72..3a42980f2d4b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -107,7 +107,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myQueue.setMergingTimeSpan(ourShowPopupGroupingTime); } }; - private final Semaphore myFreezeSemaphore; + private final Semaphore myFreezeSemaphore = new Semaphore(1); + private final Semaphore myFinishSemaphore = new Semaphore(1); private final OffsetMap myOffsetMap; private final Set>> myRestartingPrefixConditions = ContainerUtil.newConcurrentSet(); private final LookupAdapter myLookupListener = new LookupAdapter() { @@ -139,7 +140,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement @NotNull Caret caret, CompletionParameters parameters, CodeCompletionHandlerBase handler, - Semaphore freezeSemaphore, final OffsetMap offsetMap, OffsetsInFile hostOffsets, boolean hasModifiers, @@ -148,7 +148,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myCaret = caret; myParameters = parameters; myHandler = handler; - myFreezeSemaphore = freezeSemaphore; myOffsetMap = offsetMap; myHostOffsets = hostOffsets; myLookup = lookup; @@ -514,12 +513,25 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement StatisticsUpdate.cancelLastCompletionStatisticsUpdate(); } + boolean blockingWaitForFinish(int timeout) { + if (ApplicationManager.getApplication().isUnitTestMode() && !CompletionAutoPopupHandler.ourTestingAutopopup) { + assert myFinishSemaphore.waitFor(100 * 1000) : "Too long completion"; + return true; + } + if (myFreezeSemaphore.waitFor(timeout)) { + // the completion is really finished, now we may auto-insert or show lookup + return !isRunning() && !isCanceled(); + } + return false; + } + @Override public void stop() { super.stop(); myQueue.cancelAllUpdates(); myFreezeSemaphore.up(); + myFinishSemaphore.up(); GuiUtils.invokeLaterIfNeeded(() -> { final CompletionPhase phase = CompletionServiceImpl.getCompletionPhase(); @@ -773,7 +785,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement void startCompletion(final CompletionInitializationContext initContext) { - boolean sync = ApplicationManager.getApplication().isUnitTestMode() && !CompletionAutoPopupHandler.ourTestingAutopopup; + boolean sync = ApplicationManager.getApplication().isWriteAccessAllowed(); myStrategy = sync ? new SyncCompletion() : new AsyncCompletion(); myStrategy.startThread(ProgressWrapper.wrap(this), this::scheduleAdvertising); final WeighingDelegate weigher = myStrategy.delegateWeighing(this); From 2b3d7ca783a3011eef4f8eda476798943ff0ff29 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 8 Mar 2017 22:02:01 +0100 Subject: [PATCH 027/629] less spam when initializing performance test timings, don't throw --- .../com/intellij/testFramework/CpuTimings.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/CpuTimings.java b/platform/testFramework/src/com/intellij/testFramework/CpuTimings.java index f4ae11a6709e..0657d629b812 100644 --- a/platform/testFramework/src/com/intellij/testFramework/CpuTimings.java +++ b/platform/testFramework/src/com/intellij/testFramework/CpuTimings.java @@ -50,16 +50,23 @@ class CpuTimings { return "CpuTimings{" + average + ", raw=" + Arrays.toString(rawData) + ", sd=" + myStandardDeviation + '}'; } + @SuppressWarnings("UseOfSystemOutOrSystemErr") static CpuTimings calcStableCpuTiming() { - for (int i = 0; i < 200; i++) { + for (int i = 0;; i++) { CpuTimings timings = calcCpuTiming(); if (timings.myStandardDeviation < 1.8) { return timings; } - //noinspection UseOfSystemOutOrSystemErr - System.out.println("Unstable timings: " + timings); + if (i == 100) { + System.out.println("Cannot calculate timings that are stable enough, giving up"); + return timings; + } + if (i > 3) { + System.out.println(i + ": Unstable timings: " + timings); + } + System.gc(); } - throw new IllegalStateException("Cannot calculate timings that are stable enough"); + } static CpuTimings calcCpuTiming() { From 69df7429c72aa0147e827f6ca630a576234dce6d Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 8 Mar 2017 18:58:10 +0000 Subject: [PATCH 028/629] Rename inconsistent "Commit Project/Commit Changes" to plain "Commit" There was a single action class with duplicate action declarations (CheckinProject and ChangesView.Commit) and even one more action name declaration in VcsBundle. ChangesView.Commit declaration is kept, because it is used in a plugin. Fixes IDEA-66052 --- .../src/messages/ActionsBundle.properties | 4 ++-- .../platform-resources-en/src/messages/VcsBundle.properties | 1 - platform/platform-resources/src/idea/VcsActions.xml | 6 ++---- .../openapi/vcs/actions/CommonCheckinProjectAction.java | 3 ++- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index ff1e6554cb6b..1c11082dd675 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -236,7 +236,7 @@ action.Diff.PreviousConflict.description=Move to the previous unresolved conflic action.GotoChangedFile.text=Go To Changed File... action.GotoChangedFile.description=Quickly navigate to changed file by name action.Refresh.text=R_efresh -action.CheckinProject.text=Comm_it Project +action.CheckinProject.text=Comm_it action.CheckinFiles.text=Comm_it File action.UpdateFiles.text=_Update action.CheckStatusForFiles.text=Chec_k Status @@ -1230,7 +1230,7 @@ action.ChangesView.Refresh.text=Refresh action.ChangesView.Refresh.description=Refresh VCS changes action.ChangesView.NewChangeList.text=New Changelist action.ChangesView.NewChangeList.description=Create new changelist -action.ChangesView.Commit.text=Comm_it Changes +action.ChangesView.Commit.text=Comm_it action.ChangesView.Commit.description=Commit the changes in selected changelist action.ChangesView.Revert.text=_Revert action.ChangesView.Revert.description=Revert selected changes diff --git a/platform/platform-resources-en/src/messages/VcsBundle.properties b/platform/platform-resources-en/src/messages/VcsBundle.properties index d21233df57ec..d699c9bb44a9 100644 --- a/platform/platform-resources-en/src/messages/VcsBundle.properties +++ b/platform/platform-resources-en/src/messages/VcsBundle.properties @@ -95,7 +95,6 @@ action.name.checkin.directory={0} Directory action.name.checkin.file={0} File action.name.checkin.directories={0} Directories action.name.checkin.files={0} Files -action.name.commit.project=Comm&it Changes column.name.revision.list.author=Author column.name.revisions.list.filter=Date column.name.revisions.list.branch=Branch diff --git a/platform/platform-resources/src/idea/VcsActions.xml b/platform/platform-resources/src/idea/VcsActions.xml index b73a02e394b2..77c463226bf1 100644 --- a/platform/platform-resources/src/idea/VcsActions.xml +++ b/platform/platform-resources/src/idea/VcsActions.xml @@ -83,8 +83,7 @@ - + @@ -105,7 +104,7 @@ - + @@ -344,7 +343,6 @@ - diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CommonCheckinProjectAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CommonCheckinProjectAction.java index d2cf069c0b51..5e34582c1eac 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CommonCheckinProjectAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CommonCheckinProjectAction.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.vcs.actions; +import com.intellij.idea.ActionsBundle; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsBundle; @@ -44,7 +45,7 @@ public class CommonCheckinProjectAction extends AbstractCommonCheckinAction { @Override protected String getActionName(@NotNull VcsContext dataContext) { - return VcsBundle.message("action.name.commit.project"); + return ActionsBundle.message("action.CheckinProject.text"); } @Override From 8d470681e413c529112edb21510557d7a14b00c3 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 9 Mar 2017 12:49:10 +0900 Subject: [PATCH 029/629] don't remove incremental caches if project is build incrementally --- build/scripts/utils.gant | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index 63272135cc90..4af419a50fc3 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -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. @@ -206,6 +206,7 @@ binding.setVariable("prepareOutputFolder", { binding.setVariable("clearBuildCaches", { //todo[nik] this is temporary solution until we update bootstrap jps-builders jars to the new version where cleaning is performed in JpsGantProjectBuilder#cleanOutput + if (projectBuilder.buildIncrementally && !Boolean.parseBoolean(p("jps.build.clear.incremental.caches", "false"))) return def storageRoot = projectBuilder.dataStorageRoot if (storageRoot != null) { FileUtil.delete(storageRoot) From 6f60712d5a83805f79d8dc7eb8ab391d84f3194b Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 9 Mar 2017 10:54:10 +0700 Subject: [PATCH 030/629] Java9CollectionFactoryInspectionTest: updated to use MockJdk9 --- .../java9CollectionFactory/afterArrayListAsList.java | 2 +- .../java9CollectionFactory/afterArrayListDoubleBrace.java | 2 +- .../java9CollectionFactory/afterArrayListExplicit.java | 2 +- .../inspection/java9CollectionFactory/afterAsList.java | 2 +- .../inspection/java9CollectionFactory/afterHashMap10.java | 2 +- .../java9CollectionFactory/afterHashMapSimple.java | 2 +- .../java9CollectionFactory/afterHashSetAsList.java | 2 +- .../java9CollectionFactory/afterHashSetDoubleBrace.java | 2 +- .../java9CollectionFactory/afterHashSetExplicit.java | 2 +- .../afterHashSetExplicitReusedVar.java | 2 +- .../java9CollectionFactory/afterStreamToList.java | 2 +- .../java9CollectionFactory/afterStreamToSet.java | 2 +- .../java19api/Java9CollectionFactoryInspectionTest.java | 7 +++++++ 13 files changed, 19 insertions(+), 12 deletions(-) diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListAsList.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListAsList.java index 05242c299274..760dd9493d8d 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListAsList.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListAsList.java @@ -5,5 +5,5 @@ import java.util.Collections; import java.util.List; public class Test { - public static final List EVEN = List.of(2, 4, 6, 8, 10); + public static final List EVEN = List.of(2, 4, 6, 8, 10); } diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListDoubleBrace.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListDoubleBrace.java index aef70fd2cdea..c9d8eba623d6 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListDoubleBrace.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListDoubleBrace.java @@ -4,5 +4,5 @@ import java.util.Collections; import java.util.List; public class Test { - public static final List EVEN = List.of(0, 2, 4, 6, 8); + public static final List EVEN = List.of(0, 2, 4, 6, 8); } diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListExplicit.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListExplicit.java index d1188ed732b6..29e332c90bcc 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListExplicit.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterArrayListExplicit.java @@ -4,7 +4,7 @@ import java.util.*; public class Test { public void testList() { List list; - list = List.of(1, 2); + list = List.of(1, 2); System.out.println(list); } } diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterAsList.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterAsList.java index 4758a7891608..29392eb96ab9 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterAsList.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterAsList.java @@ -4,5 +4,5 @@ import java.util.Collections; import java.util.List; public class Test { - public static final List EVEN = List.of(2, 4, 6, 8, 10, 2); + public static final List EVEN = List.of(2, 4, 6, 8, 10, 2); } diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashMap10.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashMap10.java index 5762f22b378d..b60ebd145309 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashMap10.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashMap10.java @@ -5,7 +5,7 @@ public class Test { public void test() { Map myMap; - myMap = Map.of("a", "1", "b", "1", "c", "1", + myMap = Map.of("a", "1", "b", "1", "c", "1", // D follows "d", "1", "e", /* this is also 1*/ "1", "f", "1", "g", "1", // G is important! diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashMapSimple.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashMapSimple.java index 02f6e2e80d3c..a5dcd1da34d4 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashMapSimple.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashMapSimple.java @@ -4,6 +4,6 @@ import java.util.*; public class Test { public void test() { Map myMap; - myMap = Map.of("a", "b", "c", "b"); + myMap = Map.of("a", "b", "c", "b"); } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetAsList.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetAsList.java index f5d47c8a7bf5..7f2c1ffa5879 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetAsList.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetAsList.java @@ -5,5 +5,5 @@ import java.util.HashSet; import java.util.Set; public class Test { - public static final Set MY_SET = Set.of("a", "b", "c", Math.random() > 0.5 ? "d" : Math.random() > 0.5 ? "e" : "d"); + public static final Set MY_SET = Set.of("a", "b", "c", Math.random() > 0.5 ? "d" : Math.random() > 0.5 ? "e" : "d"); } diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetDoubleBrace.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetDoubleBrace.java index 2fa360827e1d..307b38126b1b 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetDoubleBrace.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetDoubleBrace.java @@ -4,5 +4,5 @@ import java.util.HashSet; import java.util.Set; public class Test { - public static final Set MY_SET = Set.of("a", "b", "c".toUpperCase()); + public static final Set MY_SET = Set.of("a", "b", "c".toUpperCase()); } diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetExplicit.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetExplicit.java index 0144d22d3fb3..81b7dd158366 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetExplicit.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetExplicit.java @@ -6,6 +6,6 @@ public class Test { static { Set set; - MY_SET = Set.of("foo", "bar", "xyz"); + MY_SET = Set.of("foo", "bar", "xyz"); } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetExplicitReusedVar.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetExplicitReusedVar.java index 8d990faece92..31d4eb7e0032 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetExplicitReusedVar.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterHashSetExplicitReusedVar.java @@ -4,7 +4,7 @@ import java.util.*; public class Test { public void test2() { Set set; - set = Set.of("foo", "bar", "xyz"); + set = Set.of("foo", "bar", "xyz"); System.out.println(set); } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterStreamToList.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterStreamToList.java index b865779c4db6..704e3a80dfa0 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterStreamToList.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterStreamToList.java @@ -5,5 +5,5 @@ import java.util.stream.Collectors; import java.util.stream.Stream; public class Test { - public static final List> MY_LIST = List.>of(String.class, int.class, Object.class); + public static final List> MY_LIST = List.of(String.class, int.class, Object.class); } diff --git a/java/java-tests/testData/inspection/java9CollectionFactory/afterStreamToSet.java b/java/java-tests/testData/inspection/java9CollectionFactory/afterStreamToSet.java index 79c8990dae50..343895844464 100644 --- a/java/java-tests/testData/inspection/java9CollectionFactory/afterStreamToSet.java +++ b/java/java-tests/testData/inspection/java9CollectionFactory/afterStreamToSet.java @@ -5,5 +5,5 @@ import java.util.stream.Collectors; import java.util.stream.Stream; public class Test { - public static final Set> MY_SET = Set.>of(String.class, int.class, Object.class); + public static final Set> MY_SET = Set.of(String.class, int.class, Object.class); } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/java19api/Java9CollectionFactoryInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/java19api/Java9CollectionFactoryInspectionTest.java index 488e25ebcfb2..4bf50a0f8b9d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/java19api/Java9CollectionFactoryInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/java19api/Java9CollectionFactoryInspectionTest.java @@ -17,7 +17,9 @@ package com.intellij.codeInspection.java19api; import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; +import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NotNull; /** @@ -35,6 +37,11 @@ public class Java9CollectionFactoryInspectionTest extends LightQuickFixParameter return new LocalInspectionTool[]{new Java9CollectionFactoryInspection()}; } + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk9(); + } + public void test() throws Exception { doAllTests(); } From 24a0bec546940e470d549b56ab9f983d4ca86991 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Thu, 9 Mar 2017 10:57:18 +0300 Subject: [PATCH 031/629] external system: fix module name dedup delimiter --- .../externalSystem/service/project/IdeModelsProviderImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/IdeModelsProviderImpl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/IdeModelsProviderImpl.java index 1ac5390e3ee1..8d2135415410 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/IdeModelsProviderImpl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/IdeModelsProviderImpl.java @@ -94,7 +94,7 @@ public class IdeModelsProviderImpl implements IdeModelsProvider { if (modulePath.getParentFile() != null) { prefix = modulePath.getParentFile().getName(); } - char delimiter = ModuleGrouperKt.isQualifiedModuleNamesEnabled() ? '.' : '_'; + char delimiter = ModuleGrouperKt.isQualifiedModuleNamesEnabled() ? '.' : '-'; return new String[]{ module.getInternalName(), prefix + delimiter + module.getInternalName(), From de8355821fd0bfb5f2c77a9aad9ec8f05180b357 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 7 Mar 2017 14:45:30 +0300 Subject: [PATCH 032/629] cleanup: unused class deleted --- .../ui/AbstractBreakpointPanel.java | 84 ------------------- 1 file changed, 84 deletions(-) delete mode 100644 platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/AbstractBreakpointPanel.java diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/AbstractBreakpointPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/AbstractBreakpointPanel.java deleted file mode 100644 index dbf252b5383e..000000000000 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/AbstractBreakpointPanel.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2000-2009 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.xdebugger.impl.breakpoints.ui; - -import com.intellij.util.EventDispatcher; - -import javax.swing.*; -import java.util.EventListener; - -/** - * @author nik - */ -public abstract class AbstractBreakpointPanel { - private final String myTabName; - private final String myHelpID; - private final Class myBreakpointClass; - private final EventDispatcher myEventDispatcher = EventDispatcher.create(ChangesListener.class); - - protected AbstractBreakpointPanel(final String tabName, final String helpID, final Class breakpointClass) { - myTabName = tabName; - myHelpID = helpID; - myBreakpointClass = breakpointClass; - } - - public String getTabTitle() { - return myTabName; - } - - public String getHelpID() { - return myHelpID; - } - - public abstract void dispose(); - - public abstract Icon getTabIcon(); - - public abstract void resetBreakpoints(); - - public abstract void saveBreakpoints(); - - public abstract JPanel getPanel(); - - public abstract boolean canSelectBreakpoint(B breakpoint); - - public abstract void selectBreakpoint(B breakpoint); - - public abstract boolean hasBreakpoints(); - - public void addChangesListener(ChangesListener listener) { - myEventDispatcher.addListener(listener); - } - - public void removeChangesListener(ChangesListener listener) { - myEventDispatcher.removeListener(listener); - } - - public Class getBreakpointClass() { - return myBreakpointClass; - } - - public void ensureSelectionExists() { - } - - protected void fireBreakpointsChanged() { - myEventDispatcher.getMulticaster().breakpointsChanged(); - } - - public interface ChangesListener extends EventListener { - void breakpointsChanged(); - } -} From 1fe899955ee07610289e174ae81ec2404b169e12 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 9 Mar 2017 11:56:59 +0300 Subject: [PATCH 033/629] project configuration: use JUnit JARs from the project sources, not from IDE's installation Future versions of IDEA may bundle different version of JUnit. Also when a project refers to two JAR files from different directories IDEA index classes from both of them even if they have the same content. --- python/educational-core/student/student.iml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/python/educational-core/student/student.iml b/python/educational-core/student/student.iml index 29d9b096e528..e9520697b646 100644 --- a/python/educational-core/student/student.iml +++ b/python/educational-core/student/student.iml @@ -25,16 +25,7 @@ - - - - - - - - - - + From 528d72e793023cdcb33da77583aaf7ba77b976cc Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 9 Mar 2017 09:58:56 +0100 Subject: [PATCH 034/629] [updater] finds a nearest candidate for move, fixed (IDEA-CR-19029) --- updater/src/com/intellij/updater/DiffCalculator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/updater/src/com/intellij/updater/DiffCalculator.java b/updater/src/com/intellij/updater/DiffCalculator.java index db6d6c721342..60f576283ec8 100644 --- a/updater/src/com/intellij/updater/DiffCalculator.java +++ b/updater/src/com/intellij/updater/DiffCalculator.java @@ -87,6 +87,7 @@ public class DiffCalculator { private static String findBestCandidateForMove(List paths, String path) { if (paths == null) return null; + if (paths.size() == 1) return paths.get(0); String best = ""; @@ -111,6 +112,8 @@ public class DiffCalculator { } } + if (best.isEmpty()) throw new AssertionError("Failed to find a candidate for '" + path + "' in " + paths); + return best; } From 4e4f40b003fe039975cfc9235982b9fb120dc6ce Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 9 Mar 2017 10:38:41 +0100 Subject: [PATCH 035/629] [tests] adds a couple of regression tests for IDEA-12099 --- .../openapi/vfs/local/FileWatcherTest.kt | 7 ++-- .../vfs/local/LocalFileSystemTest.java | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.kt b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.kt index 57f92ef47f85..b49d38c781db 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.kt @@ -454,14 +454,11 @@ class FileWatcherTest : BareTestFixtureTestCase() { assertEvents({ file.renameTo(newFile) }, mapOf(newFile to 'P')) } - // tests the same scenario with an active file watcher (prevents explicit marking of refreshed paths) + // tests the same scenarios with an active file watcher (prevents explicit marking of refreshed paths) @Test fun testPartialRefresh() = LocalFileSystemTest.doTestPartialRefresh(tempDir.newFolder("top")) - - // tests the same scenario with an active file watcher (prevents explicit marking of refreshed paths) @Test fun testInterruptedRefresh() = LocalFileSystemTest.doTestInterruptedRefresh(tempDir.newFolder("top")) - - // tests the same scenario with an active file watcher (prevents explicit marking of refreshed paths) @Test fun testRefreshAndFindFile() = LocalFileSystemTest.doTestRefreshAndFindFile(tempDir.newFolder("top")) + @Test fun testRefreshEquality() = LocalFileSystemTest.doTestRefreshEquality(tempDir.newFolder("top")) @Test fun testUnicodePaths() { val root = tempDir.newFolder(UNICODE_NAME_1) diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java index c0c90fdff9f8..92059ffc43ea 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java @@ -177,6 +177,38 @@ public class LocalFileSystemTest extends PlatformTestCase { assertNotNull(lfs.refreshAndFindFileByPath(file3.getPath())); } + public void testRefreshEquality() throws IOException { + doTestRefreshEquality(createTempDirectory()); + } + + public static void doTestRefreshEquality(@NotNull File tempDir) throws IOException { + LocalFileSystem lfs = LocalFileSystem.getInstance(); + VirtualFile tempVDir = lfs.refreshAndFindFileByPath(tempDir.getPath()); + assertNotNull(tempVDir); + assertEquals(0, tempVDir.getChildren().length); + + FileUtil.writeToFile(new File(tempDir, "file1.txt"), "hello"); + tempVDir.refresh(false, false); + assertEquals(1, tempVDir.getChildren().length); + FileUtil.writeToFile(new File(tempDir, "file2.txt"), "hello"); + tempVDir.refresh(false, true); + assertEquals(2, tempVDir.getChildren().length); + + File tempDir1 = IoTestUtil.createTestDir(tempDir, "sub1"); + VirtualFile tempVDir1 = lfs.refreshAndFindFileByIoFile(tempDir1); + assertNotNull(tempVDir1); + FileUtil.writeToFile(new File(tempDir1, "file.txt"), "hello"); + tempVDir1.refresh(false, false); + assertEquals(1, tempVDir1.getChildren().length); + + File tempDir2 = IoTestUtil.createTestDir(tempDir, "sub2"); + VirtualFile tempVDir2 = lfs.refreshAndFindFileByIoFile(tempDir2); + assertNotNull(tempVDir2); + FileUtil.writeToFile(new File(tempDir2, "file.txt"), "hello"); + tempVDir2.refresh(false, true); + assertEquals(1, tempVDir2.getChildren().length); + } + public void testCopyFile() throws Exception { File fromDir = createTempDirectory(); File toDir = createTempDirectory(); From 7ba6c5dab14ccdaf3a41e0164d7d79fff585fe9f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 9 Mar 2017 11:49:13 +0100 Subject: [PATCH 036/629] [java] highlights external implementations in 'provides' (IDEA-169193) --- .../daemon/impl/analysis/ModuleHighlightUtil.java | 5 +++++ java/java-psi-impl/src/messages/JavaErrorMessages.properties | 1 + .../intellij/codeInsight/daemon/ModuleHighlightingTest.kt | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java index 1a88b089b664..fd15a87163ef 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java @@ -359,6 +359,11 @@ public class ModuleHighlightUtil { PsiClass implClass = (PsiClass)implTarget; PsiMethod provider; + if (findModule(statement) != findModule(implClass)) { + String message = JavaErrorMessages.message("module.service.alien"); + results.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(implRef)).descriptionAndTooltip(message).create()); + } + if (InheritanceUtil.isInheritorOrSelf(implClass, (PsiClass)intTarget, true)) { if (implClass.hasModifierProperty(PsiModifier.ABSTRACT)) { String message = JavaErrorMessages.message("module.service.abstract", implClass.getName()); diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index d7b2f6cbe5e5..da06fa4af591 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -410,6 +410,7 @@ module.opens.in.weak.module='opens' is not allowed in an open module package.not.found=Package not found: {0} package.is.empty=Package is empty: {0} module.service.enum=The service definition is an enum: {0} +module.service.alien=The service implementation must be defined in the same module as the provides directive module.service.impl=The service implementation type must be a subtype of the service interface type, or have a public static no-args 'provider' method module.service.abstract=The service implementation is an abstract class: {0} module.service.inner=The service implementation is an inner class: {0} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt index ce7ffce24ba0..c9de28eda2fe 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ModuleHighlightingTest.kt @@ -151,8 +151,12 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() { addFile("pkg/main/Impl7.java", "package pkg.main;\npublic class Impl7 {\n public static void provider();\n}") addFile("pkg/main/Impl8.java", "package pkg.main;\npublic class Impl8 {\n public static C provider();\n}") addFile("pkg/main/Impl9.java", "package pkg.main;\npublic class Impl9 {\n public class Inner implements C { }\n}") + addFile("module-info.java", "module M2 {\n exports pkg.m2;\n}", M2) + addFile("pkg/m2/C.java", "package pkg.m2;\npublic class C { }", M2) + addFile("pkg/m2/Impl.java", "package pkg.m2;\npublic class Impl extends C { }", M2) highlight(""" module M { + requires M2; provides pkg.main.C with pkg.main.NoImpl; provides pkg.main.C with pkg.main.Impl1; provides pkg.main.C with pkg.main.Impl2; @@ -163,6 +167,7 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() { provides pkg.main.C with pkg.main.Impl7; provides pkg.main.C with pkg.main.Impl8; provides pkg.main.C with pkg.main.Impl9.Inner; + provides pkg.m2.C with pkg.m2.Impl; }""".trimIndent()) } From 0ec02fd482b4b8aebe2f02a0ac94a4ec6d1e90dc Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 9 Mar 2017 11:59:46 +0100 Subject: [PATCH 037/629] have a separate SemVerMatcher for parsing semver versions in 2 variants: strict or partial. Fixes SemVerTest --- .../src/com/intellij/util/text/SemVer.java | 32 +--------- .../com/intellij/util/text/SemVerMatcher.java | 61 +++++++++++++++++++ .../com/intellij/util/text/SemVerTest.java | 4 +- 3 files changed, 64 insertions(+), 33 deletions(-) create mode 100644 platform/util/src/com/intellij/util/text/SemVerMatcher.java diff --git a/platform/util/src/com/intellij/util/text/SemVer.java b/platform/util/src/com/intellij/util/text/SemVer.java index 075c48a60cf1..953edb4491d0 100644 --- a/platform/util/src/com/intellij/util/text/SemVer.java +++ b/platform/util/src/com/intellij/util/text/SemVer.java @@ -15,7 +15,6 @@ */ package com.intellij.util.text; -import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -86,39 +85,10 @@ public class SemVer implements Comparable { return myRawVersion; } - @Nullable - public static SemVer parseFromText(@NotNull String text) { - int majorEndInd = text.indexOf('.'); - if (majorEndInd < 0) { - final int major = StringUtil.parseInt(text, -1); - return major < 0 ? null : new SemVer(text, major, 0, 0); - } - int major = StringUtil.parseInt(text.substring(0, majorEndInd), -1); - int minorEndInd = text.indexOf('.', majorEndInd + 1); - if (minorEndInd < 0) { - final int minor = StringUtil.parseInt(text.substring(majorEndInd + 1), -1); - return new SemVer(text, major, minor < 0 ? 0 : minor, 0); - } - int minor = StringUtil.parseInt(text.substring(majorEndInd + 1, minorEndInd), -1); - final String patchStr; - int dashInd = text.indexOf('-', minorEndInd + 1); - if (dashInd >= 0) { - patchStr = text.substring(minorEndInd + 1, dashInd); - } - else { - patchStr = text.substring(minorEndInd + 1); - } - int patch = StringUtil.parseInt(patchStr, -1); - if (major >= 0 && minor >= 0 && patch >= 0) { - return new SemVer(text, major, minor, patch); - } - return null; - } - @NotNull public static SemVer parseFromTextNonNullize(@Nullable final String text) { if (text == null) return UNKNOWN; - final SemVer ver = parseFromText(text); + final SemVer ver = SemVerMatcher.parseFromText(text); return ver == null ? UNKNOWN : ver; } diff --git a/platform/util/src/com/intellij/util/text/SemVerMatcher.java b/platform/util/src/com/intellij/util/text/SemVerMatcher.java new file mode 100644 index 000000000000..384e4dfce11e --- /dev/null +++ b/platform/util/src/com/intellij/util/text/SemVerMatcher.java @@ -0,0 +1,61 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.text; + +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Irina.Chernushina on 3/9/2017. + */ +public class SemVerMatcher { + @Nullable + public static SemVer parseFromText(@NotNull String text) { + return parseFromText(text, false); + } + + @Nullable + public static SemVer parseFromText(@NotNull String text, final boolean allowPartial) { + int majorEndInd = text.indexOf('.'); + if (majorEndInd < 0) { + if (!allowPartial) return null; + final int major = StringUtil.parseInt(text, -1); + return major < 0 ? null : new SemVer(text, major, 0, 0); + } + int major = StringUtil.parseInt(text.substring(0, majorEndInd), -1); + int minorEndInd = text.indexOf('.', majorEndInd + 1); + if (minorEndInd < 0) { + if (!allowPartial) return null; + final int minor = StringUtil.parseInt(text.substring(majorEndInd + 1), -1); + return new SemVer(text, major, minor < 0 ? 0 : minor, 0); + } + int minor = StringUtil.parseInt(text.substring(majorEndInd + 1, minorEndInd), -1); + final String patchStr; + int dashInd = text.indexOf('-', minorEndInd + 1); + if (dashInd >= 0) { + patchStr = text.substring(minorEndInd + 1, dashInd); + } + else { + patchStr = text.substring(minorEndInd + 1); + } + int patch = StringUtil.parseInt(patchStr, -1); + if (major >= 0 && minor >= 0 && patch >= 0) { + return new SemVer(text, major, minor, patch); + } + return null; + } +} diff --git a/platform/util/testSrc/com/intellij/util/text/SemVerTest.java b/platform/util/testSrc/com/intellij/util/text/SemVerTest.java index 00f39f14aa73..00bdd74e16e2 100644 --- a/platform/util/testSrc/com/intellij/util/text/SemVerTest.java +++ b/platform/util/testSrc/com/intellij/util/text/SemVerTest.java @@ -47,7 +47,7 @@ public class SemVerTest extends TestCase { } private static void checkNotParsed(@NotNull String version) { - assertNull(SemVer.parseFromText(version)); + assertNull(SemVerMatcher.parseFromText(version)); } public void testCompare() throws Exception { @@ -65,7 +65,7 @@ public class SemVerTest extends TestCase { @NotNull private static SemVer parseNotNull(@NotNull String text) { - SemVer semVer = SemVer.parseFromText(text); + SemVer semVer = SemVerMatcher.parseFromText(text); assertNotNull(semVer); return semVer; } From b2c890260ae41eba306dc086a35ed65b366e6be7 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 9 Mar 2017 12:02:19 +0100 Subject: [PATCH 038/629] + also have an old method in place. (Have a separate SemVerMatcher for parsing semver versions in 2 variants: strict or partial. Fixes SemVerTest) --- platform/util/src/com/intellij/util/text/SemVer.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/util/src/com/intellij/util/text/SemVer.java b/platform/util/src/com/intellij/util/text/SemVer.java index 953edb4491d0..7f0dd4bbaf08 100644 --- a/platform/util/src/com/intellij/util/text/SemVer.java +++ b/platform/util/src/com/intellij/util/text/SemVer.java @@ -85,6 +85,11 @@ public class SemVer implements Comparable { return myRawVersion; } + @Nullable + public static SemVer parseFromText(@NotNull String text) { + return SemVerMatcher.parseFromText(text); + } + @NotNull public static SemVer parseFromTextNonNullize(@Nullable final String text) { if (text == null) return UNKNOWN; From cc08e4bf659ffc967556bc58c957aaaba83f9b2e Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 9 Mar 2017 12:15:38 +0100 Subject: [PATCH 039/629] + also have an old method in place. (Have a separate SemVerMatcher for parsing semver versions in 2 variants: strict or partial. Fixes SemVerTest) --- platform/util/testSrc/com/intellij/util/text/SemVerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/util/testSrc/com/intellij/util/text/SemVerTest.java b/platform/util/testSrc/com/intellij/util/text/SemVerTest.java index 00bdd74e16e2..00f39f14aa73 100644 --- a/platform/util/testSrc/com/intellij/util/text/SemVerTest.java +++ b/platform/util/testSrc/com/intellij/util/text/SemVerTest.java @@ -47,7 +47,7 @@ public class SemVerTest extends TestCase { } private static void checkNotParsed(@NotNull String version) { - assertNull(SemVerMatcher.parseFromText(version)); + assertNull(SemVer.parseFromText(version)); } public void testCompare() throws Exception { @@ -65,7 +65,7 @@ public class SemVerTest extends TestCase { @NotNull private static SemVer parseNotNull(@NotNull String text) { - SemVer semVer = SemVerMatcher.parseFromText(text); + SemVer semVer = SemVer.parseFromText(text); assertNotNull(semVer); return semVer; } From 785d4fb8b481fb3b10771d8ea0f0290beac80219 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 9 Mar 2017 14:31:57 +0300 Subject: [PATCH 040/629] IDEA-158609 lst: adjust colors for color-blindness theme --- .../platform-resources/src/DefaultColorSchemesManager.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml index aea714307d99..22746f21901b 100644 --- a/platform/platform-resources/src/DefaultColorSchemesManager.xml +++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml @@ -23,10 +23,10 @@