Merge remote-tracking branch 'origin/master' into amakeev/symlinks
authorAnton Makeev <Anton.Makeev@jetbrains.com>
Wed, 31 Aug 2016 15:25:44 +0000 (17:25 +0200)
committerAnton Makeev <Anton.Makeev@jetbrains.com>
Wed, 31 Aug 2016 15:25:44 +0000 (17:25 +0200)
198 files changed:
RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java
RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java
RegExpSupport/src/org/intellij/lang/regexp/UnicodeCharacterNames.java
RegExpSupport/test/org/intellij/lang/regexp/RegExpCompletionTest.java
build/groovy/org/jetbrains/intellij/build/BuildContext.groovy
build/groovy/org/jetbrains/intellij/build/CommunityRepositoryModules.groovy
build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy
build/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy
build/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy
build/groovy/org/jetbrains/intellij/build/impl/DistributionJARsBuilder.groovy
java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java
java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java
java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java
java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetector.java
java/java-analysis-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java
java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaConstructorCallElement.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodCallElement.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaModuleCompletion.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
java/java-impl/src/com/intellij/codeInsight/completion/MemberLookupHelper.java
java/java-impl/src/com/intellij/codeInsight/template/macro/JavaTemplateCompletionProcessor.java
java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsPresentation.java
java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java
java/java-impl/src/com/intellij/reporting/ReportMissingOrExcessiveInlineHint.kt
java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
java/java-psi-impl/src/com/intellij/lang/java/parser/ModuleParser.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiAnonymousClassImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiEnumConstantImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiFieldImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImportStatementBaseImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImportStatementImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiMethodImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterListImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReferenceListImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiNameValuePairImpl.java
java/java-tests/testData/inspection/streamApiCallChains/afterCollectorCounting.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterCollectorMapping.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterCollectorMaxBy.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterCollectorMinBy.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterCollectorReducing1.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterCollectorReducing2.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterCollectorReducing3.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterCollectorSummingInt.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterCollectorSummingLong.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorCounting.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorMapping.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorMaxBy.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorMinBy.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorReducing1.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorReducing2.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorReducing3.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorSummingInt.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorSummingLong.java [new file with mode: 0644]
java/java-tests/testData/psi/parser-partial/modules/Provides7.txt [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/completion/ModuleCompletionTest.kt
java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ModuleParserTest.java
java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/VoidConversionRule.java
jps/jps-builders/src/org/jetbrains/jps/incremental/CompiledClass.java
jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/BaseInstrumentingBuilder.java
jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/NotNullInstrumentingBuilder.java
jps/jps-builders/src/org/jetbrains/jps/incremental/messages/CompilerMessage.java
json/src/com/jetbrains/jsonSchema/extension/schema/JsonSchemaDefinitionResolver.java
json/src/com/jetbrains/jsonSchema/extension/schema/JsonSchemaFileIndex.java
platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java
platform/analysis-impl/src/com/intellij/profile/codeInspection/ProjectInspectionProfileManager.kt
platform/configuration-store-impl/src/SchemeManagerImpl.kt
platform/core-api/src/com/intellij/diagnostic/ImplementationConflictException.java [new file with mode: 0644]
platform/core-api/src/com/intellij/lang/Language.java
platform/core-api/src/com/intellij/openapi/module/Module.java
platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java
platform/lang-impl/src/com/intellij/codeInsight/template/TemplateManager.java
platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java
platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java
platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java
platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProviderImpl.java
platform/lang-impl/src/com/intellij/codeInspection/ex/SequentialCleanupTask.java [deleted file]
platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java
platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java
platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateSettings.java
platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewToolWindowFactory.java
platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java
platform/platform-api/src/com/intellij/openapi/wm/ToolWindowFactory.java
platform/platform-api/src/com/intellij/openapi/wm/ToolWindowFactoryEx.java
platform/platform-impl/src/com/intellij/diagnostic/PluginConflictReporter.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/diagnostic/errordialog/PluginConflictDialog.form [new file with mode: 0644]
platform/platform-impl/src/com/intellij/diagnostic/errordialog/PluginConflictDialog.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/idea/IdeaLogger.java
platform/platform-impl/src/com/intellij/openapi/application/actions.kt
platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowInfoImpl.java
platform/platform-impl/src/com/intellij/reporting/Reporter.kt
platform/platform-resources-en/src/messages/DiagnosticBundle.properties
platform/platform-resources-en/src/messages/InspectionsBundle.properties
platform/platform-tests/testSrc/com/intellij/ide/fileTemplates/impl/LightFileTemplatesTest.java
platform/projectModel-impl/src/com/intellij/configurationStore/scheme-impl.kt
platform/projectModel-impl/src/com/intellij/jdom.kt
platform/util/src/com/intellij/openapi/util/text/StringUtil.java
platform/util/testSrc/com/intellij/util/text/StringUtilTest.java
platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateCurrentRevisionAction.java
platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotatePreviousRevisionAction.java
platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateRevisionAction.java
platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpointType.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/LineBreakpointState.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DeleteUnnecessaryStatementFix.java
plugins/copyright/copyright.iml
plugins/copyright/src/CopyrightManager.kt [new file with mode: 0644]
plugins/copyright/src/META-INF/plugin.xml
plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java [deleted file]
plugins/copyright/src/com/maddyhome/idea/copyright/actions/AbstractFileProcessor.java
plugins/copyright/src/com/maddyhome/idea/copyright/actions/GenerateCopyrightAction.java
plugins/copyright/src/com/maddyhome/idea/copyright/actions/UpdateCopyrightAction.java
plugins/copyright/src/com/maddyhome/idea/copyright/actions/UpdateCopyrightProcessor.java
plugins/copyright/src/com/maddyhome/idea/copyright/pattern/VelocityHelper.java
plugins/copyright/src/com/maddyhome/idea/copyright/psi/AbstractUpdateCopyright.java
plugins/copyright/src/com/maddyhome/idea/copyright/psi/UpdatePsiFileCopyright.java
plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightConfigurable.java
plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProfilesPanel.java
plugins/copyright/src/com/maddyhome/idea/copyright/ui/ProjectSettingsPanel.java
plugins/copyright/src/com/maddyhome/idea/copyright/ui/TemplateCommentPanel.java
plugins/copyright/src/com/maddyhome/idea/copyright/util/NewFileTracker.java
plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java
plugins/git4idea/src/git4idea/annotate/GitFileAnnotation.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/style/GrUnnecessarySemicolonInspection.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java
plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyAppLineMarkerContributor.java
plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestLineMarkerContributor.java
plugins/groovy/test/org/jetbrains/plugins/groovy/codeInspection/style/GrUnnecessarySemicolonInspectionTest.groovy
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
plugins/settings-repository/src/authForm.kt
python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityBuilder.groovy [new file with mode: 0644]
python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy [new file with mode: 0644]
python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmMacDistributionCustomizer.groovy [new file with mode: 0644]
python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmPropertiesBase.groovy [new file with mode: 0644]
python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmWindowsDistributionCustomizer.groovy [new file with mode: 0644]
python/build/paths.nsi [deleted file]
python/build/plugin-list.txt
python/build/pycharm64_community_launcher.properties [deleted file]
python/build/pycharm_community_build.gant
python/build/pycharm_community_launcher.properties [deleted file]
python/build/python-community-build.iml
python/build/resources/install.ico [moved from python/build/resources/PC_instCom.ico with 100% similarity]
python/build/resources/pycharm_inst.ico [deleted file]
python/build/resources/pycharm_uninst.ico [deleted file]
python/build/resources/uninstall.ico [moved from python/build/resources/PC_uninstCom.ico with 100% similarity]
python/build/strings.nsi [deleted file]
python/educational-python/build/groovy/org/jetbrains/intellij/build/pycharm/edu/PyCharmEduProperties.groovy
python/educational-python/build/pycharm_edu_build.gant
python/educational-python/build/python-edu-build.iml
python/helpers/pydev/_pydev_bundle/_pydev_calltip_util.py [new file with mode: 0644]
python/helpers/pydev/_pydev_bundle/_pydev_imports_tipper.py
python/helpers/pydev/_pydev_bundle/pydev_console_utils.py
python/helpers/pydev/_pydevd_bundle/pydevd_comm.py
python/helpers/pydev/_pydevd_bundle/pydevd_console.py
python/helpers/pydev/_pydevd_bundle/pydevd_process_net_command.py
python/psi-api/src/com/jetbrains/python/psi/resolve/PyResolveContext.java
python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java
python/pydevSrc/com/jetbrains/python/debugger/pydev/GetDescriptionCommand.java [new file with mode: 0644]
python/pydevSrc/com/jetbrains/python/debugger/pydev/MultiProcessDebugger.java
python/pydevSrc/com/jetbrains/python/debugger/pydev/ProcessDebugger.java
python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java
python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java
python/src/com/jetbrains/python/PyParameterInfoHandler.java
python/src/com/jetbrains/python/console/PydevConsoleRunner.java
python/src/com/jetbrains/python/console/PydevDocumentationProvider.java
python/src/com/jetbrains/python/console/PythonDebugConsoleCommunication.java
python/src/com/jetbrains/python/console/completion/PydevConsoleReference.java
python/src/com/jetbrains/python/console/parsing/PyConsoleParser.java
python/src/com/jetbrains/python/debugger/PyDebugProcess.java
python/src/com/jetbrains/python/debugger/PyLineBreakpointType.java
python/src/com/jetbrains/python/debugger/array/ArrayTableCellRenderer.java
python/src/com/jetbrains/python/debugger/array/JBTableWithRowHeaders.java
python/src/com/jetbrains/python/debugger/containerview/ColoredCellRenderer.java
python/src/com/jetbrains/python/debugger/containerview/NumericContainerViewTable.java
python/src/com/jetbrains/python/debugger/containerview/PyViewNumericContainerAction.java
python/src/com/jetbrains/python/debugger/dataframe/DataFrameTableCellRenderer.java
python/src/com/jetbrains/python/psi/PyFileElementType.java
python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
updater/testSrc/com/intellij/updater/PatchTest.java
xml/dom-openapi/src/com/intellij/util/xml/ModuleContentRootSearchScope.java

index dc81e12c3030b7d569163a5bb0d89fc07de77233..97425853729825bebe61aa7051c7d0d972cd07e9 100644 (file)
@@ -97,6 +97,12 @@ public final class RegExpCompletionContributor extends CompletionContributor {
       final ElementPattern<PsiElement> propertyNamePattern
               = psiElement().afterLeaf(psiElement().withText("{").afterLeaf(propertyPattern));
       extend(CompletionType.BASIC, propertyNamePattern, new PropertyNameCompletionProvider());
+
+      final PsiElementPattern.Capture<PsiElement> namedCharacterPattern = psiElement().withText("N");
+      extend(CompletionType.BASIC, psiElement().afterLeaf(namedCharacterPattern),
+             new NamedCharacterCompletionProvider(true));
+      extend(CompletionType.BASIC, psiElement().afterLeaf(psiElement(RegExpTT.LBRACE).afterLeaf(namedCharacterPattern)),
+             new NamedCharacterCompletionProvider(false));
     }
   }
 
index 5b6e3305ba6d57cf986e43d63c512dfc652bbcda..493c0f76b24eef0b29a95331b300244f185fa022 100644 (file)
  */
 package org.intellij.lang.regexp;
 
-import com.intellij.lang.injection.InjectedLanguageManager;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.util.ClassExtension;
-import com.intellij.psi.*;
-import com.intellij.psi.impl.source.resolve.FileContextUtil;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
 import org.intellij.lang.regexp.psi.*;
 import org.jetbrains.annotations.Contract;
 import org.jetbrains.annotations.NotNull;
@@ -51,36 +51,19 @@ public final class RegExpLanguageHosts extends ClassExtension<RegExpLanguageHost
   @Contract("null -> null")
   @Nullable
   private static RegExpLanguageHost findRegExpHost(@Nullable final PsiElement element) {
-    if (ApplicationManager.getApplication().isUnitTestMode() && myHost != null) {
-      return myHost;
-    }
     if (element == null) {
       return null;
     }
-    PsiLanguageInjectionHost injectionHost = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element);
-    final RegExpLanguageHost host = getRegExpHost(injectionHost);
-    if (host != null) {
-      return host;
+    if (ApplicationManager.getApplication().isUnitTestMode() && myHost != null) {
+      return myHost;
     }
     final PsiFile file = element.getContainingFile();
-    final SmartPsiElementPointer pointer = file.getUserData(FileContextUtil.INJECTED_IN_ELEMENT);
-    if (pointer == null) {
-      return null;
-    }
-    final PsiElement pointerElement = pointer.getElement();
-    if (pointerElement == null) {
-      return null;
-    }
-    return getRegExpHost(pointerElement);
-  }
-
-  @Nullable
-  private static RegExpLanguageHost getRegExpHost(@Nullable PsiElement languageInjectionHostElement) {
-    if (languageInjectionHostElement instanceof RegExpLanguageHost) {
-      return (RegExpLanguageHost)languageInjectionHostElement;
+    final PsiElement context = file.getContext();
+    if (context instanceof RegExpLanguageHost) {
+      return (RegExpLanguageHost)context;
     }
-    if (languageInjectionHostElement != null) {
-      return INSTANCE.forClass(languageInjectionHostElement.getClass());
+    if (context != null) {
+      return INSTANCE.forClass(context.getClass());
     }
     return null;
   }
@@ -171,7 +154,6 @@ public final class RegExpLanguageHosts extends ClassExtension<RegExpLanguageHost
 
   public boolean supportsNamedCharacters(@NotNull final RegExpNamedCharacter namedCharacter) {
     final RegExpLanguageHost host = findRegExpHost(namedCharacter);
-    System.out.println("host = " + host);
     return host != null && host.supportsNamedCharacters(namedCharacter);
   }
 
index 57a465111d169593c5a5ec3e5f0b34006322a769..a84105ec40df0d2f2236c9506cb8e0122fde88b9 100644 (file)
@@ -33,14 +33,16 @@ public class UnicodeCharacterNames {
     try {
       final Class<?> aClass = Class.forName("java.lang.CharacterName");
       final Method initNamePool = ReflectionUtil.getDeclaredMethod(aClass, "initNamePool");
-      final int[][] lookup2d = ReflectionUtil.getField(aClass, null, int[][].class, "lookup");
-      if (initNamePool != null && lookup2d != null) { // jdk 8
-        byte[] namePool = (byte[])initNamePool.invoke(null);
+      if (initNamePool != null) { // jdk 8
+        byte[] namePool = (byte[])initNamePool.invoke(null); // initializes "lookup" field
+        final int[][] lookup2d = ReflectionUtil.getStaticFieldValue(aClass, int[][].class, "lookup");
+        if (lookup2d == null) {
+          return;
+        }
         for (int[] indexes : lookup2d) {
           if (indexes != null) {
             for (int index : indexes) {
               if (index != 0) {
-                ;
                 final String name = new String(namePool, index >>> 8, index & 0xff, AsciiUtil.ASCII_CHARSET);
                 consumer.accept(name);
               }
index 3ba88ab02baae4ec78638ebaf44c6b436dd7a882..abdee64fbc053f4f82356e644e0889f5f7d3a004 100644 (file)
  */
 package org.intellij.lang.regexp;
 
+import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -57,6 +59,17 @@ public class RegExpCompletionTest extends CodeInsightFixtureTestCase {
       myFixture.checkResult("[[:^alpha:]<caret>");
     }
 
+    public void testNamedCharacter() {
+      myFixture.configureByText(RegExpFileType.INSTANCE, "\\\\N{SMILE<caret>}");
+      final LookupElement[] elements = myFixture.completeBasic();
+      final List<String> strings = ContainerUtil.map(elements, LookupElement::getLookupString);
+      assertEquals(Arrays.asList("SMILE", "SMILING FACE WITH SMILING EYES", "SMILING FACE WITH HEART-SHAPED EYES",
+                                 "SMILING CAT FACE WITH HEART-SHAPED EYES", "SMILING FACE WITH OPEN MOUTH AND SMILING EYES",
+                                 "SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES", "CAT FACE WITH WRY SMILE",
+                                 "GRINNING CAT FACE WITH SMILING EYES", "GRINNING FACE WITH SMILING EYES",
+                                 "KISSING FACE WITH SMILING EYES"), strings);
+    }
+
     public void testBackSlashVariants() throws Throwable {
         List<String> nameList =
           new ArrayList<>(Arrays.asList("d", "D", "s", "S", "w", "W", "b", "B", "A", "G", "Z", "z", "Q", "E",
index aababf51b22b8bae256801f7c5bef2480dce9757..121e52b0b0c4461364b95c08652995cc8ec2ece8 100644 (file)
@@ -65,6 +65,12 @@ abstract class BuildContext {
 
   abstract boolean includeBreakGenLibraries()
 
+  /**
+   * If the method returns {@code false} 'idea.jars.nocopy' property will be set to {@code true} in idea.properties by default. Otherwise it
+   * won't be set and the IDE will copy library *.jar files to avoid their locking when running under Windows.
+   */
+  abstract boolean shouldIDECopyJarsByDefault()
+
   abstract void patchInspectScript(String path)
 
   abstract String getAdditionalJvmArguments()
index 56199beed1662d25685e35a592d64aecf26f264c..47a6c04b73fb3c5b33b30608f69e3f92395c11b2 100644 (file)
@@ -178,6 +178,7 @@ class CommunityRepositoryModules {
     plugin("course-creator"),
     plugin("course-creator-python"),
     plugin("ipnb"),
-    plugin("IntelliLang-python")
+    plugin("IntelliLang-python"),
+    plugin("python-rest")
   ]
 }
\ No newline at end of file
index 8302320628e96f49aa189f5c66f149635e4768e3..d7316081fb6eea5e668931b879225090508eb925 100644 (file)
@@ -78,7 +78,7 @@ abstract class WindowsDistributionCustomizer {
   /**
    * The returned name will be used to create links on Desktop
    */
-  String fullNameIncludingEditionAndVendor(ApplicationInfoProperties applicationInfo) { applicationInfo.shortCompanyName + " " + applicationInfo.productName }
+  String fullNameIncludingEditionAndVendor(ApplicationInfoProperties applicationInfo) { applicationInfo.shortCompanyName + " " + fullNameIncludingEdition(applicationInfo) }
 
   String uninstallFeedbackPageUrl(ApplicationInfoProperties applicationInfo) {
     return null
index b741ca5fdbbe17441f6e6c98030d72b3fa37d6a6..5fe53ef1e02964796e0ff8cdc7ff262b8c199229 100644 (file)
@@ -259,8 +259,18 @@ class BuildContextImpl extends BuildContext {
 
   @Override
   boolean includeBreakGenLibraries() {
+    return isJavaSupportedInProduct()
+  }
+
+  @Override
+  boolean shouldIDECopyJarsByDefault() {
+    return isJavaSupportedInProduct()
+  }
+
+  private boolean isJavaSupportedInProduct() {
     def productLayout = productProperties.productLayout
-    return productLayout.mainJarName == null || //todo[nik] remove this condition later
+    return productLayout.mainJarName == null ||
+           //todo[nik] remove this condition later; currently build scripts for IDEA don't fully migrated to the new scheme
            productLayout.includedPlatformModules.contains("execution-impl")
   }
 
index 81592affda5ee0885ff66cea7daa3c85d675885f..6d03a54eca4074122a965adfb3dae8b826aeb7e2 100644 (file)
@@ -84,7 +84,7 @@ class BuildTasksImpl extends BuildTasks {
 
   @Override
   void buildSearchableOptions(String targetModuleName, List<String> modulesToIndex, List<String> pathsToLicenses) {
-    buildSearchableOptions(new File(buildContext.projectBuilder.moduleOutput(buildContext.findModule(targetModuleName))), modulesToIndex, pathsToLicenses)
+    buildSearchableOptions(new File(buildContext.projectBuilder.moduleOutput(buildContext.findRequiredModule(targetModuleName))), modulesToIndex, pathsToLicenses)
   }
 
 //todo[nik] do we need 'cp' and 'jvmArgs' parameters?
@@ -143,6 +143,14 @@ class BuildTasksImpl extends BuildTasks {
     File originalFile = new File("$buildContext.paths.communityHome/bin/idea.properties")
 
     String text = originalFile.text
+    if (!buildContext.shouldIDECopyJarsByDefault()) {
+      text += """
+#---------------------------------------------------------------------
+# IDE can copy library .jar files to prevent their locking. Set this property to 'false' to enable copying.
+#---------------------------------------------------------------------
+idea.jars.nocopy=true
+"""
+    }
     buildContext.productProperties.additionalIDEPropertiesFilePaths.each {
       text += "\n" + new File(it).text
     }
index 9df697b418b8316586ffbae65d0cbe4a6187ffb6..f0930d64183d4ad10f883b373fa78420b78986cb 100644 (file)
@@ -79,6 +79,7 @@ class DistributionJARsBuilder {
       exclude(name: "tips/**")
       exclude(name: "tips")
       exclude(name: "search/**")
+      exclude(name: "**/icon-robots.txt")
     }
 
     def productLayout = buildContext.productProperties.productLayout
@@ -146,7 +147,8 @@ class DistributionJARsBuilder {
 
   List<String> getPlatformModules() {
     (platform.moduleJars.values() as List<String>) +
-    ["java-runtime" /*required to build searchable options index*/, "updater"]
+    ["java-runtime", "platform-main", /*required to build searchable options index*/
+     "updater", buildContext.productProperties.productLayout.mainModule]
 
   }
 
index 707612ab4bce67a4420368a11b0135138229ab5f..0d46f2fba155cfb74bf2e6830a95d4e3cae265a5 100644 (file)
 package com.intellij.debugger.actions;
 
 import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.engine.DebuggerUtils;
 import com.intellij.debugger.engine.SuspendContextImpl;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
+import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
 import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
+import com.intellij.debugger.impl.DebuggerContextImpl;
 import com.intellij.debugger.impl.DebuggerSession;
 import com.intellij.debugger.impl.DebuggerUtilsEx;
 import com.intellij.debugger.jdi.MethodBytecodeUtil;
@@ -36,6 +41,7 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
 import com.intellij.util.DocumentUtil;
 import com.intellij.util.Range;
+import com.intellij.util.ThreeState;
 import com.intellij.util.containers.OrderedSet;
 import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
 import com.sun.jdi.Location;
@@ -68,7 +74,7 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
       @Override
       public void threadAction(@NotNull SuspendContextImpl suspendContext) {
         List<SmartStepTarget> targets = ApplicationManager.getApplication().runReadAction(
-          (Computable<List<SmartStepTarget>>)() -> findSmartStepTargets(position, suspendContext));
+          (Computable<List<SmartStepTarget>>)() -> findSmartStepTargets(position, suspendContext, getDebuggerContext()));
         DebuggerUIUtil.invokeLater(() -> {
           if (targets.isEmpty()) {
             doStepInto(session, Registry.is("debugger.single.smart.step.force"), null);
@@ -93,7 +99,9 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
     throw new IllegalStateException("Should not be used");
   }
 
-  protected List<SmartStepTarget> findSmartStepTargets(final SourcePosition position, @Nullable SuspendContextImpl suspendContext) {
+  protected List<SmartStepTarget> findSmartStepTargets(final SourcePosition position,
+                                                       @Nullable SuspendContextImpl suspendContext,
+                                                       @NotNull DebuggerContextImpl debuggerContext) {
     final int line = position.getLine();
     if (line < 0) {
       return Collections.emptyList(); // the document has been changed
@@ -174,38 +182,78 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
 
         @Override
         public void visitField(PsiField field) {
-          TextRange range = field.getTextRange();
-          if (lineRange.intersects(range)) {
-            //textRange.set(textRange.get().union(range));
+          if (checkTextRange(field, false)) {
             super.visitField(field);
           }
         }
 
         @Override
         public void visitMethod(PsiMethod method) {
-          TextRange range = method.getTextRange();
-          if (lineRange.intersects(range)) {
-            //textRange.set(textRange.get().union(range));
+          if (checkTextRange(method, false)) {
             super.visitMethod(method);
           }
         }
 
         @Override
         public void visitStatement(PsiStatement statement) {
-          TextRange range = statement.getTextRange();
-          if (lineRange.intersects(range)) {
-            textRange.set(textRange.get().union(range));
+          if (checkTextRange(statement, true)) {
             super.visitStatement(statement);
           }
         }
 
+        @Override
+        public void visitIfStatement(PsiIfStatement statement) {
+          visitConditional(statement.getCondition(), statement.getThenBranch(), statement.getElseBranch());
+        }
+
+        @Override
+        public void visitConditionalExpression(PsiConditionalExpression expression) {
+          visitConditional(expression.getCondition(), expression.getThenExpression(), expression.getElseExpression());
+        }
+
+        private void visitConditional(@Nullable PsiElement condition,
+                                      @Nullable PsiElement thenBranch,
+                                      @Nullable PsiElement elseBranch) {
+          if (condition != null) {
+            condition.accept(this);
+          }
+          ThreeState conditionRes = evaluateCondition(condition);
+          if (conditionRes != ThreeState.NO && thenBranch != null) {
+            thenBranch.accept(this);
+          }
+          if (conditionRes != ThreeState.YES && elseBranch != null) {
+            elseBranch.accept(this);
+          }
+        }
+
+        private ThreeState evaluateCondition(@Nullable PsiElement condition) {
+          if (condition != null && !DebuggerUtils.hasSideEffects(condition)) {
+            try {
+              ExpressionEvaluator evaluator = EvaluatorBuilderImpl.getInstance().build(condition, position);
+              return ThreeState.fromBoolean(DebuggerUtilsEx.evaluateBoolean(evaluator, debuggerContext.createEvaluationContext()));
+            }
+            catch (EvaluateException e) {
+              LOG.info(e);
+            }
+          }
+          return ThreeState.UNSURE;
+        }
+
         @Override
         public void visitExpression(PsiExpression expression) {
+          checkTextRange(expression, true);
+          super.visitExpression(expression);
+        }
+
+        boolean checkTextRange(PsiElement expression, boolean expand) {
           TextRange range = expression.getTextRange();
           if (lineRange.intersects(range)) {
-            textRange.set(textRange.get().union(range));
+            if (expand) {
+              textRange.set(textRange.get().union(range));
+            }
+            return true;
           }
-          super.visitExpression(expression);
+          return false;
         }
 
         public void visitExpressionList(PsiExpressionList expressionList) {
index 14a8a1994abd135eee37bf75268dfba4075eab96..6d34c7f0dc6970bc47a18408b2c8cbcf8f2271ba 100644 (file)
@@ -25,6 +25,8 @@ import com.intellij.debugger.SourcePosition;
 import com.intellij.debugger.engine.*;
 import com.intellij.debugger.engine.evaluation.*;
 import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder;
+import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
+import com.intellij.debugger.engine.evaluation.expression.UnBoxingEvaluator;
 import com.intellij.debugger.engine.requests.RequestManagerImpl;
 import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
 import com.intellij.debugger.requests.Requestor;
@@ -865,6 +867,14 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
     return PsiParameter.EMPTY_ARRAY;
   }
 
+  public static boolean evaluateBoolean(ExpressionEvaluator evaluator, EvaluationContextImpl context) throws EvaluateException {
+    Object value = UnBoxingEvaluator.unbox(evaluator.evaluate(context), context);
+    if (!(value instanceof BooleanValue)) {
+      throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.boolean.expected"));
+    }
+    return ((BooleanValue)value).booleanValue();
+  }
+
   public static boolean intersects(@NotNull TextRange range, @NotNull PsiElement elem) {
     TextRange elemRange = elem.getTextRange();
     return elemRange != null && elemRange.intersects(range);
index cfee49e7c3997ee1dae61bb5072a2af49404838c..c76b62fb1f6802f9655bf64db0cea73655476787 100644 (file)
@@ -25,8 +25,8 @@ import com.intellij.debugger.engine.*;
 import com.intellij.debugger.engine.evaluation.*;
 import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
 import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
-import com.intellij.debugger.engine.evaluation.expression.UnBoxingEvaluator;
 import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
+import com.intellij.debugger.impl.DebuggerUtilsEx;
 import com.intellij.debugger.jdi.StackFrameProxyImpl;
 import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
 import com.intellij.debugger.requests.ClassPrepareRequestor;
@@ -371,13 +371,7 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
           return EvaluatorBuilderImpl.build(getCondition(), contextPsiElement, contextSourcePosition, project);
         }
       });
-      Object value = UnBoxingEvaluator.unbox(evaluator.evaluate(context), context);
-      if (!(value instanceof BooleanValue)) {
-        throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.boolean.expected"));
-      }
-      if (!((BooleanValue)value).booleanValue()) {
-        return false;
-      }
+      return DebuggerUtilsEx.evaluateBoolean(evaluator, context);
     }
     catch (EvaluateException ex) {
       if (ex.getCause() instanceof VMDisconnectedException) {
@@ -387,7 +381,6 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
         DebuggerBundle.message("error.failed.evaluating.breakpoint.condition", getCondition(), ex.getMessage())
       );
     }
-    return true;
   }
 
   protected String calculateEventClass(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
index 2f382f0ca80fd9f683213a7eed5ea0da04134784..f81fee18734927b1edb29afbf92b14c99461e9f3 100644 (file)
@@ -423,11 +423,14 @@ public abstract class DebuggerUtils {
     }
   }
 
-  public static boolean hasSideEffects(PsiElement element) {
+  public static boolean hasSideEffects(@Nullable PsiElement element) {
     return hasSideEffectsOrReferencesMissingVars(element, null);
   }
   
-  public static boolean hasSideEffectsOrReferencesMissingVars(PsiElement element, @Nullable final Set<String> visibleLocalVariables) {
+  public static boolean hasSideEffectsOrReferencesMissingVars(@Nullable PsiElement element, @Nullable final Set<String> visibleLocalVariables) {
+    if (element == null) {
+      return false;
+    }
     final Ref<Boolean> rv = new Ref<>(Boolean.FALSE);
     element.accept(new JavaRecursiveElementWalkingVisitor() {
       @Override 
index 399c004e1e14071e04c005e1ed311c0f2a3693c5..e6baf6ba00a5b3daf13bb62933d26598222dea5b 100644 (file)
@@ -112,7 +112,7 @@ public class JUnitUtil {
     if (psiMethod.hasModifierProperty(PsiModifier.STATIC) && SUITE_METHOD_NAME.equals(psiMethod.getName())) return false;
     if (!psiMethod.getName().startsWith("test")) return false;
     PsiClass testCaseClass = getTestCaseClassOrNull(location);
-    return testCaseClass != null && psiMethod.getContainingClass().isInheritor(testCaseClass, true);
+    return testCaseClass != null && psiMethod.getContainingClass().isInheritor(testCaseClass, true) && PsiType.VOID.equals(psiMethod.getReturnType());
   }
 
   public static boolean isTestCaseInheritor(final PsiClass aClass) {
index f0259c79d5cbaa7c5054052240122066d7b3c6c1..800a82d71a05249729a2ca9edfbfda05d030bd92 100644 (file)
@@ -33,6 +33,10 @@ public abstract class JavaSourceRootDetector extends ProjectStructureDetector {
   @Override
   public DirectoryProcessingResult detectRoots(@NotNull File dir, @NotNull File[] children, @NotNull File base,
                                                @NotNull List<DetectedProjectRoot> result) {
+    if (dir.getName().equals("node_modules")) {
+      return DirectoryProcessingResult.SKIP_CHILDREN;
+    }
+
     final String fileExtension = getFileExtension();
     for (File child : children) {
       if (child.isFile() && FileUtilRt.extensionEquals(child.getName(), fileExtension)) {
index 823513cdef5d7f4bea30df2e8cd3a5f400367adc..5dfb5cfd8ae66854dd0d3668d8c96ef87c30b210 100644 (file)
@@ -45,6 +45,16 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
   private static final String EMPTY_SET_METHOD = "emptySet";
   private static final String SINGLETON_LIST_METHOD = "singletonList";
   private static final String SINGLETON_METHOD = "singleton";
+  private static final String COLLECT_METHOD = "collect";
+
+  private static final String COUNTING_COLLECTOR = "counting";
+  private static final String MIN_BY_COLLECTOR = "minBy";
+  private static final String MAX_BY_COLLECTOR = "maxBy";
+  private static final String MAPPING_COLLECTOR = "mapping";
+  private static final String REDUCING_COLLECTOR = "reducing";
+  private static final String SUMMING_INT_COLLECTOR = "summingInt";
+  private static final String SUMMING_LONG_COLLECTOR = "summingLong";
+  private static final String SUMMING_DOUBLE_COLLECTOR = "summingDouble";
 
   @Override
   public boolean isEnabledByDefault() {
@@ -95,6 +105,44 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
             holder.registerProblem(methodCall, null, fix.getMessage(), fix);
           }
         }
+        else if (isCallOf(method, CommonClassNames.JAVA_UTIL_STREAM_STREAM, COLLECT_METHOD, 1)) {
+          PsiElement parameter = methodCall.getArgumentList().getExpressions()[0];
+          if(parameter instanceof PsiMethodCallExpression) {
+            PsiMethodCallExpression collectorCall = (PsiMethodCallExpression)parameter;
+            PsiMethod collectorMethod = collectorCall.resolveMethod();
+            ReplaceCollectorFix fix = null;
+            if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, COUNTING_COLLECTOR, 0)) {
+              fix = new ReplaceCollectorFix(COUNTING_COLLECTOR, "count()", false);
+            } else if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, MIN_BY_COLLECTOR, 1)) {
+              fix = new ReplaceCollectorFix(MIN_BY_COLLECTOR, "min({1})", true);
+            } else if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, MAX_BY_COLLECTOR, 1)) {
+              fix = new ReplaceCollectorFix(MAX_BY_COLLECTOR, "max({1})", true);
+            } else if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, MAPPING_COLLECTOR, 2)) {
+              fix = new ReplaceCollectorFix(MAPPING_COLLECTOR, "map({1}).collect({2})", false);
+            } else if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, REDUCING_COLLECTOR, 1)) {
+              fix = new ReplaceCollectorFix(REDUCING_COLLECTOR, "reduce({1})", true);
+            } else if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, REDUCING_COLLECTOR, 2)) {
+              fix = new ReplaceCollectorFix(REDUCING_COLLECTOR, "reduce({1}, {2})", false);
+            } else if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, REDUCING_COLLECTOR, 3)) {
+              fix = new ReplaceCollectorFix(REDUCING_COLLECTOR, "map({2}).reduce({1}, {3})", false);
+            } else if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, SUMMING_INT_COLLECTOR, 1)) {
+              fix = new ReplaceCollectorFix(SUMMING_INT_COLLECTOR, "mapToInt({1}).sum()", false);
+            } else if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, SUMMING_LONG_COLLECTOR, 1)) {
+              fix = new ReplaceCollectorFix(SUMMING_LONG_COLLECTOR, "mapToLong({1}).sum()", false);
+            } else if(isCallOf(collectorMethod, CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, SUMMING_DOUBLE_COLLECTOR, 1)) {
+              fix = new ReplaceCollectorFix(SUMMING_DOUBLE_COLLECTOR, "mapToDouble({1}).sum()", false);
+            }
+            if (fix != null &&
+                collectorCall.getArgumentList().getExpressions().length == collectorMethod.getParameterList().getParametersCount()) {
+              TextRange range = methodCall.getTextRange();
+              PsiElement nameElement = methodCall.getMethodExpression().getReferenceNameElement();
+              if(nameElement != null) {
+                range = new TextRange(nameElement.getTextOffset(), range.getEndOffset());
+              }
+              holder.registerProblem(methodCall, range.shiftRight(-methodCall.getTextOffset()), fix.getMessage(), fix);
+            }
+          }
+        }
         else {
           final String name;
           if (isCallOf(method, CommonClassNames.JAVA_UTIL_STREAM_STREAM, FOR_EACH_METHOD, 1)) {
@@ -390,4 +438,87 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
       }
     }
   }
+
+  private static class ReplaceCollectorFix implements LocalQuickFix {
+    private final String myCollector;
+    private final String myStreamSequence;
+    private final String myStreamSequenceStripped;
+    private final boolean myChangeSemantics;
+
+    public ReplaceCollectorFix(String collector, String streamSequence, boolean changeSemantics) {
+      myCollector = collector;
+      myStreamSequence = streamSequence;
+      myStreamSequenceStripped = streamSequence.replaceAll("\\([^)]+\\)", "()");
+      myChangeSemantics = changeSemantics;
+    }
+
+    @Nls
+    @NotNull
+    @Override
+    public String getName() {
+      return getFamilyName();
+    }
+
+    @Nls
+    @NotNull
+    @Override
+    public String getFamilyName() {
+      return "Replace Stream.collect(" + myCollector +
+             "()) with Stream." + myStreamSequenceStripped +
+             (myChangeSemantics ? " (may change semantics when result is null)" : "");
+    }
+
+    @Override
+    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+      PsiElement element = descriptor.getStartElement();
+      if (element instanceof PsiMethodCallExpression) {
+        PsiMethodCallExpression collectCall = (PsiMethodCallExpression)element;
+        PsiExpression qualifierExpression = collectCall.getMethodExpression().getQualifierExpression();
+        if (qualifierExpression != null) {
+          PsiElement parameter = collectCall.getArgumentList().getExpressions()[0];
+          if (parameter instanceof PsiMethodCallExpression) {
+            PsiMethodCallExpression collectorCall = (PsiMethodCallExpression)parameter;
+            PsiExpression[] collectorArgs = collectorCall.getArgumentList().getExpressions();
+            String result = myStreamSequence;
+            for(int i=0; i<collectorArgs.length; i++) {
+              result = result.replace("{"+(i+1)+"}", collectorArgs[i].getText());
+            }
+            if (!FileModificationService.getInstance().preparePsiElementForWrite(element.getContainingFile())) return;
+            PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+            PsiExpression replacement = factory.createExpressionFromText(
+              qualifierExpression.getText() + "." + result, collectCall);
+            PsiElement expression = collectCall.replace(replacement);
+            // Replacements like .collect(counting()) -> .count() change the result type from boxed to primitive
+            // In rare cases it's necessary to add cast to return back to boxed type
+            // example:
+            // List<Integer> intList; List<String> stringList;
+            // intList.remove(stringList.stream().collect(summingInt(String::length)) -- remove given element
+            // intList.remove(stringList.stream().mapToInt(String::length).sum()) -- remove element by index
+            if(expression instanceof PsiExpression) {
+              PsiType type = ((PsiExpression)expression).getType();
+              if(type instanceof PsiPrimitiveType) {
+                PsiClassType boxedType = ((PsiPrimitiveType)type).getBoxedType(expression);
+                if(boxedType != null) {
+                  PsiExpression castExpression =
+                    factory.createExpressionFromText("(" + boxedType.getCanonicalText() + ") " + expression.getText(), expression);
+                  PsiElement cast = expression.replace(castExpression);
+                  if (cast instanceof PsiTypeCastExpression && RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)cast)) {
+                    RedundantCastUtil.removeCast((PsiTypeCastExpression)cast);
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    @NotNull
+    String getMessage() {
+      return "Stream.collect(" + myCollector +
+             "()) can be replaced with Stream." + myStreamSequenceStripped + "()" +
+             (myChangeSemantics ? " (may change semantics when result is null)" : "");
+    }
+  }
+
 }
index 8d244022701a04b8657039bf64563f7b32780f7b..06a9ed709b4de03ddbad1294fed6af2db66ae2c8 100644 (file)
@@ -126,13 +126,8 @@ public class AllClassesGetter {
   public static final InsertHandler<JavaPsiClassReferenceElement> INSERT_FQN = (context, item) -> {
     final String qName = item.getQualifiedName();
     if (qName != null) {
-      int start = context.getTailOffset() - 1;
-      while (start >= 0) {
-        final char ch = context.getDocument().getCharsSequence().charAt(start);
-        if (!Character.isJavaIdentifierPart(ch) && ch != '.') break;
-        start--;
-      }
-      context.getDocument().replaceString(start + 1, context.getTailOffset(), qName);
+      int start = JavaCompletionUtil.findQualifiedNameStart(context);
+      context.getDocument().replaceString(start, context.getTailOffset(), qName);
       LOG.assertTrue(context.getTailOffset() >= 0);
     }
   };
index b0dc386a4a57946c7dc1a55c304cdea434585654..d31afee0a8990df0863c553c7779f2c77f60d21b 100644 (file)
@@ -7,7 +7,10 @@ import com.intellij.codeInsight.generation.OverrideImplementExploreUtil;
 import com.intellij.codeInsight.generation.OverrideImplementUtil;
 import com.intellij.codeInsight.generation.PsiGenerationInfo;
 import com.intellij.codeInsight.intention.impl.TypeExpression;
-import com.intellij.codeInsight.lookup.*;
+import com.intellij.codeInsight.lookup.Lookup;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementDecorator;
+import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
 import com.intellij.codeInsight.template.*;
 import com.intellij.featureStatistics.FeatureUsageTracker;
 import com.intellij.openapi.application.ApplicationManager;
@@ -260,6 +263,8 @@ public class ConstructorInsertHandler implements InsertHandler<LookupElementDeco
 
   private static Runnable createOverrideRunnable(final Editor editor, final PsiFile file, final Project project) {
     return () -> {
+      TemplateManager.getInstance(project).finishTemplate(editor);
+
       PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
       final PsiAnonymousClass
         aClass = PsiTreeUtil.findElementOfClassAtOffset(file, editor.getCaretModel().getOffset(), PsiAnonymousClass.class, false);
index dcd1e597ae48e04f49d8998447771e8972fd046c..4026930f4e6ff22af95deb5e90bc218b7d48a4b1 100644 (file)
@@ -16,7 +16,6 @@
 package com.intellij.codeInsight.completion;
 
 import com.intellij.codeInsight.AutoPopupController;
-import com.intellij.codeInsight.ExpectedTypeInfo;
 import com.intellij.codeInsight.ExpectedTypesProvider;
 import com.intellij.codeInsight.lookup.Lookup;
 import com.intellij.codeInsight.lookup.LookupElement;
@@ -34,6 +33,7 @@ import com.intellij.psi.javadoc.PsiDocComment;
 import com.intellij.psi.javadoc.PsiDocTag;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 
 import static com.intellij.psi.codeStyle.JavaCodeStyleSettings.*;
@@ -159,18 +159,17 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
 
     final PsiElement prevElement = FilterPositionUtil.searchNonSpaceNonCommentBack(ref);
     if (prevElement != null && prevElement.getParent() instanceof PsiNewExpression) {
-      for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes((PsiExpression)prevElement.getParent(), true)) {
-        if (info.getType() instanceof PsiArrayType) {
-          return false;
-        }
-      }
-
-      return true;
+      return !isArrayTypeExpected((PsiExpression)prevElement.getParent());
     }
 
     return false;
   }
 
+  static boolean isArrayTypeExpected(PsiExpression expr) {
+    return ContainerUtil.exists(ExpectedTypesProvider.getExpectedTypes(expr, true),
+                                info -> info.getType() instanceof PsiArrayType);
+  }
+
   private static boolean insertingAnnotation(InsertionContext context, LookupElement item) {
     final Object obj = item.getObject();
     if (!(obj instanceof PsiClass) || !((PsiClass)obj).isAnnotationType()) return false;
index 3e75097517544f6dc7cb028fa13beb5336ee18d7..f8a321402aabb865b54d44757321b318116ab819 100644 (file)
@@ -226,12 +226,8 @@ public class JavaCompletionContributor extends CompletionContributor {
     PrefixMatcher matcher = result.getPrefixMatcher();
     PsiElement parent = position.getParent();
 
-    if (JavaModuleCompletion.isModuleFile(position.getContainingFile())) {
-      JavaModuleCompletion.addVariants(position, element -> {
-        if (element.getLookupString().startsWith(result.getPrefixMatcher().getPrefix())) {
-          result.addElement(element);
-        }
-      });
+    if (JavaModuleCompletion.isModuleFile(parameters.getOriginalFile())) {
+      JavaModuleCompletion.addVariants(position, result);
       result.stopHere();
       return;
     }
index ca955ed337c0fb0b56526495ef557d83912bf094..b69f87c235220fc011f35cf02ce4c2e75e8b820b 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.
@@ -528,10 +528,7 @@ public class JavaCompletionUtil {
                                                                                                                .accepts(reference),
                                                                                                              JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER,
                                                                                                              Conditions.alwaysTrue());
-        if (JavaClassNameCompletionContributor.AFTER_NEW.accepts(reference)) {
-          return JBIterable.from(classItems).flatMap(i -> JavaConstructorCallElement.wrap(i, reference.getElement()));
-        }
-        return classItems;
+        return JBIterable.from(classItems).flatMap(i -> JavaConstructorCallElement.wrap(i, reference.getElement()));
       }
     }
     
@@ -544,11 +541,7 @@ public class JavaCompletionUtil {
     if (completion instanceof PsiClass) {
       JavaPsiClassReferenceElement classItem =
         JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true).setSubstitutor(substitutor);
-      if (JavaClassNameCompletionContributor.AFTER_NEW.accepts(reference)) {
-        return JavaConstructorCallElement.wrap(classItem, reference.getElement());
-      }
-
-      return Collections.singletonList(classItem);
+      return JavaConstructorCallElement.wrap(classItem, reference.getElement());
     }
     if (completion instanceof PsiMethod) {
       JavaMethodCallElement item = new JavaMethodCallElement((PsiMethod)completion).setQualifierSubstitutor(substitutor);
@@ -935,4 +928,14 @@ public class JavaCompletionUtil {
     }
     return false;
   }
-}
+
+  public static int findQualifiedNameStart(@NotNull InsertionContext context) {
+    int start = context.getTailOffset() - 1;
+    while (start >= 0) {
+      char ch = context.getDocument().getCharsSequence().charAt(start);
+      if (!Character.isJavaIdentifierPart(ch) && ch != '.') break;
+      start--;
+    }
+    return start + 1;
+  }
+}
\ No newline at end of file
index f9e5fa120837f3ea6e8a086558f7cde8bc854435..29bbd8b9b80ae91f6ef2ee45b46af03329c23519 100644 (file)
@@ -20,7 +20,11 @@ import com.intellij.codeInsight.lookup.LookupElementDecorator;
 import com.intellij.codeInsight.lookup.LookupElementPresentation;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.containers.JBIterable;
 import org.jetbrains.annotations.NotNull;
 
@@ -42,6 +46,10 @@ public class JavaConstructorCallElement extends JavaMethodCallElement {
     myType = type.get();
     setQualifierSubstitutor(myType.resolveGenerics().getSubstitutor());
 
+    markClassItemWrapped(classItem);
+  }
+
+  private void markClassItemWrapped(@NotNull LookupElement classItem) {
     LookupElement delegate = classItem;
     while (true) {
       delegate.putUserData(WRAPPING_CONSTRUCTOR_CALL, this);
@@ -65,19 +73,24 @@ public class JavaConstructorCallElement extends JavaMethodCallElement {
   @Override
   public void renderElement(LookupElementPresentation presentation) {
     myClassItem.renderElement(presentation);
-    String itemText = presentation.getItemText();
 
-    super.renderElement(presentation);
-    presentation.setItemText(itemText);
+    String tailText = StringUtil.notNullize(presentation.getTailText());
+    int genericsEnd = tailText.lastIndexOf('>') + 1;
+
+    presentation.clearTail();
+    presentation.appendTailText(tailText.substring(0, genericsEnd), false);
+    presentation.appendTailText(MemberLookupHelper.getMethodParameterString(getObject(), getSubstitutor()), false);
+    presentation.appendTailText(tailText.substring(genericsEnd), true);
   }
 
-  static List<? extends LookupElement> wrap(JavaPsiClassReferenceElement classItem, PsiElement position) {
+  static List<? extends LookupElement> wrap(@NotNull JavaPsiClassReferenceElement classItem, @NotNull PsiElement position) {
     PsiClass psiClass = classItem.getObject();
     return wrap(classItem, psiClass, position, () -> JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, PsiSubstitutor.EMPTY));
   }
 
-  static List<? extends LookupElement> wrap(LookupElement classItem, PsiClass psiClass, PsiElement position, Supplier<PsiClassType> type) {
-    if (Registry.is("java.completion.show.constructors") && JavaClassNameCompletionContributor.AFTER_NEW.accepts(position)) {
+  static List<? extends LookupElement> wrap(@NotNull LookupElement classItem, @NotNull PsiClass psiClass,
+                                            @NotNull PsiElement position, @NotNull Supplier<PsiClassType> type) {
+    if (Registry.is("java.completion.show.constructors") && isConstructorCallPlace(position)) {
       PsiMethod[] constructors = psiClass.getConstructors();
       if (constructors.length > 0) {
         return JBIterable.of(constructors).
@@ -89,6 +102,14 @@ public class JavaConstructorCallElement extends JavaMethodCallElement {
     return Collections.singletonList(classItem);
   }
 
+  private static boolean isConstructorCallPlace(@NotNull PsiElement position) {
+    return CachedValuesManager.getCachedValue(position, () -> {
+      boolean result = JavaClassNameCompletionContributor.AFTER_NEW.accepts(position) &&
+                       !JavaClassNameInsertHandler.isArrayTypeExpected(PsiTreeUtil.getParentOfType(position, PsiNewExpression.class));
+      return CachedValueProvider.Result.create(result, position);
+    });
+  }
+
   static boolean isWrapped(LookupElement element) {
     return element.getUserData(WRAPPING_CONSTRUCTOR_CALL) != null;
   }
index 9a6925cf58fd2275e8f30568be896ecb78feec79..2c7275accd5ed8bff5bcbe1a821ae087e9e0e5cb 100644 (file)
@@ -22,10 +22,15 @@ import com.intellij.codeInsight.template.Template;
 import com.intellij.codeInsight.template.TemplateManager;
 import com.intellij.codeInsight.template.impl.ConstantNode;
 import com.intellij.codeInsight.template.impl.MacroCallNode;
+import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
+import com.intellij.codeInsight.template.impl.TemplateState;
 import com.intellij.codeInsight.template.macro.CompleteMacro;
 import com.intellij.featureStatistics.FeatureUsageTracker;
 import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.util.ClassConditionKey;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.pom.java.LanguageLevel;
@@ -170,7 +175,7 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
       }
     }
 
-    if (hasParams && Registry.is("java.completion.argument.live.template")) {
+    if (hasParams && context.getCompletionChar() != Lookup.COMPLETE_STATEMENT_SELECT_CHAR && Registry.is("java.completion.argument.live.template")) {
       startArgumentLiveTemplate(context, method);
     }
   }
@@ -187,7 +192,8 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
     qualifyMethodCall(file, startOffset, document);
   }
 
-  private static void startArgumentLiveTemplate(InsertionContext context, PsiMethod method) {
+  public static final Key<JavaMethodCallElement> ARGUMENT_TEMPLATE_ACTIVE = Key.create("ARGUMENT_TEMPLATE_ACTIVE");
+  private void startArgumentLiveTemplate(InsertionContext context, PsiMethod method) {
     TemplateManager manager = TemplateManager.getInstance(method.getProject());
     Template template = manager.createTemplate("", "");
     PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -199,7 +205,18 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
       template.addVariable(name, new MacroCallNode(new CompleteMacro()), new ConstantNode(name), true);
     }
 
-    manager.startTemplate(context.getEditor(), template);
+    Editor editor = context.getEditor();
+    manager.startTemplate(editor, template);
+
+    TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
+    if (templateState == null) return;
+
+    editor.putUserData(ARGUMENT_TEMPLATE_ACTIVE, this);
+    Disposer.register(templateState, () -> {
+      if (editor.getUserData(ARGUMENT_TEMPLATE_ACTIVE) == this) {
+        editor.putUserData(ARGUMENT_TEMPLATE_ACTIVE, null);
+      }
+    });
   }
 
   private boolean shouldInsertTypeParameters() {
index d9414f11c9b43fd142671ee81fe2eb8506d304bd..2620e664e599a9d7d80bd84e1d4b8ff671163b32 100644 (file)
@@ -19,21 +19,22 @@ import com.intellij.codeInsight.TailType;
 import com.intellij.codeInsight.completion.JavaKeywordCompletion.OverrideableSpace;
 import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.codeInsight.lookup.LookupElementBuilder;
-import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleUtilCore;
 import com.intellij.openapi.module.impl.scopes.ModulesScope;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
-import com.intellij.psi.impl.file.impl.JavaFileManager;
 import com.intellij.psi.impl.java.stubs.index.JavaModuleNameIndex;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.ProjectScope;
+import com.intellij.psi.util.InheritanceUtil;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.Consumer;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.function.Predicate;
+
 import static com.intellij.codeInsight.completion.JavaKeywordCompletion.createKeyword;
 
 class JavaModuleCompletion {
@@ -41,7 +42,13 @@ class JavaModuleCompletion {
     return PsiUtil.isLanguageLevel9OrHigher(file) && PsiJavaModule.MODULE_INFO_FILE.equals(file.getName());
   }
 
-  static void addVariants(@NotNull PsiElement position, @NotNull Consumer<LookupElement> result) {
+  static void addVariants(@NotNull PsiElement position, @NotNull CompletionResultSet resultSet) {
+    Consumer<LookupElement> result = element -> {
+      if (element.getLookupString().startsWith(resultSet.getPrefixMatcher().getPrefix())) {
+        resultSet.addElement(element);
+      }
+    };
+
     if (position instanceof PsiIdentifier) {
       PsiElement context = position.getParent();
       if (context instanceof PsiErrorElement) context = context.getParent();
@@ -52,11 +59,14 @@ class JavaModuleCompletion {
       else if (context instanceof PsiJavaModule) {
         addModuleStatementKeywords(position, result);
       }
+      else if (context instanceof PsiProvidesStatement) {
+        addProvidesStatementKeywords(position, result);
+      }
       else if (context instanceof PsiJavaModuleReferenceElement) {
         addModuleReferences(context, result);
       }
       else if (context instanceof PsiJavaCodeReferenceElement) {
-        addCodeReferences(context, result);
+        addCodeReferences(context, result, resultSet);
       }
     }
   }
@@ -74,6 +84,10 @@ class JavaModuleCompletion {
     result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.PROVIDES), TailType.HUMBLE_SPACE_BEFORE_WORD));
   }
 
+  private static void addProvidesStatementKeywords(PsiElement position, Consumer<LookupElement> result) {
+    result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.WITH), TailType.HUMBLE_SPACE_BEFORE_WORD));
+  }
+
   private static void addModuleReferences(PsiElement context, Consumer<LookupElement> result) {
     PsiJavaModule host = PsiTreeUtil.getParentOfType(context, PsiJavaModule.class);
     if (host != null) {
@@ -90,24 +104,81 @@ class JavaModuleCompletion {
     }
   }
 
-  private static void addCodeReferences(PsiElement context, Consumer<LookupElement> result) {
-    PsiElement statement = PsiTreeUtil.skipParentsOfType(context, PsiJavaCodeReferenceElement.class);
+  private static void addCodeReferences(PsiElement context, Consumer<LookupElement> result, CompletionResultSet resultSet) {
+    PsiElement statement = context.getParent();
     if (statement instanceof PsiExportsStatement) {
       Module module = ModuleUtilCore.findModuleForPsiElement(context);
-      PsiPackage topPackage = ServiceManager.getService(context.getProject(), JavaFileManager.class).findPackage("");
+      PsiPackage topPackage = JavaPsiFacade.getInstance(context.getProject()).findPackage("");
       if (module != null && topPackage != null) {
         processPackage(topPackage, new ModulesScope(module), result);
       }
     }
+    else if (statement instanceof PsiUsesStatement) {
+      processClasses(context.getProject(), null, resultSet, SERVICE_FILTER, TailType.SEMICOLON);
+    }
+    else if (statement instanceof PsiProvidesStatement) {
+      PsiJavaCodeReferenceElement intRef = ((PsiProvidesStatement)statement).getInterfaceReference();
+      if (context == intRef) {
+        processClasses(context.getProject(), null, resultSet, SERVICE_FILTER, TailType.HUMBLE_SPACE_BEFORE_WORD);
+      }
+      else if (context == ((PsiProvidesStatement)statement).getImplementationReference() && intRef != null) {
+        PsiElement service = intRef.resolve();
+        Module module = ModuleUtilCore.findModuleForPsiElement(context);
+        if (service instanceof PsiClass && module != null) {
+          Predicate<PsiClass> filter = psiClass -> !psiClass.hasModifierProperty(PsiModifier.ABSTRACT) &&
+                                                   InheritanceUtil.isInheritorOrSelf(psiClass, (PsiClass)service, true);
+          processClasses(context.getProject(), new ModulesScope(module), resultSet, filter, TailType.SEMICOLON);
+        }
+      }
+    }
   }
 
   private static void processPackage(PsiPackage pkg, ModulesScope scope, Consumer<LookupElement> result) {
     String packageName = pkg.getQualifiedName();
-    if (packageName.indexOf('.') > 0 && !PsiUtil.isPackageEmpty(pkg.getDirectories(scope), packageName)) {
-      result.consume(new OverrideableSpace(LookupElementBuilder.create(packageName), TailType.SEMICOLON));
+    if (isQualified(packageName) && !PsiUtil.isPackageEmpty(pkg.getDirectories(scope), packageName)) {
+      result.consume(new OverrideableSpace(lookupElement(pkg), TailType.SEMICOLON));
     }
     for (PsiPackage subPackage : pkg.getSubPackages(scope)) {
       processPackage(subPackage, scope, result);
     }
   }
+
+  private static final Predicate<PsiClass> SERVICE_FILTER =
+    psiClass -> !psiClass.isEnum() && psiClass.hasModifierProperty(PsiModifier.PUBLIC);
+
+  private static void processClasses(Project project,
+                                     GlobalSearchScope scope,
+                                     CompletionResultSet resultSet,
+                                     Predicate<PsiClass> filter,
+                                     TailType tail) {
+    GlobalSearchScope _scope = scope != null ? scope : ProjectScope.getAllScope(project);
+    AllClassesGetter.processJavaClasses(resultSet.getPrefixMatcher(), project, _scope, psiClass -> {
+      if (isQualified(psiClass.getQualifiedName()) && filter.test(psiClass)) {
+        resultSet.addElement(new OverrideableSpace(lookupElement(psiClass), tail));
+      }
+      return true;
+    });
+  }
+
+  private static LookupElementBuilder lookupElement(PsiNamedElement e) {
+    LookupElementBuilder lookup = LookupElementBuilder.create(e).withInsertHandler(FQN_INSERT_HANDLER);
+    String fqn = e instanceof PsiClass ? ((PsiClass)e).getQualifiedName() : ((PsiQualifiedNamedElement)e).getQualifiedName();
+    return fqn != null ? lookup.withPresentableText(fqn) : lookup;
+  }
+
+  private static boolean isQualified(String name) {
+    return name != null && name.indexOf('.') > 0;
+  }
+
+  private static final InsertHandler<LookupElement> FQN_INSERT_HANDLER = new InsertHandler<LookupElement>() {
+    @Override
+    public void handleInsert(InsertionContext context, LookupElement item) {
+      Object e = item.getObject();
+      String fqn = e instanceof PsiClass ? ((PsiClass)e).getQualifiedName() : ((PsiQualifiedNamedElement)e).getQualifiedName();
+      if (fqn != null) {
+        int start = JavaCompletionUtil.findQualifiedNameStart(context);
+        context.getDocument().replaceString(start, context.getTailOffset(), fqn);
+      }
+    }
+  };
 }
\ No newline at end of file
index 5b80538771b4d63ee51354925b4939508cd468be..aa69cb91909bc61d0813a48f59917f74a087d966 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 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.
@@ -42,6 +42,10 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement;
 public class JavaNoVariantsDelegator extends CompletionContributor {
   @Override
   public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
+    if (JavaModuleCompletion.isModuleFile(parameters.getOriginalFile())) {
+      return;
+    }
+
     final JavaCompletionSession session = new JavaCompletionSession(result);
     ResultTracker tracker = new ResultTracker(result) {
       @Override
index 6589f4a815e3dccad57cdabe0f793345baa871d9..cd338c747c8683c95d511ce588783dae568b22f1 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiFormatUtil;
 import com.intellij.psi.util.PsiFormatUtilBase;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.List;
@@ -78,9 +79,7 @@ public class MemberLookupHelper {
     final String params = myMergedOverloads
                           ? "(...)"
                           : myMember instanceof PsiMethod
-                            ? PsiFormatUtil.formatMethod((PsiMethod)myMember, substitutor,
-                                                         PsiFormatUtilBase.SHOW_PARAMETERS,
-                                                         PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE)
+                            ? getMethodParameterString((PsiMethod)myMember, substitutor)
                             : "";
     presentation.clearTail();
     presentation.appendTailText(params, false);
@@ -96,5 +95,9 @@ public class MemberLookupHelper {
     }
   }
 
-
+  @NotNull
+  static String getMethodParameterString(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor) {
+    return PsiFormatUtil.formatMethod(method, substitutor,
+                                      PsiFormatUtilBase.SHOW_PARAMETERS, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE);
+  }
 }
index 75d4d7ec2cdeb1573fc44f34bef7745994a14408..06491b964227a95661b8f7f2c8be64ed776b6a35 100644 (file)
 package com.intellij.codeInsight.template.macro;
 
 import com.intellij.codeInsight.completion.JavaCompletionUtil;
+import com.intellij.codeInsight.completion.JavaMethodCallElement;
+import com.intellij.codeInsight.completion.SmartCompletionDecorator;
 import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.codeInsight.template.ExpressionContext;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.ClassConditionKey;
 import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
 import com.intellij.psi.PsiPackage;
 
 import java.util.List;
@@ -34,6 +37,12 @@ public class JavaTemplateCompletionProcessor implements TemplateCompletionProces
     if (elements != null && elements.size() == 1 && elements.get(0) instanceof PsiPackage) {
       return false;
     }
+
+    Editor editor = context.getEditor();
+    if (editor != null && editor.getUserData(JavaMethodCallElement.ARGUMENT_TEMPLATE_ACTIVE) != null) {
+      return item.as(ClassConditionKey.create(SmartCompletionDecorator.class)) != null;
+    }
+
     return true;
   }
 }
index c53f363a470bf892c0855146bd7544a82686d2d9..0aac8ceb56c6261f5045741efd3c3eaa40f462c4 100644 (file)
@@ -15,7 +15,6 @@
  */
 package com.intellij.codeInspection.deadCode;
 
-import com.intellij.codeInspection.CommonProblemDescriptor;
 import com.intellij.codeInspection.GlobalJavaInspectionContext;
 import com.intellij.codeInspection.InspectionsBundle;
 import com.intellij.codeInspection.ex.*;
@@ -24,6 +23,7 @@ import com.intellij.codeInspection.reference.RefEntity;
 import com.intellij.codeInspection.reference.RefJavaElement;
 import com.intellij.codeInspection.ui.InspectionNode;
 import com.intellij.codeInspection.ui.InspectionResultsView;
+import com.intellij.codeInspection.ui.InspectionTree;
 import com.intellij.codeInspection.ui.InspectionTreeNode;
 import com.intellij.codeInspection.util.RefFilter;
 import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -43,7 +43,7 @@ public class DummyEntryPointsPresentation extends UnusedDeclarationPresentation
   }
 
   @Override
-  public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, CommonProblemDescriptor[] allowedDescriptors) {
+  public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, InspectionTree tree) {
     if (myQuickFixActions == null) {
       myQuickFixActions = new QuickFixAction[]{new MoveEntriesToSuspicious(getToolWrapper())};
     }
index 341b24194be49ec581cc0212670d9a1b5feab1ff..11482cb727c3fb6ad1a8edb7a0162255eaf1303c 100644 (file)
@@ -67,6 +67,7 @@ import javax.swing.text.html.HTML;
 import javax.swing.text.html.HTMLDocument;
 import javax.swing.text.html.HTMLEditorKit;
 import javax.swing.text.html.StyleSheet;
+import javax.swing.tree.TreePath;
 import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
@@ -182,7 +183,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta
   }
 
   @Override
-  public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, CommonProblemDescriptor[] allowedDescriptors) {
+  public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, InspectionTree tree) {
     boolean showFixes = false;
     for (RefEntity element : refElements) {
       if (!getIgnoredRefElements().contains(element) && element.isValid()) {
@@ -192,8 +193,23 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta
     }
 
     if (showFixes) {
-      final QuickFixAction[] fixes = super.getQuickFixes(refElements, allowedDescriptors);
-      return fixes != null ? ArrayUtil.mergeArrays(fixes, myQuickFixActions) : myQuickFixActions;
+      final TreePath[] paths = tree.getSelectionPaths();
+      if (paths != null) {
+        int count = 0;
+        for (TreePath path : paths) {
+          final Object component = path.getLastPathComponent();
+          if (component instanceof ProblemDescriptionNode) {
+            count++;
+          }
+        }
+        if (count > 0) {
+          final QuickFixAction[] fixes = super.getQuickFixes(refElements, tree);
+          if (fixes != null) {
+            return count == paths.length ? fixes : ArrayUtil.mergeArrays(fixes, myQuickFixActions);
+          }
+        }
+      }
+      return myQuickFixActions;
     }
     return QuickFixAction.EMPTY;
   }
index ccb63e96b143925e4fbae70d87d11ebc3fee79bc..544a739d08c6e7fa93057de8ee152e3f743b056f 100644 (file)
@@ -23,6 +23,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.actionSystem.CommonDataKeys
 import com.intellij.openapi.application.ApplicationManager
 import com.intellij.openapi.application.PathManager
+import com.intellij.openapi.diagnostic.Logger
 import com.intellij.openapi.editor.Editor
 import com.intellij.openapi.editor.Inlay
 import com.intellij.openapi.project.Project
@@ -35,6 +36,10 @@ class ReportMissingOrExcessiveInlineHint : AnAction() {
   private val text = "Report Missing or Excessive Inline Hint"
   private val description = "Text line at caret will be anonymously reported to our servers"
   
+  companion object {
+    private val LOG = Logger.getInstance(ReportMissingOrExcessiveInlineHint::class.java)
+  }
+  
   init {
     val presentation = templatePresentation
     presentation.text = text
@@ -85,12 +90,14 @@ class ReportMissingOrExcessiveInlineHint : AnAction() {
   }
 
   private fun trySendFileInBackground() {
+    LOG.debug("File: ${file.path} Length: ${file.length()}")
     if (!file.exists() || file.length() == 0L) return
-
     ApplicationManager.getApplication().executeOnPooledThread {
       val text = file.readText()
+      LOG.debug("File text $text")
       if (StatsSender.send(text)) {
         file.delete()
+        LOG.debug("File deleted")
       }
     }
   }
index c2a01117d72b859882c5549937de38e74e0dd553..7ac842b289283cedc14d5454e081559b6103bb74 100644 (file)
@@ -63,9 +63,10 @@ class ConstructorReferencesSearchHelper {
     DumbService.getInstance(project).runReadActionInSmartMode(new Computable<Void>() {
       @Override
       public Void compute() {
-        constructorCanBeCalledImplicitly[0] = constructor.getParameterList().getParametersCount() == 0;
+        final PsiParameter[] parameters = constructor.getParameterList().getParameters();
+        constructorCanBeCalledImplicitly[0] = parameters.length == 0;
         if (!constructorCanBeCalledImplicitly[0]) {
-          constructorCanBeCalledImplicitly[0] = hasDefaultConstructorWithVarargParameter(containingClass);
+          constructorCanBeCalledImplicitly[0] = parameters.length == 1 && parameters[0].isVarArgs();
         }
         isEnum[0] = containingClass.isEnum();
         isUnder18[0] = PsiUtil.getLanguageLevel(containingClass).isAtLeast(LanguageLevel.JDK_1_8);
@@ -127,17 +128,6 @@ class ConstructorReferencesSearchHelper {
     return ClassInheritorsSearch.search(containingClass, searchScope, false).forEach(processor2);
   }
 
-  private static boolean hasDefaultConstructorWithVarargParameter(@NotNull PsiClass containingClass) {
-    final PsiMethod[] constructors = containingClass.getConstructors();
-    for (PsiMethod ctr : constructors) {
-      final PsiParameter[] parameters = ctr.getParameterList().getParameters();
-      if (parameters.length == 1 && parameters[0].isVarArgs()) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   private static boolean processEnumReferences(@NotNull final Processor<PsiReference> processor,
                                                @NotNull final PsiMethod constructor,
                                                @NotNull final Project project,
index deb016b7d84ad9851efc181072901129961d70d2..9216f033cb5aa108d5f19003d293adfe767ec9d7 100644 (file)
@@ -21,13 +21,19 @@ import com.intellij.psi.JavaTokenType;
 import com.intellij.psi.PsiKeyword;
 import com.intellij.psi.impl.source.tree.JavaElementType;
 import com.intellij.psi.tree.IElementType;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Set;
+
 import static com.intellij.lang.PsiBuilderUtil.expect;
 import static com.intellij.lang.java.parser.JavaParserUtil.error;
 import static com.intellij.lang.java.parser.JavaParserUtil.semicolon;
 
 public class ModuleParser {
+  private static final Set<String> STATEMENT_KEYWORDS =
+    ContainerUtil.newHashSet(PsiKeyword.REQUIRES, PsiKeyword.EXPORTS, PsiKeyword.USES, PsiKeyword.PROVIDES);
+
   public static void parseModule(@NotNull PsiBuilder builder) {
     PsiBuilder.Marker module = builder.mark();
     mapAndAdvance(builder, JavaTokenType.MODULE_KEYWORD);
@@ -225,7 +231,15 @@ public class ModuleParser {
       }
     }
     else if (!hasError) {
-      error(builder, JavaErrorMessages.message("expected.with"));
+      IElementType next = builder.getTokenType();
+      if (next == JavaTokenType.IDENTIFIER && !STATEMENT_KEYWORDS.contains(builder.getTokenText())) {
+        PsiBuilder.Marker marker = builder.mark();
+        builder.advanceLexer();
+        marker.error(JavaErrorMessages.message("expected.with"));
+      }
+      else {
+        error(builder, JavaErrorMessages.message("expected.with"));
+      }
       hasError = true;
     }
 
index ca9663bdaf8da8cf1cfe55b79b732ca839de2550..d63e372a501f9565208232b6c17f1651a906e116 100644 (file)
@@ -20,7 +20,6 @@ import com.intellij.psi.*;
 import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
 import com.intellij.psi.impl.java.stubs.PsiClassStub;
 import com.intellij.psi.impl.source.tree.ChildRole;
-import com.intellij.psi.impl.source.tree.SharedImplUtil;
 import com.intellij.psi.scope.PsiScopeProcessor;
 import com.intellij.reference.SoftReference;
 import com.intellij.util.IncorrectOperationException;
@@ -66,7 +65,7 @@ public class PsiAnonymousClassImpl extends PsiClassImpl implements PsiAnonymousC
   @Override
   @NotNull
   public PsiClassType getBaseClassType() {
-    final PsiClassStub stub = getStub();
+    final PsiClassStub stub = getGreenStub();
     if (stub == null) {
       myCachedBaseType = null;
       return getTypeByTree();
@@ -192,7 +191,7 @@ public class PsiAnonymousClassImpl extends PsiClassImpl implements PsiAnonymousC
 
   @Override
   public boolean isInQualifiedNew() {
-    final PsiClassStub stub = getStub();
+    final PsiClassStub stub = getGreenStub();
     if (stub != null) {
       return stub.isAnonymousInQualifiedNew();
     }
index e016b427967028ff8a54d05a1cceb3a21b69e1fa..ab28e1992311a44eb58eb514b0f39eed4681e12b 100644 (file)
@@ -242,7 +242,7 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements
   @Override
   @Nullable
   public PsiClass getContainingClass() {
-    final PsiClassStub stub = getStub();
+    final PsiClassStub stub = getGreenStub();
     if (stub != null) {
       StubElement parent = stub.getParentStub();
       return parent instanceof PsiClassStub ? ((PsiClassStub<?>)parent).getPsi() : null;
@@ -540,7 +540,7 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements
   private static boolean isAnonymousOrLocal(PsiClass aClass) {
     if (aClass instanceof PsiAnonymousClass) return true;
 
-    final PsiClassStub stub = ((PsiClassImpl)aClass).getStub();
+    final PsiClassStub stub = ((PsiClassImpl)aClass).getGreenStub();
     if (stub != null) {
       final StubElement parentStub = stub.getParentStub();
       return !(parentStub instanceof PsiClassStub || parentStub instanceof PsiFileStub);
index 3ffb565ab5ca416be706a9ccc431aa7fad8b93d5..47b3d271e948ab2790a9cfc314c6c042b9d4268d 100644 (file)
@@ -174,7 +174,7 @@ public class PsiEnumConstantImpl extends JavaStubPsiElement<PsiFieldStub> implem
   @Override
   @NotNull
   public String getName() {
-    final PsiFieldStub stub = getStub();
+    final PsiFieldStub stub = getGreenStub();
     if (stub != null) {
       return stub.getName();
     }
@@ -194,7 +194,7 @@ public class PsiEnumConstantImpl extends JavaStubPsiElement<PsiFieldStub> implem
 
   @Override
   public boolean isDeprecated() {
-    final PsiFieldStub stub = getStub();
+    final PsiFieldStub stub = getGreenStub();
     if (stub != null) {
       return stub.isDeprecated();
     }
index db17f1a9b9e5d5e66797bf7d2ecea22832279a41..3b0ad2efed612ff9d88048aff871b335eb1c81ef 100644 (file)
@@ -104,7 +104,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
   @Override
   @NotNull
   public String getName() {
-    final PsiFieldStub stub = getStub();
+    final PsiFieldStub stub = getGreenStub();
     if (stub != null) {
       return stub.getName();
     }
@@ -185,7 +185,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
   private PsiField findFirstFieldInDeclaration() {
     if (getSelfModifierList() != null) return this;
 
-    final PsiFieldStub stub = getStub();
+    final PsiFieldStub stub = getGreenStub();
     if (stub != null) {
       final List siblings = stub.getParentStub().getChildrenStubs();
       final int idx = siblings.indexOf(stub);
@@ -226,7 +226,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
   // avoids stub-to-AST switch if possible,
   // returns the light generated initializer literal expression if stored in stubs, the regular initializer if wasn't
   public PsiExpression getDetachedInitializer() {
-    final PsiFieldStub stub = getStub();
+    final PsiFieldStub stub = getGreenStub();
     PsiExpression initializer;
     if (stub == null) {
       initializer = getInitializer();
@@ -251,7 +251,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
 
   @Override
   public boolean hasInitializer() {
-    PsiFieldStub stub = getStub();
+    PsiFieldStub stub = getGreenStub();
     if (stub != null) {
       return stub.getInitializerText() != null;
     }
@@ -299,7 +299,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
 
   @Override
   public boolean isDeprecated() {
-    final PsiFieldStub stub = getStub();
+    final PsiFieldStub stub = getGreenStub();
     if (stub != null) {
       return stub.isDeprecated() || stub.hasDeprecatedAnnotation() && PsiImplUtil.isDeprecatedByAnnotation(this);
     }
@@ -309,7 +309,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
 
   @Override
   public PsiDocComment getDocComment(){
-    final PsiFieldStub stub = getStub();
+    final PsiFieldStub stub = getGreenStub();
     if (stub != null && !stub.hasDocComment()) return null;
 
     CompositeElement treeElement = getNode();
index c5af2ad5b312cafa51e255f7ae81bafacfec1876..ceb6ce7d91165a49d4dc2abcbf0d76016ba4843a 100644 (file)
@@ -40,7 +40,7 @@ public abstract class PsiImportStatementBaseImpl extends JavaStubPsiElement<PsiI
 
   @Override
   public boolean isOnDemand(){
-    final PsiImportStatementStub stub = getStub();
+    final PsiImportStatementStub stub = getGreenStub();
     if (stub != null) {
       return stub.isOnDemand();
     }
index 80461d3208eb1b62aa6272fa100a01e1bd6ec6a0..7557e97b7c3c8c29ee89c33726ddde1bad6ce04b 100644 (file)
@@ -42,7 +42,7 @@ public class PsiImportStatementImpl extends PsiImportStatementBaseImpl implement
 
   @Override
   public String getQualifiedName() {
-    PsiImportStatementStub stub = getStub();
+    PsiImportStatementStub stub = getGreenStub();
     if (stub != null) {
       return stub.getImportReferenceText();
     }
index f38b9673640ef4b1e93fbc0dabcba67ea8d52426..4b271df37581fd3873ca09349cc9db2550fde2b2 100644 (file)
@@ -38,7 +38,7 @@ public class PsiJavaFileImpl extends PsiJavaFileBaseImpl {
   @Nullable
   @Override
   public PsiJavaModule getModuleDeclaration() {
-    PsiJavaFileStub stub = (PsiJavaFileStub)getStub();
+    PsiJavaFileStub stub = (PsiJavaFileStub)getGreenStub();
     if (stub != null) {
       return stub.getModule();
     }
index 9e1194a6da50470237a9e4e805c7e17c565aa9ef..3ac01a892e8d9889360b1ffb5a2d16c12128c9d0 100644 (file)
@@ -43,7 +43,7 @@ public class PsiJavaModuleImpl extends JavaStubPsiElement<PsiJavaModuleStub> imp
   @NotNull
   @Override
   public String getModuleName() {
-    PsiJavaModuleStub stub = getStub();
+    PsiJavaModuleStub stub = getGreenStub();
     if (stub != null) {
       return stub.getName();
     }
index f565fc1541d4038906222faf500c27495f8e4ecb..e9e08148a1faf819027b33e1fba15ee523ebf908 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.navigation.ItemPresentation;
 import com.intellij.navigation.ItemPresentationProviders;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.ui.Queryable;
+import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Computable;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.ElementPresentationUtil;
@@ -136,7 +137,7 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
   @NotNull
   public String getName() {
     final String name;
-    final PsiMethodStub stub = getStub();
+    final PsiMethodStub stub = getGreenStub();
     if (stub != null) {
       name = stub.getName();
     }
@@ -241,7 +242,7 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
 
   @Override
   public boolean isDeprecated() {
-    final PsiMethodStub stub = getStub();
+    final PsiMethodStub stub = getGreenStub();
     if (stub != null) {
       return stub.isDeprecated() || stub.hasDeprecatedAnnotation() && PsiImplUtil.isDeprecatedByAnnotation(this);
     }
@@ -251,7 +252,7 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
 
   @Override
   public PsiDocComment getDocComment() {
-    final PsiMethodStub stub = getStub();
+    final PsiMethodStub stub = getGreenStub();
     if (stub != null && !stub.hasDocComment()) return null;
 
     return (PsiDocComment)getNode().findChildByRoleAsPsiElement(ChildRole.DOC_COMMENT);
@@ -259,7 +260,7 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
 
   @Override
   public boolean isConstructor() {
-    final PsiMethodStub stub = getStub();
+    final PsiMethodStub stub = getGreenStub();
     if (stub != null) {
       return stub.isConstructor();
     }
@@ -269,7 +270,7 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
 
   @Override
   public boolean isVarArgs() {
-    final PsiMethodStub stub = getStub();
+    final PsiMethodStub stub = getGreenStub();
     if (stub != null) {
       return stub.isVarArgs();
     }
index 5276b11f0efa47569afde5d0c5b4b6f8bfdfa4a2..c9cc626e371bf903d02147ffc015739652c1c47c 100644 (file)
@@ -113,7 +113,7 @@ public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> imple
   @Override
   @NotNull
   public final String getName() {
-    PsiParameterStub stub = getStub();
+    PsiParameterStub stub = getGreenStub();
     if (stub != null) {
       return stub.getName();
     }
@@ -269,7 +269,7 @@ public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> imple
 
   @Override
   public boolean isVarArgs() {
-    final PsiParameterStub stub = getStub();
+    final PsiParameterStub stub = getGreenStub();
     if (stub != null) {
       return stub.isParameterTypeEllipsis();
     }
index 687c19f90dfefc28818c945022da3427621955e0..c4ac677bacfa887180f88ef25b0ae3be6bc5ff44 100644 (file)
@@ -59,7 +59,7 @@ public class PsiParameterListImpl extends JavaStubPsiElement<PsiParameterListStu
 
   @Override
   public int getParametersCount() {
-    final PsiParameterListStub stub = getStub();
+    final PsiParameterListStub stub = getGreenStub();
     if (stub != null) {
       return stub.getChildrenStubs().size();
     }
index 45af142ce662e759ef1a6094c8173b7ade745dc6..ec047c75b55b660e5c8ed807676b3f56d2132e35 100644 (file)
@@ -47,7 +47,7 @@ public class PsiReferenceListImpl extends JavaStubPsiElement<PsiClassReferenceLi
   @Override
   @NotNull
   public PsiClassType[] getReferencedTypes() {
-    PsiClassReferenceListStub stub = getStub();
+    PsiClassReferenceListStub stub = getGreenStub();
     if (stub != null) {
       return stub.getReferencedTypes();
     }
index c72dd2e848c912950ffb55b244ba085b9b698713..19bddc67cebd55179ef07501b53f3ddaba4caca6 100644 (file)
@@ -98,7 +98,7 @@ public class PsiLiteralExpressionImpl
   }
 
   public IElementType getLiteralElementType() {
-    PsiLiteralStub stub = getStub();
+    PsiLiteralStub stub = getGreenStub();
     if (stub != null) return stub.getLiteralType();
 
     return getNode().getFirstChildNode().getElementType();
@@ -111,7 +111,7 @@ public class PsiLiteralExpressionImpl
 
   @Override
   public String getText() {
-    PsiLiteralStub stub = getStub();
+    PsiLiteralStub stub = getGreenStub();
     if (stub != null) return stub.getLiteralText();
 
     return super.getText();
index 82055e0facfa7b1aa5a7414dd399c67e546209b4..91ca51afe8d21de1354496b9cfd363abc4e062e8 100644 (file)
@@ -103,7 +103,7 @@ public class PsiNameValuePairImpl extends JavaStubPsiElement<PsiNameValuePairStu
   @Override
   @Nullable
   public PsiAnnotationMemberValue getDetachedValue() {
-    PsiNameValuePairStub stub = getStub();
+    PsiNameValuePairStub stub = getGreenStub();
     if (stub != null) {
       String text = stub.getValue();
       PsiAnnotationMemberValue result = SoftReference.dereference(myDetachedValue);
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorCounting.java b/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorCounting.java
new file mode 100644 (file)
index 0000000..71e3b19
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(counting()) with Stream.count()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public long count(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).count();
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorMapping.java b/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorMapping.java
new file mode 100644 (file)
index 0000000..5947f90
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(mapping()) with Stream.map().collect()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public List<Integer> sizes(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).map(String::length).collect(Collectors.toList());
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorMaxBy.java b/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorMaxBy.java
new file mode 100644 (file)
index 0000000..d854a72
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(maxBy()) with Stream.max() (may change semantics when result is null)" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public String max(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).max(String.CASE_INSENSITIVE_ORDER).orElse("");
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorMinBy.java b/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorMinBy.java
new file mode 100644 (file)
index 0000000..c9feaba
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(minBy()) with Stream.min() (may change semantics when result is null)" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public Optional<String> min(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).min(String.CASE_INSENSITIVE_ORDER);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorReducing1.java b/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorReducing1.java
new file mode 100644 (file)
index 0000000..37374e3
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(reducing()) with Stream.reduce() (may change semantics when result is null)" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public Optional<String> concat(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).reduce(String::concat);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorReducing2.java b/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorReducing2.java
new file mode 100644 (file)
index 0000000..a5a5a24
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(reducing()) with Stream.reduce()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public String concat(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).reduce("", String::concat);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorReducing3.java b/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorReducing3.java
new file mode 100644 (file)
index 0000000..ab3b2cc
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(reducing()) with Stream.map().reduce()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public int sum(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).map(String::length).reduce(0, Integer::sum);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorSummingInt.java b/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorSummingInt.java
new file mode 100644 (file)
index 0000000..249a035
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(summingInt()) with Stream.mapToInt().sum()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public void remove(List<Integer> ints, List<String> data) {
+    ints.remove((Integer) data.stream().mapToInt(String::length).sum());
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorSummingLong.java b/java/java-tests/testData/inspection/streamApiCallChains/afterCollectorSummingLong.java
new file mode 100644 (file)
index 0000000..6b86f89
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(summingLong()) with Stream.mapToLong().sum()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public void remove(List<Integer> ints, List<String> data) {
+    ints.remove(data.stream().mapToLong(String::length).sum());
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorCounting.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorCounting.java
new file mode 100644 (file)
index 0000000..b403422
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(counting()) with Stream.count()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public long count(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).collect(Collectors.<caret>counting());
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorMapping.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorMapping.java
new file mode 100644 (file)
index 0000000..a6642d7
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(mapping()) with Stream.map().collect()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public List<Integer> sizes(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).collect(Collectors.mapping(Str<caret>ing::length, Collectors.toList()));
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorMaxBy.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorMaxBy.java
new file mode 100644 (file)
index 0000000..e6c59cd
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(maxBy()) with Stream.max() (may change semantics when result is null)" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public String max(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).collect(Collectors.maxBy(String.CASE_INSENSIT<caret>IVE_ORDER)).orElse("");
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorMinBy.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorMinBy.java
new file mode 100644 (file)
index 0000000..7be18c5
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(minBy()) with Stream.min() (may change semantics when result is null)" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public Optional<String> min(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).collect(Collectors.minBy(Str<caret>ing.CASE_INSENSITIVE_ORDER));
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorReducing1.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorReducing1.java
new file mode 100644 (file)
index 0000000..a10971f
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(reducing()) with Stream.reduce() (may change semantics when result is null)" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public Optional<String> concat(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).colle<caret>ct(Collectors.reducing(String::concat));
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorReducing2.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorReducing2.java
new file mode 100644 (file)
index 0000000..0f0da24
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(reducing()) with Stream.reduce()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public String concat(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).colle<caret>ct(Collectors.reducing("", String::concat));
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorReducing3.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorReducing3.java
new file mode 100644 (file)
index 0000000..7ac6bff
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(reducing()) with Stream.map().reduce()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public int sum(List<String> data) {
+    return data.stream().filter(x -> x.startsWith("xyz")).colle<caret>ct(Collectors.reducing(0, String::length, Integer::sum));
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorSummingInt.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorSummingInt.java
new file mode 100644 (file)
index 0000000..0a0e776
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(summingInt()) with Stream.mapToInt().sum()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public void remove(List<Integer> ints, List<String> data) {
+    ints.remove(data.stream().collect(Collectors<caret>.summingInt(String::length)));
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorSummingLong.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeCollectorSummingLong.java
new file mode 100644 (file)
index 0000000..305cc7b
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.collect(summingLong()) with Stream.mapToLong().sum()" "true"
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Main {
+  public void remove(List<Integer> ints, List<String> data) {
+    ints.remove(data.stream().collect(Collectors<caret>.summingLong(String::length)));
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/modules/Provides7.txt b/java/java-tests/testData/psi/parser-partial/modules/Provides7.txt
new file mode 100644 (file)
index 0000000..df577c3
--- /dev/null
@@ -0,0 +1,21 @@
+PsiJavaFile:Provides7.java
+  PsiJavaModule:M
+    PsiKeyword:module('module')
+    PsiWhiteSpace(' ')
+    PsiJavaModuleReference
+      PsiIdentifier:M('M')
+    PsiWhiteSpace(' ')
+    PsiJavaToken:LBRACE('{')
+    PsiWhiteSpace(' ')
+    PsiProvidesStatement
+      PsiKeyword:provides('provides')
+      PsiWhiteSpace(' ')
+      PsiJavaCodeReferenceElement:Spi
+        PsiIdentifier:Spi('Spi')
+        PsiReferenceParameterList
+          <empty list>
+      PsiWhiteSpace(' ')
+      PsiErrorElement:'with' expected
+        PsiIdentifier:_('_')
+    PsiWhiteSpace(' ')
+    PsiJavaToken:RBRACE('}')
\ No newline at end of file
index 28dd8eb350898f64f143f6dfdb8081187abc0277..9fcd9c2fc2a0deb4eac4db1621040362382537b2 100644 (file)
@@ -33,7 +33,22 @@ class ModuleCompletionTest : LightFixtureCompletionTestCase() {
     addFile("pkg/empty/package-info.java", "package pkg.empty;")
     addFile("pkg/main/C.java", "package pkg.main;\nclass C { }")
     addFile("pkg/other/C.groovy", "package pkg.other\nclass C { }")
-    variants("module M { exports pkg.<caret> }", "pkg.main", "pkg.other")
+    variants("module M { exports pkg.<caret> }", "main", "other")
+    complete("module M { exports pkg.o<caret> }", "module M { exports pkg.other;<caret> }")
+  }
+
+  fun testUses() {
+    addFile("pkg/main/MySvc.java", "package pkg.main;\npublic class MySvc { }")
+    addFile("pkg/main/MySvcImpl.java", "package pkg.main;\nclass MySvcImpl extends MySvc { }")
+    complete("module M { uses MyS<caret> }", "module M { uses pkg.main.MySvc;<caret> }")
+  }
+
+  fun testProvides() {
+    addFile("pkg/main/MySvc.java", "package pkg.main;\npublic class MySvc { }")
+    addFile("pkg/main/MySvcImpl.java", "package pkg.main;\nclass MySvcImpl extends MySvc { }")
+    complete("module M { provides MyS<caret> }", "module M { provides pkg.main.MySvc <caret> }")
+    complete("module M { provides pkg.main.MySvc <caret> }", "module M { provides pkg.main.MySvc with <caret> }")
+    complete("module M { provides pkg.main.MySvc with MSI<caret> }", "module M { provides pkg.main.MySvc with pkg.main.MySvcImpl;<caret> }")
   }
 
   //<editor-fold desc="Helpers.">
index 2c4ad310ede7d37e24778eeebd46881286b38325..5141a5d897a1b92683e123939452634765a5dd2f 100644 (file)
@@ -69,6 +69,7 @@ public class ModuleParserTest extends JavaParsingTestCase {
   public void testProvides4() { doParserTest("module M { provides Spi with ; }"); }
   public void testProvides5() { doParserTest("module M { provides Spi with Impl }"); }
   public void testProvides6() { doParserTest("module M { provides Spi with Impl; }"); }
+  public void testProvides7() { doParserTest("module M { provides Spi _ }"); }
 
   private void doParserTest(String text) {
     doParserTest(text, builder -> JavaParser.INSTANCE.getFileParser().parse(builder));
index 6385b079f4504ca9e5d6a2514e3deec27b694d22..748e49e02da67c54d14fc29fce45ef0f035c3461 100644 (file)
  */
 package com.intellij.refactoring.typeMigration.rules;
 
+import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
 import com.intellij.refactoring.typeMigration.TypeEvaluator;
 import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
 import com.intellij.util.IncorrectOperationException;
 import com.siyeh.ig.controlflow.UnnecessaryReturnInspection;
+import com.siyeh.ig.fixes.DeleteUnnecessaryStatementFix;
 import com.siyeh.ig.psiutils.SideEffectChecker;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -43,10 +45,11 @@ public class VoidConversionRule extends TypeConversionRule {
         @Override
         public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException {
           final PsiElement parent = expression.getParent();
+          final Project project = expression.getProject();
           if (parent instanceof PsiReturnStatement) {
-            expression.delete();
-            if (UnnecessaryReturnInspection.isReturnRedundant((PsiReturnStatement)parent, false, null)) {
-              parent.delete();
+            final PsiReturnStatement replaced = (PsiReturnStatement)parent.replace(JavaPsiFacade.getElementFactory(project).createStatementFromText("return;", null));
+            if (UnnecessaryReturnInspection.isReturnRedundant(replaced, false, null)) {
+              DeleteUnnecessaryStatementFix.deleteUnnecessaryStatement(replaced);
             }
           }
           return null;
index 6a57e2707ac7b3d4bee520790783054b93eb2315..5dacdb596078845b66abf943a4a777cb16f52943 100644 (file)
@@ -28,6 +28,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 
 /**
  * In-memory representation of JVM *.class file produced by a compiler.
@@ -84,7 +85,7 @@ public class CompiledClass extends UserDataHolderBase{
   }
 
   @NotNull
-  public Collection<String> getSourceFilesPaths() {
+  public List<String> getSourceFilesPaths() {
     return ContainerUtil.map(mySourceFiles, new Function<File, String>() {
       @Override
       public String fun(File file) {
index fffa64cb6ccbb5903a8c0bb48e3d1708efada2df..f8c46abf3e5711c7a94b354ae34094a468a87db4 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
 import com.intellij.compiler.instrumentation.InstrumenterClassWriter;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Key;
+import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.jps.ModuleChunk;
 import org.jetbrains.jps.incremental.*;
@@ -72,7 +73,7 @@ public abstract class BaseInstrumentingBuilder extends ClassProcessingBuilder {
         LOG.info(e);
         final String message = e.getMessage();
         if (message != null) {
-          context.processMessage(new CompilerMessage(getPresentableName(), message, compiledClass.getSourceFilesPaths(), BuildMessage.Kind.ERROR));
+          context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, message, ContainerUtil.getFirstItem(compiledClass.getSourceFilesPaths())));
         }
         else {
           context.processMessage(new CompilerMessage(getPresentableName(), e));
index 5ae766ce0e59300ec85287662c6fd14310cc6874..a4e7873b373b0bf78caf9ee10b522272e91d30da 100644 (file)
@@ -93,9 +93,9 @@ public class NotNullInstrumentingBuilder extends BaseInstrumentingBuilder{
         }
       }) + ": " + e.getMessage();
       context.processMessage(new CompilerMessage(getPresentableName(),
+                                                 BuildMessage.Kind.ERROR,
                                                  msg,
-                                                 compiledClass.getSourceFilesPaths(),
-                                                 BuildMessage.Kind.ERROR));
+                                                 ContainerUtil.getFirstItem(compiledClass.getSourceFilesPaths())));
     }
     return null;
   }
index c627ab7df75a09c9fc4f318465a2e954d91e3a7b..a594a9bef12d11a993563c1a573706b187184068 100644 (file)
 package org.jetbrains.jps.incremental.messages;
 
 import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.Function;
-import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.PrintStream;
-import java.util.Collection;
-import java.util.Collections;
 
 /**
  * @author Eugene Zhuravlev
@@ -37,28 +33,24 @@ public class CompilerMessage extends BuildMessage {
   private final long myProblemBeginOffset;
   private final long myProblemEndOffset;
   private final long myProblemLocationOffset;
-  private final Collection<String> mySourcePaths;
+  private final String mySourcePath;
   private final long myLine;
   private final long myColumn;
 
   public CompilerMessage(@NotNull String compilerName, @NotNull Throwable internalError) {
-    this(compilerName, Kind.ERROR, getTextFromThrowable(internalError));
+    this(compilerName, Kind.ERROR, getTextFromThrowable(internalError), null, -1L, -1L, -1L, -1L, -1L);
   }
 
   public CompilerMessage(@NotNull String compilerName, Kind kind, String messageText) {
-    this(compilerName, kind, messageText, (String)null, -1L, -1L, -1L, -1L, -1L);
-  }
-
-  public CompilerMessage(@NotNull String compilerName, String messageText, Collection<String> sourcePaths, Kind kind) {
-    this(compilerName, kind, messageText, sourcePaths, -1L, -1L, -1L, -1L, -1L);
+    this(compilerName, kind, messageText, null, -1L, -1L, -1L, -1L, -1L);
   }
 
   public CompilerMessage(@NotNull String compilerName, Kind kind, String messageText, String sourcePath) {
-    this(compilerName, messageText, sourcePath == null ? Collections.<String>emptyList() : Collections.singleton(sourcePath), kind);
+    this(compilerName, kind, messageText, sourcePath, -1L, -1L, -1L, -1L, -1L);
   }
 
   public CompilerMessage(@NotNull String compilerName, Kind kind, String messageText,
-                         @NotNull Collection<String> sourcePaths,
+                         @Nullable String sourcePath,
                          long problemBeginOffset,
                          long problemEndOffset,
                          long problemLocationOffset,
@@ -69,34 +61,11 @@ public class CompilerMessage extends BuildMessage {
     myProblemBeginOffset = problemBeginOffset;
     myProblemEndOffset = problemEndOffset;
     myProblemLocationOffset = problemLocationOffset;
-    mySourcePaths = ContainerUtil.map(sourcePaths, new Function<String, String>() {
-      @Override
-      public String fun(String s) {
-        return s.replace(File.separatorChar, '/');
-      }
-    });
+    mySourcePath = sourcePath != null && !sourcePath.isEmpty()? sourcePath.replace(File.separatorChar, '/') : null;
     myLine = locationLine;
     myColumn = locationColumn;
   }
 
-  public CompilerMessage(@NotNull String compilerName, Kind kind, String messageText,
-                         @Nullable String sourcePath,
-                         long problemBeginOffset,
-                         long problemEndOffset,
-                         long problemLocationOffset,
-                         long locationLine,
-                         long locationColumn) {
-    this(compilerName,
-         kind,
-         messageText,
-         sourcePath == null ? Collections.<String>emptyList() : Collections.singleton(sourcePath),
-         problemBeginOffset,
-         problemEndOffset,
-         problemLocationOffset,
-         locationLine,
-         locationColumn);
-  }
-
   @NotNull
   public String getCompilerName() {
     return myCompilerName;
@@ -104,7 +73,7 @@ public class CompilerMessage extends BuildMessage {
 
   @Nullable
   public String getSourcePath() {
-    return mySourcePaths.size() == 1 ? ContainerUtil.getFirstItem(mySourcePaths) : null;
+    return mySourcePath;
   }
 
   public long getLine() {
@@ -130,16 +99,7 @@ public class CompilerMessage extends BuildMessage {
   public String toString() {
     final StringBuilder builder = new StringBuilder();
     builder.append(getCompilerName()).append(":").append(getKind().name()).append(":").append(super.toString());
-    String result;
-    if (mySourcePaths.isEmpty()) {
-      result = null;
-    }
-    else if (mySourcePaths.size() == 1) {
-      result = ContainerUtil.getFirstItem(mySourcePaths);
-    } else {
-      result = mySourcePaths.toString();
-    }
-    final String path = result;
+    final String path = getSourcePath();
     if (path != null) {
       builder.append("; file: ").append(path);
       final long line = getLine();
index 78c18d1aef00bacc7594ae35603bf7876a54fa1e..444c78bd77b86c9b95f03feefd019790f5afff0a 100644 (file)
@@ -121,8 +121,7 @@ public class JsonSchemaDefinitionResolver {
         if (parSchema.getId() != null) {
           schemaFile = JsonSchemaService.Impl.getEx(myElement.getProject()).getSchemaFileById(parSchema.getId());
         }
-        return resolveInSomeSchema(definitionAddress.substring(1) + PROPERTIES + propertyName, myElement.getProject(), parSchema.getId(),
-                                   schemaFile != null ? GlobalSearchScope.fileScope(myElement.getProject(), schemaFile) : null);
+        return resolveInSomeSchema(definitionAddress.substring(1) + PROPERTIES + propertyName, myElement.getProject(), parSchema.getId(), schemaFile);
       } else {
         String relative = splitter.getRelativePath();
         if (StringUtil.isEmptyOrSpaces(relative)) {
@@ -139,19 +138,20 @@ public class JsonSchemaDefinitionResolver {
     if (myRef == null) initializeName();
     if (myRef == null) return null;
 
-    GlobalSearchScope filter = null;
+    VirtualFile filter = null;
     if (mySchemaId != null && myRef.startsWith("#/")) {
-      filter = GlobalSearchScope.fileScope(myElement.getContainingFile());
+      filter = myElement.getContainingFile().getVirtualFile();
     }
     else {
       final JsonSchemaServiceEx schemaServiceEx = JsonSchemaService.Impl.getEx(myElement.getProject());
       final Collection<Pair<VirtualFile, String>> pairs = schemaServiceEx.getSchemaFilesByFile(myElement.getContainingFile().getVirtualFile());
       if (pairs != null && ! pairs.isEmpty()) {
         for (Pair<VirtualFile, String> pair : pairs) {
-          final PsiElement element = resolveInSomeSchema(myRef, myElement.getProject(), pair.getSecond(),
-                                                         GlobalSearchScope.fileScope(myElement.getProject(), pair.getFirst()));
+          final PsiElement element = resolveInSomeSchema(myRef, myElement.getProject(), pair.getSecond(), pair.getFirst());
           if (element != null) return element;
         }
+        // if not in schema file
+        if (mySchemaId == null) return null;
       }
     }
     return resolveInSomeSchema(myRef, myElement.getProject(), mySchemaId, filter);
@@ -161,10 +161,13 @@ public class JsonSchemaDefinitionResolver {
   private static PsiElement resolveInSomeSchema(@NotNull String referenceName,
                                                 @NotNull final Project project,
                                                 @Nullable final String schemaId,
-                                                final @Nullable GlobalSearchScope filter) {
+                                                final @Nullable VirtualFile filterFile) {
     final Ref<Pair<VirtualFile, Integer>> reference = new Ref<>();
 
     final FileBasedIndex index = FileBasedIndex.getInstance();
+    final GlobalSearchScope fileScope = filterFile == null ? null : GlobalSearchScope.fileScope(project, filterFile);
+    final GlobalSearchScope enlarged = fileScope != null && JsonSchemaResourcesRootsProvider.ourFiles.getValue().contains(filterFile) ? fileScope :
+                                       JsonSchemaResourcesRootsProvider.enlarge(project, fileScope == null ? GlobalSearchScope.allScope(project) : fileScope);
     index.processValues(JsonSchemaFileIndex.PROPERTIES_INDEX, referenceName, null, new FileBasedIndex.ValueProcessor<Integer>() {
       @Override
       public boolean process(VirtualFile file, Integer value) {
@@ -176,7 +179,7 @@ public class JsonSchemaDefinitionResolver {
         reference.set(Pair.create(file, value));
         return false;
       }
-    }, JsonSchemaResourcesRootsProvider.enlarge(project, filter == null ? GlobalSearchScope.allScope(project) : filter));
+    }, enlarged);
 
     if (!reference.isNull()) {
       final Pair<VirtualFile, Integer> pair = reference.get();
index 296bf2d23f2a06992f7e447546f9451b95a8ad20..d61dea1c9ca5106f48d95c052021af8bb0af65b9 100644 (file)
@@ -35,7 +35,7 @@ import java.util.Map;
  */
 public class JsonSchemaFileIndex extends FileBasedIndexExtension<String, Integer> {
   public static final ID<String, Integer> PROPERTIES_INDEX = ID.create("json.schema.properties.index");
-  public static final int VERSION = 4;
+  public static final int VERSION = 5;
   private IntInlineKeyDescriptor myKeyDescriptor = new IntInlineKeyDescriptor();
 
   @NotNull
index dd6801d6a9313c4f2945a61f553b5a4ecc2df468..97637deb51f817eb7af7268e0ade6f7c0fc20f39 100644 (file)
@@ -159,6 +159,11 @@ public class SeverityRegistrar implements Comparator<HighlightSeverity> {
         read.add(severity);
       }
     }
+    myOrderMap = ensureAllStandardIncluded(read, knownSeverities);
+    severitiesChanged();
+  }
+
+  private OrderMap ensureAllStandardIncluded(List<HighlightSeverity> read, final List<HighlightSeverity> knownSeverities) {
     OrderMap orderMap = fromList(read);
     if (orderMap.isEmpty()) {
       orderMap = fromList(knownSeverities);
@@ -182,8 +187,7 @@ public class SeverityRegistrar implements Comparator<HighlightSeverity> {
       }
       orderMap = fromList(list);
     }
-    myOrderMap = orderMap;
-    severitiesChanged();
+    return orderMap;
   }
 
   public void writeExternal(Element element) {
@@ -345,7 +349,7 @@ public class SeverityRegistrar implements Comparator<HighlightSeverity> {
   }
 
   public void setOrder(@NotNull List<HighlightSeverity> orderList) {
-    myOrderMap = fromList(orderList);
+    myOrderMap = ensureAllStandardIncluded(orderList, getDefaultOrder());
     myReadOrder = null;
     severitiesChanged();
   }
index a0ea74611b0df4cc3d8ee65804b8565cff4da567..cf06a8f296f87d914640cbaabf5257cd180cd080 100644 (file)
@@ -21,6 +21,7 @@ import com.intellij.codeInspection.ex.InspectionToolRegistrar
 import com.intellij.configurationStore.SchemeDataHolder
 import com.intellij.configurationStore.SchemeManagerIprProvider
 import com.intellij.configurationStore.digest
+import com.intellij.configurationStore.wrapState
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.application.ApplicationManager
 import com.intellij.openapi.components.PersistentStateComponent
@@ -32,7 +33,6 @@ import com.intellij.openapi.project.ProjectManager
 import com.intellij.openapi.project.ProjectManagerListener
 import com.intellij.openapi.startup.StartupActivity
 import com.intellij.openapi.util.Disposer
-import com.intellij.openapi.util.JDOMUtil
 import com.intellij.openapi.util.text.StringUtil
 import com.intellij.packageDependencies.DependencyValidationManager
 import com.intellij.profile.Profile
@@ -209,6 +209,23 @@ class ProjectInspectionProfileManager(val project: Project,
     }
   }
 
+  @Synchronized override fun getState(): Element? {
+    val result = Element("settings")
+
+    schemeManagerIprProvider?.writeState(result)
+
+    val state = this.state
+    state.projectProfile = schemeManager.currentSchemeName
+    XmlSerializer.serializeInto(state, result, skipDefaultsSerializationFilter)
+    if (!result.children.isEmpty()) {
+      result.addContent(Element("version").setAttribute("value", VERSION))
+    }
+
+    severityRegistrar.writeExternal(result)
+
+    return wrapState(result)
+  }
+
   @Synchronized override fun loadState(state: Element) {
     val data = state.getChild("settings")
 
@@ -250,29 +267,6 @@ class ProjectInspectionProfileManager(val project: Project,
     }
   }
 
-  @Synchronized override fun getState(): Element? {
-    val result = Element("settings")
-
-    schemeManagerIprProvider?.writeState(result)
-
-    val state = this.state
-    state.projectProfile = schemeManager.currentSchemeName
-    XmlSerializer.serializeInto(state, result, skipDefaultsSerializationFilter)
-    if (!result.children.isEmpty()) {
-      result.addContent(Element("version").setAttribute("value", VERSION))
-    }
-
-    severityRegistrar.writeExternal(result)
-
-    if (JDOMUtil.isEmpty(result)) {
-      result.name = "state"
-      return result
-    }
-    else {
-      return Element("state").addContent(result)
-    }
-  }
-
   override fun getScopesManager() = scopeManager
 
   @Synchronized override fun getProfiles(): Collection<Profile> {
index 50634e5b4433552666b8f85b0d3443009ae9ab47..3b759da23c1135cd87ac60bbd0ed90cab626c508 100644 (file)
@@ -370,12 +370,16 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
 
     override fun updateDigest(scheme: MUTABLE_SCHEME) {
       try {
-        externalInfo.digest = (processor.writeScheme(scheme) as Element).digest()
+        updateDigest(processor.writeScheme(scheme) as Element)
       }
       catch (e: WriteExternalException) {
         LOG.error("Cannot update digest", e)
       }
     }
+
+    override fun updateDigest(data: Element) {
+      externalInfo.digest = data.digest()
+    }
   }
 
   private fun loadScheme(fileName: String, input: InputStream, schemes: MutableList<T>, filesToDelete: MutableSet<String>? = null): MUTABLE_SCHEME? {
@@ -438,7 +442,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
           XmlPullParser.START_TAG -> {
             if (!isUseOldFileNameSanitize || parser.name != "component") {
               var name: String? = null
-              if (isUseOldFileNameSanitize && parser.name == "profile") {
+              if (isUseOldFileNameSanitize && (parser.name == "profile" || parser.name == "copyright")) {
                 eventType = parser.next()
                 findName@ while (eventType != XmlPullParser.END_DOCUMENT) {
                   when (eventType) {
diff --git a/platform/core-api/src/com/intellij/diagnostic/ImplementationConflictException.java b/platform/core-api/src/com/intellij/diagnostic/ImplementationConflictException.java
new file mode 100644 (file)
index 0000000..e934873
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.diagnostic;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class ImplementationConflictException extends RuntimeException {
+
+  @NotNull
+  private final Collection<Class<?>> myConflictingClasses;
+
+  public ImplementationConflictException(String message, Throwable cause, @NotNull Object ...implementationObjects) {
+    super(message, cause);
+    final List<Class<?>> classes = new ArrayList<Class<?>>();
+    for (Object object : implementationObjects) {
+      classes.add(object.getClass());
+    }
+
+    myConflictingClasses = Collections.unmodifiableList(classes);
+  }
+
+  @NotNull
+  public Collection<Class<?>> getConflictingClasses() {
+    return myConflictingClasses;
+  }
+}
index d941110520dcab377a17534edc79ef4537b74ffe..9dbe2bccff2f1563e4c8b0a03db888038425742d 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.
@@ -15,6 +15,7 @@
  */
 package com.intellij.lang;
 
+import com.intellij.diagnostic.ImplementationConflictException;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.fileTypes.FileTypeRegistry;
@@ -24,7 +25,6 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.ConcurrencyUtil;
 import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -33,12 +33,10 @@ import java.util.concurrent.ConcurrentMap;
 
 /**
  * The base class for all programming language support implementations. Specific language implementations should inherit from this class
- * and its register instance wrapped with {@link com.intellij.openapi.fileTypes.LanguageFileType} instance through
- * <code>FileTypeManager.getInstance().registerFileType</code>
+ * and its register instance wrapped with {@link LanguageFileType} instance via {@code FileTypeManager.getInstance().registerFileType()}.
  * There should be exactly one instance of each Language.
- * It is usually created when creating {@link com.intellij.openapi.fileTypes.LanguageFileType} and can be retrieved later
- * with {@link #findInstance(Class)}.
- * For the list of standard languages, see {@link com.intellij.lang.StdLanguages}.
+ * It is usually created when creating {@link LanguageFileType} and can be retrieved later with {@link #findInstance(Class)}.
+ * For the list of standard languages, see {@code com.intellij.lang.StdLanguages}.
  */
 public abstract class Language extends UserDataHolderBase {
   private static final Logger LOG = Logger.getInstance("#com.intellij.lang.Language");
@@ -46,14 +44,15 @@ public abstract class Language extends UserDataHolderBase {
   private static final Map<Class<? extends Language>, Language> ourRegisteredLanguages = ContainerUtil.newConcurrentMap();
   private static final ConcurrentMap<String, List<Language>> ourRegisteredMimeTypes = ContainerUtil.newConcurrentMap();
   private static final Map<String, Language> ourRegisteredIDs = ContainerUtil.newConcurrentMap();
+
   private final Language myBaseLanguage;
   private final String myID;
   private final String[] myMimeTypes;
   private final List<Language> myDialects = ContainerUtil.createLockFreeCopyOnWriteList();
+
   public static final Language ANY = new Language("") {
     @Override
     public String toString() {
-      //noinspection HardCodedStringLiteral
       return "Language: ANY";
     }
 
@@ -64,28 +63,31 @@ public abstract class Language extends UserDataHolderBase {
     }
   };
 
-  protected Language(@NotNull @NonNls String ID) {
+  protected Language(@NotNull String ID) {
     this(ID, ArrayUtil.EMPTY_STRING_ARRAY);
   }
 
-  protected Language(@NotNull @NonNls final String ID, @NotNull @NonNls final String... mimeTypes) {
+  protected Language(@NotNull String ID, @NotNull String... mimeTypes) {
     this(null, ID, mimeTypes);
   }
 
-  protected Language(@Nullable Language baseLanguage, @NotNull @NonNls final String ID, @NotNull @NonNls final String... mimeTypes) {
+  protected Language(@Nullable Language baseLanguage, @NotNull String ID, @NotNull String... mimeTypes) {
     myBaseLanguage = baseLanguage;
     myID = ID;
     myMimeTypes = mimeTypes;
+
     Class<? extends Language> langClass = getClass();
     Language prev = ourRegisteredLanguages.put(langClass, this);
     if (prev != null) {
-      LOG.error("Language of '" + langClass + "' is already registered: " + prev);
+      LOG.error(new ImplementationConflictException("Language of '" + langClass + "' is already registered: " + prev, null, prev, this));
       return;
     }
+
     prev = ourRegisteredIDs.put(ID, this);
     if (prev != null) {
-      LOG.error("Language with ID '" + ID + "' is already registered: " + prev.getClass());
+      LOG.error(new ImplementationConflictException("Language with ID '" + ID + "' is already registered: " + prev.getClass(), null, prev, this));
     }
+
     for (String mimeType : mimeTypes) {
       if (StringUtil.isEmpty(mimeType)) {
         continue;
@@ -96,6 +98,7 @@ public abstract class Language extends UserDataHolderBase {
       }
       languagesByMimeType.add(this);
     }
+
     if (baseLanguage != null) {
       baseLanguage.myDialects.add(this);
     }
@@ -129,10 +132,8 @@ public abstract class Language extends UserDataHolderBase {
     return result == null ? Collections.<Language>emptyList() : Collections.unmodifiableCollection(result);
   }
 
-
   @Override
   public String toString() {
-    //noinspection HardCodedStringLiteral
     return "Language: " + myID;
   }
 
@@ -228,4 +229,4 @@ public abstract class Language extends UserDataHolderBase {
     myBaseLanguage = null;
     myMimeTypes = null;
   }
-}
+}
\ No newline at end of file
index 36c9bef94dc930e28fe091a485595d3aeafae64d..155d71eb9bdd8d86a7b77e7a1a898011bd5a0d5a 100644 (file)
@@ -102,41 +102,58 @@ public interface Module extends ComponentManager, AreaInstance, Disposable {
   String getOptionValue(@NotNull String key);
 
   /**
-   * Returns module scope including sources and tests, excluding libraries and dependencies.
-   *
-   * @return scope including sources and tests, excluding libraries and dependencies.
+   * @return module scope including source and tests, excluding libraries and dependencies.
    */
   @NotNull
   GlobalSearchScope getModuleScope();
 
+  /**
+   * @param includeTests whether to include test source
+   * @return module scope including source and, optionally, tests, excluding libraries and dependencies.
+   */
   @NotNull
   GlobalSearchScope getModuleScope(boolean includeTests);
 
   /**
-   * Returns module scope including sources, tests, and libraries, excluding dependencies.
-   *
-   * @return scope including sources, tests, and libraries, excluding dependencies.
+   * @return module scope including source, tests, and libraries, excluding dependencies.
    */
   @NotNull
   GlobalSearchScope getModuleWithLibrariesScope();
 
   /**
-   * Returns module scope including sources, tests, and dependencies, excluding libraries.
-   *
-   * @return scope including sources, tests, and dependencies, excluding libraries.
+   * @return module scope including source, tests, and dependencies, excluding libraries.
    */
   @NotNull
   GlobalSearchScope getModuleWithDependenciesScope();
 
+  /**
+   * @return a scope that includes everything in module content roots, without any dependencies or libraries
+   */
   @NotNull
   GlobalSearchScope getModuleContentScope();
+
+  /**
+   * @return a scope that includes everything under the content roots of this module and its dependencies, with test source
+   */
   @NotNull
   GlobalSearchScope getModuleContentWithDependenciesScope();
 
+  /**
+   * @param includeTests whether test source and test dependencies should be included
+   * @return a scope including module source and dependencies with libraries
+   */
   @NotNull
   GlobalSearchScope getModuleWithDependenciesAndLibrariesScope(boolean includeTests);
+
+  /**
+   * @return a scope including everything under the content roots of this module and all modules that depend on it, directly or indirectly (via exported dependencies), excluding test source and resources
+   */
   @NotNull
   GlobalSearchScope getModuleWithDependentsScope();
+
+  /**
+   * @return same as {@link #getModuleWithDependentsScope()}, but with test source/resources included
+   */
   @NotNull
   GlobalSearchScope getModuleTestsWithDependentsScope();
   @NotNull
index fcf71fd24fc1f8b7de1e5c0146fe375b06d36088..2221418c116c7470f16914bea1b6c681139199bd 100644 (file)
@@ -383,11 +383,10 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
   private void registerComponents(@NotNull ComponentConfig config) {
     ClassLoader loader = config.getClassLoader();
     try {
-      final Class<?> interfaceClass = Class.forName(config.getInterfaceClass(), true, loader);
-      final Class<?> implementationClass = Comparing.equal(config.getInterfaceClass(), config.getImplementationClass())
-                                           ?
-                                           interfaceClass
-                                           : StringUtil.isEmpty(config.getImplementationClass()) ? null : Class.forName(config.getImplementationClass(), true, loader);
+      Class<?> interfaceClass = Class.forName(config.getInterfaceClass(), true, loader);
+      Class<?> implementationClass = Comparing.equal(config.getInterfaceClass(), config.getImplementationClass()) ? interfaceClass :
+                                     StringUtil.isEmpty(config.getImplementationClass()) ? null :
+                                     Class.forName(config.getImplementationClass(), true, loader);
       MutablePicoContainer picoContainer = getPicoContainer();
       if (config.options != null && Boolean.parseBoolean(config.options.get("overrides"))) {
         ComponentAdapter oldAdapter = picoContainer.getComponentAdapterOfType(interfaceClass);
@@ -398,8 +397,8 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
       }
       // implementationClass == null means we want to unregister this component
       if (implementationClass != null) {
-        picoContainer.registerComponent(new ComponentConfigComponentAdapter(interfaceClass, implementationClass, config.getPluginId(),
-                                                                            config.options != null && Boolean.parseBoolean(config.options.get("workspace"))));
+        boolean ws = config.options != null && Boolean.parseBoolean(config.options.get("workspace"));
+        picoContainer.registerComponent(new ComponentConfigComponentAdapter(interfaceClass, implementationClass, config.getPluginId(), ws));
       }
     }
     catch (Throwable t) {
@@ -522,4 +521,4 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
       return "ComponentConfigAdapter[" + getComponentKey() + "]: implementation=" + getComponentImplementation() + ", plugin=" + myPluginId;
     }
   }
-}
+}
\ No newline at end of file
index 9153a80dd67d17755bb4797fb3fec5f4db7c58fa..4ec77f5e5b8c942935f1aecf37cef985d361ea3c 100644 (file)
@@ -115,12 +115,8 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
 
   private void refresh() {
     int maxIndex = mySeverityRegistrar.getSeverityMaxIndex();
-    if (errorCount != null && maxIndex == errorCount.length) return;
-    int[] newErrors = new int[maxIndex+1];
-    if (errorCount != null) {
-      System.arraycopy(errorCount, 0, newErrors, 0, Math.min(errorCount.length, newErrors.length));
-    }
-    errorCount = newErrors;
+    if (errorCount != null && maxIndex + 1 == errorCount.length) return;
+    errorCount = new int[maxIndex + 1];
   }
 
   static void setOrRefreshErrorStripeRenderer(@NotNull EditorMarkupModel editorMarkupModel,
@@ -334,7 +330,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
 
     Icon icon = AllIcons.General.InspectionsOK;
     for (int i = status.errorCount.length - 1; i >= 0; i--) {
-      if (status.errorCount[i] != 0) {
+      if (status.errorCount[i] > 0) {
         icon = SeverityRegistrar.getSeverityRegistrar(project).getRendererIconByIndex(i);
         break;
       }
index b4d905848c2c130c57e1b6bbb94f0455fec5bd29..ffe46825d84b9317fbd4c884d964ab2f5c0a9060 100644 (file)
@@ -56,4 +56,10 @@ public abstract class TemplateManager {
 
   @Nullable
   public abstract Template getActiveTemplate(@NotNull Editor editor);
+
+  /**
+   * Finished a live template in the given editor, if it's present
+   * @return whether a live template was present
+   */
+  public abstract boolean finishTemplate(@NotNull Editor editor);
 }
index 64d7fe640fd515f2cd1c2e4e0007e6492f6f10ab..6f5e4f455133d05216e53706d5860269212510d2 100644 (file)
@@ -521,6 +521,16 @@ public class TemplateManagerImpl extends TemplateManager implements Disposable {
     return templateState != null ? templateState.getTemplate() : null;
   }
 
+  @Override
+  public boolean finishTemplate(@NotNull Editor editor) {
+    TemplateState state = getTemplateState(editor);
+    if (state != null) {
+      state.gotoEnd();
+      return true;
+    }
+    return false;
+  }
+
   public static boolean isApplicable(PsiFile file, int offset, TemplateImpl template) {
     return isApplicable(template, getApplicableContextTypes(file, offset));
   }
index 813412589ea6f856d78426b87f1f26e5c3bb46a4..0a4e9104df616bf87d631291e73b563e69aa245f 100644 (file)
@@ -31,16 +31,16 @@ import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.progress.EmptyProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Computable;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.SequentialModalProgressTask;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
 /**
@@ -74,39 +74,45 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
 
   @Override
   public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
-    if (!FileModificationService.getInstance().preparePsiElementForWrite(file)) return;
+
     final List<ProblemDescriptor> descriptions =
       ProgressManager.getInstance().runProcess(() -> {
         InspectionManager inspectionManager = InspectionManager.getInstance(project);
         return InspectionEngine.runInspectionOnFile(file, myToolWrapper, inspectionManager.createNewGlobalContext(false));
       }, new EmptyProgressIndicator());
 
-    Collections.sort(descriptions, new Comparator<CommonProblemDescriptor>() {
-      @Override
-      public int compare(final CommonProblemDescriptor o1, final CommonProblemDescriptor o2) {
-        final ProblemDescriptorBase d1 = (ProblemDescriptorBase)o1;
-        final ProblemDescriptorBase d2 = (ProblemDescriptorBase)o2;
-        final int offset2 = d2.getTextRange().getStartOffset();
-        final int offset1 = d1.getTextRange().getStartOffset();
-        return offset2 < offset1 ? -1 : offset1 == offset2 ? 0 : 1;
-      }
+    if (!descriptions.isEmpty() && !FileModificationService.getInstance().preparePsiElementForWrite(file)) return;
+
+    final AbstractPerformFixesTask fixesTask = applyFixes(project, "Apply Fixes", descriptions, myQuickfixClass);
+
+    if (!fixesTask.isApplicableFixFound()) {
+      HintManager.getInstance().showErrorHint(editor, "Unfortunately '" + myText + "' is currently not available for batch mode\n User interaction is required for each problem found");
+    }
+  }
+
+  public static AbstractPerformFixesTask applyFixes(@NotNull Project project,
+                                                    @NotNull String presentationText,
+                                                    @NotNull List<ProblemDescriptor> descriptions,
+                                                    @Nullable Class quickfixClass) {
+    Collections.sort(descriptions, (o1, o2) -> {
+      final ProblemDescriptorBase d1 = (ProblemDescriptorBase)o1;
+      final ProblemDescriptorBase d2 = (ProblemDescriptorBase)o2;
+      return -PsiUtilCore.compareElementsByPosition(d1.getPsiElement(), d2.getPsiElement());
     });
-    
-    final String templatePresentationText = "Apply Fixes";
+
     final SequentialModalProgressTask progressTask =
-      new SequentialModalProgressTask(project, templatePresentationText, true);
-    final boolean isBatch = BatchQuickFix.class.isAssignableFrom(myQuickfixClass);
-    final AbstractPerformFixesTask fixesTask = createTask(project, descriptions.toArray(new ProblemDescriptor[descriptions.size()]), progressTask, isBatch);
+      new SequentialModalProgressTask(project, presentationText, true);
+    final boolean isBatch = quickfixClass != null && BatchQuickFix.class.isAssignableFrom(quickfixClass);
+    final AbstractPerformFixesTask fixesTask = isBatch ?
+                  new PerformBatchFixesTask(project, descriptions.toArray(ProblemDescriptor.EMPTY_ARRAY), progressTask, quickfixClass) :
+                  new PerformFixesTask(project, descriptions.toArray(ProblemDescriptor.EMPTY_ARRAY), progressTask, quickfixClass);
     CommandProcessor.getInstance().executeCommand(project, () -> {
       CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
       progressTask.setMinIterationTime(200);
       progressTask.setTask(fixesTask);
       ProgressManager.getInstance().run(progressTask);
-    }, templatePresentationText, null);
-
-    if (!fixesTask.isApplicableFixFound()) {
-      HintManager.getInstance().showErrorHint(editor, "Unfortunately '" + myText + "' is currently not available for batch mode\n User interaction is required for each problem found");
-    }
+    }, presentationText, null);
+    return fixesTask;
   }
 
   @Override
@@ -120,23 +126,16 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
     return false;
   }
 
-  @NotNull
-  private AbstractPerformFixesTask createTask(@NotNull Project project,
-                                              ProblemDescriptor[] descriptions,
-                                              SequentialModalProgressTask progressTask,
-                                              boolean isBatch) {
-    return isBatch ?
-           new PerformBatchFixesTask(project, descriptions, progressTask) :
-           new PerformFixesTask(project, descriptions, progressTask);
-  }
-
-  private abstract class AbstractPerformFixesTask extends PerformFixesModalTask {
+  private static abstract class AbstractPerformFixesTask extends PerformFixesModalTask {
     private boolean myApplicableFixFound = false;
+    protected final Class myQuickfixClass;
 
     public AbstractPerformFixesTask(@NotNull Project project,
-                            @NotNull CommonProblemDescriptor[] descriptors,
-                            @NotNull SequentialModalProgressTask task) {
+                                    @NotNull CommonProblemDescriptor[] descriptors,
+                                    @NotNull SequentialModalProgressTask task,
+                                    @Nullable Class quickfixClass) {
       super(project, descriptors, task);
+      myQuickfixClass = quickfixClass;
     }
 
     protected abstract void collectFix(QuickFix fix, ProblemDescriptor descriptor, Project project);
@@ -146,7 +145,7 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
       final QuickFix[] fixes = descriptor.getFixes();
       if (fixes != null && fixes.length > 0) {
         for (final QuickFix fix : fixes) {
-          if (fix != null && fix.getClass().isAssignableFrom(myQuickfixClass)) {
+          if (fix != null && (myQuickfixClass == null || fix.getClass().isAssignableFrom(myQuickfixClass))) {
             final ProblemDescriptor problemDescriptor = (ProblemDescriptor)descriptor;
             final PsiElement element = problemDescriptor.getPsiElement();
             if (element != null && element.isValid()) {
@@ -164,14 +163,15 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
     }
   }
 
-  private class PerformBatchFixesTask extends AbstractPerformFixesTask {
+  private static class PerformBatchFixesTask extends AbstractPerformFixesTask {
     private final List<ProblemDescriptor> myBatchModeDescriptors = new ArrayList<>();
     private boolean myApplied = false;
 
     public PerformBatchFixesTask(@NotNull Project project,
                                  @NotNull CommonProblemDescriptor[] descriptors,
-                                 @NotNull SequentialModalProgressTask task) {
-      super(project, descriptors, task);
+                                 @NotNull SequentialModalProgressTask task,
+                                 @NotNull Class quickfixClass) {
+      super(project, descriptors, task, quickfixClass);
     }
 
     @Override
@@ -204,11 +204,12 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
     }
   }
   
-  private class PerformFixesTask extends AbstractPerformFixesTask {
+  private static class PerformFixesTask extends AbstractPerformFixesTask {
     public PerformFixesTask(@NotNull Project project,
                             @NotNull CommonProblemDescriptor[] descriptors,
-                            @NotNull SequentialModalProgressTask task) {
-      super(project, descriptors, task);
+                            @NotNull SequentialModalProgressTask task,
+                            @Nullable Class quickFixClass) {
+      super(project, descriptors, task, quickFixClass);
     }
 
     @Override
index aa16bf133356875d2726b3d737a18a9122054974..f5fba8dec4731e70142d867c998afc2c90c46db2 100644 (file)
@@ -20,10 +20,10 @@ import com.intellij.analysis.AnalysisScope;
 import com.intellij.analysis.AnalysisUIOptions;
 import com.intellij.analysis.PerformAnalysisInBackgroundOption;
 import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.daemon.impl.HighlightInfo;
 import com.intellij.codeInsight.daemon.impl.HighlightInfoProcessor;
 import com.intellij.codeInsight.daemon.impl.LocalInspectionsPass;
 import com.intellij.codeInspection.*;
+import com.intellij.codeInspection.actions.CleanupInspectionIntention;
 import com.intellij.codeInspection.lang.GlobalInspectionContextExtension;
 import com.intellij.codeInspection.reference.RefElement;
 import com.intellij.codeInspection.reference.RefEntity;
@@ -47,7 +47,6 @@ import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.application.ReadAction;
 import com.intellij.openapi.application.TransactionGuard;
 import com.intellij.openapi.application.ex.ApplicationManagerEx;
-import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.components.PathMacroManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
@@ -77,8 +76,9 @@ import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.ui.GuiUtils;
 import com.intellij.ui.content.*;
 import com.intellij.util.*;
-import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.*;
 import com.intellij.util.containers.HashMap;
+import com.intellij.util.containers.HashSet;
 import com.intellij.util.ui.UIUtil;
 import gnu.trove.THashSet;
 import org.jdom.Element;
@@ -92,6 +92,7 @@ import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.lang.reflect.Constructor;
 import java.util.*;
+import java.util.Queue;
 import java.util.concurrent.*;
 
 public class GlobalInspectionContextImpl extends GlobalInspectionContextBase implements GlobalInspectionContext {
@@ -889,8 +890,6 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
     final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
     final List<LocalInspectionToolWrapper> lTools = new ArrayList<>();
 
-    final LinkedHashMap<PsiFile, List<HighlightInfo>> results = new LinkedHashMap<>();
-
     final SearchScope searchScope = scope.toSearchScope();
     final TextRange range;
     if (searchScope instanceof LocalSearchScope) {
@@ -909,47 +908,66 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
       assert tools != null;
       return tools.getTool().getTool() instanceof CleanupLocalInspectionTool;
     });
+    List<ProblemDescriptor> descriptors = new ArrayList<>();
+    Set<PsiFile> files = new HashSet<>();
     boolean includeDoNotShow = includeDoNotShow(profile);
-    scope.accept(new PsiElementVisitor() {
-      private int myCount;
-      @Override
-      public void visitFile(PsiFile file) {
-        if (progressIndicator != null) {
-          progressIndicator.setFraction((double)++myCount / fileCount);
-        }
-        if (isBinary(file)) return;
-        for (final Tools tools : inspectionTools) {
-          final InspectionToolWrapper tool = tools.getEnabledTool(file, includeDoNotShow);
-          if (tool instanceof LocalInspectionToolWrapper) {
-            lTools.add((LocalInspectionToolWrapper)tool);
-            tool.initialize(GlobalInspectionContextImpl.this);
+    final RefManagerImpl refManager = (RefManagerImpl)getRefManager();
+    refManager.inspectionReadActionStarted();
+    try {
+      scope.accept(new PsiElementVisitor() {
+        private int myCount;
+        @Override
+        public void visitFile(PsiFile file) {
+          if (progressIndicator != null) {
+            progressIndicator.setFraction((double)++myCount / fileCount);
+          }
+          if (isBinary(file)) return;
+          for (final Tools tools : inspectionTools) {
+            final InspectionToolWrapper tool = tools.getEnabledTool(file, includeDoNotShow);
+            if (tool instanceof LocalInspectionToolWrapper) {
+              lTools.add((LocalInspectionToolWrapper)tool);
+              tool.initialize(GlobalInspectionContextImpl.this);
+            }
           }
-        }
 
-        if (!lTools.isEmpty()) {
-          final LocalInspectionsPass pass = new LocalInspectionsPass(file, PsiDocumentManager.getInstance(getProject()).getDocument(file), range != null ? range.getStartOffset() : 0,
-                                                                     range != null ? range.getEndOffset() : file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true,
-                                                                     HighlightInfoProcessor.getEmpty());
-          Runnable runnable = () -> pass.doInspectInBatch(GlobalInspectionContextImpl.this, InspectionManager.getInstance(getProject()), lTools);
-          ApplicationManager.getApplication().runReadAction(runnable);
-          final List<HighlightInfo> infos = pass.getInfos();
-          if (searchScope instanceof LocalSearchScope) {
-            for (Iterator<HighlightInfo> iterator = infos.iterator(); iterator.hasNext(); ) {
-              final HighlightInfo info = iterator.next();
-              final TextRange infoRange = new TextRange(info.getStartOffset(), info.getEndOffset());
-              if (!((LocalSearchScope)searchScope).containsRange(file, infoRange)) {
-                iterator.remove();
+          if (!lTools.isEmpty()) {
+            final LocalInspectionsPass pass = new LocalInspectionsPass(file, PsiDocumentManager.getInstance(getProject()).getDocument(file), range != null ? range.getStartOffset() : 0,
+                                                                       range != null ? range.getEndOffset() : file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true,
+                                                                       HighlightInfoProcessor.getEmpty());
+            Runnable runnable = () -> pass.doInspectInBatch(GlobalInspectionContextImpl.this, InspectionManager.getInstance(getProject()), lTools);
+            ApplicationManager.getApplication().runReadAction(runnable);
+
+            List<ProblemDescriptor> localDescriptors = new ArrayList<>();
+            for (LocalInspectionToolWrapper tool : lTools) {
+              for (CommonProblemDescriptor descriptor : getPresentation(tool).getProblemDescriptors()) {
+                if (descriptor instanceof ProblemDescriptor) {
+                  localDescriptors.add((ProblemDescriptor)descriptor);
+                }
               }
             }
-          }
-          if (!infos.isEmpty()) {
-            results.put(file, infos);
+
+            if (searchScope instanceof LocalSearchScope) {
+              for (Iterator<ProblemDescriptor> iterator = localDescriptors.iterator(); iterator.hasNext(); ) {
+                final ProblemDescriptor descriptor = iterator.next();
+                final TextRange infoRange = descriptor instanceof ProblemDescriptorBase ? ((ProblemDescriptorBase)descriptor).getTextRange() : null;
+                if (infoRange != null && !((LocalSearchScope)searchScope).containsRange(file, infoRange)) {
+                  iterator.remove();
+                }
+              }
+            }
+            if (!localDescriptors.isEmpty()) {
+              descriptors.addAll(localDescriptors);
+              files.add(file);
+            }
           }
         }
-      }
-    });
+      });
+    }
+    finally {
+      refManager.inspectionReadActionFinished();
+    }
 
-    if (results.isEmpty()) {
+    if (files.isEmpty()) {
       GuiUtils.invokeLaterIfNeeded(() -> {
         if (commandName != null) {
           NOTIFICATION_GROUP.createNotification(InspectionsBundle.message("inspection.no.problems.message", scope.getFileCount(), scope.getDisplayName()), MessageType.INFO).notify(getProject());
@@ -961,21 +979,8 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
       return;
     }
     Runnable runnable = () -> {
-      if (!FileModificationService.getInstance().preparePsiElementsForWrite(results.keySet())) return;
-
-      final String title = "Code Cleanup";
-      final SequentialModalProgressTask progressTask = new SequentialModalProgressTask(getProject(), title, true);
-      progressTask.setMinIterationTime(200);
-      progressTask.setTask(new SequentialCleanupTask(getProject(), results, progressTask));
-      CommandProcessor.getInstance().executeCommand(getProject(), () -> {
-        if (commandName != null) {
-          CommandProcessor.getInstance().markCurrentCommandAsGlobal(getProject());
-        }
-        ProgressManager.getInstance().run(progressTask);
-        if (postRunnable != null) {
-          ApplicationManager.getApplication().invokeLater(postRunnable);
-        }
-      }, title, null);
+      if (!FileModificationService.getInstance().preparePsiElementsForWrite(files)) return;
+      CleanupInspectionIntention.applyFixes(getProject(), "Code Cleanup", descriptors, null);
     };
     TransactionGuard.submitTransaction(getProject(), runnable);
   }
index 35f2ca182bb85402d8b013f7893f1294e4760e85..3251b80df54dea04669ee88970ddfed3e43b7f79 100644 (file)
@@ -20,6 +20,7 @@
  */
 package com.intellij.codeInspection.ex;
 
+import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
 import com.intellij.codeInspection.CommonProblemDescriptor;
 import com.intellij.codeInspection.QuickFix;
 import com.intellij.codeInspection.reference.RefDirectory;
@@ -279,21 +280,25 @@ public abstract class InspectionRVContentProvider {
                 continue;
               }
             }
-            for (RefElementNode parentNode : parentNodes) {
-              final List<ProblemDescriptionNode> nodes = new ArrayList<>();
-              TreeUtil.traverse(parentNode, new TreeUtil.Traverse() {
-                @Override
-                public boolean accept(final Object node) {
-                  if (node instanceof ProblemDescriptionNode) {
-                    nodes.add((ProblemDescriptionNode)node);
+
+            //allow unused declaration to have structure at file level even when there are unused parameters
+            if (!HighlightInfoType.UNUSED_SYMBOL_SHORT_NAME.equals(toolWrapper.getShortName())) {
+              for (RefElementNode parentNode : parentNodes) {
+                final List<ProblemDescriptionNode> nodes = new ArrayList<>();
+                TreeUtil.traverse(parentNode, new TreeUtil.Traverse() {
+                  @Override
+                  public boolean accept(final Object node) {
+                    if (node instanceof ProblemDescriptionNode) {
+                      nodes.add((ProblemDescriptionNode)node);
+                    }
+                    return true;
                   }
-                  return true;
+                });
+                if (nodes.isEmpty()) continue;
+                parentNode.removeAllChildren();
+                for (ProblemDescriptionNode node : nodes) {
+                  parentNode.add(node);
                 }
-              });
-              if (nodes.isEmpty()) continue;  //FilteringInspectionTool == DeadCode
-              parentNode.removeAllChildren();
-              for (ProblemDescriptionNode node : nodes) {
-                parentNode.add(node);
               }
             }
             for (RefElementNode node : parentNodes) {
index 57635c5a0c5f24aab96345e47d1535f463de1295..01a27855fce9780b8c7dde531e88ab4532d51ff3 100644 (file)
@@ -81,7 +81,7 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider
   public QuickFixAction[] getQuickFixes(@NotNull final InspectionToolWrapper toolWrapper, @NotNull final InspectionTree tree) {
     final RefEntity[] refEntities = tree.getSelectedElements();
     InspectionToolPresentation presentation = tree.getContext().getPresentation(toolWrapper);
-    return refEntities.length == 0 ? null : presentation.getQuickFixes(refEntities, tree.getSelectedDescriptors());
+    return refEntities.length == 0 ? null : presentation.getQuickFixes(refEntities, tree);
   }
 
 
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/SequentialCleanupTask.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/SequentialCleanupTask.java
deleted file mode 100644 (file)
index f72eaba..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2000-2015 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.codeInspection.ex;
-
-import com.intellij.codeInsight.daemon.impl.HighlightInfo;
-import com.intellij.openapi.actionSystem.ActionManager;
-import com.intellij.openapi.application.AccessToken;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.WriteAction;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.progress.ProcessCanceledException;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiFile;
-import com.intellij.util.SequentialModalProgressTask;
-import com.intellij.util.SequentialTask;
-
-import java.util.*;
-
-class SequentialCleanupTask implements SequentialTask {
-  private static final Logger LOG = Logger.getInstance(SequentialCleanupTask.class);
-
-  private final Project myProject;
-  private final List<Pair<PsiFile, HighlightInfo>> myResults = new ArrayList<>();
-  private final SequentialModalProgressTask myProgressTask;
-  private int myCount = 0;
-  
-  public SequentialCleanupTask(Project project, LinkedHashMap<PsiFile, List<HighlightInfo>> results, SequentialModalProgressTask task) {
-    myProject = project;
-    for (Map.Entry<PsiFile, List<HighlightInfo>> entry : results.entrySet()) {
-      PsiFile file = entry.getKey();
-      List<HighlightInfo> infos = entry.getValue();
-      // sort from bottom to top
-      Collections.sort(infos, (info1, info2) -> info2.getStartOffset() - info1.getStartOffset());
-      for (HighlightInfo info : infos) {
-        myResults.add(Pair.create(file, info));
-      }
-    }
-    myProgressTask = task;
-  }
-
-  @Override
-  public void prepare() {}
-
-  @Override
-  public boolean isDone() {
-    return myCount > myResults.size() - 1;
-  }
-
-  @Override
-  public boolean iteration() {
-    final Pair<PsiFile, HighlightInfo> pair = myResults.get(myCount++);
-    final ProgressIndicator indicator = myProgressTask.getIndicator();
-    if (indicator != null) {
-      indicator.setFraction((double) myCount/myResults.size());
-      indicator.setText("Processing " + pair.first.getName());
-    }
-    for (final Pair<HighlightInfo.IntentionActionDescriptor, TextRange> actionRange : pair.second.quickFixActionRanges) {
-      final AccessToken token = WriteAction.start();
-      try {
-        actionRange.getFirst().getAction().invoke(myProject, null, pair.first);
-      }
-      catch (ProcessCanceledException e) {
-        throw e;
-      }
-      catch (Exception e) {
-        LOG.error(e);
-      }
-      finally {
-        token.finish();
-      }
-    }
-    return true;
-  }
-
-  @Override
-  public void stop() {}
-}
index 1eea4e076c80ccf6dbed1a6a71ae71eb51211141..7111ed4853f5ba2435b7b95a3d0aa2d0ae12cc93 100644 (file)
@@ -618,8 +618,8 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
 
   @Override
   @Nullable
-  public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, CommonProblemDescriptor[] allowedDescriptors) {
-    return extractActiveFixes(refElements, getProblemElements(), allowedDescriptors);
+  public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, InspectionTree tree) {
+    return extractActiveFixes(refElements, getProblemElements(), tree != null ? tree.getSelectedDescriptors() : null);
   }
 
   @Override
index d77a3d7d34e6282d6e51d1362e41e5c5a6539fa3..be718f0fb4c6e477e75647e53a784ca12ace6d00 100644 (file)
@@ -80,7 +80,7 @@ public interface InspectionToolPresentation extends ProblemDescriptionsProcessor
   @NotNull
   Set<RefModule> getModuleProblems();
   @Nullable
-  QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, @Nullable CommonProblemDescriptor[] descriptors);
+  QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, @Nullable InspectionTree tree);
   @NotNull
   Map<RefEntity, CommonProblemDescriptor[]> getProblemElements();
   @NotNull
index 3a93d1a617f535745f855fc969ab6d79f9c7c258..b6e96738bdede2eb1b7e024d7030bc2b44782168 100644 (file)
@@ -52,7 +52,7 @@ public class FileTemplateSettings extends FileTemplatesLoader implements Persist
   @Nullable
   @Override
   public Element getState() {
-    Element element = null;
+    Element element = new Element("fileTemplateSettings");
     for (FTManager manager : getAllManagers()) {
       Element templatesGroup = null;
       for (FileTemplateBase template : manager.getAllTemplates(true)) {
@@ -75,9 +75,6 @@ public class FileTemplateSettings extends FileTemplatesLoader implements Persist
 
         if (templatesGroup == null) {
           templatesGroup = new Element(getXmlElementGroupName(manager));
-          if (element == null) {
-            element = new Element("fileTemplateSettings");
-          }
           element.addContent(templatesGroup);
         }
         templatesGroup.addContent(templateElement);
index f4b3803a63d0069f2e9143068eac60298ca347d4..764228fc4ef579daa85142c0317a90daf540ef76 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.
@@ -22,13 +22,13 @@ import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.openapi.wm.ToolWindow;
-import com.intellij.openapi.wm.ToolWindowFactoryEx;
+import com.intellij.openapi.wm.ToolWindowFactory;
 import org.jetbrains.annotations.NotNull;
 
 /**
  * @author yole
  */
-public class ProjectViewToolWindowFactory implements ToolWindowFactoryEx, DumbAware {
+public class ProjectViewToolWindowFactory implements ToolWindowFactory, DumbAware {
   @Override
   public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
     ((ProjectViewImpl) ProjectView.getInstance(project)).setupImpl(toolWindow);
index 7cfc0ee621fa834ba986e73f3cd22e037f78b653..3f0e5c0341f8c9ab5a2fadaa787618a13b44a2f0 100644 (file)
@@ -667,9 +667,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable
 
   @Override
   public JComponent getPreferredFocusedComponent() {
-    final InspectionProfileImpl inspectionProfile = myProfiles.getProfilesComboBox().getSelectedProfile();
-    SingleInspectionProfilePanel panel = getProfilePanel(inspectionProfile);
-    return panel == null ? null : panel.getPreferredFocusedComponent();
+    return myProfilePanelHolder;
   }
 
   private void showProfile(InspectionProfileImpl profile) {
index cc198e18a14050426d3e286e49c4affe572aeb06..7ae725e4ac62a6651238f5cf07f1bbbc4a1c9284 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.
@@ -23,8 +23,24 @@ import org.jetbrains.annotations.NotNull;
  * Performs lazy initialization of a toolwindow registered in plugin.xml.
  *
  * @author yole
+ * @author Konstantin Bulenkov
  * @see ToolWindowEP
  */
 public interface ToolWindowFactory {
   void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow);
+
+  /**
+   * Perform additional initialisation routine here
+   * @param window Tool Window
+   */
+  default void init(ToolWindow window) {}
+
+  /**
+   * Tool Window saves its state on project close and restore on when project opens
+   * In some cases, it is useful to postpone Tool Window activation until user explicitly activates it.
+   * Example: Tool Window initialisation takes huge amount of time and makes project loading slower.
+   * @return {@code true} if Tool Window should not be activated on start even if was opened previously.
+   *         {@code false} otherwise.
+   */
+  default boolean isDoNotActivateOnStart() {return false;}
 }
index 2179adb0cefe027bb683f62329f7e7a3e78d58d4..d5fbea89e15111b675bef06661e6af566c3655a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 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.
@@ -17,7 +17,7 @@ package com.intellij.openapi.wm;
 
 /**
  * @author Dennis.Ushakov
+ * @deprecated use {@link ToolWindowFactory}
  */
 public interface ToolWindowFactoryEx extends ToolWindowFactory {
-  void init(ToolWindow window);
 }
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/PluginConflictReporter.java b/platform/platform-impl/src/com/intellij/diagnostic/PluginConflictReporter.java
new file mode 100644 (file)
index 0000000..de67043
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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.diagnostic;
+
+import com.intellij.diagnostic.errordialog.PluginConflictDialog;
+import com.intellij.ide.plugins.cl.PluginClassLoader;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.wm.WindowManager;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public enum PluginConflictReporter {
+  INSTANCE;
+
+  public void reportConflictByClasses(@NotNull Collection<Class<?>> conflictingClasses) {
+    final Set<PluginId> foundPlugins = new HashSet<>();
+    boolean hasConflictWithPlatform = false;
+
+    if (conflictingClasses.size() < 2) {
+      throw new IllegalArgumentException("The conflict should has been caused by at least two classes");
+    }
+
+    for (Class<?> aClass : conflictingClasses) {
+      final ClassLoader classLoader = aClass.getClassLoader();
+      if (classLoader instanceof PluginClassLoader) {
+        foundPlugins.add(((PluginClassLoader)classLoader).getPluginId());
+      }
+      else {
+        hasConflictWithPlatform = true;
+      }
+    }
+
+    if (foundPlugins.isEmpty()) {
+      Logger.getInstance(PluginConflictReporter.class).warn("The conflict has not come from PluginClassLoader");
+      return;
+    }
+
+    boolean finalHasConflictWithPlatform = hasConflictWithPlatform;
+    ApplicationManager.getApplication().invokeLater(() -> {
+      final JFrame frame = WindowManager.getInstance().findVisibleFrame();
+      if (frame != null) {
+        new PluginConflictDialog(frame, new ArrayList<>(foundPlugins), finalHasConflictWithPlatform).show();
+      }
+    });
+  }
+}
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/PluginConflictDialog.form b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/PluginConflictDialog.form
new file mode 100644 (file)
index 0000000..b9a7ed6
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.diagnostic.errordialog.PluginConflictDialog">
+  <grid id="27dc6" binding="myContentPane" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="500" height="400"/>
+    </constraints>
+    <properties>
+      <preferredSize width="400" height="-1"/>
+    </properties>
+    <border type="none"/>
+    <children>
+      <component id="94dfc" class="com.intellij.ui.components.JBLabel" binding="myTopMessageLabel">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+      </component>
+      <grid id="99a5b" binding="myConflictingPluginsListPanel" custom-create="true" layout-manager="FlowLayout" hgap="5" vgap="5" flow-align="0">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children/>
+      </grid>
+      <component id="d6b86" class="com.intellij.ui.components.JBLabel" binding="myBottomMessageLabel">
+        <constraints>
+          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+      </component>
+      <vspacer id="a4d4f">
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+    </children>
+  </grid>
+</form>
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/PluginConflictDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/PluginConflictDialog.java
new file mode 100644 (file)
index 0000000..011231a
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * 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.diagnostic.errordialog;
+
+import com.intellij.diagnostic.DiagnosticBundle;
+import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.PluginManagerConfigurable;
+import com.intellij.ide.plugins.PluginManagerCore;
+import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.ui.components.JBRadioButton;
+import com.intellij.util.ui.JBEmptyBorder;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PluginConflictDialog extends DialogWrapper {
+  public static final int WIDTH = 510;
+
+  @NotNull
+  private final List<PluginId> myConflictingPlugins;
+
+  private final boolean myIsConflictWithPlatform;
+  @Nullable
+  private final List<JBRadioButton> myRadioButtons;
+
+  private JPanel myContentPane;
+
+  private JBLabel myTopMessageLabel;
+
+  private JPanel myConflictingPluginsListPanel;
+
+  private JBLabel myBottomMessageLabel;
+
+  public PluginConflictDialog(@NotNull Component parent,
+                              @NotNull List<PluginId> conflictingPlugins,
+                              boolean isConflictWithPlatform) {
+    super(parent, false);
+
+    myConflictingPlugins = conflictingPlugins;
+    myIsConflictWithPlatform = isConflictWithPlatform;
+
+    if (myIsConflictWithPlatform) {
+      myRadioButtons = null;
+    }
+    else {
+      myRadioButtons = new ArrayList<>();
+    }
+
+    $$$setupUI$$$();
+    setTitle(DiagnosticBundle.message("error.dialog.conflict.plugin.title"));
+    init();
+
+    myTopMessageLabel.setText(getTopMessageText(conflictingPlugins, isConflictWithPlatform));
+    myBottomMessageLabel.setText(DiagnosticBundle.message("error.dialog.conflict.plugin.footer"));
+
+    myTopMessageLabel.setPreferredSize(new Dimension(WIDTH, (int)myTopMessageLabel.getPreferredSize().getHeight()));
+    myContentPane.setPreferredSize(new Dimension(WIDTH, (int)myContentPane.getMinimumSize().getHeight()));
+  }
+
+  private static String getTopMessageText(@NotNull List<PluginId> conflictingPlugins, boolean isConflictWithPlatform) {
+    final int pluginsNumber = conflictingPlugins.size();
+    if (isConflictWithPlatform) {
+      return DiagnosticBundle.message("error.dialog.conflict.plugin.header.platform", pluginsNumber);
+    }
+    else {
+      final List<String> names = conflictingPlugins.stream()
+        .map(PluginConflictDialog::getPluginNameOrId)
+        .map(s -> "<b>" + s + "</b>")
+        .collect(Collectors.toList());
+      return DiagnosticBundle.message("error.dialog.conflict.plugin.header.each.other",
+                                      StringUtil.join(names.subList(0, pluginsNumber - 1), ", "),
+                                      names.get(pluginsNumber - 1));
+    }
+  }
+
+  private void $$$setupUI$$$() {
+  }
+
+  @Nullable
+  @Override
+  protected JComponent createCenterPanel() {
+    return myContentPane;
+  }
+
+  private void createUIComponents() {
+    final ButtonGroup buttonGroup = new ButtonGroup();
+
+    myConflictingPluginsListPanel = new JPanel(new GridLayout(0, 1));
+    final List<JPanel> pluginDescriptions = myConflictingPlugins.stream()
+      .map(plugin -> getChooserPanelForPlugin(buttonGroup, plugin))
+      .collect(Collectors.toList());
+
+    if (!myIsConflictWithPlatform) {
+      pluginDescriptions.add(0, getChooserPanelForPlugin(buttonGroup, null));
+    }
+
+    for (JPanel panel : pluginDescriptions) {
+      myConflictingPluginsListPanel.add(panel);
+    }
+
+    setUpDefaultSelection();
+  }
+
+  @NotNull
+  private JPanel getChooserPanelForPlugin(@NotNull ButtonGroup buttonGroup, @Nullable PluginId plugin) {
+    final JPanel panel = new JPanel(new BorderLayout());
+    if (!myIsConflictWithPlatform) {
+      assert myRadioButtons != null;
+
+      final JBRadioButton radioButton = new JBRadioButton();
+      myRadioButtons.add(radioButton);
+      buttonGroup.add(radioButton);
+
+      panel.add(radioButton, BorderLayout.WEST);
+      panel.addMouseListener(new MouseAdapter() {
+        @Override
+        public void mouseClicked(MouseEvent e) {
+          radioButton.setSelected(true);
+        }
+      });
+    }
+
+    final JPanel descriptionPanel;
+    if (plugin != null) {
+      descriptionPanel = getPluginDescriptionPanel(plugin, !myIsConflictWithPlatform);
+    }
+    else {
+      descriptionPanel = getDisableAllPanel();
+    }
+    descriptionPanel.setBorder(new JBEmptyBorder(10, myIsConflictWithPlatform ? 10 : 0, 10, 20));
+
+    panel.add(descriptionPanel, BorderLayout.CENTER);
+    return panel;
+  }
+
+  private void setUpDefaultSelection() {
+    if (myIsConflictWithPlatform) {
+      return;
+    }
+    assert myRadioButtons != null && myRadioButtons.size() == myConflictingPlugins.size() + 1;
+
+    for (int i = 0; i < myConflictingPlugins.size(); i++) {
+      final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(myConflictingPlugins.get(i));
+      if (pluginDescriptor != null
+          && (pluginDescriptor.isBundled() || StringUtil.equalsIgnoreCase(pluginDescriptor.getVendor(), "JetBrains"))) {
+        myRadioButtons.get(i).setSelected(true);
+        return;
+      }
+    }
+    myRadioButtons.get(myRadioButtons.size() - 1).setSelected(true);
+  }
+
+  @NotNull
+  private static JPanel getPluginDescriptionPanel(@NotNull PluginId plugin, boolean addUseWord) {
+    final JPanel panel = new JPanel(new BorderLayout());
+
+    final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(plugin);
+    if (pluginDescriptor == null) {
+      panel.add(new JBLabel(plugin.getIdString()), BorderLayout.CENTER);
+      return panel;
+    }
+
+    final StringBuilder sb = new StringBuilder("<html>");
+    if (addUseWord) {
+      sb.append("Use ");
+    }
+    sb.append(pluginDescriptor.getName());
+    if (pluginDescriptor.getVendor() != null) {
+      sb.append(" by ").append(pluginDescriptor.getVendor());
+    }
+    sb.append("</html>");
+    panel.add(new JBLabel(sb.toString()));
+    return panel;
+  }
+
+  @NotNull
+  private static String getPluginNameOrId(@NotNull PluginId pluginId) {
+    final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(pluginId);
+    if (pluginDescriptor == null) {
+      return pluginId.getIdString();
+    }
+    else {
+      return pluginDescriptor.getName();
+    }
+  }
+
+  @NotNull
+  private static JPanel getDisableAllPanel() {
+    final JPanel panel = new JPanel(new BorderLayout());
+    panel.add(new JBLabel(DiagnosticBundle.message("error.dialog.conflict.plugin.disable.all")));
+    return panel;
+  }
+
+  @NotNull
+  @Override
+  protected Action getOKAction() {
+    return new DisableAction();
+  }
+
+  private class DisableAction extends DialogWrapperAction {
+    protected DisableAction() {
+      super(DiagnosticBundle.message("error.dialog.disable.plugin.action.disable"));
+      putValue(DEFAULT_ACTION, Boolean.TRUE);
+    }
+
+    @Override
+    protected void doAction(ActionEvent e) {
+      for (int i = 0; i < myConflictingPlugins.size(); ++i) {
+        if (myRadioButtons == null || !myRadioButtons.get(i).isSelected()) {
+          PluginManagerCore.disablePlugin(myConflictingPlugins.get(i).getIdString());
+        }
+      }
+      close(OK_EXIT_CODE);
+      PluginManagerConfigurable.shutdownOrRestartApp("");
+    }
+  }
+}
index cbc22c5f149e8576ceccdcf2f3f9ddc5f549ad13..793f11e029f3db99fe0fe86573d2e013e8b29cbf 100644 (file)
@@ -15,7 +15,9 @@
  */
 package com.intellij.idea;
 
+import com.intellij.diagnostic.ImplementationConflictException;
 import com.intellij.diagnostic.LogMessageEx;
+import com.intellij.diagnostic.PluginConflictReporter;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ex.ApplicationInfoEx;
 import com.intellij.openapi.application.impl.ApplicationImpl;
@@ -123,6 +125,10 @@ public class IdeaLogger extends Log4jBasedLogger {
       }
     }
 
+    if (t instanceof ImplementationConflictException) {
+      PluginConflictReporter.INSTANCE.reportConflictByClasses(((ImplementationConflictException)t).getConflictingClasses());
+    }
+
     String detailString = StringUtil.join(details, "\n");
 
     if (ourErrorsOccurred == null) {
index 820f04dee7da87e02cf4b2a1337e6939124d59b5..2188fe08777f46244f01b0ce23bd4ec46a8ef3b0 100644 (file)
@@ -38,12 +38,21 @@ inline fun <T> runBatchUpdate(messageBus: MessageBus, runnable: () -> T): T {
 /**
  * @exclude Internal use only
  */
-fun invokeAndWaitIfNeed(runnable: () -> Unit) {
+fun <T> invokeAndWaitIfNeed(runnable: () -> T): T {
   val app = ApplicationManager.getApplication()
   if (app == null) {
-    if (SwingUtilities.isEventDispatchThread()) runnable() else SwingUtilities.invokeAndWait(runnable)
+    if (SwingUtilities.isEventDispatchThread()) {
+      return runnable()
+    }
+    else {
+      var result: T? = null
+      SwingUtilities.invokeAndWait { result = runnable() }
+      return result as T
+    }
   }
   else {
-    app.invokeAndWait(runnable, ModalityState.defaultModalityState())
+    var result: T? = null
+    app.invokeAndWait({ result = runnable() }, ModalityState.defaultModalityState())
+    return result as T
   }
 }
\ No newline at end of file
index 84c4f7db20459204bcf1d2cc3cf54c5c8b5f62a0..874685d1ac0a67370663b10d3684b2d898e7f094 100644 (file)
@@ -493,7 +493,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret, Dumpable {
       }
     }
 
-    myEditor.getFoldingModel().flushCaretPosition();
+    myEditor.getFoldingModel().flushCaretPosition(this);
 
     VerticalInfo oldInfo = myCaretInfo;
     LogicalPosition oldCaretPosition = myLogicalCaret;
@@ -682,7 +682,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret, Dumpable {
 
     updateVisualLineInfo();
 
-    myEditor.getFoldingModel().flushCaretPosition();
+    myEditor.getFoldingModel().flushCaretPosition(this);
 
     setLastColumnNumber(myLogicalCaret.column);
     myDesiredSelectionStartColumn = myDesiredSelectionEndColumn = -1;
@@ -872,7 +872,6 @@ public class CaretImpl extends UserDataHolderBase implements Caret, Dumpable {
       }
     }
 
-    updateVisualLineInfo();
     updateSelectionOnDocumentChange();
   }
 
index df72e381909146fcb9932227e2dbc0db96d32da7..6a482d6c16f4e4bc5dbbbbf2ce93e8bdc78ced3c 100644 (file)
@@ -523,10 +523,8 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedInternalDocu
     return myFoldTextAttributes;
   }
 
-  public void flushCaretPosition() {
-    for (Caret caret : myEditor.getCaretModel().getAllCarets()) {
-      caret.putUserData(SAVED_CARET_POSITION, null);
-    }
+  void flushCaretPosition(@NotNull Caret caret) {
+    caret.putUserData(SAVED_CARET_POSITION, null);
   }
 
   void onBulkDocumentUpdateStarted() {
index c97831818eec42f2f00f1e46a92efee8fa33dff3..649fe18153ae8975f2b8aee32f258e15e4d3fa44 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.
@@ -555,9 +555,7 @@ public final class ToolWindowImpl implements ToolWindowEx {
 
   public void setContentFactory(ToolWindowFactory contentFactory) {
     myContentFactory = contentFactory;
-    if (contentFactory instanceof ToolWindowFactoryEx) {
-      ((ToolWindowFactoryEx)contentFactory).init(this);
-    }
+    contentFactory.init(this);
   }
 
   public void ensureContentInitialized() {
index ff006a1156e2011790719944ffdf89f47787579d..6de3fdc79d3fc033434ed58e714782022d3dd56d 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.
@@ -263,7 +263,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
     myId = element.getAttributeValue(ID_ATTR);
     myWasRead = true;
     try {
-      myActive = Boolean.valueOf(element.getAttributeValue(ACTIVE_ATTR)).booleanValue();
+      myActive = Boolean.valueOf(element.getAttributeValue(ACTIVE_ATTR)).booleanValue() && canActivateOnStart(myId);
     }
     catch (NumberFormatException ignored) {
     }
@@ -283,7 +283,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
     }
     catch (IllegalArgumentException ignored) {
     }
-    myVisible = Boolean.valueOf(element.getAttributeValue(VISIBLE_ATTR)).booleanValue();
+    myVisible = Boolean.valueOf(element.getAttributeValue(VISIBLE_ATTR)).booleanValue() && canActivateOnStart(myId);
     if (element.getAttributeValue(SHOW_STRIPE_BUTTON) != null) {
       myShowStripeButton = Boolean.valueOf(element.getAttributeValue(SHOW_STRIPE_BUTTON)).booleanValue();
     }
@@ -319,6 +319,16 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
     myContentUiType = ToolWindowContentUiType.getInstance(element.getAttributeValue(CONTENT_UI_ATTR));
   }
 
+  private static boolean canActivateOnStart(String id) {
+    for (ToolWindowEP ep : ToolWindowEP.EP_NAME.getExtensions()) {
+      if (id.equals(ep.id)) {
+        ToolWindowFactory factory = ep.getToolWindowFactory();
+        return !factory.isDoNotActivateOnStart();
+      }
+    }
+    return true;
+  }
+
   /**
    * Sets new anchor.
    */
index 5da107a0da14cec27bbe89721e000976989efb64..728f1bed7ca335393afbd4267ff5b6c22e32f5ab 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.reporting
 
 import com.google.gson.Gson
 import com.intellij.openapi.application.PermanentInstallationID
+import com.intellij.openapi.diagnostic.Logger
 import org.apache.http.client.fluent.Request
 import org.apache.http.entity.ContentType
 
@@ -32,7 +33,8 @@ private object Utils {
 
 object StatsSender {
   private val infoUrl = "https://www.jetbrains.com/config/features-service-status.json"
-
+  private val LOG = Logger.getInstance(StatsSender::class.java)
+  
   private fun requestServerUrl(): String? {
     try {
       val response = Request.Get(infoUrl).execute().returnContent().asString()
@@ -40,6 +42,7 @@ object StatsSender {
       if (info.isServiceAlive()) return info.url
     }
     catch (e: Exception) {
+      LOG.debug(e)
     }
 
     return null
@@ -55,6 +58,7 @@ object StatsSender {
       }
     }
     catch (e: Exception) {
+      LOG.debug(e)
     }
     return false
   }
index e26b4ae549e31da75ce7772a45f6e174c6af5ca5..e4c6d820b884a6672503755fe3e14e52981e14b8 100644 (file)
@@ -92,5 +92,10 @@ error.dialog.attachment.path.column.title=Path
 error.dialog.attachment.include.column.title=Include
 error.attachments.tab.title=Attachments
 error.dialog.filecontent.title=File content
+error.dialog.conflict.plugin.title=Initialization Failure
+error.dialog.conflict.plugin.header.platform=The following plugin{0,choice,1#|2#s} conflict{0,choice,1#s|2#} with IDE platform:
+error.dialog.conflict.plugin.header.each.other=<html><p style="line-height: 150%;">The following plugins conflict with each other: {0} and {1}</p></html>
+error.dialog.conflict.plugin.footer=It is highly recommended to resolve this conflict by disabling redundant plugins.
+error.dialog.conflict.plugin.disable.all=Disable all
 diagnostic.error.report.include.attachment.warning=Report will include attachment: ''<a>{0}</a>''.
 diagnostic.error.report.include.attachments.warning=Report will include <a>{0} attachments</a>.
index ca0f3b785cd109c34ead323d66284667e09336bb..bd39fea4686373eb95d7cab464be3d0307e79d95 100644 (file)
@@ -317,13 +317,13 @@ inspection.javadoc.html.not.required.label.text=Additional Not Required Html Att
 inspection.javadoc.html.not.required.dialog.title=Edit Additional Not Required Html Attributes
 inspection.required.attributes.display.name=Missing required attribute
 
-inspection.unused.symbol.check.localvars=&Local variables (Editor only)
-inspection.unused.symbol.check.fields=&Fields:
-inspection.unused.symbol.check.methods=&Methods:
-inspection.unused.symbol.check.accessors=&Getters/setters
-inspection.unused.symbol.check.classes=&Classes:
-inspection.unused.symbol.check.inner.classes=&Inner classes:
-inspection.unused.symbol.check.parameters=&Parameters in
+inspection.unused.symbol.check.localvars=Local variables (Editor only)
+inspection.unused.symbol.check.fields=Fields:
+inspection.unused.symbol.check.methods=Methods:
+inspection.unused.symbol.check.accessors=Getters/setters
+inspection.unused.symbol.check.classes=Classes:
+inspection.unused.symbol.check.inner.classes=Inner classes:
+inspection.unused.symbol.check.parameters=Parameters in
 
 inspection.results.for.profile.toolwindow.title=''{0}'' Profile on {1}
 inspection.results.for.inspection.toolwindow.title=''{0}'' Inspection on {1}
index f925c43f6fcba34b37816d51e732ea0f332ffffd..f628f6e7a36566e5190491c30b61876525f50536 100644 (file)
@@ -182,12 +182,12 @@ public class LightFileTemplatesTest extends LightPlatformTestCase {
     FileTemplateBase template = (FileTemplateBase)myTemplateManager.getTemplate("templateWithLiveTemplate.txt");
     assertTrue(template.isLiveTemplateEnabledByDefault());
     FileTemplateSettings settings = ServiceManager.getService(ExportableFileTemplateSettings.class);
-    assertNull(settings.getState());
+    assertEquals(0, settings.getState().getContentSize());
     template.setLiveTemplateEnabled(false);
     Element state = settings.getState();
     assertNotNull(state);
     template.setLiveTemplateEnabled(true);
-    assertNull(settings.getState());
+    assertEquals(0, settings.getState().getContentSize());
   }
 
   private FileTemplateManagerImpl myTemplateManager;
index a00f58e525830618d3a162763f3f5b708f24daed..abf0dd8098625d91063fd88fcd34f7d284dacf2c 100644 (file)
  */
 package com.intellij.configurationStore
 
+import com.intellij.openapi.options.ExternalizableSchemeAdapter
 import com.intellij.openapi.options.Scheme
 import com.intellij.openapi.options.SchemeProcessor
+import com.intellij.openapi.options.SchemeState
+import com.intellij.util.isEmpty
 import org.jdom.Element
 import java.io.OutputStream
 import java.security.MessageDigest
@@ -29,6 +32,8 @@ interface SchemeDataHolder<in MUTABLE_SCHEME : Scheme> {
   fun read(): Element
 
   fun updateDigest(scheme: MUTABLE_SCHEME)
+
+  fun updateDigest(data: Element)
 }
 
 interface SerializableScheme {
@@ -84,4 +89,35 @@ fun Element.digest(): ByteArray {
   val digest = MessageDigest.getInstance("SHA-1")
   serializeElementToBinary(this, DigestOutputStream(digest))
   return digest.digest()
+}
+
+abstract class SchemeWrapper<out T : Scheme>(name: String) : ExternalizableSchemeAdapter(), SerializableScheme {
+  protected abstract val lazyScheme: Lazy<T>
+
+  val scheme: T
+    get() = lazyScheme.value
+
+  val schemeState: SchemeState
+    get() = if (lazyScheme.isInitialized()) SchemeState.POSSIBLY_CHANGED else SchemeState.UNCHANGED
+
+  init {
+    this.name = name
+  }
+}
+
+class InitializedSchemeWrapper<out T : Scheme>(scheme: T, private val writer: (scheme: T) -> Element) : SchemeWrapper<T>(scheme.name) {
+  override val lazyScheme = lazyOf(scheme)
+
+  override fun writeScheme() = writer(scheme)
+}
+
+fun wrapState(element: Element): Element {
+  if (element.isEmpty()) {
+    element.name = "state"
+    return element
+  }
+
+  val wrapper = Element("state")
+  wrapper.addContent(element)
+  return wrapper
 }
\ No newline at end of file
index ef460e6902cd894b1e6318c778b41f9e5298884c..f1e45ae5c543b4771bec7ff33db98340037265e9 100644 (file)
@@ -82,6 +82,8 @@ fun Element.element(name: String): Element {
   return element
 }
 
+fun Element.attribute(name: String, value: String?): Element = setAttribute(name, value)
+
 fun <T> Element.remove(name: String, transform: (child: Element) -> T): List<T> {
   val result = SmartList<T>()
   val groupIterator = getContent(ElementFilter(name)).iterator()
index 60a758a6ae6d4590b70e0368aa8f6e5269ea4168..ba678c929ff9728ae3f45771a16b2b19e1dfafac 100644 (file)
@@ -3147,10 +3147,23 @@ public class StringUtil extends StringUtilRt {
   public static LineSeparator detectSeparators(@NotNull CharSequence text) {
     int index = indexOfAny(text, "\n\r");
     if (index == -1) return null;
-    if (startsWith(text, index, "\r\n")) return LineSeparator.CRLF;
-    if (text.charAt(index) == '\r') return LineSeparator.CR;
-    if (text.charAt(index) == '\n') return LineSeparator.LF;
-    throw new IllegalStateException();
+    LineSeparator lineSeparator = findStartingLineSeparator(text, index);
+    if (lineSeparator == null) {
+      throw new AssertionError();
+    }
+    return lineSeparator;
+  }
+
+  @Nullable
+  public static LineSeparator findStartingLineSeparator(@NotNull CharSequence text, int startIndex) {
+    if (startIndex < 0 || startIndex >= text.length()) {
+      return null;
+    }
+    char ch = text.charAt(startIndex);
+    if (ch == '\r') {
+      return startIndex + 1 < text.length() && text.charAt(startIndex + 1) == '\n' ? LineSeparator.CRLF : LineSeparator.CR;
+    }
+    return ch == '\n' ? LineSeparator.LF : null;
   }
 
   @NotNull
index 569734335156dbc7a4703e42c39b11719f73a77b..b8791aea3bf85714155bcbd8852f5d6507162aae 100644 (file)
@@ -373,6 +373,28 @@ public class StringUtilTest {
     assertEquals(LineSeparator.CRLF, StringUtil.detectSeparators("asd\r\nads\n"));
   }
 
+  @Test
+  public void testFindStartingLineSeparator() {
+    assertEquals(null, StringUtil.findStartingLineSeparator("", -1));
+    assertEquals(null, StringUtil.findStartingLineSeparator("", 0));
+    assertEquals(null, StringUtil.findStartingLineSeparator("", 1));
+    assertEquals(null, StringUtil.findStartingLineSeparator("\nHello", -1));
+    assertEquals(null, StringUtil.findStartingLineSeparator("\nHello", 1));
+    assertEquals(null, StringUtil.findStartingLineSeparator("\nH\rel\nlo", 6));
+
+    assertEquals(LineSeparator.LF, StringUtil.findStartingLineSeparator("\nHello", 0));
+    assertEquals(LineSeparator.LF, StringUtil.findStartingLineSeparator("\nH\rel\nlo", 5));
+    assertEquals(LineSeparator.LF, StringUtil.findStartingLineSeparator("Hello\n", 5));
+
+    assertEquals(LineSeparator.CR, StringUtil.findStartingLineSeparator("\rH\r\nello", 0));
+    assertEquals(LineSeparator.CR, StringUtil.findStartingLineSeparator("Hello\r", 5));
+    assertEquals(LineSeparator.CR, StringUtil.findStartingLineSeparator("Hello\b\r", 6));
+
+    assertEquals(LineSeparator.CRLF, StringUtil.findStartingLineSeparator("\rH\r\nello", 2));
+    assertEquals(LineSeparator.CRLF, StringUtil.findStartingLineSeparator("\r\nH\r\nello", 0));
+    assertEquals(LineSeparator.CRLF, StringUtil.findStartingLineSeparator("\r\nH\r\nello\r\n", 9));
+  }
+
   @Test
   public void testFormatFileSize() {
     assertEquals("0B", StringUtil.formatFileSize(0));
index 0103ef58d28f0c712a99e8acbb8e0ec133a27e39..65bff2ce30fc7024384e0b86a507fa8daa50e0ff 100644 (file)
@@ -30,6 +30,8 @@ class AnnotateCurrentRevisionAction extends AnnotateRevisionAction {
   @Override
   protected VcsFileRevision getRevision(int lineNumber) {
     assert myProvider != null;
+
+    if (lineNumber < 0 || lineNumber >= myAnnotation.getLineCount()) return null;
     return myProvider.getRevision(lineNumber);
   }
 }
index dba8837c48dac1375ad33c0c46a52254a1331bfd..248be76a3a2e06976883a56a6041dcda28f95b25 100644 (file)
@@ -31,10 +31,12 @@ class AnnotatePreviousRevisionAction extends AnnotateRevisionAction {
   @Override
   protected VcsFileRevision getRevision(int lineNumber) {
     assert myProvider != null;
+
     if (lineNumber == UpToDateLineNumberProvider.ABSENT_LINE_NUMBER) {
       return myProvider.getLastRevision();
     }
     else {
+      if (lineNumber < 0 || lineNumber >= myAnnotation.getLineCount()) return null;
       return myProvider.getPreviousRevision(lineNumber);
     }
   }
index c51fb9d2e9d3df2d71de98914f14def327b0b7a2..7bf3ce4c9f008dd9ffc1cbba6569f17300f12ce7 100644 (file)
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
 import javax.swing.*;
 
 abstract class AnnotateRevisionAction extends AnnotateRevisionActionBase implements DumbAware, UpToDateLineNumberListener {
-  @NotNull private final FileAnnotation myAnnotation;
+  @NotNull protected final FileAnnotation myAnnotation;
   @NotNull private final AbstractVcs myVcs;
 
   private int currentLine;
@@ -83,7 +83,6 @@ abstract class AnnotateRevisionAction extends AnnotateRevisionActionBase impleme
   @Nullable
   @Override
   protected VcsFileRevision getFileRevision(@NotNull AnActionEvent e) {
-    if (currentLine < 0 || currentLine >= myAnnotation.getLineCount()) return null;
     return getRevision(currentLine);
   }
 
index a41635140e740b4a8b3af3873378a71081d1d629..d9005fd5a4e3a24b61523216148ad17cdbeb1d4a 100644 (file)
@@ -84,6 +84,10 @@ public abstract class XBreakpointType<B extends XBreakpoint<P>, P extends XBreak
     return mySuspendThreadSupported;
   }
 
+  public SuspendPolicy getDefaultSuspendPolicy() {
+    return SuspendPolicy.ALL;
+  }
+
   public enum StandardPanels {SUSPEND_POLICY, ACTIONS, DEPENDENCY}
 
   public EnumSet<StandardPanels> getVisibleStandardPanels() {
index 8631b8fc901bb0ade668d7e7799bc8e88b0072d5..8dd934a48c94512a5e1df53918f6d113f364c43a 100644 (file)
@@ -53,10 +53,11 @@ public class BreakpointState<B extends XBreakpoint<P>, P extends XBreakpointProp
   public BreakpointState() {
   }
 
-  public BreakpointState(final boolean enabled, final String typeId, final long timeStamp) {
+  public BreakpointState(final boolean enabled, final String typeId, final long timeStamp, final SuspendPolicy suspendPolicy) {
     myEnabled = enabled;
     myTypeId = typeId;
     myTimeStamp = timeStamp;
+    mySuspendPolicy = suspendPolicy;
   }
 
   @Attribute("enabled")
index c843d9ef53c1b4e98b70c1f1fd72d8f31b73dd97..534db7761a7953cbbd693c9fef535ca64e8150c5 100644 (file)
@@ -16,6 +16,7 @@
 package com.intellij.xdebugger.impl.breakpoints;
 
 import com.intellij.util.xmlb.annotations.Tag;
+import com.intellij.xdebugger.breakpoints.SuspendPolicy;
 import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
 import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
 import com.intellij.xdebugger.breakpoints.XLineBreakpointType;
@@ -33,8 +34,9 @@ public class LineBreakpointState<P extends XBreakpointProperties> extends Breakp
   public LineBreakpointState() {
   }
 
-  public LineBreakpointState(final boolean enabled, final String typeId, final String fileUrl, final int line, boolean temporary, final long timeStamp) {
-    super(enabled, typeId, timeStamp);
+  public LineBreakpointState(final boolean enabled, final String typeId, final String fileUrl, final int line, boolean temporary,
+                             final long timeStamp, final SuspendPolicy suspendPolicy) {
+    super(enabled, typeId, timeStamp, suspendPolicy);
     myFileUrl = fileUrl;
     myLine = line;
     myTemporary = temporary;
index 0c9f0bdd806ca69cf7c092b1398b3060b69c1d62..f6038c693eb2355d64dc83e129a88f41f70f27d2 100644 (file)
@@ -121,7 +121,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
                                                                                       boolean defaultBreakpoint) {
     BreakpointState<?,T,?> state = new BreakpointState<>(enabled,
                                                          type.getId(),
-                                                         defaultBreakpoint ? 0 : myTime++);
+                                                         defaultBreakpoint ? 0 : myTime++, type.getDefaultSuspendPolicy());
     getBreakpointDefaults(type).applyDefaults(state);
     state.setGroup(myDefaultGroup);
     return new XBreakpointBase<XBreakpoint<T>,T, BreakpointState<?,T,?>>(type, this, properties, state);
@@ -217,7 +217,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
                                                                                 boolean temporary) {
     ApplicationManager.getApplication().assertWriteAccessAllowed();
     LineBreakpointState<T> state = new LineBreakpointState<>(true, type.getId(), fileUrl, line, temporary,
-                                                             myTime++);
+                                                             myTime++, type.getDefaultSuspendPolicy());
     getBreakpointDefaults(type).applyDefaults(state);
     state.setGroup(myDefaultGroup);
     XLineBreakpointImpl<T> breakpoint = new XLineBreakpointImpl<>(type, this, properties,
@@ -508,6 +508,7 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
   private static BreakpointState createBreakpointDefaults(@NotNull XBreakpointType type) {
     BreakpointState state = new BreakpointState();
     state.setTypeId(type.getId());
+    state.setSuspendPolicy(type.getDefaultSuspendPolicy());
     return state;
   }
 
index 947693068e21fb0d1888bac90439a40e0705362f..2d2f918a01b6aa23f3ca0bca2bebf30883e4141b 100644 (file)
@@ -169,7 +169,7 @@ public class XSuspendPolicyPanel extends XBreakpointPropertiesSubPanel {
       return mySuspendAll.isSelected() ? SuspendPolicy.ALL : SuspendPolicy.THREAD;
     }
     else {
-      return SuspendPolicy.ALL;
+      return myBreakpoint.getType().getDefaultSuspendPolicy();
     }
   }
 
index deb46eccd664d9b4dfb2e4d8093f01e9c72e0c5e..f05aa239df8e3cc86b492925ec2c6a4dbbd29a44 100644 (file)
@@ -56,6 +56,10 @@ public class DeleteUnnecessaryStatementFix extends InspectionGadgetsFix {
     if (statement == null) {
       return;
     }
+    deleteUnnecessaryStatement(statement);
+  }
+
+  public static void deleteUnnecessaryStatement(PsiStatement statement) {
     final PsiElement parent = statement.getParent();
     if (parent instanceof PsiIfStatement ||
         parent instanceof PsiWhileStatement ||
index 126c6110fa435c42c70204138ad2885cc6b22d92..e9b97f5b12bfae4291d976b9f4bfed21b1261df0 100644 (file)
@@ -14,5 +14,6 @@
     <orderEntry type="module" module-name="openapi" />
     <orderEntry type="library" name="Velocity" level="project" />
     <orderEntry type="module" module-name="xml" />
+    <orderEntry type="library" name="KotlinJavaRuntime" level="project" />
   </component>
 </module>
\ No newline at end of file
diff --git a/plugins/copyright/src/CopyrightManager.kt b/plugins/copyright/src/CopyrightManager.kt
new file mode 100644 (file)
index 0000000..046b415
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * 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.copyright
+
+import com.intellij.configurationStore.*
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.application.ModalityState
+import com.intellij.openapi.components.PersistentStateComponent
+import com.intellij.openapi.components.State
+import com.intellij.openapi.components.Storage
+import com.intellij.openapi.components.service
+import com.intellij.openapi.diagnostic.Logger
+import com.intellij.openapi.editor.EditorFactory
+import com.intellij.openapi.editor.event.DocumentAdapter
+import com.intellij.openapi.editor.event.DocumentEvent
+import com.intellij.openapi.fileEditor.FileDocumentManager
+import com.intellij.openapi.options.SchemeManagerFactory
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.roots.ProjectRootManager
+import com.intellij.openapi.startup.StartupActivity
+import com.intellij.openapi.util.Disposer
+import com.intellij.openapi.util.InvalidDataException
+import com.intellij.openapi.util.WriteExternalException
+import com.intellij.openapi.util.text.StringUtil
+import com.intellij.packageDependencies.DependencyValidationManager
+import com.intellij.project.isDirectoryBased
+import com.intellij.psi.PsiFile
+import com.intellij.psi.PsiManager
+import com.intellij.util.attribute
+import com.intellij.util.element
+import com.maddyhome.idea.copyright.CopyrightProfile
+import com.maddyhome.idea.copyright.actions.UpdateCopyrightProcessor
+import com.maddyhome.idea.copyright.options.LanguageOptions
+import com.maddyhome.idea.copyright.options.Options
+import com.maddyhome.idea.copyright.util.FileTypeUtil
+import com.maddyhome.idea.copyright.util.NewFileTracker
+import org.jdom.Element
+import java.util.*
+import java.util.concurrent.atomic.AtomicReference
+import java.util.function.Function
+
+private const val DEFAULT = "default"
+private const val MODULE2COPYRIGHT = "module2copyright"
+private const val COPYRIGHT = "copyright"
+private const val ELEMENT = "element"
+private const val MODULE = "module"
+
+private val LOG = Logger.getInstance(CopyrightManager::class.java)
+
+@State(name = "CopyrightManager", storages = arrayOf(Storage(value = "copyright/profiles_settings.xml", exclusive = true)))
+class CopyrightManager(private val project: Project, schemeManagerFactory: SchemeManagerFactory) : PersistentStateComponent<Element> {
+  companion object {
+    @JvmStatic
+    fun getInstance(project: Project) = project.service<CopyrightManager>()
+  }
+
+  private var defaultCopyrightName: String? = null
+
+  var defaultCopyright: CopyrightProfile?
+    get() = defaultCopyrightName?.let { schemeManager.findSchemeByName(it)?.scheme }
+    set(value) {
+      defaultCopyrightName = value?.name
+    }
+
+  val scopeToCopyright = LinkedHashMap<String, String>()
+  val options = Options()
+
+  private val schemeManagerIprProvider = if (project.isDirectoryBased) null else SchemeManagerIprProvider()
+
+  val schemeManager = schemeManagerFactory.create("copyright", object : LazySchemeProcessor<SchemeWrapper<CopyrightProfile>, SchemeWrapper<CopyrightProfile>>() {
+    override fun createScheme(dataHolder: SchemeDataHolder<SchemeWrapper<CopyrightProfile>>,
+                              name: String,
+                              attributeProvider: Function<String, String?>): SchemeWrapper<CopyrightProfile> {
+      return LazySchemeWrapper(name, dataHolder, schemeWriter)
+    }
+
+    override fun getState(scheme: SchemeWrapper<CopyrightProfile>) = scheme.schemeState
+
+    override fun isSchemeFile(name: CharSequence) = !StringUtil.equals(name, "profiles_settings.xml")
+  }, isUseOldFileNameSanitize = true, streamProvider = schemeManagerIprProvider)
+
+  init {
+    val app = ApplicationManager.getApplication()
+    if (project.isDirectoryBased || !app.isUnitTestMode) {
+      schemeManager.loadSchemes()
+    }
+  }
+
+  fun mapCopyright(scopeName: String, copyrightProfileName: String) {
+    scopeToCopyright.put(scopeName, copyrightProfileName)
+  }
+
+  fun unmapCopyright(scopeName: String) {
+    scopeToCopyright.remove(scopeName)
+  }
+
+  fun hasAnyCopyrights(): Boolean {
+    return defaultCopyrightName != null || !scopeToCopyright.isEmpty()
+  }
+
+  override fun getState(): Element? {
+    val result = Element("settings")
+    try {
+      schemeManagerIprProvider?.writeState(result)
+
+      if (!scopeToCopyright.isEmpty()) {
+        val map = Element(MODULE2COPYRIGHT)
+        for ((scopeName, profileName) in scopeToCopyright) {
+          map.element(ELEMENT)
+              .attribute(MODULE, scopeName)
+              .attribute(COPYRIGHT, profileName)
+        }
+        result.addContent(map)
+      }
+
+      options.writeExternal(result)
+    }
+    catch (e: WriteExternalException) {
+      LOG.error(e)
+      return null
+    }
+
+    defaultCopyrightName?.let {
+      result.setAttribute(DEFAULT, it)
+    }
+
+    return wrapState(result)
+  }
+
+  override fun loadState(state: Element) {
+    val data: Element? = state.getChild("settings")
+
+    schemeManagerIprProvider?.let {
+      it.load(data)
+      schemeManager.reload()
+    }
+
+    if (data == null) {
+      return
+    }
+
+    val moduleToCopyright = data.getChild(MODULE2COPYRIGHT)
+    if (moduleToCopyright != null) {
+      for (element in moduleToCopyright.getChildren(ELEMENT)) {
+        scopeToCopyright.put(element.getAttributeValue(MODULE), element.getAttributeValue(COPYRIGHT))
+      }
+    }
+
+    try {
+      defaultCopyrightName = data.getAttributeValue(DEFAULT)
+      options.readExternal(data)
+    }
+    catch (e: InvalidDataException) {
+      LOG.error(e)
+    }
+  }
+
+  fun addCopyright(profile: CopyrightProfile) {
+    schemeManager.addScheme(InitializedSchemeWrapper(profile, schemeWriter))
+  }
+
+  fun getCopyrights(): Collection<CopyrightProfile> = schemeManager.allSchemes.map { it.scheme }
+
+  fun clearMappings() {
+    scopeToCopyright.clear()
+  }
+
+  fun removeCopyright(copyrightProfile: CopyrightProfile) {
+    schemeManager.removeScheme(copyrightProfile.name)
+
+    val it = scopeToCopyright.keys.iterator()
+    while (it.hasNext()) {
+      if (scopeToCopyright.get(it.next()) == copyrightProfile.name) {
+        it.remove()
+      }
+    }
+  }
+
+  fun replaceCopyright(name: String, profile: CopyrightProfile) {
+    val existingScheme = schemeManager.findSchemeByName(name)
+    if (existingScheme == null) {
+      addCopyright(profile)
+    }
+    else {
+      existingScheme.scheme.copyFrom(profile)
+    }
+  }
+
+  fun getCopyrightOptions(file: PsiFile): CopyrightProfile? {
+    val virtualFile = file.virtualFile
+    if (virtualFile == null || options.getOptions(virtualFile.fileType.name).getFileTypeOverride() == LanguageOptions.NO_COPYRIGHT) {
+      return null
+    }
+
+    val validationManager = DependencyValidationManager.getInstance(project)
+    for (scopeName in scopeToCopyright.keys) {
+      val packageSet = validationManager.getScope(scopeName)?.value ?: continue
+      if (packageSet.contains(file, validationManager)) {
+        scopeToCopyright.get(scopeName)?.let { schemeManager.findSchemeByName(it) }?.let { return it.scheme }
+      }
+    }
+    return defaultCopyright
+  }
+}
+
+private class CopyrightManagerPostStartupActivity : StartupActivity {
+  val newFileTracker = NewFileTracker()
+
+  override fun runActivity(project: Project) {
+    Disposer.register(project, Disposable { newFileTracker.clear() })
+
+    EditorFactory.getInstance().eventMulticaster.addDocumentListener(object : DocumentAdapter() {
+      override fun documentChanged(e: DocumentEvent) {
+        val virtualFile = FileDocumentManager.getInstance().getFile(e.document) ?: return
+        val module = ProjectRootManager.getInstance(project).fileIndex.getModuleForFile(virtualFile) ?: return
+        if (!newFileTracker.poll(virtualFile) ||
+            !FileTypeUtil.getInstance().isSupportedFile(virtualFile) ||
+            PsiManager.getInstance(project).findFile(virtualFile) == null) {
+          return
+        }
+
+        ApplicationManager.getApplication().invokeLater(Runnable {
+          if (!virtualFile.isValid) {
+            return@Runnable
+          }
+
+          val file = PsiManager.getInstance(project).findFile(virtualFile)
+          if (file != null && file.isWritable) {
+            CopyrightManager.getInstance(project).getCopyrightOptions(file)?.let {
+              UpdateCopyrightProcessor(project, module, file).run()
+            }
+          }
+        }, ModalityState.NON_MODAL, project.disposed)
+      }
+    }, project)
+  }
+}
+
+private fun wrapScheme(element: Element): Element {
+  val wrapper = Element("component")
+      .attribute("name", "CopyrightManager")
+  wrapper.addContent(element)
+  return wrapper
+}
+
+private val schemeWriter = { scheme: CopyrightProfile ->
+  val element = Element("copyright")
+  scheme.writeExternal(element)
+  wrapScheme(element)
+}
+
+private class LazySchemeWrapper(name: String,
+                        dataHolder: SchemeDataHolder<SchemeWrapper<CopyrightProfile>>,
+                        private val writer: (scheme: CopyrightProfile) -> Element,
+                        private val subStateTagName: String = "copyright") : SchemeWrapper<CopyrightProfile>(name) {
+  private val dataHolder = AtomicReference(dataHolder)
+
+  override val lazyScheme = lazy {
+    val scheme = CopyrightProfile()
+    @Suppress("NAME_SHADOWING")
+    val dataHolder = this.dataHolder.getAndSet(null)
+    val element = dataHolder.read().getChild(subStateTagName)
+    scheme.readExternal(element)
+    dataHolder.updateDigest(writer(scheme))
+    scheme
+  }
+
+  override fun writeScheme(): Element {
+    val dataHolder = dataHolder.get()
+    return if (dataHolder == null) writer(scheme) else dataHolder.read()
+  }
+}
\ No newline at end of file
index 87b49a360163ae61cb96773e125607084f94c4db..0a583be018b5784c5c67c39030cdcd00aa72c218 100644 (file)
@@ -1,56 +1,50 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-
-
 <idea-plugin version="2">
-    <name>Copyright</name>
-    <id>com.intellij.copyright</id>
-    <description>
-        Copyright Notice. This plugin is used to ensure files in a project or module have
-        a consistent copyright notice.
-    </description>
-    <version>8.1</version>
-    <vendor>JetBrains</vendor>
-    <depends optional="true" config-file="java.xml">com.intellij.modules.java</depends>
+  <name>Copyright</name>
+  <id>com.intellij.copyright</id>
+  <description>
+    Copyright Notice. This plugin is used to ensure files in a project or module have a consistent copyright notice.
+  </description>
+  <version>8.1</version>
+  <vendor>JetBrains</vendor>
+  <depends optional="true" config-file="java.xml">com.intellij.modules.java</depends>
 
-    <extensions defaultExtensionNs="com.intellij">
-      <projectConfigurable groupId="editor" groupWeight="110" dynamic="true" displayName="Copyright" id="copyright" instance="com.maddyhome.idea.copyright.ui.CopyrightProjectConfigurable"/>
-      <checkinHandlerFactory implementation="com.maddyhome.idea.copyright.actions.UpdateCopyrightCheckinHandlerFactory"/>
-      <applicationService serviceInterface="com.maddyhome.idea.copyright.util.FileTypeUtil"
-                          serviceImplementation="com.maddyhome.idea.copyright.util.FileTypeUtil"/>
-      <projectService serviceInterface="com.maddyhome.idea.copyright.actions.UpdateCopyrightCheckinHandlerState"
-                      serviceImplementation="com.maddyhome.idea.copyright.actions.UpdateCopyrightCheckinHandlerState"/>
-    </extensions>
+  <extensions defaultExtensionNs="com.intellij">
+    <projectConfigurable groupId="editor" groupWeight="110" dynamic="true" displayName="Copyright" id="copyright"
+                         instance="com.maddyhome.idea.copyright.ui.CopyrightProjectConfigurable"/>
+    <checkinHandlerFactory implementation="com.maddyhome.idea.copyright.actions.UpdateCopyrightCheckinHandlerFactory"/>
+    <applicationService serviceInterface="com.maddyhome.idea.copyright.util.FileTypeUtil"
+                        serviceImplementation="com.maddyhome.idea.copyright.util.FileTypeUtil"/>
+    <projectService serviceInterface="com.maddyhome.idea.copyright.actions.UpdateCopyrightCheckinHandlerState"
+                    serviceImplementation="com.maddyhome.idea.copyright.actions.UpdateCopyrightCheckinHandlerState"/>
+    <postStartupActivity implementation="com.intellij.copyright.CopyrightManagerPostStartupActivity"/>
 
-    <project-components>
-        <component>
-          <implementation-class>com.maddyhome.idea.copyright.CopyrightManager</implementation-class>
-          <loadForDefaultProject/>
-        </component>
-    </project-components>
+    <projectService serviceImplementation="com.intellij.copyright.CopyrightManager"/>
+  </extensions>
 
-    <extensions defaultExtensionNs="com.intellij.copyright">
-      <updater filetype="XML" implementationClass="com.maddyhome.idea.copyright.psi.UpdateXmlCopyrightsProvider"/>
-      <updater filetype="HTML" implementationClass="com.maddyhome.idea.copyright.psi.UpdateXmlCopyrightsProvider"/>
-    </extensions>
-    <extensionPoints>
-      <extensionPoint name="updater" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint">
-        <with attribute="implementationClass" implements="com.maddyhome.idea.copyright.psi.UpdateCopyrightsProvider"/>
-      </extensionPoint>
-      <extensionPoint name="variablesProvider" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint">
-        <with attribute="implementationClass" implements="com.maddyhome.idea.copyright.pattern.CopyrightVariablesProvider"/>
-      </extensionPoint>
-      
-    </extensionPoints>
+  <extensions defaultExtensionNs="com.intellij.copyright">
+    <updater filetype="XML" implementationClass="com.maddyhome.idea.copyright.psi.UpdateXmlCopyrightsProvider"/>
+    <updater filetype="HTML" implementationClass="com.maddyhome.idea.copyright.psi.UpdateXmlCopyrightsProvider"/>
+  </extensions>
+  <extensionPoints>
+    <extensionPoint name="updater" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint">
+      <with attribute="implementationClass" implements="com.maddyhome.idea.copyright.psi.UpdateCopyrightsProvider"/>
+    </extensionPoint>
+    <extensionPoint name="variablesProvider" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint">
+      <with attribute="implementationClass" implements="com.maddyhome.idea.copyright.pattern.CopyrightVariablesProvider"/>
+    </extensionPoint>
 
+  </extensionPoints>
 
-    <actions>
-        <action id="UpdateCopyright" class="com.maddyhome.idea.copyright.actions.UpdateCopyrightAction" text="Update Copyright..." description="Generate/Update the copyright notice.">
-            <add-to-group group-id="ProjectViewPopupMenu" anchor="last"/>
-            <add-to-group group-id="CodeMenu" anchor="last"/>
-            <add-to-group group-id="NavbarPopupMenu" anchor="last"/>
-        </action>
-        <action id="GenerateCopyright" class="com.maddyhome.idea.copyright.actions.GenerateCopyrightAction" text="Copyright" description="Generate/Update the copyright notice.">
-            <add-to-group group-id="GenerateGroup" anchor="last"/>
-        </action>
-    </actions>
+  <actions>
+    <action id="UpdateCopyright" class="com.maddyhome.idea.copyright.actions.UpdateCopyrightAction" text="Update Copyright..."
+            description="Generate/Update the copyright notice.">
+      <add-to-group group-id="ProjectViewPopupMenu" anchor="last"/>
+      <add-to-group group-id="CodeMenu" anchor="last"/>
+      <add-to-group group-id="NavbarPopupMenu" anchor="last"/>
+    </action>
+    <action id="GenerateCopyright" class="com.maddyhome.idea.copyright.actions.GenerateCopyrightAction" text="Copyright"
+            description="Generate/Update the copyright notice.">
+      <add-to-group group-id="GenerateGroup" anchor="last"/>
+    </action>
+  </actions>
 </idea-plugin>
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java b/plugins/copyright/src/com/maddyhome/idea/copyright/CopyrightManager.java
deleted file mode 100644 (file)
index be5cebf..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * 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.maddyhome.idea.copyright;
-
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.components.*;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.EditorFactory;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.editor.event.DocumentListener;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.startup.StartupManager;
-import com.intellij.openapi.util.*;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.packageDependencies.DependencyValidationManager;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
-import com.intellij.psi.search.scope.packageSet.NamedScope;
-import com.intellij.psi.search.scope.packageSet.PackageSet;
-import com.maddyhome.idea.copyright.actions.UpdateCopyrightProcessor;
-import com.maddyhome.idea.copyright.options.LanguageOptions;
-import com.maddyhome.idea.copyright.options.Options;
-import com.maddyhome.idea.copyright.util.FileTypeUtil;
-import com.maddyhome.idea.copyright.util.NewFileTracker;
-import org.jdom.Element;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-@State(name = "CopyrightManager", storages = @Storage(value = "copyright", stateSplitter = CopyrightManager.CopyrightStateSplitter.class))
-public class CopyrightManager extends AbstractProjectComponent implements PersistentStateComponent<Element> {
-  private static final Logger LOG = Logger.getInstance("#" + CopyrightManager.class.getName());
-  @Nullable
-  private CopyrightProfile myDefaultCopyright = null;
-  private final LinkedHashMap<String, String> myModuleToCopyrights = new LinkedHashMap<>();
-  private final Map<String, CopyrightProfile> myCopyrights = new TreeMap<>();
-  private final Options myOptions = new Options();
-
-  public CopyrightManager(@NotNull Project project,
-                          @NotNull final EditorFactory editorFactory,
-                          @NotNull final Application application,
-                          @NotNull final FileDocumentManager fileDocumentManager,
-                          @NotNull final FileTypeUtil fileTypeUtil,
-                          @NotNull final ProjectRootManager projectRootManager,
-                          @NotNull final PsiManager psiManager,
-                          @NotNull StartupManager startupManager) {
-    super(project);
-    if (!myProject.isDefault()) {
-      final NewFileTracker newFileTracker = NewFileTracker.getInstance();
-      Disposer.register(myProject, new Disposable() {
-        @Override
-        public void dispose() {
-          newFileTracker.clear();
-        }
-      });
-      startupManager.runWhenProjectIsInitialized(() -> {
-        DocumentListener listener = new DocumentAdapter() {
-          @Override
-          public void documentChanged(DocumentEvent e) {
-            final Document document = e.getDocument();
-            final VirtualFile virtualFile = fileDocumentManager.getFile(document);
-            if (virtualFile == null) return;
-            final Module module = projectRootManager.getFileIndex().getModuleForFile(virtualFile);
-            if (module == null) return;
-            if (!newFileTracker.poll(virtualFile)) return;
-            if (!fileTypeUtil.isSupportedFile(virtualFile)) return;
-            if (psiManager.findFile(virtualFile) == null) return;
-            application.invokeLater(() -> {
-              if (!virtualFile.isValid()) return;
-              final PsiFile file = psiManager.findFile(virtualFile);
-              if (file != null && file.isWritable()) {
-                final CopyrightProfile opts = getCopyrightOptions(file);
-                if (opts != null) {
-                  new UpdateCopyrightProcessor(myProject, module, file).run();
-                }
-              }
-            }, ModalityState.NON_MODAL, myProject.getDisposed());
-          }
-        };
-        editorFactory.getEventMulticaster().addDocumentListener(listener, myProject);
-      });
-    }
-  }
-
-  @NonNls
-  static final String COPYRIGHT = "copyright";
-  @NonNls
-  private static final String MODULE2COPYRIGHT = "module2copyright";
-  @NonNls
-  private static final String ELEMENT = "element";
-  @NonNls
-  private static final String MODULE = "module";
-  @NonNls
-  private static final String DEFAULT = "default";
-
-  public static CopyrightManager getInstance(Project project) {
-    return project.getComponent(CopyrightManager.class);
-  }
-
-  @Override
-  @NonNls
-  @NotNull
-  public String getComponentName() {
-    return "CopyrightManager";
-  }
-
-  @Override
-  public Element getState() {
-    Element state = new Element("settings");
-
-    try {
-      if (!myCopyrights.isEmpty()) {
-        for (CopyrightProfile copyright : myCopyrights.values()) {
-          Element copyrightElement = new Element(COPYRIGHT);
-          copyright.serializeInto(copyrightElement, true);
-          if (!JDOMUtil.isEmpty(copyrightElement)) {
-            state.addContent(copyrightElement);
-          }
-        }
-      }
-
-      if (!myModuleToCopyrights.isEmpty()) {
-        final Element map = new Element(MODULE2COPYRIGHT);
-        for (String moduleName : myModuleToCopyrights.keySet()) {
-          final Element setting = new Element(ELEMENT);
-          setting.setAttribute(MODULE, moduleName);
-          setting.setAttribute(COPYRIGHT, myModuleToCopyrights.get(moduleName));
-          map.addContent(setting);
-        }
-        state.addContent(map);
-      }
-
-      myOptions.writeExternal(state);
-    }
-    catch (WriteExternalException e) {
-      LOG.error(e);
-      return null;
-    }
-
-    if (myDefaultCopyright != null) {
-      state.setAttribute(DEFAULT, myDefaultCopyright.getName());
-    }
-
-    return state;
-  }
-
-  @Override
-  public void loadState(Element state) {
-    clearCopyrights();
-
-    final Element moduleToCopyright = state.getChild(MODULE2COPYRIGHT);
-    if (moduleToCopyright != null) {
-      for (Element element : moduleToCopyright.getChildren(ELEMENT)) {
-        myModuleToCopyrights.put(element.getAttributeValue(MODULE), element.getAttributeValue(COPYRIGHT));
-      }
-    }
-
-    try {
-      for (Element element : state.getChildren(COPYRIGHT)) {
-        final CopyrightProfile copyrightProfile = new CopyrightProfile();
-        copyrightProfile.readExternal(element);
-        myCopyrights.put(copyrightProfile.getName(), copyrightProfile);
-      }
-      myDefaultCopyright = myCopyrights.get(StringUtil.notNullize(state.getAttributeValue(DEFAULT)));
-      myOptions.readExternal(state);
-    }
-    catch (InvalidDataException e) {
-      LOG.error(e);
-    }
-  }
-
-  public Map<String, String> getCopyrightsMapping() {
-    return myModuleToCopyrights;
-  }
-
-  public void setDefaultCopyright(@Nullable CopyrightProfile copyright) {
-    myDefaultCopyright = copyright;
-  }
-
-  @Nullable
-  public CopyrightProfile getDefaultCopyright() {
-    return myDefaultCopyright;
-  }
-
-  public void addCopyright(CopyrightProfile copyrightProfile) {
-    myCopyrights.put(copyrightProfile.getName(), copyrightProfile);
-  }
-
-  public void removeCopyright(CopyrightProfile copyrightProfile) {
-    myCopyrights.values().remove(copyrightProfile);
-    for (Iterator<String> it = myModuleToCopyrights.keySet().iterator(); it.hasNext();) {
-      final String profileName = myModuleToCopyrights.get(it.next());
-      if (profileName.equals(copyrightProfile.getName())) {
-        it.remove();
-      }
-    }
-  }
-
-  public void clearCopyrights() {
-    myDefaultCopyright = null;
-    myCopyrights.clear();
-    myModuleToCopyrights.clear();
-  }
-
-  public void mapCopyright(String scopeName, String copyrightProfileName) {
-    myModuleToCopyrights.put(scopeName, copyrightProfileName);
-  }
-
-  public void unmapCopyright(String scopeName) {
-    myModuleToCopyrights.remove(scopeName);
-  }
-
-  public Collection<CopyrightProfile> getCopyrights() {
-    return myCopyrights.values();
-  }
-
-  public boolean hasAnyCopyrights() {
-    return myDefaultCopyright != null || !myModuleToCopyrights.isEmpty();
-  }
-
-  @Nullable
-  public CopyrightProfile getCopyrightOptions(@NotNull PsiFile file) {
-    final VirtualFile virtualFile = file.getVirtualFile();
-    if (virtualFile == null || myOptions.getOptions(virtualFile.getFileType().getName()).getFileTypeOverride() == LanguageOptions.NO_COPYRIGHT) return null;
-    final DependencyValidationManager validationManager = DependencyValidationManager.getInstance(myProject);
-    for (String scopeName : myModuleToCopyrights.keySet()) {
-      final NamedScope namedScope = validationManager.getScope(scopeName);
-      if (namedScope != null) {
-        final PackageSet packageSet = namedScope.getValue();
-        if (packageSet != null) {
-          if (packageSet.contains(file, validationManager)) {
-            final CopyrightProfile profile = myCopyrights.get(myModuleToCopyrights.get(scopeName));
-            if (profile != null) {
-              return profile;
-            }
-          }
-        }
-      }
-    }
-    return myDefaultCopyright != null ? myDefaultCopyright : null;
-  }
-
-  public Options getOptions() {
-    return myOptions;
-  }
-
-  public void replaceCopyright(String displayName, CopyrightProfile copyrightProfile) {
-    if (myDefaultCopyright != null && Comparing.strEqual(myDefaultCopyright.getName(), displayName)) {
-      myDefaultCopyright = copyrightProfile;
-    }
-    myCopyrights.remove(displayName);
-    addCopyright(copyrightProfile);
-  }
-
-  static final class CopyrightStateSplitter extends MainConfigurationStateSplitter {
-    @NotNull
-    @Override
-    protected String getComponentStateFileName() {
-      return "profiles_settings";
-    }
-
-    @NotNull
-    @Override
-    protected String getSubStateTagName() {
-      return COPYRIGHT;
-    }
-  }
-}