Merge remote-tracking branch 'origin/master'
authorDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Fri, 7 Oct 2016 10:28:00 +0000 (13:28 +0300)
committerDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Fri, 7 Oct 2016 10:28:00 +0000 (13:28 +0300)
191 files changed:
java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryExtension.java
java/idea-ui/src/com/intellij/ide/util/importProject/ModuleInsight.java
java/java-analysis-impl/src/com/intellij/codeInspection/OptionalIsPresentInspection.java
java/java-analysis-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java
java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8CollectionRemoveIfInspection.java
java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8ReplaceMapGetInspection.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/ParameterNameHintsManager.java
java/java-impl/src/com/intellij/codeInspection/streamMigration/MigrateToStreamFix.java
java/java-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithFindFirstFix.java
java/java-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithMatchFix.java
java/java-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java
java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/breakStringOnLineBreaks/beforeLastSlashN.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/breakStringOnLineBreaks/beforeLastSlashNSlashR.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeVarargsCallMoreArgs.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUncheckedVarargs/before7.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchArrayAssignment.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchUnreachableReturn.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstReAssignment.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstReturnUnreachable.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchArrayAssignment.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchUnreachableReturn.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstReAssignment.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstReturnUnreachable.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppressLocalInspection/before6.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppressNonInspections/before10.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppressNonInspections/before8.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/wrapObjectWithOptional/beforeInvalidTypeParameter.java
java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedLambda.java
java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedLambdaTwice.java
java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedPrimitive.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegated.java
java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegatedLambdaTwice.java
java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegatedPrimitive.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegated.java
java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegatedLambda.java
java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegatedPrimitive.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegated.java
java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedLambda.java
java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedLambdaTwice.java
java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedPrimitive.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegated.java
java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedLambda.java
java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedLambdaTwice.java
java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedPrimitive.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegated.java
java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegatedLambda.java
java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegatedPrimitive.java [new file with mode: 0644]
java/java-tests/testData/inspection/stringTokenizerDelimiter/beforeConstructorNoDuplicates.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SuppressLocalInspectionTest.java
java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java
java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java
jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java
jps/jps-builders/src/org/jetbrains/jps/indices/impl/ModuleExcludeIndexImpl.java
jps/jps-builders/testData/output/sourceRootUnderExcluded/exc/src/B.java [new file with mode: 0644]
jps/jps-builders/testData/output/sourceRootUnderExcluded/sourceRootUnderExcluded.iml [new file with mode: 0644]
jps/jps-builders/testData/output/sourceRootUnderExcluded/sourceRootUnderExcluded.ipr [new file with mode: 0644]
jps/jps-builders/testData/output/sourceRootUnderExcluded/src/A.java [new file with mode: 0644]
jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/ModuleRebuildTest.kt
jps/jps-builders/testSrc/org/jetbrains/jps/indices/ModuleExcludeIndexTest.java
json/src/com/jetbrains/jsonSchema/impl/JsonBySchemaObjectAnnotator.java
native/WinLauncher/WinLauncher/WinLauncher.vcxproj
platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffToolUtil.java
platform/icons/src/nodes/finalMark.png
platform/icons/src/nodes/finalMark@2x.png
platform/icons/src/nodes/finalMark@2x_dark.png [deleted file]
platform/icons/src/nodes/finalMark_dark.png [deleted file]
platform/icons/src/nodes/locked.png
platform/icons/src/nodes/locked@2x.png
platform/icons/src/nodes/pinToolWindow.png
platform/icons/src/nodes/pinToolWindow@2x.png
platform/icons/src/nodes/staticMark.png
platform/icons/src/nodes/staticMark@2x.png
platform/icons/src/nodes/tabPin.png
platform/icons/src/nodes/tabPin@2x.png
platform/icons/src/toolwindows/toolWindowChanges.png
platform/icons/src/toolwindows/toolWindowChanges@2x.png
platform/icons/src/toolwindows/toolWindowChanges@2x_dark.png
platform/icons/src/toolwindows/toolWindowChanges_dark.png
platform/lang-api/src/com/intellij/framework/detection/FacetBasedFrameworkDetector.java
platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java
platform/lang-impl/src/com/intellij/openapi/wm/impl/status/TogglePopupHintsPanel.java
platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java
platform/platform-api/src/com/intellij/ui/paint/EffectPainter.java
platform/platform-impl/src/com/intellij/codeInsight/hints/filtering/MethodMatcher.kt [new file with mode: 0644]
platform/platform-impl/src/com/intellij/codeInsight/hints/filtering/StringMatcherBuilder.kt [new file with mode: 0644]
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java
platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java
platform/platform-resources-en/src/messages/ActionsBundle.properties
platform/platform-tests/testSrc/com/intellij/codeInsight/hints/filtering/MatcherTest.kt [new file with mode: 0644]
platform/platform-tests/testSrc/com/intellij/codeInsight/hints/filtering/PatternExtractionTest.kt [new file with mode: 0644]
platform/platform-tests/testSrc/com/intellij/codeInsight/hints/filtering/StringMatchingTest.kt [new file with mode: 0644]
platform/projectModel-impl/src/com/intellij/openapi/roots/impl/FileIndexBase.java
platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java
platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java
platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
platform/remote-servers/api/src/com/intellij/remoteServer/configuration/ServerConfiguration.java
platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/DefaultRemoteServersViewContribution.java
platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/RemoteServersViewContribution.java
platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/RemoteServersViewImpl.java
platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java
platform/testFramework/src/com/intellij/testFramework/FailedTestDebugLogConsoleFolding.java [new file with mode: 0644]
platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java
platform/util/resources/misc/registry.properties
platform/util/src/com/intellij/icons/AllIcons.java
platform/util/src/com/intellij/openapi/vfs/CharsetToolkit.java
platform/util/src/com/intellij/util/PausesStat.java
platform/util/src/com/intellij/util/containers/ContainerUtil.java
platform/util/src/com/intellij/util/containers/JBIterable.java
platform/util/src/com/intellij/util/ui/UIUtil.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java
plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineFrameworkDetector.java
plugins/groovy/groovy-psi/resources/icons/mvc/action_method.png
plugins/groovy/groovy-psi/resources/icons/mvc/action_method@2x.png
plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed.png
plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed@2x.png
plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed@2x_dark.png [deleted file]
plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed_dark.png [deleted file]
plugins/groovy/groovy-psi/resources/icons/mvc/controller.png
plugins/groovy/groovy-psi/resources/icons/mvc/controller@2x.png
plugins/groovy/groovy-psi/resources/icons/mvc/domain_class.png
plugins/groovy/groovy-psi/resources/icons/mvc/domain_class@2x.png
plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin.png
plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin@2x.png
plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin@2x_dark.png
plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin_dark.png
plugins/groovy/groovy-psi/resources/icons/mvc/modelsNode.png
plugins/groovy/groovy-psi/resources/icons/mvc/modelsNode@2x.png
plugins/groovy/groovy-psi/resources/icons/mvc/service.png
plugins/maven/src/main/resources/images/childrenProjects.png
plugins/maven/src/main/resources/images/childrenProjects_dark.png
plugins/maven/src/main/resources/images/executeMavenGoal.png
plugins/maven/src/main/resources/images/executeMavenGoal@2x.png
plugins/maven/src/main/resources/images/mavenLogo.png
plugins/maven/src/main/resources/images/mavenPlugin.png
plugins/maven/src/main/resources/images/mavenPlugin_dark.png [deleted file]
plugins/maven/src/main/resources/images/mavenProject.png
plugins/maven/src/main/resources/images/mavenProject_dark.png [deleted file]
plugins/maven/src/main/resources/images/modulesClosed.png
plugins/maven/src/main/resources/images/offlineMode.png
plugins/maven/src/main/resources/images/offlineMode_dark.png
plugins/maven/src/main/resources/images/parentProject.png
plugins/maven/src/main/resources/images/phase.png
plugins/maven/src/main/resources/images/phasesClosed.png
plugins/maven/src/main/resources/images/pluginGoal.png
plugins/maven/src/main/resources/images/pluginGoal_dark.png [deleted file]
plugins/maven/src/main/resources/images/profilesClosed.png
plugins/maven/src/main/resources/images/profilesClosed_dark.png [deleted file]
plugins/maven/src/main/resources/images/toolWindowMaven.png
plugins/maven/src/main/resources/images/toolWindowMaven@2x.png
plugins/maven/src/main/resources/images/updateFolders.png
plugins/properties/properties-psi-api/resources/icons/xmlProperties.png
plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java
python/pluginJava/com/jetbrains/python/facet/PythonFacetType.java
python/src/com/jetbrains/python/PyBundle.properties
python/src/com/jetbrains/python/buildout/BuildoutFrameworkDetector.java
python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java
python/src/com/jetbrains/python/inspections/quickfix/PyRenameElementQuickFix.java
python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy35.py [new file with mode: 0644]
python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy36.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy35.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy35_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy36.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy36_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy35.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy35_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy36.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy36_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy35.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy35_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy36.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy36_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy35.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy35_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy36.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy36_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy35.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy35_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy36.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy36_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy35.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy35_after.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy36.py [new file with mode: 0644]
python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy36_after.py [new file with mode: 0644]
python/testSrc/com/jetbrains/python/PyQuickFixTest.java
python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
python/testSrc/com/jetbrains/python/quickFixes/RenameElementQuickFixTest.java
resources/src/META-INF/IdeaPlugin.xml
updater/src/com/intellij/updater/Runner.java

index 6868023872b8aa4b9dc9b65318ada5edeee427d7..23c95d517bd6a68d86fd19a3e2086c017026caed 100644 (file)
@@ -184,6 +184,7 @@ public class TestDiscoveryExtension extends RunConfigurationExtension {
     }
   }
 
+  @SuppressWarnings("WeakerAccess")  // called via reflection from com.intellij.InternalTestDiscoveryListener.flushCurrentTraces()
   public static void processAvailableTraces(final String[] fullTestNames,
                                             final String tracesDirectory,
                                             final String moduleName,
index a52164de461d60340b8c0980c43f941fde07e94d..992491b52790d98b0445041a3e8fd2862904088a 100644 (file)
@@ -459,6 +459,9 @@ public abstract class ModuleInsight {
               catch (IOException e) {
                 LOG.info(e);
               }
+              catch (IllegalArgumentException e) { // may be thrown from java.util.zip.ZipCoder.toString for corrupted archive
+                LOG.info(e);
+              }
               catch (InternalError e) { // indicates that file is somehow damaged and cannot be processed
                 LOG.info(e);
               }
index 73d43330d3b895a96d3a947f187e35b14d8b1cca..93f360530609242f71442386ee3be7d7c4ab4e20 100644 (file)
@@ -134,7 +134,7 @@ public class OptionalIsPresentInspection extends BaseJavaBatchLocalInspectionToo
     if(!"get".equals(call.getMethodExpression().getReferenceName())) return false;
     PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
     if(!(qualifier instanceof PsiReferenceExpression)) return false;
-    return ((PsiReferenceExpression)qualifier).resolve() == variable;
+    return ((PsiReferenceExpression)qualifier).isReferenceTo(variable);
   }
 
   @Contract("null, _ -> false")
index dcb6b192a3afd030827c5aaab1c5301839421ec5..e29355b85b9caf45b2d9f81a9d3523338b9b8acc 100644 (file)
@@ -80,7 +80,10 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
     return new JavaElementVisitor() {
       @Override
       public void visitMethodCallExpression(PsiMethodCallExpression methodCall) {
-        final PsiMethod method = methodCall.resolveMethod();
+        PsiMethod method = methodCall.resolveMethod();
+        if(method == null) return;
+        PsiClass psiClass = method.getContainingClass();
+        if(psiClass == null) return;
         if (isCallOf(method, CommonClassNames.JAVA_UTIL_COLLECTION, STREAM_METHOD, 0)) {
           handleCollectionStream(methodCall);
         }
@@ -90,27 +93,28 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
         else if (isCallOf(method, CommonClassNames.JAVA_UTIL_OPTIONAL, IS_PRESENT_METHOD, 0)) {
           handleOptionalIsPresent(methodCall);
         }
-        else if (isCallOf(method, CommonClassNames.JAVA_UTIL_STREAM_STREAM, ANY_MATCH_METHOD, 1)) {
+        else if (isStreamCall(method, ANY_MATCH_METHOD)) {
           if(isParentNegated(methodCall)) {
             boolean argNegated = isArgumentLambdaNegated(methodCall);
             registerMatchFix(methodCall,
-                             new SimplifyMatchNegationFix(argNegated ? "!Stream.anyMatch(x -> !(...))" : "!Stream.anyMatch(...)",
+                             new SimplifyMatchNegationFix(
+                               "!" + psiClass.getName() + (argNegated ? ".anyMatch(x -> !(...))" : ".anyMatch(...)"),
                                                           argNegated ? ALL_MATCH_METHOD : NONE_MATCH_METHOD));
           }
         }
-        else if (isCallOf(method, CommonClassNames.JAVA_UTIL_STREAM_STREAM, NONE_MATCH_METHOD, 1)) {
+        else if (isStreamCall(method, NONE_MATCH_METHOD)) {
           if(isParentNegated(methodCall)) {
-            registerMatchFix(methodCall, new SimplifyMatchNegationFix("!Stream.noneMatch(...)", ANY_MATCH_METHOD));
+            registerMatchFix(methodCall, new SimplifyMatchNegationFix("!"+psiClass.getName()+".noneMatch(...)", ANY_MATCH_METHOD));
           }
           if(isArgumentLambdaNegated(methodCall)) {
-            registerMatchFix(methodCall, new SimplifyMatchNegationFix("Stream.noneMatch(x -> !(...))", ALL_MATCH_METHOD));
+            registerMatchFix(methodCall, new SimplifyMatchNegationFix(psiClass.getName()+".noneMatch(x -> !(...))", ALL_MATCH_METHOD));
           }
         }
-        else if (isCallOf(method, CommonClassNames.JAVA_UTIL_STREAM_STREAM, ALL_MATCH_METHOD, 1)) {
+        else if (isStreamCall(method, ALL_MATCH_METHOD)) {
           if(isArgumentLambdaNegated(methodCall)) {
             boolean parentNegated = isParentNegated(methodCall);
             registerMatchFix(methodCall,
-                             new SimplifyMatchNegationFix(parentNegated ? "!Stream.allMatch(x -> !(...))" : "Stream.allMatch(x -> !(...))",
+                             new SimplifyMatchNegationFix((parentNegated ? "!" : "") + psiClass.getName() + ".allMatch(x -> !(...))",
                                                           parentNegated ? ANY_MATCH_METHOD : NONE_MATCH_METHOD));
           }
         }
@@ -311,6 +315,14 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
     return false;
   }
 
+  static boolean isStreamCall(@Nullable PsiMethod method, @NotNull String methodName) {
+    if (method == null || !methodName.equals(method.getName()) || method.getParameterList().getParametersCount() != 1) {
+      return false;
+    }
+    final PsiClass containingClass = method.getContainingClass();
+    return containingClass != null && InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM);
+  }
+
   interface CallChainFix {
     String getName();
     void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor);
@@ -627,11 +639,11 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
 
     @Override
     public String getName() {
-      return "Replace "+myFrom+" with Stream."+myTo+"(...)";
+      return "Replace "+myFrom+" with "+myTo+"(...)";
     }
 
     public String getMessage() {
-      return myFrom+" can be replaced with Stream."+myTo+"(...)";
+      return myFrom+" can be replaced with "+myTo+"(...)";
     }
 
     @Override
index 682ed7749a319f56b4af361af071ea6c86af4cd4..2060327bd3dd3282b18e3e3daf7e4f6460bb3869 100644 (file)
@@ -239,7 +239,7 @@ public class Java8CollectionRemoveIfInspection extends BaseJavaBatchLocalInspect
       if(!method.equals(expression.getReferenceName())) return false;
       PsiExpression qualifier = expression.getQualifierExpression();
       if(!(qualifier instanceof PsiReferenceExpression)) return false;
-      return ((PsiReferenceExpression)qualifier).resolve() == myIterator;
+      return ((PsiReferenceExpression)qualifier).isReferenceTo(myIterator);
     }
 
     public PsiVariable getNextElementVariable(PsiStatement statement) {
index 030ce25d86542df2ef90bbcea20f683bd13af128..ef8f4986aa1617dd9d9be39d1bb09ef882ba78f2 100644 (file)
@@ -159,7 +159,7 @@ public class Java8ReplaceMapGetInspection extends BaseJavaBatchLocalInspectionTo
       PsiElement[] elements = declaration.getDeclaredElements();
       if(elements.length > 0) {
         PsiElement lastDeclaration = elements[elements.length - 1];
-        if(lastDeclaration instanceof PsiLocalVariable && lastDeclaration == target.resolve()) {
+        if(lastDeclaration instanceof PsiLocalVariable && target.isReferenceTo(lastDeclaration)) {
           PsiLocalVariable var = (PsiLocalVariable)lastDeclaration;
           PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(var.getInitializer());
           if (initializer instanceof PsiMethodCallExpression &&
index ed494a786136c95b77de37cecef3b3162ed48a2c..6cfe9cd1593d4788e6e2d8684aba0cbadc7cf030 100644 (file)
@@ -15,7 +15,8 @@
  */
 package com.intellij.codeInsight.daemon.impl;
 
-import com.intellij.openapi.util.Couple;
+import com.intellij.codeInsight.hints.filtering.Matcher;
+import com.intellij.codeInsight.hints.filtering.MatcherConstructor;
 import com.intellij.psi.*;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.util.TypeConversionUtil;
@@ -26,22 +27,25 @@ import org.jetbrains.annotations.Nullable;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
-import static com.intellij.openapi.util.text.StringUtil.containsIgnoreCase;
 import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
 
 public class ParameterNameHintsManager {
-  private static final List<Couple<String>> COMMONLY_USED_PARAMETER_PAIR = ContainerUtil.newArrayList(
-    Couple.of("begin", "end"),
-    Couple.of("start", "end"),
-    Couple.of("first", "last"),
-    Couple.of("first", "second"),
-    Couple.of("from", "to"),
-    Couple.of("key", "value"),
-    Couple.of("min", "max"),
-    Couple.of("format", "arg")
-  );
-  
+
+  private static List<Matcher> MATCHERS = Stream.of(
+    "(begin*, end*)",
+    "(start*, end*)",
+    "(first*, last*)",
+    "(first*, second*)",
+    "(from*, to*)",
+    "(min*, max*)",
+    "(key, value)",
+    "(format, arg)"
+  ).map((s) -> MatcherConstructor.INSTANCE.createMatcher(s))
+    .collect(Collectors.toList());
+    
   private static final Set<String> COMMON_METHOD_NAMES = ContainerUtil.newHashSet("set", "print", "println");
   
   @NotNull
@@ -173,7 +177,7 @@ public class ParameterNameHintsManager {
 
     final int totalDescriptors = descriptors.size();
     if (totalDescriptors == 1 && shouldIgnoreSingleHint(parameters, descriptors)
-        || totalDescriptors == 2 && parameters.length == 2 && isParamPairToIgnore(descriptors.get(0), descriptors.get(1))) 
+        || totalDescriptors == 2 && parameters.length == 2 && isParamPairToIgnore(descriptors)) 
     {
       return ContainerUtil.emptyList();
     }
@@ -206,18 +210,13 @@ public class ParameterNameHintsManager {
     return new InlayInfo(paramName, callArgument.getTextRange().getStartOffset(), callArgument);
   }
 
-  private static boolean isParamPairToIgnore(InlayInfo first, InlayInfo second) {
-    String firstParamName = first.getText();
-    String secondParamName = second.getText();
-
-    for (Couple<String> knownPair : COMMONLY_USED_PARAMETER_PAIR) {
-      if (containsIgnoreCase(firstParamName, knownPair.first) 
-          && containsIgnoreCase(secondParamName, knownPair.second)) {
-        return true;
-      }
-    }
+  private static boolean isParamPairToIgnore(List<InlayInfo> descriptors) {
+    List<String> params = descriptors
+      .stream()
+      .map((e) -> e.getText())
+      .collect(Collectors.toList());
 
-    return false;
+    return MATCHERS.stream().anyMatch((e) -> e.isMatching("", params));
   }
 
   private static boolean shouldInlineParameterName(@NotNull PsiExpression argument,
index 5a1a4c2d058356aff77acb14d608863774d34aff..2bdbe16a8973c361c73fa20b7e228f3727612402 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.controlFlow.*;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.siyeh.ig.psiutils.ExpressionUtils;
 import one.util.streamex.StreamEx;
@@ -152,4 +153,16 @@ abstract class MigrateToStreamFix implements LocalQuickFix {
       statement.delete();
     }
   }
+
+  static boolean isReachable(PsiReturnStatement target) {
+    ControlFlow flow;
+    try {
+      flow = ControlFlowFactory.getInstance(target.getProject())
+        .getControlFlow(target.getParent(), LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance());
+    }
+    catch (AnalysisCanceledException e) {
+      return true;
+    }
+    return ControlFlowUtil.isInstructionReachable(flow, flow.getStartOffset(target), 0);
+  }
 }
index ff9b77733dfeaeac4d8b035bbe40513978745991..cca1d5ce74eebd709cf7f1fd007defa384534b0f 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.PsiEquivalenceUtil;
 import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.refactoring.util.RefactoringUtil;
 import com.siyeh.ig.psiutils.ExpressionUtils;
 import org.jetbrains.annotations.NotNull;
@@ -52,10 +53,12 @@ class ReplaceWithFindFirstFix extends MigrateToStreamFix {
       if (!ExpressionUtils.isSimpleExpression(orElseExpression)) return null;
       stream = generateOptionalUnwrap(stream, tb, value, orElseExpression, null);
       restoreComments(loopStatement, body);
-      if (nextReturnStatement.getParent() == loopStatement.getParent()) {
+      boolean sibling = nextReturnStatement.getParent() == loopStatement.getParent();
+      PsiElement replacement = loopStatement.replace(elementFactory.createStatementFromText("return " + stream + ";", loopStatement));
+      if(sibling || !isReachable(nextReturnStatement)) {
         nextReturnStatement.delete();
       }
-      return loopStatement.replace(elementFactory.createStatementFromText("return " + stream + ";", loopStatement));
+      return replacement;
     }
     else {
       PsiStatement[] statements = tb.getStatements();
@@ -84,6 +87,17 @@ class ReplaceWithFindFirstFix extends MigrateToStreamFix {
           return replaceInitializer(loopStatement, var, initializer, replacementText, status);
         }
       }
+      PsiAssignmentExpression previousAssignment =
+        ExpressionUtils.getAssignment(PsiTreeUtil.skipSiblingsBackward(loopStatement, PsiWhiteSpace.class, PsiComment.class));
+      if(previousAssignment != null) {
+        PsiExpression prevRValue = previousAssignment.getRExpression();
+        PsiExpression prevLValue = previousAssignment.getLExpression();
+        if(prevRValue != null && prevLValue instanceof PsiReferenceExpression && ((PsiReferenceExpression)prevLValue).isReferenceTo(var)) {
+          previousAssignment.delete();
+          return loopStatement.replace(elementFactory.createStatementFromText(
+            var.getName() + " = " + generateOptionalUnwrap(stream, tb, value, prevRValue, var.getType()) + ";", loopStatement));
+        }
+      }
       return loopStatement.replace(elementFactory.createStatementFromText(
         var.getName() + " = " + generateOptionalUnwrap(stream, tb, value, lValue, var.getType()) + ";", loopStatement));
     }
index 1053a306f89c0fcba6eccad511f158218ddb1df5..1d0b0a14bfff248d3af8e52ee168574935191979 100644 (file)
@@ -69,7 +69,11 @@ class ReplaceWithMatchFix extends MigrateToStreamFix {
             removeLoop(loopStatement);
             return returnValue.replace(elementFactory.createExpressionFromText(streamText, nextReturnStatement));
           }
-          return loopStatement.replace(elementFactory.createStatementFromText("return " + streamText + ";", loopStatement));
+          PsiElement result = loopStatement.replace(elementFactory.createStatementFromText("return " + streamText + ";", loopStatement));
+          if(!isReachable(nextReturnStatement)) {
+            nextReturnStatement.delete();
+          }
+          return result;
         }
       }
     }
@@ -84,27 +88,30 @@ class ReplaceWithMatchFix extends MigrateToStreamFix {
     if(assignment != null) {
       PsiExpression lValue = assignment.getLExpression();
       PsiExpression rValue = assignment.getRExpression();
-      if (!(lValue instanceof PsiReferenceExpression) || rValue == null) return null;
-      PsiElement maybeVar = ((PsiReferenceExpression)lValue).resolve();
-      if(maybeVar instanceof PsiVariable) {
-        // Simplify single assignments like this:
-        // boolean flag = false;
-        // for(....) if(...) {flag = true; break;}
-        PsiVariable var = (PsiVariable)maybeVar;
-        PsiExpression initializer = var.getInitializer();
-        InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, loopStatement);
-        if(initializer != null && status != InitializerUsageStatus.UNKNOWN) {
-          String replacement;
-          if(ExpressionUtils.isLiteral(initializer, Boolean.FALSE) &&
-             ExpressionUtils.isLiteral(rValue, Boolean.TRUE)) {
-            replacement = streamText;
-          } else if(ExpressionUtils.isLiteral(initializer, Boolean.TRUE) &&
-                    ExpressionUtils.isLiteral(rValue, Boolean.FALSE)) {
-            replacement = "!"+streamText;
-          } else {
-            replacement = streamText + "?" + rValue.getText() + ":" + initializer.getText();
+      if ((lValue instanceof PsiReferenceExpression) && rValue != null) {
+        PsiElement maybeVar = ((PsiReferenceExpression)lValue).resolve();
+        if (maybeVar instanceof PsiVariable) {
+          // Simplify single assignments like this:
+          // boolean flag = false;
+          // for(....) if(...) {flag = true; break;}
+          PsiVariable var = (PsiVariable)maybeVar;
+          PsiExpression initializer = var.getInitializer();
+          InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, loopStatement);
+          if (initializer != null && status != InitializerUsageStatus.UNKNOWN) {
+            String replacement;
+            if (ExpressionUtils.isLiteral(initializer, Boolean.FALSE) &&
+                ExpressionUtils.isLiteral(rValue, Boolean.TRUE)) {
+              replacement = streamText;
+            }
+            else if (ExpressionUtils.isLiteral(initializer, Boolean.TRUE) &&
+                     ExpressionUtils.isLiteral(rValue, Boolean.FALSE)) {
+              replacement = "!" + streamText;
+            }
+            else {
+              replacement = streamText + "?" + rValue.getText() + ":" + initializer.getText();
+            }
+            return replaceInitializer(loopStatement, var, initializer, replacement, status);
           }
-          return replaceInitializer(loopStatement, var, initializer, replacement, status);
         }
       }
     }
index d84181e062025561a0b700d381c70e859080479a..13281bd34db409b5af8cc70f79f4d5dd349bec9a 100644 (file)
@@ -380,7 +380,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
 
   @Contract("_, null -> false")
   static boolean isIdentityMapping(PsiVariable variable, PsiExpression mapperCall) {
-    return mapperCall instanceof PsiReferenceExpression && ((PsiReferenceExpression)mapperCall).resolve() == variable;
+    return mapperCall instanceof PsiReferenceExpression && ((PsiReferenceExpression)mapperCall).isReferenceTo(variable);
   }
 
   @Nullable
@@ -724,7 +724,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
       if(args.length != 1) return null;
       comparatorExpression = args[0];
     }
-    if(!(listExpression instanceof PsiReferenceExpression) || ((PsiReferenceExpression)listExpression).resolve() != list) return null;
+    if(!(listExpression instanceof PsiReferenceExpression) || !((PsiReferenceExpression)listExpression).isReferenceTo(list)) return null;
     if(comparatorExpression == null || ExpressionUtils.isNullLiteral(comparatorExpression)) return "";
     return comparatorExpression.getText();
   }
@@ -762,7 +762,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
     PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
     if (!(qualifierExpression instanceof PsiReferenceExpression)) return null;
     PsiLocalVariable collectionVariable = extractCollectionVariable(expression.getMethodExpression().getQualifierExpression());
-    if (collectionVariable == null || ((PsiReferenceExpression)qualifierExpression).resolve() != collectionVariable) return null;
+    if (collectionVariable == null || !((PsiReferenceExpression)qualifierExpression).isReferenceTo(collectionVariable)) return null;
     PsiExpression initializer = collectionVariable.getInitializer();
     if (initializer == null) return null;
     PsiType type = initializer.getType();
@@ -1080,7 +1080,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
       // check that increment is like for(...;...;i++)
       if(!(forStatement.getUpdate() instanceof PsiExpressionStatement)) return null;
       PsiExpression lValue = extractIncrementedLValue(((PsiExpressionStatement)forStatement.getUpdate()).getExpression());
-      if(!(lValue instanceof PsiReferenceExpression) || ((PsiReferenceExpression)lValue).resolve() != counter) return null;
+      if(!(lValue instanceof PsiReferenceExpression) || !((PsiReferenceExpression)lValue).isReferenceTo(counter)) return null;
 
       // check that condition is like for(...;i<bound;...) or for(...;i<=bound;...)
       if(!(forStatement.getCondition() instanceof PsiBinaryExpression)) return null;
@@ -1104,7 +1104,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
         bound = condition.getLOperand();
         ref = condition.getROperand();
       } else return null;
-      if(bound == null || !(ref instanceof PsiReferenceExpression) || ((PsiReferenceExpression)ref).resolve() != counter) return null;
+      if(bound == null || !(ref instanceof PsiReferenceExpression) || !((PsiReferenceExpression)ref).isReferenceTo(counter)) return null;
       if(!TypeConversionUtil.areTypesAssignmentCompatible(counter.getType(), bound)) return null;
       return new CountingLoop(counter, initializer, bound, closed);
     }
index 13ca286944bfe2c8c80cd32787673254320389f8..c791ba4574b83e8eafaef4f5fc24713dbd5be394 100644 (file)
@@ -52,8 +52,6 @@ import java.io.IOException;
 import java.util.*;
 import java.util.concurrent.ConcurrentMap;
 
-import static com.intellij.openapi.util.Pair.pair;
-
 public abstract class BaseExternalAnnotationsManager extends ExternalAnnotationsManager {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.BaseExternalAnnotationsManager");
   private static final Key<Boolean> EXTERNAL_ANNO_MARKER = Key.create("EXTERNAL_ANNO_MARKER");
@@ -61,9 +59,9 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
 
   protected final PsiManager myPsiManager;
 
-  private final ConcurrentMap<VirtualFile, List<PsiFile>> myExternalAnnotations = ContainerUtil.createConcurrentWeakKeySoftValueMap();
+  private final ConcurrentMap<VirtualFile, List<PsiFile>> myExternalAnnotationsCache = ContainerUtil.createConcurrentWeakKeySoftValueMap();
   private final Map<AnnotationData, AnnotationData> myAnnotationDataCache = new WeakKeyWeakValueHashMap<AnnotationData, AnnotationData>();
-  private final ConcurrentMap<PsiFile, Pair<MostlySingularMultiMap<String, AnnotationData>, Long>> myAnnotationFileToDataAndModStamp = ContainerUtil.createConcurrentSoftMap();
+  private final ConcurrentMap<PsiFile, Pair<MostlySingularMultiMap<String, AnnotationData>, Long>> myAnnotationFileToDataAndModStampCache = ContainerUtil.createConcurrentSoftMap();
 
   public BaseExternalAnnotationsManager(@NotNull PsiManager psiManager) {
     myPsiManager = psiManager;
@@ -166,7 +164,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
 
   @NotNull
   private MostlySingularMultiMap<String, AnnotationData> getDataFromFile(@NotNull PsiFile file) {
-    Pair<MostlySingularMultiMap<String, AnnotationData>, Long> cached = myAnnotationFileToDataAndModStamp.get(file);
+    Pair<MostlySingularMultiMap<String, AnnotationData>, Long> cached = myAnnotationFileToDataAndModStampCache.get(file);
     long fileModificationStamp = file.getModificationStamp();
     if (cached != null && cached.getSecond() == fileModificationStamp) {
       return cached.getFirst();
@@ -188,7 +186,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
     }
 
     MostlySingularMultiMap<String, AnnotationData> result = handler.getResult();
-    myAnnotationFileToDataAndModStamp.put(file, pair(result, fileModificationStamp));
+    myAnnotationFileToDataAndModStampCache.put(file, Pair.create(result, fileModificationStamp));
     return result;
   }
 
@@ -234,7 +232,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
     final VirtualFile virtualFile = containingFile.getVirtualFile();
     if (virtualFile == null) return null;
     
-    final List<PsiFile> files = myExternalAnnotations.get(virtualFile);
+    final List<PsiFile> files = myExternalAnnotationsCache.get(virtualFile);
     if (files == NULL_LIST) return null;
 
     if (files != null) {
@@ -263,7 +261,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
     }
 
     if (possibleAnnotations.isEmpty()) {
-      myExternalAnnotations.put(virtualFile, NULL_LIST);
+      myExternalAnnotationsCache.put(virtualFile, NULL_LIST);
       return null;
     }
 
@@ -277,7 +275,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
         return w1 == w2 ? 0 : w1 ? -1 : 1;
       }
     });
-    myExternalAnnotations.put(virtualFile, result);
+    myExternalAnnotationsCache.put(virtualFile, result);
     return result;
   }
 
@@ -285,8 +283,8 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
   protected abstract List<VirtualFile> getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile);
 
   protected void dropCache() {
-    myExternalAnnotations.clear();
-    myAnnotationFileToDataAndModStamp.clear();
+    myExternalAnnotationsCache.clear();
+    myAnnotationFileToDataAndModStampCache.clear();
     cache.clear();
   }
 
@@ -348,7 +346,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
                                           @NotNull List<PsiFile> annotationFiles) {
     VirtualFile virtualFile = fromFile.getVirtualFile();
     if (virtualFile != null) {
-      myExternalAnnotations.put(virtualFile, annotationFiles);
+      myExternalAnnotationsCache.put(virtualFile, annotationFiles);
     }
   }
 
index 1d1261adfdb2944e27bdf8a0ecb76cd3e96f197a..2e9edf0cdcee2598fe8271cb5caa1dbd3be934c2 100644 (file)
@@ -7,6 +7,6 @@ class Example {
   }
 
   {
-    Function<String, String> r = (s) -> m(s, s);
+    Function<String, String> r = (s) -> <caret>m(s, s);
   }
 }
\ No newline at end of file
index da98e4655f5b512bae8b8e977ecf6a6b5643385d..a9d8079d459d4f834901bb9289a1c71aae62f579 100644 (file)
@@ -12,7 +12,7 @@ public class Test {
   }
 
   @SuppressWarnings("unchecked")
-  void foo() {
+  void f<caret>oo() {
     foo(new ArrayList<String>()).addAll(foo1(new ArrayList<String>);
   }
 }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchArrayAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchArrayAssignment.java
new file mode 100644 (file)
index 0000000..6364503
--- /dev/null
@@ -0,0 +1,12 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  public void testAssignment(List<String> data) {
+    String[] found = {"no"};
+      if (data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty())) {
+          found[0] = "yes";
+      }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchUnreachableReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchUnreachableReturn.java
new file mode 100644 (file)
index 0000000..93a1eb0
--- /dev/null
@@ -0,0 +1,13 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  boolean find(List<String> data) {
+    if(data != null) {
+        return data.stream().map(String::trim).anyMatch(trimmed -> trimmed.startsWith("xyz"));
+    } else {
+      throw new IllegalArgumentException();
+    }
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstReAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstReAssignment.java
new file mode 100644 (file)
index 0000000..4851693
--- /dev/null
@@ -0,0 +1,20 @@
+// "Replace with findFirst()" "true"
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class Main {
+  private int getInitialSize() {return 0;}
+
+  public void testMap(Map<String, List<String>> map) throws Exception {
+    int firstSize = 10;
+
+    System.out.println(firstSize);
+
+      // loop
+      // comment
+      firstSize = map.values().stream().filter(Objects::nonNull).findFirst().map(List::size).orElse(getInitialSize());
+    System.out.println(firstSize);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstReturnUnreachable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstReturnUnreachable.java
new file mode 100644 (file)
index 0000000..45ebed5
--- /dev/null
@@ -0,0 +1,15 @@
+// "Replace with findFirst()" "true"
+
+import java.util.Collection;
+import java.util.List;
+
+public class Main {
+  public static String find(List<List<String>> list) {
+    if(list == null) {
+      System.out.println("oops");
+      return "";
+    } else {
+        return list.stream().flatMap(Collection::stream).filter(string -> string.startsWith("ABC")).findFirst().orElse(null);
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchArrayAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchArrayAssignment.java
new file mode 100644 (file)
index 0000000..1fe8162
--- /dev/null
@@ -0,0 +1,16 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  public void testAssignment(List<String> data) {
+    String[] found = {"no"};
+    for(String str : da<caret>ta) {
+      String trimmed = str.trim();
+      if(!trimmed.isEmpty()) {
+        found[0] = "yes";
+        break;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchUnreachableReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchUnreachableReturn.java
new file mode 100644 (file)
index 0000000..2fa660e
--- /dev/null
@@ -0,0 +1,19 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  boolean find(List<String> data) {
+    if(data != null) {
+      for (String e : da<caret>ta) {
+        String trimmed = e.trim();
+        if (trimmed.startsWith("xyz")) {
+          return true;
+        }
+      }
+    } else {
+      throw new IllegalArgumentException();
+    }
+    return false;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstReAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstReAssignment.java
new file mode 100644 (file)
index 0000000..d1cd5f3
--- /dev/null
@@ -0,0 +1,25 @@
+// "Replace with findFirst()" "true"
+
+import java.util.List;
+import java.util.Map;
+
+public class Main {
+  private int getInitialSize() {return 0;}
+
+  public void testMap(Map<String, List<String>> map) throws Exception {
+    int firstSize = 10;
+
+    System.out.println(firstSize);
+
+    firstSize = getInitialSize();
+    // loop
+    for(List<String> list : map.valu<caret>es()) {
+      if(list != null) {
+        firstSize = list.size();
+        // comment
+        break;
+      }
+    }
+    System.out.println(firstSize);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstReturnUnreachable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstReturnUnreachable.java
new file mode 100644 (file)
index 0000000..a47317f
--- /dev/null
@@ -0,0 +1,21 @@
+// "Replace with findFirst()" "true"
+
+import java.util.List;
+
+public class Main {
+  public static String find(List<List<String>> list) {
+    if(list == null) {
+      System.out.println("oops");
+      return "";
+    } else {
+      for (List<String> innerList : lis<caret>t) {
+        for (String string : innerList) {
+          if (string.startsWith("ABC")) {
+            return string;
+          }
+        }
+      }
+    }
+    return null;
+  }
+}
\ No newline at end of file
index 36fd61a74e5223311fff1ab8a97d2ab8afd75e97..8f54bf7ff7a1ad75cf03e3addcb8bf4b455b6fe4 100644 (file)
@@ -1,5 +1,13 @@
 // "Suppress for field" "false"
 /** @noinspection ALL*/
 class a {
- static private  String mm = "00";
+ static private String <caret>mm = "00";
+  // The "Convert to local" inspection should be reported here if not suppressed
+
+ static void test() {
+  mm = "1";
+  if(mm == "1") {
+   mm = "2";
+  }
+ }
 }
\ No newline at end of file
index c263cb5fcae7387f04925d8320e1c6cfc163cd2d..f8b32ba0108dbbdc6b1bea655b5b97a1041e3f87 100644 (file)
@@ -4,6 +4,6 @@ public class Test {
   {
     int i = 0;
     //noinspection SillyAssignment my very long comment
-    i = i;
+    i = <caret>i;
   }
 }
index 0897593fad7036413d15458b400f3388e64bffb0..4532b812130818713ff1b74c41147389e412a266 100644 (file)
@@ -1,6 +1,6 @@
 // "Suppress for method" "false"
 /** @noinspection UNUSED_SYMBOL*/
 class a {
-private void run() {
+private void <caret>run() {
 }
 }
\ No newline at end of file
index 62a5fb1f6d4f826d4dde52d626b5e6509a160162..3f34513e4caba10ee391208a6b6b268253e1b2e5 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace Stream.allMatch(x -> !(...)) with Stream.noneMatch(...)" "true"
+// "Replace Stream.allMatch(x -> !(...)) with noneMatch(...)" "true"
 
 import java.util.*;
 
index 1b682b22e4a0e4b00c3d7d7ae59ddefccfa18184..960555bfce8899720d27dfd8a4aef64ee442859f 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace !Stream.allMatch(x -> !(...)) with Stream.anyMatch(...)" "true"
+// "Replace !Stream.allMatch(x -> !(...)) with anyMatch(...)" "true"
 
 import java.util.*;
 
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedPrimitive.java b/java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedPrimitive.java
new file mode 100644 (file)
index 0000000..9e50a19
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace DoubleStream.allMatch(x -> !(...)) with noneMatch(...)" "true"
+
+import java.util.stream.*;
+
+class Test {
+  public boolean testAllMatch(double[] data) {
+    if(DoubleStream.of(data).noneMatch(d -> Double.isNaN(d)))
+      return true;
+  }
+}
\ No newline at end of file
index 5d8217290911c0fd14b1967944857e2607c970fa..fc0d0a97111655cef5e0c3865622af89f8ac1477 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace !Stream.anyMatch(...) with Stream.noneMatch(...)" "true"
+// "Replace !Stream.anyMatch(...) with noneMatch(...)" "true"
 
 import java.util.*;
 
index d51ced9ee88ff8b790d43c911a47b30c86fe196f..fe678b9ee0ffaa5e8a039193ca76727639dcd36d 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace !Stream.anyMatch(x -> !(...)) with Stream.allMatch(...)" "true"
+// "Replace !Stream.anyMatch(x -> !(...)) with allMatch(...)" "true"
 
 import java.util.*;
 
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegatedPrimitive.java b/java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegatedPrimitive.java
new file mode 100644 (file)
index 0000000..c488190
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !LongStream.anyMatch(...) with noneMatch(...)" "true"
+
+import java.util.stream.*;
+
+class Test {
+  public boolean testAnyMatch(long[] data) {
+    if(LongStream.of(data).noneMatch(i -> i > 0))
+      return true;
+  }
+}
\ No newline at end of file
index 51b4c0b74601d7e5e0f6b46ec01ee92d1e7e6606..f2c92cf998903f50d72ca5b47661610e745cee85 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace !Stream.noneMatch(...) with Stream.anyMatch(...)" "true"
+// "Replace !Stream.noneMatch(...) with anyMatch(...)" "true"
 
 import java.util.*;
 
index e11a37fed210da7484a692a201ba5fed2086bf05..b0e0724163e41d1e9c134def7acaf44ee382bbd2 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace Stream.noneMatch(x -> !(...)) with Stream.allMatch(...)" "true"
+// "Replace Stream.noneMatch(x -> !(...)) with allMatch(...)" "true"
 
 import java.util.*;
 
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegatedPrimitive.java b/java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegatedPrimitive.java
new file mode 100644 (file)
index 0000000..b1b22f8
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !IntStream.noneMatch(...) with anyMatch(...)" "true"
+
+import java.util.stream.*;
+
+class Test {
+  public boolean testNoneMatch(int[] data) {
+    if(IntStream.of(data).anyMatch(i -> i > 0))
+      return true;
+  }
+}
\ No newline at end of file
index df19ee9bf6fa040aea5ffa45f886a1c41e86b8eb..a347338761d7e0389eb960c44c0327748fc991a8 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace Stream.allMatch(x -> !(...)) with Stream.noneMatch(...)" "false"
+// "Replace Stream.allMatch(x -> !(...)) with noneMatch(...)" "false"
 
 import java.util.*;
 
index d6c2fe534a3569c1abbb2289c61e1edb46b514d4..0b037b427bc53e28b8bf5a75d391756dc3d2d78a 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace Stream.allMatch(x -> !(...)) with Stream.noneMatch(...)" "true"
+// "Replace Stream.allMatch(x -> !(...)) with noneMatch(...)" "true"
 
 import java.util.*;
 
index 7a6514bd79c79a913a096616ce92f9fab0e7b072..82c4327b97233ad1bae3e5c7702c34e128d4a4e5 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace !Stream.allMatch(x -> !(...)) with Stream.anyMatch(...)" "true"
+// "Replace !Stream.allMatch(x -> !(...)) with anyMatch(...)" "true"
 
 import java.util.*;
 
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedPrimitive.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedPrimitive.java
new file mode 100644 (file)
index 0000000..df7b88d
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace DoubleStream.allMatch(x -> !(...)) with noneMatch(...)" "true"
+
+import java.util.stream.*;
+
+class Test {
+  public boolean testAllMatch(double[] data) {
+    if(DoubleStream.of(data).allM<caret>atch(d -> !Double.isNaN(d)))
+      return true;
+  }
+}
\ No newline at end of file
index 204e69b28f3075d50e4714c0efba214ccc31f9b4..25862a73e816cac4f258061bf046715040ae1dc4 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace !Stream.anyMatch(...) with Stream.noneMatch(...)" "true"
+// "Replace !Stream.anyMatch(...) with noneMatch(...)" "true"
 
 import java.util.*;
 
index 32ce1a0d761838b891861b01bcff16d596d0c4cb..578e2993cdf41ebc0d5b6457aeb71cd7d7b3c424 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace !Stream.anyMatch(x -> !(...)) with Stream.allMatch(...)" "false"
+// "Replace !Stream.anyMatch(x -> !(...)) with allMatch(...)" "false"
 
 import java.util.*;
 
index b2dfcd99b7ec73d5defdc9c0d01d73e91eb26703..19c55ab6cf3a1fe2d94c2a60aa75068ef0136b4d 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace !Stream.anyMatch(x -> !(...)) with Stream.allMatch(...)" "true"
+// "Replace !Stream.anyMatch(x -> !(...)) with allMatch(...)" "true"
 
 import java.util.*;
 
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedPrimitive.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedPrimitive.java
new file mode 100644 (file)
index 0000000..69a1848
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !LongStream.anyMatch(...) with noneMatch(...)" "true"
+
+import java.util.stream.*;
+
+class Test {
+  public boolean testAnyMatch(long[] data) {
+    if(!LongStream.of(data).anyM<caret>atch(i -> i > 0))
+      return true;
+  }
+}
\ No newline at end of file
index 2b01f91af7ac703e718a45037f58a1902e6850ed..f4133a02a7eb71f3167f9cfb1cfd9791112780d8 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace !Stream.noneMatch(...) with Stream.anyMatch(...)" "true"
+// "Replace !Stream.noneMatch(...) with anyMatch(...)" "true"
 
 import java.util.*;
 
index a37b825badfe24b04b6db37ca38edd3eb8e58364..b6de9b2677945e7fa85153947ef1f148f50b3cca 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace Stream.noneMatch(x -> !(...)) with Stream.allMatch(...)" "true"
+// "Replace Stream.noneMatch(x -> !(...)) with allMatch(...)" "true"
 
 import java.util.*;
 
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegatedPrimitive.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegatedPrimitive.java
new file mode 100644 (file)
index 0000000..6791ed9
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !IntStream.noneMatch(...) with anyMatch(...)" "true"
+
+import java.util.stream.*;
+
+class Test {
+  public boolean testNoneMatch(int[] data) {
+    if(!IntStream.of(data).noneM<caret>atch(i -> i > 0))
+      return true;
+  }
+}
\ No newline at end of file
index 69d4839095d8333a45d4cc01cec30ccd2afa6d61..c435409bbb78da69153da7fbe9297afe71115b16 100644 (file)
@@ -5,7 +5,7 @@ class A {
 
   void m() {
 
-    new StringTokenizer("asd", "\\\t\nqwerty!#2@$")
+    new StringTokenizer("asd", "\\\t\nqw<caret>erty!#2@$")
 
   }
 
index 8a992b117ff3ae4e0a55f9fa7c371fcd93c6933c..2e6c19f0a67fcb803d4d9b20e4061943fa1fb7c3 100644 (file)
@@ -1,8 +1,23 @@
+/*
+ * Copyright 2000-2016 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.codeInsight.daemon.quickFix;
 
 import com.intellij.codeInspection.LocalInspectionTool;
 import com.intellij.codeInspection.localCanBeFinal.LocalCanBeFinal;
-import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection;
 import com.intellij.pom.java.LanguageLevel;
 import org.jetbrains.annotations.NotNull;
 
@@ -15,7 +30,7 @@ public class SuppressLocalInspectionTest extends LightQuickFixParameterizedTestC
   @NotNull
   @Override
   protected LocalInspectionTool[] configureLocalInspectionTools() {
-    return new LocalInspectionTool[]{new LocalCanBeFinal()};
+    return new LocalInspectionTool[]{new LocalCanBeFinal(), new FieldCanBeLocalInspection()};
   }
 
   public void test() throws Exception { doAllTests(); }
index 20da5e4a31943162fc3a8dc61dd3f84070f550c1..a631a0eda761872042df1a3733c8f0ba6710268e 100644 (file)
@@ -29,6 +29,7 @@ import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
 import com.intellij.openapi.util.EmptyRunnable;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.*;
+import com.intellij.openapi.vfs.ex.http.HttpFileSystem;
 import com.intellij.testFramework.*;
 import gnu.trove.THashSet;
 import org.jetbrains.annotations.NotNull;
@@ -712,16 +713,20 @@ public class DirectoryIndexTest extends IdeaTestCase {
     assertIteratedContent(myFileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Collections.singletonList(fileRoot));
   }
 
-  private static void assertIteratedContent(ProjectFileIndex fileIndex,
+  private void assertIteratedContent(Module module, @Nullable List<VirtualFile> contains, @Nullable List<VirtualFile> doesntContain) {
+    assertIteratedContent(ModuleRootManager.getInstance(module).getFileIndex(), contains, doesntContain);
+    assertIteratedContent(myFileIndex, contains, doesntContain);
+  }
+
+  private static void assertIteratedContent(FileIndex fileIndex,
                                             @Nullable List<VirtualFile> contains,
                                             @Nullable List<VirtualFile> doesntContain) {
     final Set<VirtualFile> collected = new THashSet<>();
-    fileIndex.iterateContent(new ContentIterator() {
-      @Override
-      public boolean processFile(VirtualFile fileOrDir) {
-        collected.add(fileOrDir);
-        return true;
+    fileIndex.iterateContent(fileOrDir -> {
+      if (!collected.add(fileOrDir)) {
+        fail(fileOrDir + " visited twice");
       }
+      return true;
     });
     if (contains != null) assertContainsElements(collected, contains);
     if (doesntContain != null) assertDoesntContain(collected, doesntContain);
@@ -856,10 +861,67 @@ public class DirectoryIndexTest extends IdeaTestCase {
     assertTrue(myFileIndex.isInSource(fileSourceRoot));
   }
 
-  public void testContentRootUnderExcludedRoot() {
-    VirtualFile dirUnderExcluded = createChildDirectory(myExcludeDir, "generated");
-    PsiTestUtil.addSourceContentToRoots(myModule2, dirUnderExcluded);
-    checkInfo(dirUnderExcluded, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
+  public void testSourceContentRootsUnderExcludedRoot() {
+    VirtualFile contentRoot = createChildDirectory(myExcludeDir, "content");
+    PsiTestUtil.addContentRoot(myModule2, contentRoot);
+    checkInfo(contentRoot, myModule2, false, false, null, null, myModule2, myModule3);
+    VirtualFile excludedFile = createChildData(myExcludeDir, "excluded.txt");
+
+    VirtualFile sourceRoot = createChildDirectory(myExcludeDir, "src");
+    VirtualFile sourceFile = createChildData(sourceRoot, "source.txt");
+    PsiTestUtil.addSourceRoot(myModule2, sourceRoot);
+    assertEquals(myModule2Dir, assertInProject(sourceRoot).getContentRoot());
+    checkInfo(sourceRoot, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
+
+    VirtualFile contentSourceRoot = createChildDirectory(myExcludeDir, "content-src");
+    VirtualFile contentSourceFile = createChildData(sourceRoot, "content-source.txt");
+    PsiTestUtil.addSourceContentToRoots(myModule2, contentSourceRoot);
+    checkInfo(contentSourceRoot, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
+
+    assertIteratedContent(myModule2, Arrays.asList(sourceFile, contentSourceFile, sourceRoot, contentSourceRoot),
+                          Arrays.asList(excludedFile, myExcludeDir));
+  }
+
+  public void testSourceContentRootsUnderExcludedRootUnderSourceRoot() {
+    VirtualFile excluded = createChildDirectory(myModule2Dir, "excluded");
+    PsiTestUtil.addExcludedRoot(myModule2, excluded);
+    VirtualFile excludedFile = createChildData(excluded, "excluded.txt");
+
+    VirtualFile contentRoot = createChildDirectory(excluded, "content");
+    PsiTestUtil.addContentRoot(myModule2, contentRoot);
+    checkInfo(contentRoot, myModule2, false, false, null, null);
+
+    VirtualFile sourceRoot = createChildDirectory(excluded, "src");
+    PsiTestUtil.addSourceRoot(myModule2, sourceRoot);
+    VirtualFile sourceFile = createChildData(sourceRoot, "source.txt");
+    assertEquals(myModule2Dir, assertInProject(sourceRoot).getContentRoot());
+    checkInfo(sourceRoot, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
+
+    VirtualFile contentSourceRoot = createChildDirectory(excluded, "content-src");
+    VirtualFile contentSourceFile = createChildData(contentSourceRoot, "content-source.txt");
+    PsiTestUtil.addSourceContentToRoots(myModule2, contentSourceRoot);
+    checkInfo(contentSourceRoot, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
+
+    assertIteratedContent(myModule2, Arrays.asList(sourceFile, contentSourceFile, sourceRoot, contentSourceRoot),
+                          Arrays.asList(excludedFile, myExcludeDir));
+  }
+
+  public void testExcludedSourceRootUnderExcluded() {
+    VirtualFile excluded = createChildDirectory(myModule2Dir, "excluded");
+    PsiTestUtil.addExcludedRoot(myModule2, excluded);
+
+    VirtualFile src = createChildDirectory(excluded, "src");
+    VirtualFile sourceFile = createChildData(src, "src.txt");
+    PsiTestUtil.addSourceRoot(myModule2, src);
+    PsiTestUtil.addExcludedRoot(myModule2, src);
+    assertExcluded(src, myModule2);
+    assertIteratedContent(myModule2, null, Arrays.asList(sourceFile));
+  }
+
+  public void testSourceRootFromUnsupportedFileSystem() {
+    VirtualFile httpFile = HttpFileSystem.getInstance().findFileByPath("example.com");
+    PsiTestUtil.addSourceRoot(myModule, httpFile);
+    assertNotInProject(httpFile);
   }
 
   private void checkInfo(VirtualFile file,
index db33c980ab61c5dcbbc72e8eccb688ff055a72a3..60456ec77ef925b98fc740c1159f8f91606604a0 100644 (file)
@@ -336,7 +336,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
 
       @Override
       public void configureFromFileText(String name, String contents) throws IOException {
-        LightPlatformCodeInsightTestCase.configureFromFileText(name, contents);
+        LightPlatformCodeInsightTestCase.configureFromFileText(name, contents, true);
       }
 
       @Override
index c1020cadaa01155911a0feb7ef6ec561c7fd8ead..610290944fbea727ef3625f542bd0ea369090bf8 100644 (file)
@@ -67,128 +67,134 @@ public class BuildMain {
   @Nullable 
   private static PreloadedData ourPreloadedData;
 
-  public static void main(String[] args){
-    final long processStart = System.currentTimeMillis();
-    final String startMessage = "Build process started. Classpath: " + System.getProperty("java.class.path");
-    System.out.println(startMessage);
-    LOG.info(startMessage);
-    
-    final String host = args[HOST_ARG];
-    final int port = Integer.parseInt(args[PORT_ARG]);
-    final UUID sessionId = UUID.fromString(args[SESSION_ID_ARG]);
-    @SuppressWarnings("ConstantConditions")
-    final File systemDir = new File(FileUtil.toCanonicalPath(args[SYSTEM_DIR_ARG]));
-    Utils.setSystemRoot(systemDir);
-
-    final long connectStart = System.currentTimeMillis();
-    // IDEA-123132, let's try again
-    for (int attempt = 0; attempt < 3; attempt++) {
-      try {
-        ourEventLoopGroup = new NioEventLoopGroup(1, SharedThreadPool.getInstance());
-        break;
-      }
-      catch (IllegalStateException e) {
-        if (attempt == 2) {
-          printErrorAndExit(host, port, e);
-          return;
+  public static void main(String[] args) throws Throwable{
+    try {
+      final long processStart = System.currentTimeMillis();
+      final String startMessage = "Build process started. Classpath: " + System.getProperty("java.class.path");
+      System.out.println(startMessage);
+      LOG.info(startMessage);
+
+      final String host = args[HOST_ARG];
+      final int port = Integer.parseInt(args[PORT_ARG]);
+      final UUID sessionId = UUID.fromString(args[SESSION_ID_ARG]);
+      @SuppressWarnings("ConstantConditions")
+      final File systemDir = new File(FileUtil.toCanonicalPath(args[SYSTEM_DIR_ARG]));
+      Utils.setSystemRoot(systemDir);
+
+      final long connectStart = System.currentTimeMillis();
+      // IDEA-123132, let's try again
+      for (int attempt = 0; attempt < 3; attempt++) {
+        try {
+          ourEventLoopGroup = new NioEventLoopGroup(1, SharedThreadPool.getInstance());
+          break;
         }
-        else {
-          LOG.warn("Cannot create event loop, attempt #" + attempt, e);
-          try {
-            //noinspection BusyWait
-            Thread.sleep(10 * (attempt + 1));
+        catch (IllegalStateException e) {
+          if (attempt == 2) {
+            printErrorAndExit(host, port, e);
+            return;
           }
-          catch (InterruptedException ignored) {
+          else {
+            LOG.warn("Cannot create event loop, attempt #" + attempt, e);
+            try {
+              //noinspection BusyWait
+              Thread.sleep(10 * (attempt + 1));
+            }
+            catch (InterruptedException ignored) {
+            }
           }
         }
       }
-    }
-
-    final Bootstrap bootstrap = new Bootstrap().group(ourEventLoopGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer() {
-      @Override
-      protected void initChannel(Channel channel) throws Exception {
-        channel.pipeline().addLast(new ProtobufVarint32FrameDecoder(),
-                                   new ProtobufDecoder(CmdlineRemoteProto.Message.getDefaultInstance()),
-                                   new ProtobufVarint32LengthFieldPrepender(),
-                                   new ProtobufEncoder(),
-                                   new MyMessageHandler(sessionId));
-      }
-    }).option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true);
 
-    final ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)).awaitUninterruptibly();
+      final Bootstrap bootstrap = new Bootstrap().group(ourEventLoopGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer() {
+        @Override
+        protected void initChannel(Channel channel) throws Exception {
+          channel.pipeline().addLast(new ProtobufVarint32FrameDecoder(),
+                                     new ProtobufDecoder(CmdlineRemoteProto.Message.getDefaultInstance()),
+                                     new ProtobufVarint32LengthFieldPrepender(),
+                                     new ProtobufEncoder(),
+                                     new MyMessageHandler(sessionId));
+        }
+      }).option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true);
 
-    
-    final boolean success = future.isSuccess();
-    if (success) {
-      LOG.info("Connection to IDE established in " + (System.currentTimeMillis() - connectStart) + " ms");
+      final ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)).awaitUninterruptibly();
 
-      final String projectPathToPreload = System.getProperty(PRELOAD_PROJECT_PATH, null);
-      final String globalsPathToPreload = System.getProperty(PRELOAD_CONFIG_PATH, null); 
-      if (projectPathToPreload != null && globalsPathToPreload != null) {
-        final PreloadedData data = new PreloadedData();
-        ourPreloadedData = data;
-        try {
-          FileSystemUtil.getAttributes(projectPathToPreload); // this will pre-load all FS optimizations
 
-          final BuildRunner runner = new BuildRunner(new JpsModelLoaderImpl(projectPathToPreload, globalsPathToPreload, null));
-          data.setRunner(runner);
+      final boolean success = future.isSuccess();
+      if (success) {
+        LOG.info("Connection to IDE established in " + (System.currentTimeMillis() - connectStart) + " ms");
 
-          final File dataStorageRoot = Utils.getDataStorageRoot(projectPathToPreload);
-          final BuildFSState fsState = new BuildFSState(false);
-          final ProjectDescriptor pd = runner.load(new MessageHandler() {
-            @Override
-            public void processMessage(BuildMessage msg) {
-              data.addMessage(msg);
-            }
-          }, dataStorageRoot, fsState);
-          data.setProjectDescriptor(pd);
-          
+        final String projectPathToPreload = System.getProperty(PRELOAD_PROJECT_PATH, null);
+        final String globalsPathToPreload = System.getProperty(PRELOAD_CONFIG_PATH, null);
+        if (projectPathToPreload != null && globalsPathToPreload != null) {
+          final PreloadedData data = new PreloadedData();
+          ourPreloadedData = data;
           try {
-            final File fsStateFile = new File(dataStorageRoot, BuildSession.FS_STATE_FILE);
-            final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(fsStateFile)));
+            FileSystemUtil.getAttributes(projectPathToPreload); // this will pre-load all FS optimizations
+
+            final BuildRunner runner = new BuildRunner(new JpsModelLoaderImpl(projectPathToPreload, globalsPathToPreload, null));
+            data.setRunner(runner);
+
+            final File dataStorageRoot = Utils.getDataStorageRoot(projectPathToPreload);
+            final BuildFSState fsState = new BuildFSState(false);
+            final ProjectDescriptor pd = runner.load(new MessageHandler() {
+              @Override
+              public void processMessage(BuildMessage msg) {
+                data.addMessage(msg);
+              }
+            }, dataStorageRoot, fsState);
+            data.setProjectDescriptor(pd);
+
             try {
-              final int version = in.readInt();
-              if (version == BuildFSState.VERSION) {
-                final long savedOrdinal = in.readLong();
-                final boolean hasWorkToDo = in.readBoolean();// must skip "has-work-to-do" flag
-                fsState.load(in, pd.getModel(), pd.getBuildRootIndex());
-                data.setFsEventOrdinal(savedOrdinal);
-                data.setHasHasWorkToDo(hasWorkToDo);
+              final File fsStateFile = new File(dataStorageRoot, BuildSession.FS_STATE_FILE);
+              final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(fsStateFile)));
+              try {
+                final int version = in.readInt();
+                if (version == BuildFSState.VERSION) {
+                  final long savedOrdinal = in.readLong();
+                  final boolean hasWorkToDo = in.readBoolean();// must skip "has-work-to-do" flag
+                  fsState.load(in, pd.getModel(), pd.getBuildRootIndex());
+                  data.setFsEventOrdinal(savedOrdinal);
+                  data.setHasHasWorkToDo(hasWorkToDo);
+                }
+              }
+              finally {
+                in.close();
               }
             }
-            finally {
-              in.close();
+            catch (FileNotFoundException ignored) {
+            }
+            catch (IOException e) {
+              LOG.info("Error pre-loading FS state", e);
+              fsState.clearAll();
             }
-          }
-          catch (FileNotFoundException ignored) {
-          }
-          catch (IOException e) {
-            LOG.info("Error pre-loading FS state", e);
-            fsState.clearAll();
-          }
 
-          // preloading target configurations
-          final BuildTargetsState targetsState = pd.getTargetsState();
-          for (BuildTarget<?> target : pd.getBuildTargetIndex().getAllTargets()) {
-            targetsState.getTargetConfiguration(target);
-          }
+            // preloading target configurations
+            final BuildTargetsState targetsState = pd.getTargetsState();
+            for (BuildTarget<?> target : pd.getBuildTargetIndex().getAllTargets()) {
+              targetsState.getTargetConfiguration(target);
+            }
 
-          BuilderRegistry.getInstance();
+            BuilderRegistry.getInstance();
 
-          LOG.info("Pre-loaded process ready in " + (System.currentTimeMillis() - processStart) + " ms");
+            LOG.info("Pre-loaded process ready in " + (System.currentTimeMillis() - processStart) + " ms");
+          }
+          catch (Throwable e) {
+            LOG.info("Failed to pre-load project " + projectPathToPreload, e);
+            // just failed to preload the project, the situation will be handled later, when real build starts
+          }
         }
-        catch (Throwable e) {
-          LOG.info("Failed to pre-load project " + projectPathToPreload, e);
-          // just failed to preload the project, the situation will be handled later, when real build starts
+        else if (projectPathToPreload != null || globalsPathToPreload != null){
+          LOG.info("Skipping project pre-loading step: both paths to project configuration files and path to global settings must be specified");
         }
+        future.channel().writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createParamRequest()));
       }
-      else if (projectPathToPreload != null || globalsPathToPreload != null){
-        LOG.info("Skipping project pre-loading step: both paths to project configuration files and path to global settings must be specified");
+      else {
+        printErrorAndExit(host, port, future.cause());
       }
-      future.channel().writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createParamRequest()));
     }
-    else {
-      printErrorAndExit(host, port, future.cause());
+    catch (Throwable e) {
+      LOG.error(e);
+      throw e;
     }
   }
 
index bfb234ce59e4f5a8b439421bb9128220ed835582..ae17f7860549c2b204f5229e4af2a294e0ba3ffd 100644 (file)
@@ -26,6 +26,7 @@ import org.jetbrains.jps.model.java.JpsJavaExtensionService;
 import org.jetbrains.jps.model.java.JpsJavaModuleExtension;
 import org.jetbrains.jps.model.java.JpsJavaProjectExtension;
 import org.jetbrains.jps.model.module.JpsModule;
+import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
 import org.jetbrains.jps.util.JpsPathUtil;
 
 import java.io.File;
@@ -67,6 +68,11 @@ public class ModuleExcludeIndexImpl implements ModuleExcludeIndex {
         moduleContent.add(contentRoot);
         contentToModule.put(contentRoot, module);
       }
+      for (JpsModuleSourceRoot root : module.getSourceRoots()) {
+        File sourceRoot = root.getFile();
+        moduleContent.add(sourceRoot);
+        contentToModule.put(sourceRoot, module);
+      }
       myModuleToExcludesMap.put(module, moduleExcludes);
       myModuleToContentMap.put(module, moduleContent);
       myExcludedRoots.addAll(moduleExcludes);
diff --git a/jps/jps-builders/testData/output/sourceRootUnderExcluded/exc/src/B.java b/jps/jps-builders/testData/output/sourceRootUnderExcluded/exc/src/B.java
new file mode 100644 (file)
index 0000000..ef5f498
--- /dev/null
@@ -0,0 +1,3 @@
+class B {
+  A a;
+}
\ No newline at end of file
diff --git a/jps/jps-builders/testData/output/sourceRootUnderExcluded/sourceRootUnderExcluded.iml b/jps/jps-builders/testData/output/sourceRootUnderExcluded/sourceRootUnderExcluded.iml
new file mode 100644 (file)
index 0000000..5752f11
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/exc/src" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/exc" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/jps/jps-builders/testData/output/sourceRootUnderExcluded/sourceRootUnderExcluded.ipr b/jps/jps-builders/testData/output/sourceRootUnderExcluded/sourceRootUnderExcluded.ipr
new file mode 100644 (file)
index 0000000..8d3cc78
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/sourceRootUnderExcluded.iml" filepath="$PROJECT_DIR$/sourceRootUnderExcluded.iml" />
+    </modules>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>
+
diff --git a/jps/jps-builders/testData/output/sourceRootUnderExcluded/src/A.java b/jps/jps-builders/testData/output/sourceRootUnderExcluded/src/A.java
new file mode 100644 (file)
index 0000000..398760c
--- /dev/null
@@ -0,0 +1,3 @@
+class A {
+  B b;
+}
\ No newline at end of file
index 078a823fe18a3933b0209abe6e233faf5701ae33..9b0658807a0527f75ca90253f7feac0dead587ff 100644 (file)
@@ -69,6 +69,17 @@ class ModuleRebuildTest: JpsRebuildTestCase() {
     })
   }
 
+  fun testSourceRootUnderExcluded() {
+    doTest("sourceRootUnderExcluded/sourceRootUnderExcluded.ipr", fs {
+      dir("production") {
+        dir("sourceRootUnderExcluded") {
+          file("A.class")
+          file("B.class")
+        }
+      }
+    })
+  }
+
   fun testResourceCopying() {
     doTest("resourceCopying/resourceCopying.ipr", fs {
       dir("production") {
index a7858910f3a550fb0780a7ac1683620a26e6a2d6..abf828ad81957ffe21c518641c052b8a90d57e94 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.io.FileUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.jps.indices.impl.ModuleExcludeIndexImpl;
 import org.jetbrains.jps.model.JpsJavaModelTestCase;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
 import org.jetbrains.jps.model.java.JpsJavaModuleExtension;
 import org.jetbrains.jps.model.module.JpsModule;
 import org.jetbrains.jps.util.JpsPathUtil;
@@ -138,6 +139,24 @@ public class ModuleExcludeIndexTest extends JpsJavaModelTestCase {
     assertFalse(index.isExcludedFromModule(innerRoot, inner));
   }
 
+  public void testSourceRootUnderExcluded() {
+    File project = new File(myRoot, "project");
+    File exc = new File(project, "exc");
+    File src = new File(exc, "src");
+    JpsModule module = addModule();
+    addContentRoot(module, project);
+    addExcludedRoot(module, exc);
+    addSourceRoot(module, src);
+    assertNotExcluded(src);
+
+    addExcludedRoot(module, src);
+    assertExcluded(src);
+  }
+
+  private static void addSourceRoot(JpsModule module, File src) {
+    module.addSourceRoot(JpsPathUtil.pathToUrl(src.getAbsolutePath()), JavaSourceRootType.SOURCE);
+  }
+
   private static void addExcludedRoot(JpsModule module, File root) {
     module.getExcludeRootsList().addUrl(JpsPathUtil.pathToUrl(root.getAbsolutePath()));
   }
index b889494eb67a376d216aa5e2f261f1c39740ea2f..67caf00eebcaea491e391e2edb613a65bdac0bb0 100644 (file)
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2016 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.jetbrains.jsonSchema.impl;
 
 import com.intellij.json.psi.*;
@@ -244,7 +259,8 @@ class JsonBySchemaObjectAnnotator implements Annotator {
     }
 
     private boolean checkForEnum(JsonValue value, JsonSchemaObject schema) {
-      if (schema.getEnum() == null) return true;
+      //enum values + pattern -> don't check enum values
+      if (schema.getEnum() == null || schema.getPattern() != null)  return true;
       final String text = value.getText();
       final List<Object> objects = schema.getEnum();
       for (Object object : objects) {
index 45f32292dccad9eda2a822d4896ca0eecb5353d7..d4ed96a539b69a69ddc1abe05d186281f8b3f478 100644 (file)
@@ -65,7 +65,6 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
     <IncludePath>$(JdkPath)\include;$(JdkPath)\include\win32;$(IncludePath)</IncludePath>
-    <OutDir>..\..\..\bin\WinLauncher</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
@@ -80,7 +79,6 @@
     <LinkIncremental>false</LinkIncremental>
     <IncludePath>$(JdkPath)\include;$(JdkPath)\include\win32;$(IncludePath)</IncludePath>
     <TargetName>$(ProjectName)64</TargetName>
-    <OutDir>..\..\..\bin\WinLauncher</OutDir>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
index 2eccc8d703ed975e6961efbda61c5fb50a36b221..936ee405660f77cb98fcbf68f5c808901d2a967a 100644 (file)
@@ -129,7 +129,7 @@ public class ExternalDiffToolUtil {
 
     byte[] bytes = contentData.getBytes(charset);
 
-    byte[] bom = hasBom ? CharsetToolkit.getBom(charset) : null;
+    byte[] bom = hasBom ? CharsetToolkit.getPossibleBom(charset) : null;
     if (bom != null) {
       bytes = ArrayUtil.mergeArrays(bom, bytes);
     }
index 07108b11e771851019b153493f6e66cb412ff82b..46528820f11c9130ee053d2b153b5911351148a7 100644 (file)
Binary files a/platform/icons/src/nodes/finalMark.png and b/platform/icons/src/nodes/finalMark.png differ
index b352d6e880b2693b6549e9787d0ab49ee13f6f58..74a829a70f91a68d495a084e371d40ef220e27e0 100644 (file)
Binary files a/platform/icons/src/nodes/finalMark@2x.png and b/platform/icons/src/nodes/finalMark@2x.png differ
diff --git a/platform/icons/src/nodes/finalMark@2x_dark.png b/platform/icons/src/nodes/finalMark@2x_dark.png
deleted file mode 100644 (file)
index 7191a20..0000000
Binary files a/platform/icons/src/nodes/finalMark@2x_dark.png and /dev/null differ
diff --git a/platform/icons/src/nodes/finalMark_dark.png b/platform/icons/src/nodes/finalMark_dark.png
deleted file mode 100644 (file)
index e66746a..0000000
Binary files a/platform/icons/src/nodes/finalMark_dark.png and /dev/null differ
index 135aad51099a1b5f3c733bd0d2d0513594d82de7..0ac9c45018eae170ba7986f2f41e2dbf35b980c0 100644 (file)
Binary files a/platform/icons/src/nodes/locked.png and b/platform/icons/src/nodes/locked.png differ
index 69846f2ed0ae17928bd2f38dcbb220a832732907..668c1a1b3069b71002b6cca1366d9544f17451a9 100644 (file)
Binary files a/platform/icons/src/nodes/locked@2x.png and b/platform/icons/src/nodes/locked@2x.png differ
index 12ad583fa9c58f747b838e0e7e611c8d3eb6a140..ce689e25f50cada0b11caaeccdfd018ac71cecd4 100644 (file)
Binary files a/platform/icons/src/nodes/pinToolWindow.png and b/platform/icons/src/nodes/pinToolWindow.png differ
index aaa8dc561e981e47e576cdd75b5d32905f48620a..0054842d0c4e3270d7ea0d1d043bd44ee45a8959 100644 (file)
Binary files a/platform/icons/src/nodes/pinToolWindow@2x.png and b/platform/icons/src/nodes/pinToolWindow@2x.png differ
index 2cd063929071bad988736c48293208667b5f6302..d91297b007d4223f2cade403660471d004b7aadf 100644 (file)
Binary files a/platform/icons/src/nodes/staticMark.png and b/platform/icons/src/nodes/staticMark.png differ
index 5739660da994ab5ffd5c14bf57f527023e0cee93..48312d5fd4c207575ee52bd18c4807273aff1f8a 100644 (file)
Binary files a/platform/icons/src/nodes/staticMark@2x.png and b/platform/icons/src/nodes/staticMark@2x.png differ
index 12ad583fa9c58f747b838e0e7e611c8d3eb6a140..3a4da89092111239739636a159b5d126a4f27a85 100644 (file)
Binary files a/platform/icons/src/nodes/tabPin.png and b/platform/icons/src/nodes/tabPin.png differ
index aaa8dc561e981e47e576cdd75b5d32905f48620a..5236c0f58779a3559cbbd9bd0fa9d7fed0702834 100644 (file)
Binary files a/platform/icons/src/nodes/tabPin@2x.png and b/platform/icons/src/nodes/tabPin@2x.png differ
index dd459d0025f03c59cdb6ac0837bed4b6769d4fc9..d1cb6f7413d936508b25c1cec89df45adf2862e9 100644 (file)
Binary files a/platform/icons/src/toolwindows/toolWindowChanges.png and b/platform/icons/src/toolwindows/toolWindowChanges.png differ
index c7474de5c719e8b08bedeb8b922323eab7877793..fa63ee8e675860c499c275fb1b24cc24dde87fd2 100644 (file)
Binary files a/platform/icons/src/toolwindows/toolWindowChanges@2x.png and b/platform/icons/src/toolwindows/toolWindowChanges@2x.png differ
index 470142ff90919e4efb19c175cd2c3448ec8b550d..ab35ec6f9d85257bf445dc5696ef3c85cdcb2d5e 100644 (file)
Binary files a/platform/icons/src/toolwindows/toolWindowChanges@2x_dark.png and b/platform/icons/src/toolwindows/toolWindowChanges@2x_dark.png differ
index 8b6ff5a10d256d714728afd09064780792655ad0..952c31ce17a29933fb88d33e6d3929cdcc8f4b33 100644 (file)
Binary files a/platform/icons/src/toolwindows/toolWindowChanges_dark.png and b/platform/icons/src/toolwindows/toolWindowChanges_dark.png differ
index 0a2db890febe856e1056f6c58df8f4f47a69664b..3b0768415a0aa19ac24a16467d1ce6e90529d3eb 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.framework.detection;
 
 import com.intellij.facet.*;
 import com.intellij.framework.FrameworkType;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.roots.ModifiableRootModel;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -36,6 +37,8 @@ import java.util.Set;
  * @author nik
  */
 public abstract class FacetBasedFrameworkDetector<F extends Facet, C extends FacetConfiguration> extends FrameworkDetector {
+  private static final Logger LOG = Logger.getInstance(FacetBasedFrameworkDetector.class);
+
   protected FacetBasedFrameworkDetector(String detectorId) {
     super(detectorId);
   }
@@ -44,6 +47,7 @@ public abstract class FacetBasedFrameworkDetector<F extends Facet, C extends Fac
     super(detectorId, detectorVersion);
   }
 
+  @NotNull
   public abstract FacetType<F, C> getFacetType();
 
   /**
@@ -83,7 +87,10 @@ public abstract class FacetBasedFrameworkDetector<F extends Facet, C extends Fac
 
   @Override
   public FrameworkType getFrameworkType() {
-    return createFrameworkType(getFacetType());
+    FacetType<F, C> type = getFacetType();
+    //noinspection ConstantConditions todo[nik] remove later: this is added to find implementations which incorrectly return 'null' from 'getFacetType'
+    LOG.assertTrue(type != null, "'getFacetType' returns 'null' in " + getClass());
+    return createFrameworkType(type);
   }
 
   static FrameworkType createFrameworkType(final FacetType<?, ?> facetType) {
@@ -104,7 +111,7 @@ public abstract class FacetBasedFrameworkDetector<F extends Facet, C extends Fac
     private final FacetType<?, ?> myFacetType;
     private final Icon myIcon;
 
-    public FacetBasedFrameworkType(FacetType<?, ?> facetType) {
+    public FacetBasedFrameworkType(@NotNull FacetType<?, ?> facetType) {
       super(facetType.getStringId());
       myFacetType = facetType;
       final Icon icon = myFacetType.getIcon();
index 0c5d26fdaf1568414c2cc3576523ce0b1bc73dde..422bc7ba2af136e069fa42295575edb1fe3244d4 100644 (file)
@@ -105,7 +105,7 @@ public abstract class MarkRootActionBase extends DumbAwareAction {
   @Override
   public void update(AnActionEvent e) {
     RootsSelection selection = getSelection(e);
-    doUpdate(e, e.getData(LangDataKeys.MODULE), selection);
+    doUpdate(e, selection.myModule, selection);
   }
 
   protected void doUpdate(@NotNull AnActionEvent e, @Nullable Module module, @NotNull RootsSelection selection) {
@@ -121,21 +121,16 @@ public abstract class MarkRootActionBase extends DumbAwareAction {
     Module module = getModule(e, files);
     if (module == null) return RootsSelection.EMPTY;
 
-    RootsSelection selection = new RootsSelection();
+    RootsSelection selection = new RootsSelection(module);
     final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex();
     for (VirtualFile file : files) {
       if (!file.isDirectory()) {
         return RootsSelection.EMPTY;
       }
-      if (!fileIndex.isInContent(file)) {
-        ExcludeFolder excludeFolder = ProjectRootsUtil.findExcludeFolder(module, file);
-        if (excludeFolder != null) {
-          selection.mySelectedExcludeRoots.add(excludeFolder);
-          continue;
-        }
-        else {
-          return RootsSelection.EMPTY;
-        }
+      ExcludeFolder excludeFolder = ProjectRootsUtil.findExcludeFolder(module, file);
+      if (excludeFolder != null) {
+        selection.mySelectedExcludeRoots.add(excludeFolder);
+        continue;
       }
       SourceFolder folder = ProjectRootsUtil.findSourceFolder(module, file);
       if (folder != null) {
@@ -180,7 +175,12 @@ public abstract class MarkRootActionBase extends DumbAwareAction {
   }
 
   public static class RootsSelection {
-    public static final RootsSelection EMPTY = new RootsSelection();
+    public static final RootsSelection EMPTY = new RootsSelection(null);
+    public final Module myModule;
+
+    public RootsSelection(Module module) {
+      myModule = module;
+    }
 
     public List<SourceFolder> mySelectedRoots = new ArrayList<>();
     public List<ExcludeFolder> mySelectedExcludeRoots = new ArrayList<>();
index 0376ef6b2a480f680b624a58933f091135433715..126765c510a65b741bdca095185d65459ce06ccb 100644 (file)
@@ -33,6 +33,7 @@ import com.intellij.psi.PsiManager;
 import com.intellij.ui.UIBundle;
 import com.intellij.ui.awt.RelativePoint;
 import com.intellij.util.Consumer;
+import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -47,12 +48,7 @@ public class TogglePopupHintsPanel extends EditorBasedWidget implements StatusBa
   public TogglePopupHintsPanel(@NotNull final Project project) {
     super(project);
     myCurrentIcon = AllIcons.Ide.HectorNo;
-    myConnection.subscribe(PowerSaveMode.TOPIC, new PowerSaveMode.Listener() {
-      @Override
-      public void powerSaveStateChanged() {
-        updateStatus();
-      }
-    });
+    myConnection.subscribe(PowerSaveMode.TOPIC, this::updateStatus);
   }
 
   @Override
@@ -115,10 +111,11 @@ public class TogglePopupHintsPanel extends EditorBasedWidget implements StatusBa
   }
 
   public void updateStatus() {
-    updateStatus(getCurrentFile());
+    UIUtil.invokeLaterIfNeeded(() -> updateStatus(getCurrentFile()));
   }
 
   private void updateStatus(PsiFile file) {
+    if (isDisposed()) return;
     if (isStateChangeable(file)) {
       if (PowerSaveMode.isEnabled()) {
         myCurrentIcon = AllIcons.Ide.HectorNo;
index 40531f53318c371fce1b2847a47b29695c449556..4d035cd990fbfc5a4656923a4c7232c02d3fffa9 100644 (file)
@@ -830,18 +830,18 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co
 
       // 1. Strikeout effect
       if (attributes.isStrikeout() && !attributes.isSearchMatch()) {
-        EffectPainter.STRIKE_THROUGH.paint(g, offset, textBaseline, fragmentWidth, getCharHeight(g), null);
+        EffectPainter.STRIKE_THROUGH.paint(g, offset, textBaseline, fragmentWidth, getCharHeight(g), font);
       }
       // 2. Waved effect
       if (attributes.isWaved()) {
         if (attributes.getWaveColor() != null) {
           g.setColor(attributes.getWaveColor());
         }
-        EffectPainter.WAVE_UNDERSCORE.paint(g, offset, textBaseline + 1, fragmentWidth, Math.max(2, metrics.getDescent()), null);
+        EffectPainter.WAVE_UNDERSCORE.paint(g, offset, textBaseline + 1, fragmentWidth, Math.max(2, metrics.getDescent()), font);
       }
       // 3. Underline
       if (attributes.isUnderline()) {
-        EffectPainter.LINE_UNDERSCORE.paint(g, offset, textBaseline, fragmentWidth, metrics.getDescent(), null);
+        EffectPainter.LINE_UNDERSCORE.paint(g, offset, textBaseline, fragmentWidth, metrics.getDescent(), font);
       }
       // 4. Bold Dotted Line
       if (attributes.isBoldDottedLine()) {
@@ -885,7 +885,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co
       g.drawString(text, x1, baseline);
 
       if (((SimpleTextAttributes)info[5]).isStrikeout()) {
-        EffectPainter.STRIKE_THROUGH.paint(g, x1, baseline, x2 - x1, getCharHeight(g), null);
+        EffectPainter.STRIKE_THROUGH.paint(g, x1, baseline, x2 - x1, getCharHeight(g), g.getFont());
       }
     }
     return offset;
index 0b48426310c6f8a7293d0df09591af85ee91e324..632edb25cf58775d22941170759bb1ac516ecbf9 100644 (file)
@@ -15,7 +15,6 @@
  */
 package com.intellij.ui.paint;
 
-import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.util.JBHiDPIScaledImage;
 import com.intellij.util.ui.JBUI;
@@ -24,6 +23,7 @@ import com.intellij.util.ui.UIUtil;
 import com.intellij.util.ui.WavePainter;
 
 import java.awt.*;
+import java.awt.font.LineMetrics;
 import java.awt.geom.*;
 import java.awt.image.BufferedImage;
 import java.util.concurrent.ConcurrentHashMap;
@@ -31,7 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
 /**
  * @author Sergey.Malenkov
  */
-public enum EffectPainter implements RegionPainter<Paint> {
+public enum EffectPainter implements RegionPainter<Font> {
   /**
    * @see com.intellij.openapi.editor.markup.EffectType#LINE_UNDERSCORE
    */
@@ -44,17 +44,15 @@ public enum EffectPainter implements RegionPainter<Paint> {
      * @param y      text baseline
      * @param width  text width
      * @param height available space under text
-     * @param paint  optional color patterns
+     * @param font   optional font to calculate line metrics
      */
     @Override
-    public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
+    public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
       if (!Registry.is("ide.text.effect.new")) {
-        if (paint != null) g.setPaint(paint);
         g.drawLine(x, y + 1, x + width, y + 1);
       }
       else if (width > 0 && height > 0) {
-        if (paint != null) g.setPaint(paint);
-        drawLineUnderscore(g, x, y, width, height, 1, this);
+        drawLineUnderscore(g, x, y, width, height, font, 1, this);
       }
     }
   },
@@ -70,18 +68,16 @@ public enum EffectPainter implements RegionPainter<Paint> {
      * @param y      text baseline
      * @param width  text width
      * @param height available space under text
-     * @param paint  optional color patterns
+     * @param font   optional font to calculate line metrics
      */
     @Override
-    public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
+    public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
       if (!Registry.is("ide.text.effect.new")) {
-        if (paint != null) g.setPaint(paint);
         int h = JBUI.scale(Registry.intValue("editor.bold.underline.height", 2));
         g.fillRect(x, y, width, h);
       }
       else if (width > 0 && height > 0) {
-        if (paint != null) g.setPaint(paint);
-        drawLineUnderscore(g, x, y, width, height, 2, this);
+        drawLineUnderscore(g, x, y, width, height, font, 2, this);
       }
     }
   },
@@ -97,16 +93,12 @@ public enum EffectPainter implements RegionPainter<Paint> {
      * @param y      text baseline
      * @param width  text width
      * @param height available space under text
-     * @param paint  optional color patterns
+     * @param font   optional font to calculate line metrics
      */
     @Override
-    public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
-      if (!Registry.is("ide.text.effect.new")) {
-        UIUtil.drawBoldDottedLine(g, x, x + width, SystemInfo.isMac ? y : y + 1, g.getColor(), (Color)paint, false);
-      }
-      else if (width > 0 && height > 0) {
-        if (paint != null) g.setPaint(paint);
-        drawLineUnderscore(g, x, y, width, height, 2, this);
+    public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
+      if (width > 0 && height > 0) {
+        drawLineUnderscore(g, x, y, width, height, font, 2, this);
       }
     }
   },
@@ -122,16 +114,15 @@ public enum EffectPainter implements RegionPainter<Paint> {
      * @param y      text baseline
      * @param width  text width
      * @param height available space under text
-     * @param paint  optional color patterns
+     * @param font   optional font to calculate line metrics
      */
     @Override
-    public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
+    public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
       if (!Registry.is("ide.text.effect.new")) {
-        if (paint != null) g.setPaint(paint);
         WavePainter.forColor(g.getColor()).paint(g, x, x + width, y + height);
       }
       else if (width > 0 && height > 0) {
-        Cached.WAVE_UNDERSCORE.paint(g, x, y, width, height, paint);
+        Cached.WAVE_UNDERSCORE.paint(g, x, y, width, height, null);
       }
     }
   },
@@ -147,13 +138,21 @@ public enum EffectPainter implements RegionPainter<Paint> {
      * @param y      text baseline
      * @param width  text width
      * @param height text height
-     * @param paint  optional color patterns
+     * @param font   optional font to calculate line metrics
      */
     @Override
-    public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
+    public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
       if (width > 0 && height > 0) {
-        if (paint != null) g.setPaint(paint);
-        drawLineCentered(g, x, y - height, width, height, 1, this);
+        if (!Registry.is("ide.text.effect.new.metrics")) {
+          drawLineCentered(g, x, y - height, width, height, 1, this);
+        }
+        else {
+          if (font == null) font = g.getFont();
+          LineMetrics metrics = font.getLineMetrics("", g.getFontRenderContext());
+          int offset = (int)(0.5 - metrics.getStrikethroughOffset());
+          int thickness = Math.max(1, (int)(0.5 + metrics.getStrikethroughThickness()));
+          drawLine(g, x, y - offset, width, thickness, this);
+        }
       }
     }
   };
@@ -162,16 +161,28 @@ public enum EffectPainter implements RegionPainter<Paint> {
     return height > 7 && Registry.is("ide.text.effect.new.scale") ? height >> 1 : 3;
   }
 
-  private static void drawLineUnderscore(Graphics2D g, int x, int y, int width, int height, int thickness, EffectPainter painter) {
-    if (height > 3) {
-      int max = getMaxHeight(height);
-      y += height - max;
-      height = max;
-      if (thickness > 1 && height > 3) {
-        thickness = JBUI.scale(thickness);
+  private static void drawLineUnderscore(Graphics2D g, int x, int y, int width, int height, Font font, int thickness,
+                                         EffectPainter painter) {
+    if (width > 0 && height > 0) {
+      if (Registry.is("ide.text.effect.new.metrics")) {
+        if (font == null) font = g.getFont();
+        LineMetrics metrics = font.getLineMetrics("", g.getFontRenderContext());
+        int offset = Math.max(1, (int)(0.5 + metrics.getUnderlineOffset()));
+        thickness = Math.max(thickness, (int)(0.5 + thickness * metrics.getUnderlineThickness()));
+        drawLine(g, x, y + offset, width, thickness, painter);
+      }
+      else {
+        if (height > 3) {
+          int max = getMaxHeight(height);
+          y += height - max;
+          height = max;
+          if (thickness > 1 && height > 3) {
+            thickness = JBUI.scale(thickness);
+          }
+        }
+        drawLineCentered(g, x, y, width, height, thickness, painter);
       }
     }
-    drawLineCentered(g, x, y, width, height, thickness, painter);
   }
 
   private static void drawLineCentered(Graphics2D g, int x, int y, int width, int height, int thickness, EffectPainter painter) {
@@ -180,6 +191,10 @@ public enum EffectPainter implements RegionPainter<Paint> {
       y += offset - (offset >> 1);
       height = thickness;
     }
+    drawLine(g, x, y, width, height, painter);
+  }
+
+  private static void drawLine(Graphics2D g, int x, int y, int width, int height, EffectPainter painter) {
     if (painter == BOLD_DOTTED_UNDERSCORE) {
       int dx = (x % height + height) % height;
       int w = width + dx;
diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hints/filtering/MethodMatcher.kt b/platform/platform-impl/src/com/intellij/codeInsight/hints/filtering/MethodMatcher.kt
new file mode 100644 (file)
index 0000000..32cfbfd
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2000-2016 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.codeInsight.hints.filtering
+
+import com.intellij.openapi.util.Couple
+
+
+interface ParamMatcher {
+  fun isMatching(paramNames: List<String>): Boolean
+}
+
+interface MethodMatcher {
+  fun isMatching(fullyQualifiedMethodName: String, paramNames: List<String>): Boolean
+}
+
+object AnyParamMatcher: ParamMatcher {
+  override fun isMatching(paramNames: List<String>) = true
+}
+
+class StringParamMatcher(private val paramMatchers: List<StringMatcher>): ParamMatcher {
+  override fun isMatching(paramNames: List<String>): Boolean {
+    if (paramNames.size != paramMatchers.size) {
+      return false
+    }
+
+    return paramMatchers
+        .zip(paramNames)
+        .find { !it.first.isMatching(it.second) } == null
+  }
+}
+
+class Matcher(private val methodNameMatcher: StringMatcher, 
+              private val paramMatchers: ParamMatcher): MethodMatcher 
+{
+  override fun isMatching(fullyQualifiedMethodName: String, paramNames: List<String>): Boolean {
+    return methodNameMatcher.isMatching(fullyQualifiedMethodName) && paramMatchers.isMatching(paramNames)
+  }
+}
+
+object MatcherConstructor {
+
+  fun extract(matcher: String): Couple<String>? {
+    val trimmedMatcher = matcher.trim()
+    if (trimmedMatcher.isEmpty()) return null
+
+    val index = trimmedMatcher.indexOf('(')
+    if (index < 0) {
+      return Couple(trimmedMatcher, "")
+    }
+    else if (index == 0) {
+      return Couple("", trimmedMatcher)
+    }
+
+    val methodMatcher = trimmedMatcher.substring(0, index)
+    val paramsMatcher = trimmedMatcher.substring(index)
+
+    return Couple(methodMatcher.trim(), paramsMatcher.trim())
+  }
+
+  private fun createParametersMatcher(paramsMatcher: String): ParamMatcher? {
+    if (paramsMatcher.length <= 2) return null
+
+    val paramsString = paramsMatcher.substring(1, paramsMatcher.length - 1)
+    val params = paramsString.split(',').map(String::trim)
+    if (params.find(String::isEmpty) != null) return null
+
+    val matchers = params.mapNotNull { StringMatcherBuilder.create(it) }
+    return if (matchers.size == params.size) StringParamMatcher(matchers) else null
+  }
+
+  fun createMatcher(matcher: String): Matcher? {
+    val pair = extract(matcher) ?: return null
+
+    val methodNameMatcher = StringMatcherBuilder.create(pair.first) ?: return null
+    val paramMatcher = if (pair.second.isEmpty()) AnyParamMatcher else createParametersMatcher(pair.second)
+    
+    return if (paramMatcher != null) Matcher(methodNameMatcher, paramMatcher) else null
+  }
+
+
+}
+
+
diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hints/filtering/StringMatcherBuilder.kt b/platform/platform-impl/src/com/intellij/codeInsight/hints/filtering/StringMatcherBuilder.kt
new file mode 100644 (file)
index 0000000..f86a617
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2016 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.codeInsight.hints.filtering
+
+interface StringMatcher {
+  fun isMatching(text: String): Boolean
+}
+
+class StringMatcherImpl(private val matcher: (String) -> Boolean) : StringMatcher {
+  override fun isMatching(text: String) = matcher(text)
+}
+
+object StringMatcherBuilder {
+
+  fun create(matcher: String): StringMatcher? {
+    if (matcher.isEmpty()) return StringMatcherImpl { true }
+
+    val asterisksCount = matcher.count { it == '*' }
+    if (asterisksCount > 1) return null
+    if (asterisksCount == 1) return createAsterisksMatcher(matcher)
+
+    return StringMatcherImpl { it == matcher }
+  }
+
+  private fun createAsterisksMatcher(matcher: String): StringMatcher? {
+    if (matcher == "*") {
+      return StringMatcherImpl { true }
+    }
+
+    if (matcher.startsWith('*')) {
+      val target = matcher.substring(1)
+      return StringMatcherImpl { it.endsWith(target) }
+    }
+
+    if (matcher.endsWith('*')) {
+      val target = matcher.substring(0, matcher.length - 1)
+      return StringMatcherImpl { it.startsWith(target) }
+    }
+
+    return null
+  }
+
+}
\ No newline at end of file
index 870585cb01dc8ebd925e90c2109b2f0a80dacf23..83bea60533a69b8540c899b029d6d6e5faedc0d6 100644 (file)
@@ -2456,21 +2456,26 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
       }
       if (attributes != null && attributes.getEffectColor() != null) {
         int y = visibleLineToY(visibleStartLine) + getAscent() + 1;
+        g.setColor(attributes.getEffectColor());
         if (attributes.getEffectType() == EffectType.WAVE_UNDERSCORE) {
-          EffectPainter.WAVE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(), attributes.getEffectColor());
+          EffectPainter.WAVE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(),
+                                              getColorsScheme().getFont(EditorFontType.PLAIN));
         }
         else if (attributes.getEffectType() == EffectType.BOLD_DOTTED_LINE) {
-          g.setColor(getBackgroundColor(attributes));
-          EffectPainter.BOLD_DOTTED_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(), attributes.getEffectColor());
+          EffectPainter.BOLD_DOTTED_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(),
+                                                     getColorsScheme().getFont(EditorFontType.PLAIN));
         }
         else if (attributes.getEffectType() == EffectType.STRIKEOUT) {
-          EffectPainter.STRIKE_THROUGH.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getCharHeight(), attributes.getEffectColor());
+          EffectPainter.STRIKE_THROUGH.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getCharHeight(),
+                                             getColorsScheme().getFont(EditorFontType.PLAIN));
         }
         else if (attributes.getEffectType() == EffectType.BOLD_LINE_UNDERSCORE) {
-          EffectPainter.BOLD_LINE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(), attributes.getEffectColor());
+          EffectPainter.BOLD_LINE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(),
+                                                   getColorsScheme().getFont(EditorFontType.PLAIN));
         }
         else if (attributes.getEffectType() != EffectType.BOXED) {
-          EffectPainter.LINE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(), attributes.getEffectColor());
+          EffectPainter.LINE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(),
+                                              getColorsScheme().getFont(EditorFontType.PLAIN));
         }
       }
     }
@@ -3568,6 +3573,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
 
     if (effectColor != null) {
       final Color savedColor = g.getColor();
+      g.setColor(effectColor);
 
 //      myBorderEffect.flushIfCantProlong(g, this, effectType, effectColor);
       int xEnd = x;
@@ -3583,25 +3589,26 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
       }
 
       if (effectType == EffectType.LINE_UNDERSCORE) {
-        EffectPainter.LINE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(), effectColor);
-        g.setColor(savedColor);
+        EffectPainter.LINE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(),
+                                            getColorsScheme().getFont(EditorFontType.PLAIN));
       }
       else if (effectType == EffectType.BOLD_LINE_UNDERSCORE) {
-        EffectPainter.BOLD_LINE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(), effectColor);
-        g.setColor(savedColor);
+        EffectPainter.BOLD_LINE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(),
+                                                 getColorsScheme().getFont(EditorFontType.PLAIN));
       }
       else if (effectType == EffectType.STRIKEOUT) {
-        EffectPainter.STRIKE_THROUGH.paint((Graphics2D)g, xStart, y, xEnd - xStart, getCharHeight(), effectColor);
-        g.setColor(savedColor);
+        EffectPainter.STRIKE_THROUGH.paint((Graphics2D)g, xStart, y, xEnd - xStart, getCharHeight(),
+                                           getColorsScheme().getFont(EditorFontType.PLAIN));
       }
       else if (effectType == EffectType.WAVE_UNDERSCORE) {
-        EffectPainter.WAVE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(), effectColor);
-        g.setColor(savedColor);
+        EffectPainter.WAVE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(),
+                                            getColorsScheme().getFont(EditorFontType.PLAIN));
       }
       else if (effectType == EffectType.BOLD_DOTTED_LINE) {
-        g.setColor(getBackgroundColor());
-        EffectPainter.BOLD_DOTTED_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(), effectColor);
+        EffectPainter.BOLD_DOTTED_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(),
+                                                   getColorsScheme().getFont(EditorFontType.PLAIN));
       }
+      g.setColor(savedColor);
     }
 
     return x;
index 61ba33408d260b86b889a886385040aca3bfb448..986bdac24bb5bbad2282b3cd0859cc1d20d252a0 100644 (file)
@@ -431,26 +431,30 @@ class EditorPainter implements TextDrawingCallback {
   }
 
   private void paintTextEffect(Graphics2D g, float xFrom, float xTo, int y, Color effectColor, EffectType effectType, boolean allowBorder) {
+    g.setColor(effectColor);
     int xStart = (int)xFrom;
     int xEnd = (int)xTo;
     if (effectType == EffectType.LINE_UNDERSCORE) {
-      EffectPainter.LINE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(), effectColor);
+      EffectPainter.LINE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(),
+                                          myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
     }
     else if (effectType == EffectType.BOLD_LINE_UNDERSCORE) {
-      EffectPainter.BOLD_LINE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(), effectColor);
+      EffectPainter.BOLD_LINE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(),
+                                               myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
     }
     else if (effectType == EffectType.STRIKEOUT) {
-      EffectPainter.STRIKE_THROUGH.paint(g, xStart, y, xEnd - xStart, myView.getCharHeight(), effectColor);
+      EffectPainter.STRIKE_THROUGH.paint(g, xStart, y, xEnd - xStart, myView.getCharHeight(),
+                                         myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
     }
     else if (effectType == EffectType.WAVE_UNDERSCORE) {
-      EffectPainter.WAVE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(), effectColor);
+      EffectPainter.WAVE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(),
+                                          myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
     }
     else if (effectType == EffectType.BOLD_DOTTED_LINE) {
-      g.setColor(myEditor.getBackgroundColor());
-      EffectPainter.BOLD_DOTTED_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(), effectColor);
+      EffectPainter.BOLD_DOTTED_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(),
+                                                 myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
     }
     else if (allowBorder && (effectType == EffectType.BOXED || effectType == EffectType.ROUNDED_BOX)) {
-      g.setColor(effectColor);
       drawSimpleBorder(g, xStart, xEnd - 1, y - myView.getAscent(), effectType == EffectType.ROUNDED_BOX);
     }
   }
index 3200bf9f471cdad6a6aa5e00aa7559c346014d90..617fce5e27810c0ef48ad0aa46b5fc2f4f188a93 100644 (file)
@@ -192,6 +192,7 @@ public class SwingHelper {
 
   public static void adjustDialogSizeToFitPreferredSize(@NotNull DialogWrapper dialogWrapper) {
     JRootPane rootPane = dialogWrapper.getRootPane();
+    if (rootPane == null) return;
     Dimension componentSize = rootPane.getSize();
     Dimension componentPreferredSize = rootPane.getPreferredSize();
     if (componentPreferredSize.width <= componentSize.width && componentPreferredSize.height <= componentSize.height) {
index fcd5d571cb2e241080e30e34ae42be7823ab420a..1290f2bf384c8b337b3d3c8b5bf6463100a9c568 100644 (file)
@@ -1476,7 +1476,7 @@ group.Vcs.Browse.text=Browse VCS Repository
 action.Graph.print.reset=Reset
 action.MarkExcludeRoot.text=Excluded
 action.UnmarkRoot.text=Unmark Root
-action.MarkAsContentRoot.text=Cancel Exclusion
+action.MarkAsContentRoot.text=Not Excluded
 action.MarkAsContentRoot.description=Cancel exclusion for the selected directory to make its files processable by IDE's actions
 action.CreateLibraryFromFile.text=Add as Library...
 action.ImportModuleFromImlFile.text=Import Module
diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/hints/filtering/MatcherTest.kt b/platform/platform-tests/testSrc/com/intellij/codeInsight/hints/filtering/MatcherTest.kt
new file mode 100644 (file)
index 0000000..d842cd7
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2016 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.codeInsight.hints.filtering
+
+import junit.framework.TestCase
+import org.assertj.core.api.Assertions.assertThat
+
+class MatcherTest : TestCase() {
+
+  fun Matcher.assertIsMatching(fullyQualifiedMethodName: String, vararg params: String) {
+    assertThat(isMatching(fullyQualifiedMethodName, listOf(*params))).isTrue()
+  }
+
+  fun Matcher.assertNotMatching(fullyQualifiedMethodName: String, vararg params: String) {
+    assertThat(isMatching(fullyQualifiedMethodName, listOf(*params))).isFalse()
+  }
+
+  fun `test simple matcher`() {
+    val matcher = MatcherConstructor.createMatcher("*.String(old*, new*)")!!
+
+    matcher.assertIsMatching("java.lang.String", "oldValue", "newValue")
+    matcher.assertIsMatching("java.lang.String", "old", "new")
+
+    matcher.assertNotMatching("java.lang.String", "valueOld", "valueNew")
+    matcher.assertNotMatching("Boolean", "old", "new")
+  }
+
+  fun `test any single param method matcher`() {
+    val matchers = listOf(MatcherConstructor.createMatcher("*(*)")!!, MatcherConstructor.createMatcher("(*)")!!)
+    
+    matchers.forEach {
+      it.assertIsMatching("java.lang.String.indexOf", "ch")
+      it.assertIsMatching("java.lang.String.charAt", "index")
+      it.assertIsMatching("java.lang.Boolean.valueOf", "value")
+      it.assertNotMatching("java.lang.Boolean.substring", "from", "to")
+    }
+  }
+
+  fun `test any with key value`() {
+    val matcher = MatcherConstructor.createMatcher("*(key, value)")!!
+    matcher.assertIsMatching("java.util.Map.put", "key", "value")
+    matcher.assertIsMatching("java.util.HashMap.put", "key", "value")
+    matcher.assertIsMatching("java.util.HashMap.putIfNeeded", "key", "value")
+  }
+
+  fun `test couple contains`() {
+    val matcher = MatcherConstructor.createMatcher("*(first*, last*)")!!
+
+    matcher.assertIsMatching("java.util.Str.subs", "firstIndex", "lastIndex")
+    matcher.assertIsMatching("java.util.Str.subs", "first", "last")
+  }
+
+
+}
\ No newline at end of file
diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/hints/filtering/PatternExtractionTest.kt b/platform/platform-tests/testSrc/com/intellij/codeInsight/hints/filtering/PatternExtractionTest.kt
new file mode 100644 (file)
index 0000000..a72a87e
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2016 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.codeInsight.hints.filtering
+
+import junit.framework.TestCase
+import org.assertj.core.api.Assertions.assertThat
+
+class PatternExtractionTest : TestCase() {
+
+  fun String.assertMatcher(nameMatcher: String, paramsMatcher: String) {
+    val matcher = MatcherConstructor.extract(this)
+    if (matcher == null) {
+      assertThat(nameMatcher).isEmpty()
+      assertThat(paramsMatcher).isEmpty()
+      return
+    }
+
+    assertThat(nameMatcher).isEqualTo(matcher.first)
+    assertThat(paramsMatcher).isEqualTo(matcher.second)
+  }
+
+  fun `test match all methods from package`() {
+    val text = "java.lang.*"
+    text.assertMatcher("java.lang.*", "")
+  }
+
+  fun `test match all methods from class String`() {
+    val text = "java.lang.String.*"
+    text.assertMatcher("java.lang.String.*", "")
+  }
+
+  fun `test match all replace methods`() {
+    val text = "*.replace"
+    text.assertMatcher("*.replace", "")
+  }
+
+  fun `test match all replace methods with couple params`() {
+    val text = "*.replace(*, *)"
+    text.assertMatcher("*.replace", "(*, *)")
+  }
+
+  fun `test match only one replace method with couple params`() {
+    val text = "java.lang.String.replace(*,*)"
+    text.assertMatcher("java.lang.String.replace", "(*,*)")
+  }
+
+  fun `test match debug particular method`() {
+    val text = "org.logger.Log.debug(format,arg)"
+    text.assertMatcher("org.logger.Log.debug", "(format,arg)")
+  }
+
+  fun `test match method with single param`() {
+    val text = "class.method(*)"
+    text.assertMatcher("class.method", "(*)")
+  }
+
+  fun `test match all methods with single param`() {
+    val text = "*(*)"
+    text.assertMatcher("*", "(*)")
+  }
+
+  fun `test simplified params matcher`() {
+    val text = "(*)"
+    text.assertMatcher("", "(*)")
+  }
+
+  fun `test shit`() {
+    val text = "            foooo      (*)      "
+    text.assertMatcher("foooo", "(*)")
+  }
+
+}
\ No newline at end of file
diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/hints/filtering/StringMatchingTest.kt b/platform/platform-tests/testSrc/com/intellij/codeInsight/hints/filtering/StringMatchingTest.kt
new file mode 100644 (file)
index 0000000..982e1ed
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2016 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.codeInsight.hints.filtering
+
+import junit.framework.TestCase
+import org.assertj.core.api.Assertions.assertThat
+
+class StringMatchingTest : TestCase() {
+
+  fun com.intellij.codeInsight.hints.filtering.StringMatcher.assertMatches(vararg matched: String) {
+    matched.forEach { assertThat(isMatching(it)).isTrue() }
+  }
+
+  fun com.intellij.codeInsight.hints.filtering.StringMatcher.assertNotMatches(vararg unmatched: String) {
+    unmatched.forEach { assertThat(isMatching(it)).isFalse() }
+  }
+  
+  fun `test simple`() {
+    val matcher = com.intellij.codeInsight.hints.filtering.StringMatcherBuilder.create("aaa")!!
+    
+    matcher.assertMatches("aaa")
+    matcher.assertNotMatches("aaaa", "aab", "", "*", "a", "baaa")
+  }
+  
+  fun `test asterisks before`() {
+    val matcher = com.intellij.codeInsight.hints.filtering.StringMatcherBuilder.create("aaa*")!!
+    
+    matcher.assertMatches("aaa", "aaaa", "aaaaaa", "aaaqwe")
+    matcher.assertNotMatches("baaa", "nnaaa", "qweaaa")
+  }
+
+  fun `test asterisks after`() {
+    val matcher = com.intellij.codeInsight.hints.filtering.StringMatcherBuilder.create("*aaa")!!
+    
+    matcher.assertMatches("aaa", "aaaa", "baaa", "aawweraaa")
+    matcher.assertNotMatches("aaab", "aaabaa")
+  }
+  
+}
\ No newline at end of file
index c0ca9d99a3bd66f30d13a9b6e95778aea29725fc..25be05c4013fea9dc2e079bd0e55dbef4e51d276 100644 (file)
@@ -2,8 +2,10 @@ package com.intellij.openapi.roots.impl;
 
 import com.intellij.injected.editor.VirtualFileWindow;
 import com.intellij.openapi.fileTypes.FileTypeRegistry;
+import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.FileIndex;
+import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.vfs.VirtualFile;
 import org.jetbrains.annotations.NotNull;
 
@@ -33,4 +35,9 @@ public abstract class FileIndexBase implements FileIndex {
            !myFileTypeRegistry.isFileIgnored(file) &&
            isInSourceContent(file);
   }
+
+  @NotNull
+  protected static VirtualFile[][] getModuleContentAndSourceRoots(Module module) {
+    return new VirtualFile[][]{ModuleRootManager.getInstance(module).getContentRoots(), ModuleRootManager.getInstance(module).getSourceRoots()};
+  }
 }
index 1ea6a212a9c540aa76091fdb6027db47e7edace3..9871077f4f8fbbe39b45bf71194df66617153052 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileFilter;
+import com.intellij.openapi.vfs.VirtualFileWithId;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
@@ -45,23 +46,26 @@ public class ModuleFileIndexImpl extends FileIndexBase implements ModuleFileInde
 
   @Override
   public boolean iterateContent(@NotNull ContentIterator iterator) {
-    final List<VirtualFile> contentRoots = ApplicationManager.getApplication().runReadAction(new Computable<List<VirtualFile>>() {
-      @Override
-      public List<VirtualFile> compute() {
-        if (myModule.isDisposed()) return Collections.emptyList();
-        
-        List<VirtualFile> result = ContainerUtil.newArrayList();
-        for (VirtualFile contentRoot : ModuleRootManager.getInstance(myModule).getContentRoots()) {
-          VirtualFile parent = contentRoot.getParent();
+    final Set<VirtualFile> contentRoots = ApplicationManager.getApplication().runReadAction((Computable<Set<VirtualFile>>)() -> {
+      if (myModule.isDisposed()) return Collections.emptySet();
+
+      Set<VirtualFile> result = new LinkedHashSet<>();
+      VirtualFile[][] allRoots = getModuleContentAndSourceRoots(myModule);
+      for (VirtualFile[] roots : allRoots) {
+        for (VirtualFile root : roots) {
+          DirectoryInfo info = getInfoForFileOrDirectory(root);
+          if (!info.isInProject()) continue;
+
+          VirtualFile parent = root.getParent();
           if (parent != null) {
             DirectoryInfo parentInfo = myDirectoryIndex.getInfoForFile(parent);
             if (parentInfo.isInProject() && myModule.equals(parentInfo.getModule())) continue; // inner content - skip it
           }
-          result.add(contentRoot);
+          result.add(root);
         }
-
-        return result;
       }
+
+      return result;
     });
     for (VirtualFile contentRoot : contentRoots) {
       boolean finished = VfsUtilCore.iterateChildrenRecursively(contentRoot, myContentFilter, iterator);
index 1fadbde8a58ec946decbc909e974916ec7e595b8..f477dc6c04c8ec10f7a35b016cba6db45451e641 100644 (file)
@@ -38,6 +38,7 @@ import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
 import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
 
 import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -54,12 +55,7 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn
 
   @Override
   public boolean iterateContent(@NotNull ContentIterator iterator) {
-    Module[] modules = ApplicationManager.getApplication().runReadAction(new Computable<Module[]>() {
-      @Override
-      public Module[] compute() {
-        return ModuleManager.getInstance(myProject).getModules();
-      }
-    });
+    Module[] modules = ApplicationManager.getApplication().runReadAction((Computable<Module[]>)() -> ModuleManager.getInstance(myProject).getModules());
     for (final Module module : modules) {
       for (VirtualFile contentRoot : getRootsToIterate(module)) {
         boolean finished = VfsUtilCore.iterateChildrenRecursively(contentRoot, myContentFilter, iterator);
@@ -70,28 +66,27 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn
     return true;
   }
 
-  private List<VirtualFile> getRootsToIterate(final Module module) {
-    return ApplicationManager.getApplication().runReadAction(new Computable<List<VirtualFile>>() {
-      @Override
-      public List<VirtualFile> compute() {
-        if (module.isDisposed()) return Collections.emptyList();
+  private Set<VirtualFile> getRootsToIterate(final Module module) {
+    return ApplicationManager.getApplication().runReadAction((Computable<Set<VirtualFile>>)() -> {
+      if (module.isDisposed()) return Collections.emptySet();
 
-        List<VirtualFile> result = ContainerUtil.newArrayList();
-        for (VirtualFile contentRoot : ModuleRootManager.getInstance(module).getContentRoots()) {
-          DirectoryInfo info = getInfoForFileOrDirectory(contentRoot);
+      Set<VirtualFile> result = new LinkedHashSet<>();
+      for (VirtualFile[] roots : getModuleContentAndSourceRoots(module)) {
+        for (VirtualFile root : roots) {
+          DirectoryInfo info = getInfoForFileOrDirectory(root);
           if (!info.isInProject()) continue; // is excluded or ignored
           if (!module.equals(info.getModule())) continue; // maybe 2 modules have the same content root?
 
-          VirtualFile parent = contentRoot.getParent();
+          VirtualFile parent = root.getParent();
           if (parent != null) {
             DirectoryInfo parentInfo = getInfoForFileOrDirectory(parent);
             if (parentInfo.isInProject() && parentInfo.getModule() != null) continue;
           }
-          result.add(contentRoot);
+          result.add(root);
         }
-
-        return result;
       }
+
+      return result;
     });
   }
 
index 31831cc1b52e9bc0d3136cdd34dc412e4ed6e525..e0587269baa5171e283d154a41450f2db6c395ba 100644 (file)
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileWithId;
 import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
 import com.intellij.util.CollectionQuery;
 import com.intellij.util.Query;
@@ -179,6 +180,10 @@ public class RootIndex {
   }
 
   private static boolean ensureValid(@NotNull VirtualFile file, @NotNull Object container) {
+    if (!(file instanceof VirtualFileWithId)) {
+      //skip roots from unsupported file systems (e.g. http)
+      return false;
+    }
     if (!file.isValid()) {
       LOG.error("Invalid root " + file + " in " + container);
       return false;
@@ -367,7 +372,7 @@ public class RootIndex {
       @Nullable VirtualFile librarySourceRoot = myRootInfo.findLibraryRootInfo(roots, true);
       result.addAll(myRootInfo.getLibraryOrderEntries(roots, libraryClassRoot, librarySourceRoot, myLibClassRootEntries, myLibSourceRootEntries));
 
-      VirtualFile moduleContentRoot = myRootInfo.findModuleRootInfo(roots);
+      VirtualFile moduleContentRoot = myRootInfo.findNearestContentRoot(roots);
       if (moduleContentRoot != null) {
         ContainerUtil.addIfNotNull(result, myRootInfo.getModuleSourceEntry(roots, moduleContentRoot, myLibClassRootEntries));
       }
@@ -541,16 +546,39 @@ public class RootIndex {
       return result;
     }
 
+    /**
+     * Returns nearest content root for a file by its parent directories hierarchy. If the file is excluded (i.e. located under an excluded
+     * root and there are no source roots on the path to the excluded root) returns {@code null}.
+     */
     @Nullable
-    private VirtualFile findModuleRootInfo(@NotNull List<VirtualFile> hierarchy) {
+    private VirtualFile findNearestContentRoot(@NotNull List<VirtualFile> hierarchy) {
+      Collection<Module> sourceRootOwners = null;
+      boolean underExcludedSourceRoot = false;
       for (VirtualFile root : hierarchy) {
         Module module = contentRootOf.get(root);
         Module excludedFrom = excludedFromModule.get(root);
-        if (module != null && excludedFrom != module) {
+        if (module != null && (excludedFrom != module || underExcludedSourceRoot && sourceRootOwners.contains(module))) {
           return root;
         }
         if (excludedFrom != null || excludedFromProject.contains(root)) {
-          return null;
+          if (sourceRootOwners != null) {
+            underExcludedSourceRoot = true;
+          }
+          else {
+            return null;
+          }
+        }
+
+        if (!underExcludedSourceRoot && sourceRootOf.containsKey(root)) {
+          Collection<Module> modulesForSourceRoot = sourceRootOf.get(root);
+          if (!modulesForSourceRoot.isEmpty()) {
+            if (sourceRootOwners == null) {
+              sourceRootOwners = modulesForSourceRoot;
+            }
+            else {
+              sourceRootOwners = ContainerUtil.union(sourceRootOwners, modulesForSourceRoot);
+            }
+          }
         }
       }
       return null;
@@ -662,7 +690,7 @@ public class RootIndex {
   private static Pair<DirectoryInfo, String> calcDirectoryInfo(@NotNull final VirtualFile root,
                                                                @NotNull final List<VirtualFile> hierarchy,
                                                                @NotNull RootInfo info) {
-    VirtualFile moduleContentRoot = info.findModuleRootInfo(hierarchy);
+    VirtualFile moduleContentRoot = info.findNearestContentRoot(hierarchy);
     VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false);
     VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true);
     boolean inProject = moduleContentRoot != null || libraryClassRoot != null || librarySourceRoot != null;
index 255bdb8344808e99913b97b552d7d19e2c534c36..cd4c661c0f38defee8fdccb9f06f8525c1faf3a8 100644 (file)
@@ -1,10 +1,16 @@
 package com.intellij.remoteServer.configuration;
 
 import com.intellij.openapi.components.PersistentStateComponent;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * @author nik
  */
 public abstract class ServerConfiguration {
   public abstract PersistentStateComponent<?> getSerializer();
+
+  @Nullable
+  public String getCustomToolWindowId() {
+    return null;
+  }
 }
index f3c44c154990297cb042479bd5b80e18b4d69df7..a2ea8089463ed87855ea15920f207b8989b059a2 100644 (file)
@@ -17,12 +17,9 @@ package com.intellij.remoteServer.impl.runtime.ui;
 
 import com.intellij.ide.util.treeView.AbstractTreeNode;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
 import com.intellij.remoteServer.configuration.RemoteServer;
-import com.intellij.remoteServer.configuration.RemoteServersManager;
 import com.intellij.remoteServer.impl.runtime.ui.tree.TreeBuilderBase;
 import com.intellij.ui.treeStructure.Tree;
-import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -82,6 +79,6 @@ public class DefaultRemoteServersViewContribution extends RemoteServersViewContr
 
   @Override
   public List<RemoteServer<?>> getRemoteServers() {
-    return ContainerUtil.filter(RemoteServersManager.getInstance().getServers(), server -> server.getType().getCustomToolWindowId() == null);
+    return getRemoteServersByToolWindowId(null);
   }
 }
index 72f6768cba322a48c29049de2002b99f70d49902..5a59656748d7dee869866e95a231862688bde7b4 100644 (file)
@@ -18,10 +18,13 @@ package com.intellij.remoteServer.impl.runtime.ui;
 import com.intellij.ide.util.treeView.AbstractTreeNode;
 import com.intellij.openapi.project.Project;
 import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.remoteServer.configuration.RemoteServersManager;
 import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeNodeSelector;
 import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
 import com.intellij.remoteServer.runtime.ServerConnection;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.List;
 
@@ -58,4 +61,14 @@ public abstract class RemoteServersViewContribution extends RemoteServersViewCon
       }
     };
   }
+
+  public static String getRemoteServerToolWindowId(RemoteServer<?> server) {
+    String serverToolWindowId = server.getConfiguration().getCustomToolWindowId();
+    return serverToolWindowId != null ? serverToolWindowId : server.getType().getCustomToolWindowId();
+  }
+
+  protected static List<RemoteServer<?>> getRemoteServersByToolWindowId(@Nullable String toolWindowId) {
+    return ContainerUtil.filter(RemoteServersManager.getInstance().getServers(),
+                                server -> getRemoteServerToolWindowId(server) == toolWindowId);
+  }
 }
index e4bd3b0f7cd863214b5a23e7244dcf9d7fe73295..df77826516ae939aee076792e616ea95c88cc596 100644 (file)
@@ -52,7 +52,7 @@ public class RemoteServersViewImpl extends RemoteServersView {
   }
 
   private static String getToolWindowId(ServerConnection<?> connection) {
-    String customToolWindowId = connection.getServer().getType().getCustomToolWindowId();
+    String customToolWindowId = RemoteServersViewContribution.getRemoteServerToolWindowId(connection.getServer());
     return StringUtil.notNullize(customToolWindowId, DefaultServersToolWindowManager.WINDOW_ID);
   }
 }
index 8005327e8149872b2820b7ae02b655629c9de342..5f8310e103b78d7bc9bc6c2945e5acec08c92d92 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -474,6 +474,18 @@ public class EditorTestUtil {
       this.carets = carets;
       this.blockSelection = blockSelection;
     }
+
+    /**
+     * Returns true if current CaretAndSelectionState contains at least one caret or selection explicitly specified
+     */
+    public boolean hasExplicitCaret() {
+      if(carets.isEmpty()) return false;
+      if(blockSelection == null && carets.size() == 1) {
+        CaretInfo caret = carets.get(0);
+        return caret.position != null || caret.selection != null;
+      }
+      return true;
+    }
   }
 
   public static class CaretInfo {
diff --git a/platform/testFramework/src/com/intellij/testFramework/FailedTestDebugLogConsoleFolding.java b/platform/testFramework/src/com/intellij/testFramework/FailedTestDebugLogConsoleFolding.java
new file mode 100644 (file)
index 0000000..a9517fe
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2016 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.execution.ConsoleFolding;
+
+import java.util.List;
+
+public class FailedTestDebugLogConsoleFolding extends ConsoleFolding {
+  @Override
+  public boolean shouldFoldLine(String line) {
+    return line.indexOf(TestLoggerFactory.FAILED_TEST_DEBUG_OUTPUT_MARKER) != -1;
+  }
+
+  @Override
+  public String getPlaceholderText(List<String> lines) {
+    return " <Failed tests DEBUG log>";
+  }
+}
index e133b0146a5958823bf5f939995854c04d0fa4f8..2a35ff76b0e609c105bde83870d58c15c57d3ed0 100644 (file)
@@ -146,12 +146,28 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
    */
   @NotNull
   protected static Document configureFromFileText(@NonNls @NotNull final String fileName, @NonNls @NotNull final String fileText) {
+    return configureFromFileText(fileName, fileText, false);
+  }
+
+  /**
+   * Same as configureByFile but text is provided directly.
+   * @param fileName - name of the file.
+   * @param fileText - data file text.
+   * @param checkCaret - if true, if will be verified that file contains at least one caret or selection marker
+   */
+  @NotNull
+  protected static Document configureFromFileText(@NonNls @NotNull final String fileName,
+                                                  @NonNls @NotNull final String fileText,
+                                                  boolean checkCaret) {
     return new WriteCommandAction<Document>(null) {
       @Override
       protected void run(@NotNull Result<Document> result) throws Throwable {
         final Document fakeDocument = new DocumentImpl(fileText);
 
         EditorTestUtil.CaretAndSelectionState caretsState = EditorTestUtil.extractCaretAndSelectionMarkers(fakeDocument);
+        if(checkCaret) {
+          assertTrue("No caret specified in " + fileName, caretsState.hasExplicitCaret());
+        }
 
         String newFileText = fakeDocument.getText();
         Document document;
index 7f9752c9d06a52726b79b1c0f3bf7c5a4b955f4b..75f22b2e4e5f0c9c8a356efa064fe477e7b016e2 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.LineTokenizer;
 import com.intellij.openapi.util.text.StringUtil;
 import org.apache.log4j.*;
 import org.apache.log4j.spi.LoggingEvent;
@@ -145,6 +146,8 @@ public class TestLoggerFactory implements Logger.Factory {
 
   private static final StringWriter STRING_WRITER = new StringWriter();
   private static final StringBuffer BUFFER = STRING_WRITER.getBuffer();
+  static final char FAILED_TEST_DEBUG_OUTPUT_MARKER = '\u2003';
+  // inserted unicode whitespace to be able to tell these failed tests log lines from the others and fold them
   private static final WriterAppender APPENDER = new WriterAppender(new PatternLayout("%d{HH:mm:ss,SSS} %p %.30c - %m%n"), STRING_WRITER);
   private static final int MAX_BUFFER_LENGTH = 100000;
   private static final String CFQN = Category.class.getName();
@@ -165,8 +168,20 @@ public class TestLoggerFactory implements Logger.Factory {
   }
 
   public static void onTestFinished(boolean success) {
-    if (!success) {
-      System.err.println(BUFFER);
+    if (!success && BUFFER.length() != 0) {
+      if (UsefulTestCase.IS_UNDER_TEAMCITY) {
+        // print in one statement to avoid exception text cutting in between causing this fold to expand
+        BUFFER.insert(0, "##teamcity[blockOpened name='DEBUG log']\n");
+        BUFFER.append( "\n##teamcity[blockClosed name='DEBUG log']\n");
+        System.err.println(BUFFER);
+      }
+      else {
+        // mark each line in IDEA console with this hidden mark to be able to fold it automatically
+        String[] lines = LineTokenizer.tokenize(BUFFER, false, false);
+        String text = StringUtil.join(lines, FAILED_TEST_DEBUG_OUTPUT_MARKER + "\n");
+        if (!text.startsWith("\n")) text = "\n" + text;
+        System.err.println(text);
+      }
     }
     BUFFER.setLength(0);
   }
index 03d437856f27cd2f211ba9e1365fd24b2d5d904d..3a1526a700267fa836088bc0da68ff04df39b1e2 100644 (file)
@@ -830,6 +830,8 @@ ide.text.effect.new=true
 ide.text.effect.new.description=Enables new effect painter for text
 ide.text.effect.new.scale=true
 ide.text.effect.new.scale.description=Enables scalable effect painter for text
+ide.text.effect.new.metrics=true
+ide.text.effect.new.metrics.description=Use line metrics to calculate text offset in the effect painter
 
 ide.intellij.laf.win10.ui=false
 ide.intellij.laf.win10.ui.description=Enables Windows 10 look
index 8f2be85a9d4d8f0739092f6c6992ed1a52810c0b..249ff563b2d4453ce3a235f6fe5fd8f19caffb72 100644 (file)
@@ -783,7 +783,7 @@ public class AllIcons {
     public static final Icon DeleteContentFolderRollover = IconLoader.getIcon("/modules/deleteContentFolderRollover.png"); // 9x9
     public static final Icon DeleteContentRoot = IconLoader.getIcon("/modules/deleteContentRoot.png"); // 9x9
     public static final Icon DeleteContentRootRollover = IconLoader.getIcon("/modules/deleteContentRootRollover.png"); // 9x9
-    public static final Icon Edit = IconLoader.getIcon("/modules/edit.png"); // 14x14
+    public static final Icon Edit = IconLoader.getIcon("/modules/edit.png"); // 16x16
     public static final Icon EditFolder = IconLoader.getIcon("/modules/editFolder.png"); // 16x16
     public static final Icon ExcludedGeneratedRoot = IconLoader.getIcon("/modules/excludedGeneratedRoot.png"); // 16x16
     public static final Icon ExcludeRoot = IconLoader.getIcon("/modules/excludeRoot.png"); // 16x16
@@ -828,7 +828,7 @@ public class AllIcons {
     public static final Icon Annotationtype = IconLoader.getIcon("/nodes/annotationtype.png"); // 16x16
     public static final Icon AnonymousClass = IconLoader.getIcon("/nodes/anonymousClass.png"); // 16x16
     public static final Icon Artifact = IconLoader.getIcon("/nodes/artifact.png"); // 16x16
-    public static final Icon Aspect = IconLoader.getIcon("/nodes/aspect.png"); // 14x14
+    public static final Icon Aspect = IconLoader.getIcon("/nodes/aspect.png"); // 16x16
     public static final Icon C_plocal = IconLoader.getIcon("/nodes/c_plocal.png"); // 16x16
     public static final Icon C_private = IconLoader.getIcon("/nodes/c_private.png"); // 16x16
     public static final Icon C_protected = IconLoader.getIcon("/nodes/c_protected.png"); // 16x16
@@ -887,9 +887,9 @@ public class AllIcons {
       public static final Icon Component = IconLoader.getIcon("/nodes/jsf/component.png"); // 16x16
       public static final Icon Converter = IconLoader.getIcon("/nodes/jsf/converter.png"); // 16x16
       public static final Icon General = IconLoader.getIcon("/nodes/jsf/general.png"); // 16x16
-      public static final Icon GenericValue = IconLoader.getIcon("/nodes/jsf/genericValue.png"); // 18x18
+      public static final Icon GenericValue = IconLoader.getIcon("/nodes/jsf/genericValue.png"); // 16x16
       public static final Icon ManagedBean = IconLoader.getIcon("/nodes/jsf/managedBean.png"); // 16x16
-      public static final Icon NavigationCase = IconLoader.getIcon("/nodes/jsf/navigationCase.png"); // 18x18
+      public static final Icon NavigationCase = IconLoader.getIcon("/nodes/jsf/navigationCase.png"); // 16x16
       public static final Icon NavigationRule = IconLoader.getIcon("/nodes/jsf/navigationRule.png"); // 16x16
       public static final Icon Renderer = IconLoader.getIcon("/nodes/jsf/renderer.png"); // 16x16
       public static final Icon RenderKit = IconLoader.getIcon("/nodes/jsf/renderKit.png"); // 16x16
@@ -909,9 +909,9 @@ public class AllIcons {
     public static final Icon Module = IconLoader.getIcon("/nodes/Module.png"); // 16x16
     public static final Icon ModuleGroup = IconLoader.getIcon("/nodes/moduleGroup.png"); // 16x16
     public static final Icon NativeLibrariesFolder = IconLoader.getIcon("/nodes/nativeLibrariesFolder.png"); // 16x16
-    public static final Icon NewException = IconLoader.getIcon("/nodes/newException.png"); // 14x14
+    public static final Icon NewException = IconLoader.getIcon("/nodes/newException.png"); // 16x16
     public static final Icon NewFolder = IconLoader.getIcon("/nodes/newFolder.png"); // 16x16
-    public static final Icon NewParameter = IconLoader.getIcon("/nodes/newParameter.png"); // 14x14
+    public static final Icon NewParameter = IconLoader.getIcon("/nodes/newParameter.png"); // 16x16
     public static final Icon NodePlaceholder = IconLoader.getIcon("/nodes/nodePlaceholder.png"); // 16x16
     public static final Icon Package = IconLoader.getIcon("/nodes/package.png"); // 16x16
     public static final Icon Padlock = IconLoader.getIcon("/nodes/padlock.png"); // 16x16
index 178936acf6ec360136196e1674c8d65c17359685..b8f94ab9e12e928c719e52a4e131be912801bef3 100644 (file)
@@ -624,8 +624,12 @@ public class CharsetToolkit {
     return CHARSET_TO_MANDATORY_BOM.get(charset);
   }
 
+  /**
+   * @return BOM which can be associated with this charset, or null otherwise.
+   *         Currently these are UTF-16xx, UTF-32xx and UTF-8.
+   */
   @Nullable
-  public static byte[] getBom(@NotNull Charset charset) {
+  public static byte[] getPossibleBom(@NotNull Charset charset) {
     if (charset.equals(UTF8_CHARSET)) return UTF8_BOM;
     return CHARSET_TO_MANDATORY_BOM.get(charset);
   }
index 06070fa8d4021a7546576045c301dac3f54a34ce..540e17014032970870e0d13b142ba6f59f39b574 100644 (file)
@@ -67,7 +67,7 @@ public class PausesStat {
     long finishStamp = System.currentTimeMillis();
     int duration = (int)(finishStamp - startTimeStamp);
     started = false;
-    duration = Math.min(duration, (1 << 16) - 1);
+    duration = Math.min(duration, Short.MAX_VALUE);
     if (duration > maxDuration) {
       maxDuration = duration;
       maxDurationDescription = description;
index 8e40d738099b6f1e4a71d4dc65997433ac2999cd..1fed757d77e83f86c5ca0126a1f8a304b2a243c1 100644 (file)
@@ -450,6 +450,12 @@ public class ContainerUtil extends ContainerUtilRt {
   @NotNull
   @Contract(pure=true)
   public static <T> Set<T> union(@NotNull Set<T> set, @NotNull Set<T> set2) {
+    return union((Collection<T>)set, set2);
+  }
+
+  @NotNull
+  @Contract(pure=true)
+  public static <T> Set<T> union(@NotNull Collection<T> set, @NotNull Collection<T> set2) {
     Set<T> result = new THashSet<T>(set.size() + set2.size());
     result.addAll(set);
     result.addAll(set2);
index 89b2c156c3b8435a6a79469af7446886aa237133..7e36e16c97803d970ff26d211a65abce58645be9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -161,7 +161,7 @@ public abstract class JBIterable<E> implements Iterable<E> {
    */
   @NotNull
   public static <E> JBIterable<E> of(@Nullable E... elements) {
-    return elements == null ? JBIterable.<E>empty() : from(ContainerUtilRt.newArrayList(elements));
+    return elements == null || elements.length == 0 ? JBIterable.<E>empty() : from(ContainerUtilRt.newArrayList(elements));
   }
 
   private static final JBIterable EMPTY = new JBIterable() {
@@ -363,7 +363,7 @@ public abstract class JBIterable<E> implements Iterable<E> {
 
   /**
    * Returns a {@code JBIterable} that applies {@code function} to each element of this
-   * iterable and concats the produced iterables in one.
+   * iterable and concatenates the produced iterables in one.
    * <p/>
    * <p>The returned iterable's iterator supports {@code remove()} if an underlying iterable's
    * iterator does. After a successful {@code remove()} call, this iterable no longer
index 4390e42ba52544379564e89aa2e3e7c50f17c711..93dad49bf6b52acad43b727cd56334d18a27d9a3 100644 (file)
@@ -54,7 +54,6 @@ import javax.swing.plaf.basic.BasicComboBoxUI;
 import javax.swing.plaf.basic.BasicRadioButtonUI;
 import javax.swing.plaf.basic.ComboPopup;
 import javax.swing.text.*;
-import javax.swing.text.html.HTMLDocument;
 import javax.swing.text.html.HTMLEditorKit;
 import javax.swing.text.html.StyleSheet;
 import javax.swing.undo.UndoManager;
@@ -2370,19 +2369,8 @@ public class UIUtil {
     final StyleSheet style = new StyleSheet();
     style.addStyleSheet(isUnderDarcula() ? (StyleSheet)UIManager.getDefaults().get("StyledEditorKit.JBDefaultStyle") : DEFAULT_HTML_KIT_CSS);
     style.addRule(customCss);
-    scaleStyleSheetFontSize(style, size);
 
     return new HTMLEditorKit() {
-
-      @Override
-      public Document createDefaultDocument() {
-        Document document = super.createDefaultDocument();
-        if (document instanceof HTMLDocument) {
-          scaleStyleSheetFontSize(((HTMLDocument)document).getStyleSheet(), size);
-        }
-        return document;
-      }
-
       @Override
       public StyleSheet getStyleSheet() {
         return style;
@@ -2390,14 +2378,6 @@ public class UIUtil {
     };
   }
 
-  private static void scaleStyleSheetFontSize(@Nullable StyleSheet styleSheet, int bodyFontSize) {
-    // In compliance with javax.swing.text.html.StyleSheet logic, where 14pt font size is specified in
-    // javax/swing/text/html/default.css and javax.swing.text.html.StyleSheet.sizeMapDefault[3].
-    if (styleSheet != null) {
-      styleSheet.addRule("BASE_SIZE " + bodyFontSize);
-    }
-  }
-
   public static void removeScrollBorder(final Component c) {
     for (JScrollPane scrollPane : uiTraverser(c).filter(JScrollPane.class)) {
       if (!uiParents(scrollPane, true)
index 6cd606885e809d6da04d43256ab735b0668ab7a9..3533019d82b62bc8186d57ab3b2c40a9b0e1fc6b 100644 (file)
@@ -17,15 +17,12 @@ package com.intellij.vcs.log.ui.frame;
 
 import com.google.common.primitives.Ints;
 import com.intellij.ide.CopyProvider;
-import com.intellij.ide.IdeTooltip;
-import com.intellij.ide.IdeTooltipManager;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.actionSystem.DataProvider;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.ide.CopyPasteManager;
 import com.intellij.openapi.ui.LoadingDecorator;
-import com.intellij.openapi.ui.popup.Balloon;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Couple;
 import com.intellij.openapi.util.Pair;
@@ -33,7 +30,6 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.ui.*;
 import com.intellij.ui.components.JBLabel;
-import com.intellij.ui.components.panels.Wrapper;
 import com.intellij.ui.table.JBTable;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.text.DateFormatUtil;
@@ -59,7 +55,6 @@ import com.intellij.vcs.log.ui.VcsLogUiImpl;
 import com.intellij.vcs.log.ui.render.GraphCommitCell;
 import com.intellij.vcs.log.ui.render.GraphCommitCellRenderer;
 import com.intellij.vcs.log.ui.tables.GraphTableModel;
-import com.intellij.vcs.log.util.VcsUserUtil;
 import gnu.trove.TIntHashSet;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -74,7 +69,9 @@ import java.awt.datatransfer.StringSelection;
 import java.awt.event.ComponentAdapter;
 import java.awt.event.ComponentEvent;
 import java.awt.event.MouseEvent;
-import java.util.*;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EventObject;
 import java.util.List;
 
 public class VcsLogGraphTable extends TableWithProgress implements DataProvider, CopyProvider {
@@ -94,6 +91,7 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider,
   @NotNull private final TableCellRenderer myDummyRenderer = new DefaultTableCellRenderer();
   @NotNull private final GraphCommitCellRenderer myGraphCommitCellRenderer;
   @NotNull private final GraphTableController myController;
+  private final StringCellRenderer myStringCellRenderer;
   private boolean myColumnsSizeInitialized = false;
 
   @Nullable private Selection mySelection = null;
@@ -113,12 +111,13 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider,
     myUi = ui;
     myLogData = logData;
     myGraphCommitCellRenderer = new GraphCommitCellRenderer(logData, myGraphCellPainter, this);
+    myStringCellRenderer = new StringCellRenderer();
 
     myLogData.getProgress().addProgressIndicatorListener(new MyProgressListener(), ui);
 
     setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUi));
     setDefaultRenderer(GraphCommitCell.class, myGraphCommitCellRenderer);
-    setDefaultRenderer(String.class, new StringCellRenderer());
+    setDefaultRenderer(String.class, myStringCellRenderer);
 
     setShowHorizontalLines(false);
     setIntercellSpacing(JBUI.emptySize());
@@ -187,11 +186,13 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider,
           maxWidth = Math.max(getFontMetrics(tableFont.deriveFont(Font.BOLD)).stringWidth(value), maxWidth);
           if (!value.isEmpty()) sizeCalculated = true;
         }
-        int min = Math.min(maxWidth + UIUtil.DEFAULT_HGAP, MAX_DEFAULT_AUTHOR_COLUMN_WIDTH);
+        int min =
+          Math.min(maxWidth + UIUtil.DEFAULT_HGAP, MAX_DEFAULT_AUTHOR_COLUMN_WIDTH + myStringCellRenderer.getHorizontalTextPadding());
         column.setPreferredWidth(min);
       }
       else if (i == GraphTableModel.DATE_COLUMN) { // all dates have nearly equal sizes
-        int min = getFontMetrics(tableFont.deriveFont(Font.BOLD)).stringWidth("mm" + DateFormatUtil.formatDateTime(new Date()));
+        int min = getFontMetrics(tableFont.deriveFont(Font.BOLD)).stringWidth(DateFormatUtil.formatDateTime(new Date())) +
+                  myStringCellRenderer.getHorizontalTextPadding();
         column.setPreferredWidth(min);
       }
     }
@@ -645,7 +646,12 @@ public class VcsLogGraphTable extends TableWithProgress implements DataProvider,
         return;
       }
       append(value.toString(), applyHighlighters(this, row, column, value.toString(), hasFocus, selected));
-      setBorder(null);
+    }
+
+    public int getHorizontalTextPadding() {
+      Insets borderInsets = getMyBorder().getBorderInsets(this);
+      Insets ipad = getIpad();
+      return borderInsets.left + borderInsets.right + ipad.left + ipad.right;
     }
   }
 
index bb03d9dfe79a3dd16e1589e8765ad810c304747f..ad0c72a70001972d87abd842a435e63eb7616b5d 100644 (file)
@@ -39,6 +39,7 @@ public class AppEngineFrameworkDetector extends FacetBasedFrameworkDetector<AppE
     super("appengine-java");
   }
 
+  @NotNull
   @Override
   public FacetType<AppEngineFacet, AppEngineFacetConfiguration> getFacetType() {
     return FacetType.findInstance(AppEngineFacetType.class);
index f9c6e5c64d852a9dfa57336bdf326d80092489d7..fddefdcd172d7426b6a64e857606e20f76de030d 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/action_method.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/action_method.png differ
index 9092e694173a55b55406b644ecb2c5cf7e1debab..0d12b369c0cecfb61b38a83fa9a31050f424cbd9 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/action_method@2x.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/action_method@2x.png differ
index 6a9e8e5f334037e5332716f390b23b7b147969e1..ceb667ddd877f6ada4691f37de13b3520a892571 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed.png differ
index 3bef8008ba3ccf6fcbea13a74f8fbfc2e9d8cd4a..cd8a600527a5042f9720bbd30be08a7e4594cb23 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed@2x.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed@2x.png differ
diff --git a/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed@2x_dark.png b/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed@2x_dark.png
deleted file mode 100644 (file)
index 04d2efb..0000000
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed@2x_dark.png and /dev/null differ
diff --git a/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed_dark.png b/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed_dark.png
deleted file mode 100644 (file)
index 4475d5e..0000000
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/config_folder_closed_dark.png and /dev/null differ
index c3e28a1b02f1f6a6a5d4b2c110323a97d9a138c8..140506b526105e57af6175db78e09beef762df25 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/controller.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/controller.png differ
index b2cf4ebd0678a21f5a0f9b8671ae6d256ccb0a3f..95efcf10f3054141a10333ac0da61636cd51a6f3 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/controller@2x.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/controller@2x.png differ
index 3963c9947b1b83aa31a556f9e29a8e5ef7d4f9df..f8dc55aced11e00a5204ebed7b8c8be3a48e425b 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/domain_class.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/domain_class.png differ
index dd393a002411e0c2cbc36da048db5cfa68fc0a42..d29b2126339bc14d022ac32ee8ebabba631fdd00 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/domain_class@2x.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/domain_class@2x.png differ
index cfae8c21d136bee247e68c99c794b5508d0aa657..86377886a7ee31db2984cb3d9cb2342f1dc9beff 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin.png differ
index 2caeb1851053d9484f05e2c5f666c7d3399d0527..a4dab7fae27a89cef783153d2e583a6ba3357408 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin@2x.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin@2x.png differ
index 25692091f9f21e7c986019409aac4f76eafe4495..db7cb6ac507c1bcf684de6146992e767c4aef14d 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin@2x_dark.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin@2x_dark.png differ
index 7cb96c39e34ef1df9129bad8a1fcc3cab02026d4..4f9a2ac5102117c6708ff6d4a3fc4eea2b2567aa 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin_dark.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/groovy_mvc_plugin_dark.png differ
index b1d89f6fe649a03f6db72793f67ee8346b52e0ca..a898cee4526bf2477572d1f32d55ead7de7cc972 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/modelsNode.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/modelsNode.png differ
index 3cb33651383dcd9fcef39eecc0149971fb949bf1..2abf1161e338f387e80667b0e6c9d29a881d9a76 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/modelsNode@2x.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/modelsNode@2x.png differ
index 1a71923a49b593e6f11db89a2dc0d902e57487ad..4c8668d22abddadb5e212ff1f76bdbc92b0486ea 100644 (file)
Binary files a/plugins/groovy/groovy-psi/resources/icons/mvc/service.png and b/plugins/groovy/groovy-psi/resources/icons/mvc/service.png differ
index 5aac4685fe4e5dbe893617610c382c284bded344..c5604a09e279fc9e6ae314513fd2bde1269b4060 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/childrenProjects.png and b/plugins/maven/src/main/resources/images/childrenProjects.png differ
index ac77c08c5d8ef70f074ccc873a1de96e88c82cbc..8b3ed9488eecd0492d0c976e2ebf1a555d658fec 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/childrenProjects_dark.png and b/plugins/maven/src/main/resources/images/childrenProjects_dark.png differ
index 14f11db4879c26e986597c031572c7c1c10b9718..803a47688526cc8eab8104578888508d50432a0c 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/executeMavenGoal.png and b/plugins/maven/src/main/resources/images/executeMavenGoal.png differ
index 68ce3addb4afc6bb63b5eb25f011cc992cbf671d..70d791e4651200ddc8b9cc1dd3cf33253b4f2a3a 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/executeMavenGoal@2x.png and b/plugins/maven/src/main/resources/images/executeMavenGoal@2x.png differ
index d9be9670cceebc3b4df9af7bc6a6ce7bd380b7f7..ffd73991665e0bb3e06833c049714605ca41dbb4 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/mavenLogo.png and b/plugins/maven/src/main/resources/images/mavenLogo.png differ
index 42e013c8c1cb39b4f2eda3da96f4f8d3293a7266..1aef9e55400df33eabddd6386e6a8c7815ceac6d 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/mavenPlugin.png and b/plugins/maven/src/main/resources/images/mavenPlugin.png differ
diff --git a/plugins/maven/src/main/resources/images/mavenPlugin_dark.png b/plugins/maven/src/main/resources/images/mavenPlugin_dark.png
deleted file mode 100644 (file)
index fd04d87..0000000
Binary files a/plugins/maven/src/main/resources/images/mavenPlugin_dark.png and /dev/null differ
index 55b429bf32ccabd3ce819b3b2a25ca457c79cf49..8a5048772815017073c8219f468a187314eb8ee7 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/mavenProject.png and b/plugins/maven/src/main/resources/images/mavenProject.png differ
diff --git a/plugins/maven/src/main/resources/images/mavenProject_dark.png b/plugins/maven/src/main/resources/images/mavenProject_dark.png
deleted file mode 100644 (file)
index f9892df..0000000
Binary files a/plugins/maven/src/main/resources/images/mavenProject_dark.png and /dev/null differ
index 82bb2cea2a817c052fc3c70065b26b1d71b20067..92d26833084dddb770b3417f7e3c91a627452510 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/modulesClosed.png and b/plugins/maven/src/main/resources/images/modulesClosed.png differ
index 3276aca09875f56142a5b9a8e1dcad659c51fc0d..11bae034687ce8fc92193aa7c5bbeab9f72e0061 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/offlineMode.png and b/plugins/maven/src/main/resources/images/offlineMode.png differ
index aafab915894793e3f13206888208bbd4ef08841f..c1ee9b774596af46addb3604da12b38e0e510608 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/offlineMode_dark.png and b/plugins/maven/src/main/resources/images/offlineMode_dark.png differ
index b3461b42b5f138d445eca33a89d237d98b2c08a4..da93be6526c4d3956a88d382e7144a116c752aea 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/parentProject.png and b/plugins/maven/src/main/resources/images/parentProject.png differ
index 7e8b5eb705c35f3b1fb5b14b27909cce1dc00d9a..fae789db206d20ee3a46810558362b903f9d947f 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/phase.png and b/plugins/maven/src/main/resources/images/phase.png differ
index 7604d83886e9b69e9da72a92d77daa337154ee33..ceb667ddd877f6ada4691f37de13b3520a892571 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/phasesClosed.png and b/plugins/maven/src/main/resources/images/phasesClosed.png differ
index a86657c3e4efb280eaa448711713c0b6bd85c9d6..fc3bdcee1aba15f856620dcb180032a90e93ec1d 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/pluginGoal.png and b/plugins/maven/src/main/resources/images/pluginGoal.png differ
diff --git a/plugins/maven/src/main/resources/images/pluginGoal_dark.png b/plugins/maven/src/main/resources/images/pluginGoal_dark.png
deleted file mode 100644 (file)
index 6624a75..0000000
Binary files a/plugins/maven/src/main/resources/images/pluginGoal_dark.png and /dev/null differ
index 5081a5c2ea278cf4ca72b36a1b72ea2ca350c1cd..21cbde4b8e48cedf148e758ad031d89e872d3b4d 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/profilesClosed.png and b/plugins/maven/src/main/resources/images/profilesClosed.png differ
diff --git a/plugins/maven/src/main/resources/images/profilesClosed_dark.png b/plugins/maven/src/main/resources/images/profilesClosed_dark.png
deleted file mode 100644 (file)
index c4d1ec3..0000000
Binary files a/plugins/maven/src/main/resources/images/profilesClosed_dark.png and /dev/null differ
index 6dd1711dad2af0ed02ad794f57f69ddc206a18b2..c6e9655f4a1598913fc3db78a3f8774161f3f7d9 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/toolWindowMaven.png and b/plugins/maven/src/main/resources/images/toolWindowMaven.png differ
index f77b3c6a7374dd54b0c6fa7ad6a6439894923909..ab6f0dccb0889d0a36a9baf09cd8e1682b6dbf7d 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/toolWindowMaven@2x.png and b/plugins/maven/src/main/resources/images/toolWindowMaven@2x.png differ
index 2190cc4b9c267e283aed184a8d287118ad5f63be..51715b3655bea1202b00bb78ae4d3f0db49b1e66 100644 (file)
Binary files a/plugins/maven/src/main/resources/images/updateFolders.png and b/plugins/maven/src/main/resources/images/updateFolders.png differ
index a9958c7311ada34f32a5cc2b0f040f70ae4252d0..d77e854780364c4a8dc35c4f08a05b60d30df1f1 100644 (file)
Binary files a/plugins/properties/properties-psi-api/resources/icons/xmlProperties.png and b/plugins/properties/properties-psi-api/resources/icons/xmlProperties.png differ
index d2af3f6dcc2edfe27c82f652415e42c764979c67..28c1b63f7b60c515bdd829bed4c1cab1e989daa7 100644 (file)
@@ -69,12 +69,13 @@ public class ResourceBundleFileStructureViewElement implements StructureViewTree
     final HashSet<String> remains = new HashSet<>(myElements.keySet());
     for (Map.Entry<String, Collection<IProperty>> entry : propertyNames.entrySet()) {
       final String propKey = entry.getKey();
-      final IProperty representative = entry.getValue().iterator().next();
+      Collection<IProperty> properties = entry.getValue();
       final ResourceBundlePropertyStructureViewElement oldPropertyNode = myElements.get(propKey);
-      if (oldPropertyNode != null && oldPropertyNode.getProperty() == representative) {
+      if (oldPropertyNode != null && properties.contains(oldPropertyNode.getProperty())) {
         remains.remove(propKey);
         continue;
       }
+      final IProperty representative = properties.iterator().next();
       final ResourceBundlePropertyStructureViewElement node = new ResourceBundlePropertyStructureViewElement(representative);
       myElements.put(propKey, node);
     }
index ac6f73c9ec88e898a00ce920e5d792c23566440d..c38942079016e2c06d3b217f66ca48f8ca000246 100644 (file)
@@ -80,6 +80,7 @@ public class PythonFacetType extends FacetType<PythonFacet, PythonFacetConfigura
       super("python");
     }
 
+    @NotNull
     @Override
     public FacetType<PythonFacet, PythonFacetConfiguration> getFacetType() {
       return PythonFacetType.getInstance();
index 1db11b782e1f1ecd09a554cc795027773003ce01..4bc626a4fb8026f97817873fb97448c2091bfa7b 100644 (file)
@@ -154,6 +154,7 @@ QFIX.NAME.remove.argument=Remove argument
 QFIX.NAME.remove.parameter=Remove parameter
 
 QFIX.NAME.rename.argument=Rename argument
+QFIX.NAME.rename.element=Rename element
 
 QFIX.NAME.wrap.in.exception=Wrap with Exception call
 
index c2f869ae4853aad32ce2d840adef305b3f61d7f1..bd2857d9e23fa165fc434e2f8e1d94069433d92f 100644 (file)
@@ -42,6 +42,7 @@ public class BuildoutFrameworkDetector extends FacetBasedFrameworkDetector<Build
     super("buildout-python");
   }
 
+  @NotNull
   @Override
   public FacetType<BuildoutFacet, BuildoutFacetConfiguration> getFacetType() {
     return BuildoutFacetType.getInstance();
index 4ee578511eecca42932a6735513f4bbf9796d894..8b2d0ec7dac728c7aed9320c04b6e4e1d442774e 100644 (file)
@@ -27,15 +27,14 @@ import com.intellij.openapi.util.JDOMExternalizableStringList;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiElementVisitor;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiReference;
+import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.QualifiedName;
+import com.intellij.util.ArrayUtil;
 import com.intellij.util.containers.ContainerUtil;
 import com.jetbrains.python.PyBundle;
 import com.jetbrains.python.PyNames;
+import com.jetbrains.python.inspections.quickfix.PyRenameElementQuickFix;
 import com.jetbrains.python.psi.*;
 import com.jetbrains.python.psi.impl.PyBuiltinCache;
 import com.jetbrains.python.psi.types.PyClassType;
@@ -325,5 +324,35 @@ public class PyCompatibilityInspection extends PyInspection {
         }
       }
     }
+
+    @Override
+    public void visitPyTargetExpression(PyTargetExpression node) {
+      super.visitPyTargetExpression(node);
+      warnAboutAsyncAndAwaitInPy35AndPy36(node);
+    }
+
+    @Override
+    public void visitPyClass(PyClass node) {
+      super.visitPyClass(node);
+      warnAboutAsyncAndAwaitInPy35AndPy36(node);
+    }
+
+    @Override
+    public void visitPyFunction(PyFunction node) {
+      super.visitPyFunction(node);
+      warnAboutAsyncAndAwaitInPy35AndPy36(node);
+    }
+
+    private void warnAboutAsyncAndAwaitInPy35AndPy36(@NotNull PsiNameIdentifierOwner nameIdentifierOwner) {
+      final PsiElement nameIdentifier = nameIdentifierOwner.getNameIdentifier();
+
+      if (nameIdentifier != null && ArrayUtil.contains(nameIdentifierOwner.getName(), PyNames.AWAIT, PyNames.ASYNC)) {
+        registerOnFirstMatchingVersion(level -> LanguageLevel.PYTHON35.equals(level) || LanguageLevel.PYTHON36.equals(level),
+                                       "'async' and 'await' are not recommended to be used as variable, class, function or module names. " +
+                                       "They will become proper keywords in Python 3.7.",
+                                       nameIdentifier,
+                                       new PyRenameElementQuickFix());
+      }
+    }
   }
 }
\ No newline at end of file
index 103b404bec7076865f1417a6fa9e3db468e5d1b3..02a760247f675c050c6c5ae146aecb1008e5e87b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -34,6 +34,7 @@ import com.intellij.refactoring.rename.PsiElementRenameHandler;
 import com.intellij.refactoring.rename.RenameProcessor;
 import com.intellij.refactoring.rename.RenamePsiElementProcessor;
 import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
+import com.jetbrains.python.PyBundle;
 import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
 import com.jetbrains.python.psi.PyNamedParameter;
 import com.jetbrains.python.psi.PyReferenceExpression;
@@ -49,7 +50,7 @@ public class PyRenameElementQuickFix implements LocalQuickFix {
   @NotNull
   @Override
   public String getFamilyName() {
-    return "Rename element";
+    return PyBundle.message("QFIX.NAME.rename.element");
   }
 
   @Override
diff --git a/python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy35.py b/python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy35.py
new file mode 100644 (file)
index 0000000..eea16c4
--- /dev/null
@@ -0,0 +1,14 @@
+class <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">async</warning>(object):
+    pass
+
+class <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">await</warning>(object):
+    pass
+
+def <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">async</warning>():
+    pass
+
+def <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">await</warning>():
+    pass
+
+<warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">async</warning> = 1
+<warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">await</warning> = 2
\ No newline at end of file
diff --git a/python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy36.py b/python/testData/inspections/PyCompatibilityInspection/warningAboutAsyncAndAwaitInPy36.py
new file mode 100644 (file)
index 0000000..eea16c4
--- /dev/null
@@ -0,0 +1,14 @@
+class <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">async</warning>(object):
+    pass
+
+class <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">await</warning>(object):
+    pass
+
+def <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">async</warning>():
+    pass
+
+def <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">await</warning>():
+    pass
+
+<warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">async</warning> = 1
+<warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">await</warning> = 2
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy35.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy35.py
new file mode 100644 (file)
index 0000000..bc25733
--- /dev/null
@@ -0,0 +1,2 @@
+class <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">a<caret>sync</warning>(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy35_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy35_after.py
new file mode 100644 (file)
index 0000000..1a98a9c
--- /dev/null
@@ -0,0 +1,2 @@
+class a(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy36.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy36.py
new file mode 100644 (file)
index 0000000..bc25733
--- /dev/null
@@ -0,0 +1,2 @@
+class <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">a<caret>sync</warning>(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy36_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncClassInPy36_after.py
new file mode 100644 (file)
index 0000000..1a98a9c
--- /dev/null
@@ -0,0 +1,2 @@
+class a(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy35.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy35.py
new file mode 100644 (file)
index 0000000..f48d631
--- /dev/null
@@ -0,0 +1,2 @@
+def <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">a<caret>sync</warning>():
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy35_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy35_after.py
new file mode 100644 (file)
index 0000000..690f3c1
--- /dev/null
@@ -0,0 +1,2 @@
+def a():
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy36.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy36.py
new file mode 100644 (file)
index 0000000..f48d631
--- /dev/null
@@ -0,0 +1,2 @@
+def <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">a<caret>sync</warning>():
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy36_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncFunctionInPy36_after.py
new file mode 100644 (file)
index 0000000..690f3c1
--- /dev/null
@@ -0,0 +1,2 @@
+def a():
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy35.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy35.py
new file mode 100644 (file)
index 0000000..96bae92
--- /dev/null
@@ -0,0 +1 @@
+<warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">async</warning> = 1
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy35_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy35_after.py
new file mode 100644 (file)
index 0000000..d25d49e
--- /dev/null
@@ -0,0 +1 @@
+a = 1
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy36.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy36.py
new file mode 100644 (file)
index 0000000..96bae92
--- /dev/null
@@ -0,0 +1 @@
+<warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">async</warning> = 1
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy36_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAsyncVariableInPy36_after.py
new file mode 100644 (file)
index 0000000..d25d49e
--- /dev/null
@@ -0,0 +1 @@
+a = 1
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy35.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy35.py
new file mode 100644 (file)
index 0000000..c531a43
--- /dev/null
@@ -0,0 +1,2 @@
+class <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">a<caret>wait</warning>(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy35_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy35_after.py
new file mode 100644 (file)
index 0000000..1a98a9c
--- /dev/null
@@ -0,0 +1,2 @@
+class a(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy36.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy36.py
new file mode 100644 (file)
index 0000000..c531a43
--- /dev/null
@@ -0,0 +1,2 @@
+class <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">a<caret>wait</warning>(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy36_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitClassInPy36_after.py
new file mode 100644 (file)
index 0000000..1a98a9c
--- /dev/null
@@ -0,0 +1,2 @@
+class a(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy35.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy35.py
new file mode 100644 (file)
index 0000000..c1ef9d6
--- /dev/null
@@ -0,0 +1,2 @@
+def <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">a<caret>wait</warning>():
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy35_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy35_after.py
new file mode 100644 (file)
index 0000000..690f3c1
--- /dev/null
@@ -0,0 +1,2 @@
+def a():
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy36.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy36.py
new file mode 100644 (file)
index 0000000..c1ef9d6
--- /dev/null
@@ -0,0 +1,2 @@
+def <warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">a<caret>wait</warning>():
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy36_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitFunctionInPy36_after.py
new file mode 100644 (file)
index 0000000..690f3c1
--- /dev/null
@@ -0,0 +1,2 @@
+def a():
+    pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy35.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy35.py
new file mode 100644 (file)
index 0000000..1a28415
--- /dev/null
@@ -0,0 +1 @@
+<warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">await</warning> = 1
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy35_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy35_after.py
new file mode 100644 (file)
index 0000000..d25d49e
--- /dev/null
@@ -0,0 +1 @@
+a = 1
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy36.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy36.py
new file mode 100644 (file)
index 0000000..1a28415
--- /dev/null
@@ -0,0 +1 @@
+<warning descr="'async' and 'await' are not recommended to be used as variable, class, function or module names. They will become proper keywords in Python 3.7.">await</warning> = 1
\ No newline at end of file
diff --git a/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy36_after.py b/python/testData/quickFixes/RenameElementQuickFixTest/renameAwaitVariableInPy36_after.py
new file mode 100644 (file)
index 0000000..d25d49e
--- /dev/null
@@ -0,0 +1 @@
+a = 1
\ No newline at end of file
index 7d152a5520c7aa27db97087d39a0648590d2d09f..ccea524a9b8f4f87fc658ea4f272bc3044e05f3a 100644 (file)
@@ -551,7 +551,7 @@ public class PyQuickFixTest extends PyTestCase {
     myFixture.configureByFile(fileName);
     myFixture.enableInspections(PyShadowingBuiltinsInspection.class);
     myFixture.checkHighlighting(true, false, true);
-    final IntentionAction intentionAction = myFixture.getAvailableIntention("Rename element");
+    final IntentionAction intentionAction = myFixture.getAvailableIntention(PyBundle.message("QFIX.NAME.rename.element"));
     assertNotNull(intentionAction);
     myFixture.launchAction(intentionAction);
     myFixture.checkResultByFile(graftBeforeExt(fileName, "_after"));
@@ -563,7 +563,7 @@ public class PyQuickFixTest extends PyTestCase {
     myFixture.configureByFile(fileName);
     myFixture.enableInspections(PyShadowingBuiltinsInspection.class);
     myFixture.checkHighlighting(true, false, true);
-    final IntentionAction intentionAction = myFixture.getAvailableIntention("Rename element");
+    final IntentionAction intentionAction = myFixture.getAvailableIntention(PyBundle.message("QFIX.NAME.rename.element"));
     assertNotNull(intentionAction);
     myFixture.launchAction(intentionAction);
     myFixture.checkResultByFile(graftBeforeExt(fileName, "_after"));
index 4bc87459c36fdc3141ce594c0748a389e690475d..7afe19f1f695a4356593c28bdbef3523cf40db81 100644 (file)
@@ -209,6 +209,16 @@ public class PyCompatibilityInspectionTest extends PyTestCase {
     doTest(LanguageLevel.PYTHON36);
   }
 
+  // PY-16098
+  public void testWarningAboutAsyncAndAwaitInPy35() {
+    doTest(LanguageLevel.PYTHON35);
+  }
+
+  // PY-16098
+  public void testWarningAboutAsyncAndAwaitInPy36() {
+    doTest(LanguageLevel.PYTHON36);
+  }
+
   private void doTest(@NotNull LanguageLevel level) {
     runWithLanguageLevel(level, this::doTest);
   }
index 5a63b49b66e690e70911b6cd226785e5eb264b3c..16d5a9e75bc5661705cf4c522c043b96224aef77 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -16,7 +16,9 @@
 package com.jetbrains.python.quickFixes;
 
 import com.intellij.testFramework.TestDataPath;
+import com.jetbrains.python.PyBundle;
 import com.jetbrains.python.PyQuickFixTestCase;
+import com.jetbrains.python.inspections.PyCompatibilityInspection;
 import com.jetbrains.python.inspections.PyPep8NamingInspection;
 import com.jetbrains.python.inspections.PyProtectedMemberInspection;
 import com.jetbrains.python.inspections.PyShadowingBuiltinsInspection;
@@ -28,23 +30,82 @@ import com.jetbrains.python.inspections.PyShadowingBuiltinsInspection;
 public class RenameElementQuickFixTest extends PyQuickFixTestCase {
 
   public void testProtectedMember() {
-    doQuickFixTest(PyProtectedMemberInspection.class, "Rename element");
+    doQuickFixTest(PyProtectedMemberInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
   }
 
   public void testPep8() {
-    doQuickFixTest(PyPep8NamingInspection.class, "Rename element");
+    doQuickFixTest(PyPep8NamingInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
   }
 
   public void testPep8Class() {
-    doQuickFixTest(PyPep8NamingInspection.class, "Rename element");
+    doQuickFixTest(PyPep8NamingInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
   }
 
   public void testPep8Function() {
-    doQuickFixTest(PyPep8NamingInspection.class, "Rename element");
+    doQuickFixTest(PyPep8NamingInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
   }
 
   public void testShadowingBuiltins() {
-    doQuickFixTest(PyShadowingBuiltinsInspection.class, "Rename element");
+    doQuickFixTest(PyShadowingBuiltinsInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
   }
 
+  // PY-16098
+  public void testRenameAsyncClassInPy35() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAsyncClassInPy36() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAwaitClassInPy35() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAwaitClassInPy36() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAsyncFunctionInPy35() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAsyncFunctionInPy36() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAwaitFunctionInPy35() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAwaitFunctionInPy36() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAsyncVariableInPy35() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAsyncVariableInPy36() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAwaitVariableInPy35() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
+
+  // PY-16098
+  public void testRenameAwaitVariableInPy36() {
+    doQuickFixTest(PyCompatibilityInspection.class, PyBundle.message("QFIX.NAME.rename.element"));
+  }
 }
index 2e024903503855ab027c7541bee78493d450ad5e..4de90ce9f8e32adb92e6fd472feb950d1d0a06ab 100644 (file)
     <stacktrace.fold substring="at sun.rmi."/>
     <stacktrace.fold substring="at com.sun.proxy.$Proxy"/>
     <stacktrace.fold substring="at com.intellij.rt.execution."/>
+    <console.folding implementation="com.intellij.testFramework.FailedTestDebugLogConsoleFolding"/>
 
     <debuggerEditorTextProvider language="JAVA" implementationClass="com.intellij.debugger.impl.JavaEditorTextProviderImpl"/>
 
index 4c292f22c47540ad694aebde7194a3db2c6d0ff4..990b491b6e65c345f3f0526f31d8a31869d230cc 100644 (file)
@@ -275,7 +275,10 @@ public class Runner {
 
   private static void apply(String jarFile, String destFolder) throws Exception {
      logger().info("Applying patch to the " + destFolder);
-     doInstall(jarFile, new ConsoleUpdaterUI(), destFolder);
+    final boolean success = doInstall(jarFile, new ConsoleUpdaterUI(), destFolder);
+    if (!success) {
+      System.exit(1);
+    }
   }
 
   private static boolean doInstall(String jarFile, UpdaterUI ui, String destFolder) throws OperationCancelledException {