Merge pull request #378 (https://github.com/JetBrains/intellij-community/pull/378)
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>
Wed, 6 Apr 2016 16:48:08 +0000 (18:48 +0200)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Wed, 6 Apr 2016 16:48:08 +0000 (18:48 +0200)
371 files changed:
build/groovy/org/jetbrains/intellij/build/ApplicationInfoProperties.groovy
build/scripts/libLicenses.gant
build/scripts/nsis_installer.gant
community-resources/src/idea/IdeaApplicationInfo.xml
java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java
java/idea-ui/src/com/intellij/openapi/roots/ui/OrderEntryAppearanceServiceImpl.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/SurroundElementWithAction.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/CreateModuleLibraryChooser.java
java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/UnusedSymbolUtil.java
java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java
java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java
java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java
java/java-analysis-impl/src/com/intellij/find/findUsages/JavaClassFindUsagesOptions.java
java/java-analysis-impl/src/com/intellij/find/findUsages/JavaFindUsagesOptions.java
java/java-analysis-impl/src/com/intellij/find/findUsages/JavaMethodFindUsagesOptions.java
java/java-analysis-impl/src/com/intellij/find/findUsages/JavaPackageFindUsagesOptions.java
java/java-analysis-impl/src/com/intellij/find/findUsages/JavaVariableFindUsagesOptions.java
java/java-analysis-impl/src/org/jetbrains/java/generate/inspection/GenerateToStringQuickFix.java
java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java
java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java
java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java
java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java
java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java
java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
java/java-impl/src/com/intellij/refactoring/copy/CopyClassDialog.java
java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java
java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldDialog.java
java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java
java/java-impl/src/com/intellij/refactoring/migration/EditMigrationEntryDialog.java
java/java-impl/src/com/intellij/testIntegration/JavaTestFinder.java
java/java-impl/src/com/intellij/testIntegration/TestIntegrationUtils.java
java/java-impl/src/com/intellij/testIntegration/createTest/JavaTestGenerator.java
java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java
java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java
java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java
java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java
java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
java/java-psi-impl/src/com/intellij/psi/ClassFileViewProvider.java
java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java
java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiJavaFileStubImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java
java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiGraphInferenceHelper.java
java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/ExpressionCompatibilityConstraint.java
java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
java/java-tests/testData/codeInsight/completion/smartType/SuggestMapInheritors-out.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/completion/smartType/SuggestMapInheritors.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/OperatorApplicability.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/AssignmentFromStringToObject.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8/FinalVariableMightNotHaveBeenInitializedInsideLambda.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/diamond/EraseTypeForNewExpressionWithDiamondsIfUncheckedConversionWasPerformedDuringApplicabilityCheck.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/NonCachingFolding.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/RejectCachedTopLevelSessionIfItCorrespondsToTheWrongOverload.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IgnoreStaticCorrectnessDuringOverloadResolution.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/multipleJdks/java8/p/BoxedTypesWhenPreGenericJDKPresentInProject.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java
java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk6Test.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java
java/java-tests/testSrc/com/intellij/roots/libraries/CreateModuleLibraryFromFilesTest.java [new file with mode: 0644]
java/openapi/src/com/intellij/util/xml/converters/AbstractMethodResolveConverter.java
java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java
java/testFramework/src/com/intellij/testFramework/IdeaTestCase.java
java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
java/testFramework/src/com/intellij/testFramework/PsiTestCase.java
jps/jps-builders/src/org/jetbrains/jps/api/GlobalOptions.java
jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java
jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java
jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java
jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java
platform/built-in-server-api/src/org/jetbrains/builtInWebServer/PathInfo.kt
platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebBrowserUrlProvider.java
platform/built-in-server/src/org/jetbrains/builtInWebServer/DefaultWebServerRootsProvider.kt
platform/built-in-server/src/org/jetbrains/builtInWebServer/WebServerPathToFileManager.kt
platform/configuration-store-impl/src/BinaryXmlOutputter.kt
platform/configuration-store-impl/src/ComponentStoreImpl.kt
platform/configuration-store-impl/src/StateMap.kt
platform/configuration-store-impl/src/StateStorageManagerImpl.kt
platform/configuration-store-impl/src/StorageBaseEx.kt
platform/configuration-store-impl/testSrc/BinaryXmlOutputterTest.kt [new file with mode: 0644]
platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java
platform/core-api/src/com/intellij/openapi/application/TransactionId.java
platform/core-api/src/com/intellij/openapi/application/TransactionKind.java
platform/core-api/src/com/intellij/util/AbstractQuery.java
platform/core-api/src/com/intellij/util/FilteredQuery.java
platform/core-api/src/com/intellij/util/MergeQuery.java
platform/core-api/src/com/intellij/util/Processors.java [moved from platform/platform-tests/testSrc/com/intellij/ide/updates/InfoReader.java with 53% similarity]
platform/core-api/src/com/intellij/util/UniqueResultsQuery.java
platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java
platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java
platform/core-impl/src/com/intellij/psi/PsiAnchor.java
platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java
platform/indexing-api/src/com/intellij/psi/stubs/StubIndex.java
platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java
platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.java
platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidenceEP.java
platform/lang-api/src/com/intellij/refactoring/rename/RenameInputValidator.java
platform/lang-api/src/com/intellij/refactoring/rename/RenameInputValidatorEx.java
platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java
platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtil.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightInfoProcessor.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java
platform/lang-impl/src/com/intellij/codeInsight/template/impl/editorActions/EscapeHandler.java
platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java
platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java
platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
platform/lang-impl/src/com/intellij/ide/scratch/LRUPopupBuilder.java
platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java
platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java
platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java
platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java
platform/lang-impl/src/com/intellij/refactoring/ui/RefactoringDialog.java
platform/lang-impl/src/com/intellij/util/JdkBundleList.java
platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
platform/lang-impl/src/com/intellij/util/indexing/IndexConfiguration.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java
platform/lang-impl/src/com/intellij/util/indexing/StorageGuard.java [new file with mode: 0644]
platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java
platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
platform/platform-impl/src/com/intellij/openapi/application/impl/LaterInvocator.java
platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressDialog.java
platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java
platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java
platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java
platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/UpdateStrategyCustomization.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/ChannelStatus.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateResult.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NewChannelDialog.java [deleted file]
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NewChannelForm.form [deleted file]
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesDialog.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.kt
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfo.kt
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateStrategy.java [deleted file]
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateStrategy.kt [new file with mode: 0644]
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesSettingsPanel.form
platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UserUpdateSettings.java
platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java
platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshSessionImpl.java
platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupModel.java
platform/platform-resources-en/src/messages/IdeBundle.properties
platform/platform-resources/src/brokenPlugins.txt
platform/platform-resources/src/idea/PlatformLangXmlApplicationInfo.xml
platform/platform-tests/testSrc/com/intellij/application/ApplicationImplTest.java
platform/platform-tests/testSrc/com/intellij/application/TransactionTest.groovy
platform/platform-tests/testSrc/com/intellij/execution/impl/ConsoleViewImplTest.java
platform/platform-tests/testSrc/com/intellij/execution/impl/DuplexConsoleActionsTest.java [new file with mode: 0644]
platform/platform-tests/testSrc/com/intellij/ide/updates/UpdateInfoParsingTest.kt [new file with mode: 0644]
platform/platform-tests/testSrc/com/intellij/ide/updates/UpdateStrategyTest.java [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/UpdateStrategyTest.kt [new file with mode: 0644]
platform/platform-tests/testSrc/com/intellij/ide/updates/UpdatesInfoParserTest.java [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/current.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/emptyChannels.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/idea-123280.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/idea-2eap.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/idea-new9eap.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/idea-newChannel-release.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/idea-newChannel.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/idea-newbuild.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/idea-patchAvailable.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/idea-same.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/ide/updates/oneProductOnly.xml [deleted file]
platform/platform-tests/testSrc/com/intellij/openapi/application/impl/LaterInvocatorTest.java
platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootAdapter.java
platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootListener.java
platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java
platform/projectModel-impl/src/messages/ProjectBundle.properties
platform/testFramework/src/com/intellij/FileSetTestCase.java
platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
platform/testFramework/src/com/intellij/testFramework/ThreadTracker.java
platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
platform/util/resources/misc/registry.properties
platform/util/src/com/intellij/execution/process/BaseOSProcessHandler.java
platform/util/src/com/intellij/execution/process/ProcessIOExecutorService.java [new file with mode: 0644]
platform/util/src/com/intellij/execution/process/ProcessWaitFor.java
platform/util/src/com/intellij/openapi/util/BuildNumber.java
platform/util/src/com/intellij/openapi/util/BuildRange.java [new file with mode: 0644]
platform/util/src/com/intellij/util/ArrayUtil.java
platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java
platform/util/src/com/intellij/util/containers/HashSetQueue.java
platform/util/src/com/intellij/util/io/BaseDataReader.java
platform/util/src/com/intellij/util/io/BaseInputStreamReader.java
platform/util/src/com/intellij/util/io/BaseOutputReader.java
platform/util/testSrc/com/intellij/openapi/util/BuildNumberTest.java
platform/util/testSrc/com/intellij/openapi/util/BuildRangeTest.java [new file with mode: 0644]
platform/util/testSrc/com/intellij/util/containers/HashSetQueueTest.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsFileStatusProvider.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/PsiReplacementUtil.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/FallthruInSwitchStatementInspection.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java
plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/LoopStatementsThatDontLoopInspection.java [deleted file]
plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/fallthru_in_switch_statement/FallthruInSwitch.java
plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/fallthru_in_switch_statement/expected.xml [deleted file]
plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/loop_statements_that_dont_loop/LoopStatementsThatDontLoop.java [new file with mode: 0644]
plugins/InspectionGadgets/testsrc/com/siyeh/ig/controlflow/FallthruInSwitchStatementInspectionTest.java
plugins/InspectionGadgets/testsrc/com/siyeh/ig/controlflow/LoopStatementsThatDontLoopInspectionTest.java [moved from platform/core-api/src/com/intellij/openapi/application/AcceptNestedTransactions.java with 51% similarity]
plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceOperatorAssignmentWithAssignmentIntention.java
plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/ReplaceIfWithConditionalIntention.java
plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java
plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/replaceIfWithConditional/InsideLambda1.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/replaceIfWithConditional/InsideLambda1_after.java [new file with mode: 0644]
plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/trivialif/ReplaceIfWithConditionalIntentionTest.java
plugins/copyright/src/com/maddyhome/idea/copyright/actions/UpdateCopyrightCheckinHandlerFactory.java
plugins/devkit/resources/META-INF/plugin.xml
plugins/generate-tostring/src/org/jetbrains/java/generate/GenerateToStringActionHandlerImpl.java
plugins/generate-tostring/src/org/jetbrains/java/generate/GenerateToStringWorker.java
plugins/git4idea/tests/git4idea/push/GitPushOperationSingleRepoTest.kt
plugins/gradle/gradle.iml
plugins/gradle/jps-plugin/gradle-jps-plugin.iml
plugins/gradle/lib/commons-io-1.4.jar [deleted file]
plugins/gradle/lib/commons-io-2.2.jar [new file with mode: 0644]
plugins/gradle/lib/gradle-2.12-src.zip [moved from plugins/gradle/lib/gradle-2.9-src.zip with 70% similarity]
plugins/gradle/lib/gradle-base-services-2.12.jar [moved from plugins/gradle/lib/gradle-base-services-2.9.jar with 61% similarity]
plugins/gradle/lib/gradle-base-services-groovy-2.12.jar [moved from plugins/gradle/lib/gradle-base-services-groovy-2.9.jar with 71% similarity]
plugins/gradle/lib/gradle-cli-2.12.jar [moved from plugins/gradle/lib/gradle-cli-2.9.jar with 86% similarity]
plugins/gradle/lib/gradle-core-2.12.jar [moved from plugins/gradle/lib/gradle-core-2.9.jar with 67% similarity]
plugins/gradle/lib/gradle-messaging-2.12.jar [moved from plugins/gradle/lib/gradle-messaging-2.9.jar with 86% similarity]
plugins/gradle/lib/gradle-model-core-2.12.jar [new file with mode: 0644]
plugins/gradle/lib/gradle-model-core-2.9.jar [deleted file]
plugins/gradle/lib/gradle-model-groovy-2.12.jar [new file with mode: 0644]
plugins/gradle/lib/gradle-model-groovy-2.9.jar [deleted file]
plugins/gradle/lib/gradle-native-2.12.jar [new file with mode: 0644]
plugins/gradle/lib/gradle-native-2.9.jar [deleted file]
plugins/gradle/lib/gradle-resources-2.12.jar [moved from plugins/gradle/lib/gradle-resources-2.9.jar with 80% similarity]
plugins/gradle/lib/gradle-tooling-api-2.12.jar [moved from plugins/gradle/lib/gradle-tooling-api-2.9.jar with 65% similarity]
plugins/gradle/lib/gradle-wrapper-2.12.jar [moved from plugins/gradle/lib/gradle-wrapper-2.9.jar with 89% similarity]
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleAutoImportAware.java
plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleDependenciesImportingTest.java
plugins/gradle/tooling-extension-api/gradle-tooling-extension-api.iml
plugins/gradle/tooling-extension-api/lib/gradle-build-init-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-api/lib/gradle-build-init-2.9.jar [deleted file]
plugins/gradle/tooling-extension-api/lib/gradle-ide-2.12.jar [moved from plugins/gradle/tooling-extension-api/lib/gradle-ide-2.9.jar with 52% similarity]
plugins/gradle/tooling-extension-api/lib/gradle-language-java-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-api/lib/gradle-language-java-2.9.jar [deleted file]
plugins/gradle/tooling-extension-api/lib/gradle-language-jvm-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-api/lib/gradle-language-jvm-2.9.jar [deleted file]
plugins/gradle/tooling-extension-api/lib/gradle-language-scala-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-api/lib/gradle-language-scala-2.9.jar [deleted file]
plugins/gradle/tooling-extension-api/lib/gradle-platform-base-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-api/lib/gradle-platform-base-2.9.jar [deleted file]
plugins/gradle/tooling-extension-api/lib/gradle-platform-jvm-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-api/lib/gradle-platform-jvm-2.9.jar [deleted file]
plugins/gradle/tooling-extension-api/lib/gradle-plugins-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-api/lib/gradle-plugins-2.9.jar [deleted file]
plugins/gradle/tooling-extension-api/lib/gradle-scala-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-api/lib/gradle-scala-2.9.jar [deleted file]
plugins/gradle/tooling-extension-api/lib/gradle-testing-base-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-api/lib/gradle-testing-jvm-2.12.jar [new file with mode: 0644]
plugins/gradle/tooling-extension-impl/gradle-tooling-extension-impl.iml
plugins/gradle/tooling-extension-impl/lib/gradle-ear-2.12.jar [moved from plugins/gradle/tooling-extension-impl/lib/gradle-ear-2.9.jar with 65% similarity]
plugins/gradle/tooling-extension-impl/lib/gradle-reporting-2.12.jar [moved from plugins/gradle/tooling-extension-impl/lib/gradle-reporting-2.9.jar with 88% similarity]
plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy
plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/StubIdeaModule.java
plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/DependencyResolverImpl.groovy
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/control/GroovyFallthroughInspection.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyTraitFieldsFileIndex.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyTraitMethodsFileIndex.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/stubs/GroovyShortNamesCache.java
plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GroovyMarkerTypes.java
plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/GroovyExtractMethodDialog.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrAbstractInplaceIntroducer.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantDialog.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceFieldIntroducer.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldDialog.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrInplaceParameterIntroducer.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterDialog.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GroovyIntroduceVariableDialog.java
plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfigurationType.java
plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestGenerator.java
plugins/groovy/test/org/jetbrains/plugins/groovy/inspections/GroovyFallthroughInspectionTest.groovy
plugins/hg4idea/testSrc/hg4idea/test/HgPlatformTest.java
plugins/java-i18n/src/com/intellij/codeInspection/duplicateStringLiteral/DuplicateStringLiteralInspection.java
plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java
plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxCompletionTest.java
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxEventHandlerInspection.java
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxBuiltInAttributeDescriptor.java
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxRootTagDescriptor.java
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReference.java
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReferenceProvider.java
plugins/javaFX/testData/completion/EventHandlerMethod.java [new file with mode: 0644]
plugins/javaFX/testData/completion/EventHandlerMethodSuper.java [new file with mode: 0644]
plugins/javaFX/testData/completion/EventHandlerMethodTypeParam.java [new file with mode: 0644]
plugins/javaFX/testData/completion/EventHandlerMethodTypeParamSuper.java [new file with mode: 0644]
plugins/javaFX/testData/completion/enumConstantValue.fxml [new file with mode: 0644]
plugins/javaFX/testData/completion/enumConstantValue_after.fxml [new file with mode: 0644]
plugins/javaFX/testData/completion/eventHandlerMethod.fxml [new file with mode: 0644]
plugins/javaFX/testData/completion/eventHandlerMethodTypeParam.fxml [new file with mode: 0644]
plugins/javaFX/testData/highlighting/enumConstantValue.fxml [new file with mode: 0644]
plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java
plugins/properties/properties-psi-impl/src/com/intellij/codeInspection/duplicatePropertyInspection/DuplicatePropertyInspection.java
plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java
plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorFileListener.java [new file with mode: 0644]
plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/GitTaskBranchesTest.java
plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/HgTaskBranchesTest.java
plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java
plugins/ui-designer/src/com/intellij/uiDesigner/actions/MorphAction.java
plugins/ui-designer/src/com/intellij/uiDesigner/actions/PaletteListPopupStep.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudySwingToolWindow.java
python/educational-python/resources/idea/PyCharmEduApplicationInfo.xml
python/helpers/pydev/_pydev_bundle/pydev_monkey.py
python/helpers/pydev/_pydevd_bundle/pydevd_constants.py
python/python-community-ide-resources/resources/idea/PyCharmCoreApplicationInfo.xml
python/src/com/jetbrains/python/codeInsight/intentions/PyAnnotateTypesIntention.java
python/src/com/jetbrains/python/documentation/docstrings/PyDocstringGenerator.java
python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java
python/src/com/jetbrains/python/psi/PyIndentUtil.java
python/testData/copyPaste/AmbiguousParentBlockLargestIndent.after.py [new file with mode: 0644]
python/testData/copyPaste/AmbiguousParentBlockLargestIndent.dst.py [new file with mode: 0644]
python/testData/copyPaste/AmbiguousParentBlockLargestIndent.src.py [new file with mode: 0644]
python/testData/copyPaste/AmbiguousParentBlockMidIndent.after.py [new file with mode: 0644]
python/testData/copyPaste/AmbiguousParentBlockMidIndent.dst.py [new file with mode: 0644]
python/testData/copyPaste/AmbiguousParentBlockMidIndent.src.py [new file with mode: 0644]
python/testData/copyPaste/AmbiguousParentBlockSmallestIndent.after.py [new file with mode: 0644]
python/testData/copyPaste/AmbiguousParentBlockSmallestIndent.dst.py [new file with mode: 0644]
python/testData/copyPaste/AmbiguousParentBlockSmallestIndent.src.py [new file with mode: 0644]
python/testData/copyPaste/EmptyBranchBlock.after.py [new file with mode: 0644]
python/testData/copyPaste/EmptyBranchBlock.dst.py [new file with mode: 0644]
python/testData/copyPaste/EmptyBranchBlock.src.py [new file with mode: 0644]
python/testData/copyPaste/EmptyParentBlockWithCommentInside.after.py [new file with mode: 0644]
python/testData/copyPaste/EmptyParentBlockWithCommentInside.dst.py [new file with mode: 0644]
python/testData/copyPaste/EmptyParentBlockWithCommentInside.src.py [new file with mode: 0644]
python/testSrc/com/jetbrains/python/PyCopyPasteTest.java
xml/dom-openapi/src/com/intellij/util/xml/JavaMethodSignature.java
xml/dom-openapi/src/com/intellij/util/xml/ModelMergerUtil.java
xml/impl/src/com/intellij/codeInsight/editorActions/XmlTagNameSynchronizer.java
xml/impl/src/com/intellij/psi/impl/source/xml/DefaultXmlTagNameProvider.java
xml/tests/src/com/intellij/codeInsight/completion/XmlSyncTagCommunityTest.java
xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java

index 5c74136f2264b0795fa9a53e326c39f6de3cdcbf..d4af8b3901d96c8f21a2f7863fb80719b0e45eb2 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.
@@ -24,21 +24,11 @@ class ApplicationInfoProperties {
   final String majorVersion
   final String minorVersion
   final boolean isEAP
-  final InstallOverProperties installOver
 
   ApplicationInfoProperties(String appInfoXmlPath) {
     def root = new XmlParser().parse(new File(appInfoXmlPath))
     majorVersion = root.version.first().@major
     minorVersion = root.version.first().@minor
     isEAP = Boolean.parseBoolean(root.version.first().@eap)
-    def installOverTag = root."install-over".first()
-    installOver = new InstallOverProperties(minBuild: installOverTag.@minbuild, maxBuild: installOverTag.@maxbuild, version: installOverTag.@version)
   }
-}
-
-@Immutable
-class InstallOverProperties {
-  final String minBuild
-  final String maxBuild
-  final String version
 }
\ No newline at end of file
index d957e73a886fd4e982ce79e14ddc46f4606e2149..e31fa37fd63aa1fb6c6d666df55f2eb79c1ff6bf 100644 (file)
@@ -199,8 +199,8 @@ libraryLicense(name: "fxg-utils", libraryName: "fxg-utils", version: "4.9.1", li
 libraryLicense(name: "Gant", version: "1.9.8", libraryName: "gant-1.9.11_groovy-2.3.0.jar", license: "Apache 2.0", url: "https://github.com/codehaus/gant", licenseUrl: "https://github.com/codehaus/gant/blob/master/LICENCE.txt")
 libraryLicense(name: "Gherkin", libraryName: "Gherkin", version: "2.12.2", license: "MIT", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "https://github.com/cucumber/gherkin")
 libraryLicense(name: "Google Feedback", libraryName: "GoogleFeedback.jar", version: "", license: "TBD")
-libraryLicense(name: "gradle-tooling-api-2.9.jar", version: "2.9", license: "Apache 2.0", url: "http://gradle.org/", licenseUrl: "http://gradle.org/license")
-libraryLicense(name: "Gradle", version: "2.9", license: "Apache 2.0", url: "http://gradle.org/", licenseUrl: "http://gradle.org/license")
+libraryLicense(name: "gradle-tooling-api-2.12.jar", version: "2.12", license: "Apache 2.0", url: "http://gradle.org/", licenseUrl: "http://gradle.org/license")
+libraryLicense(name: "Gradle", version: "2.12", license: "Apache 2.0", url: "http://gradle.org/", licenseUrl: "http://gradle.org/license")
 libraryLicense(name: "GradleGuava", version: "14.0.1", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0")
 libraryLicense(name: "GradleJnaPosix", version: "1.0.3", license: "LGPL 2.1", url: "http://www.jruby.org/", licenseUrl: "http://www.gnu.org/licenses/lgpl-2.1.txt")
 libraryLicense(name: "Groovy", version: "2.4.6", license: "Apache 2.0", url: "http://groovy-lang.org/")
index 1d714667a92b9881339904087eca6ae308fcef33..2ea23001cf7a82891d328ee81cf0526f04f1898e 100644 (file)
@@ -71,9 +71,6 @@ def nsis_installer(pathsToInclude, stringsFile, pathsFile, outNamePrefix, includ
     replacefilter(token: "__BUILD_NUMBER__", value: buildNumber)
     replacefilter(token: "__VERSION_MAJOR__", value: p("component.version.major"))
     replacefilter(token: "__VERSION_MINOR__", value: p("component.version.minor"))
-    replacefilter(token: "__MIN_UPGRADE_BUILD__", value: p("component.install-over.minbuild"))
-    replacefilter(token: "__MAX_UPGRADE_BUILD__", value: p("component.install-over.maxbuild"))
-    replacefilter(token: "__UPGRADE_VERSION__", value: p("component.install-over.version"))
     replacefilter(token: "__PRODUCT_PATHS_SELECTOR__", value: system_selector)
   }
 
index ceded2dcbab7e8b0a444debc773e79835b456c66..500ea220abffd8d5c62827d0cafbd59219a62c9a 100644 (file)
@@ -2,7 +2,6 @@
   <version codename="Community Edition 2016.2" major="2016" minor="2" eap="true"/>
   <company name="JetBrains s.r.o." url="https://www.jetbrains.com/?fromIDE"/>
   <build number="__BUILD_NUMBER__" date="__BUILD_DATE__"/>
-  <install-over minbuild="129.1" maxbuild="139.9999" version="14"/>
   <logo url="/idea_community_logo.png" textcolor="444444" progressColor="f87206" progressX="0" progressY="271" progressHeight="3" licenseOffsetY="30" />
   <about url="/idea_community_about.png" foreground="444444" copyrightForeground="7A858F" linkColor="9b5121" logoX="300" logoY="265" logoW="75" logoH="30"/>
   <icon size32="/icon_CE.png" size16="/icon_CEsmall.png" size128="/icon_CE_128.png" ico="idea_CE.ico"/>
index c8e88bbecdd2b6aba27a1c3b7f4cdb031ffec2a6..4acb533d5409c9201efa024c353de4da2e0c20c0 100644 (file)
@@ -1156,6 +1156,8 @@ public class BuildManager implements Disposable {
     cmdLine.addParameter("-D" + PathManager.PROPERTY_PLUGINS_PATH + "=" + PathManager.getPluginsPath());
 
     cmdLine.addParameter("-D" + GlobalOptions.LOG_DIR_OPTION + "=" + FileUtil.toSystemIndependentName(getBuildLogDirectory().getAbsolutePath()));
+    cmdLine.addParameter("-D" + GlobalOptions.FALLBACK_JDK_HOME + "=" + SystemProperties.getJavaHome());
+    cmdLine.addParameter("-D" + GlobalOptions.FALLBACK_JDK_VERSION + "=" + SystemProperties.getJavaVersion());
 
     final File workDirectory = getBuildSystemDirectory();
     //noinspection ResultOfMethodCallIgnored
index 086c6fbb9fbc4ab3f24fa5ba9a77cb2ad53ef9c1..529fcde06fbe4be2b8ae4fc4054e75bcedffa9f3 100644 (file)
@@ -20,7 +20,6 @@ import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.util.ProgressIndicatorBase;
 import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
 import com.intellij.openapi.progress.util.ReadTask;
 import com.intellij.openapi.project.DumbService;
@@ -93,7 +92,7 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler {
   protected abstract void handleBuildEvent(UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event);
 
   private void handleConstantSearchTask(final Channel channel, final UUID sessionId, final CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task) {
-    ProgressIndicatorUtils.scheduleWithWriteActionPriority(new ProgressIndicatorBase(), myTaskExecutor, new ReadTask() {
+    ProgressIndicatorUtils.scheduleWithWriteActionPriority(myTaskExecutor, new ReadTask() {
       @Override
       public Continuation runBackgroundProcess(@NotNull ProgressIndicator indicator) throws ProcessCanceledException {
         return DumbService.getInstance(myProject).runReadActionInSmartMode(new Computable<Continuation>() {
index c5fa257401f1f720bc8897b23034db6543e5cddb..86d339aee6cb2c53fce923db3b6a0552a741a207 100644 (file)
@@ -165,7 +165,9 @@ public class JavaParametersUtil {
       throw new CantRunException(ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.message", jreHome));
     }
 
-    final Sdk jdk = JavaSdk.getInstance().createJdk("", jreHome);
+    final JavaSdk javaSdk = JavaSdk.getInstance();
+    final String versionString = javaSdk.getVersionString(jreHome);
+    final Sdk jdk = javaSdk.createJdk(versionString != null ? versionString : "", jreHome);
     if (jdk == null) throw CantRunException.noJdkConfigured();
     return jdk;
   }
index fe8ce129033eb59063f1cf7d9430989bbbd058e6..ddabaf3f419ae34fa052377668e2c4e19ac81116 100644 (file)
@@ -110,7 +110,8 @@ public class OrderEntryAppearanceServiceImpl extends OrderEntryAppearanceService
     }
 
     final String url = StringUtil.trimEnd(files[0], JarFileSystem.JAR_SEPARATOR);
-    return SimpleTextCellAppearance.regular(PathUtil.getFileName(url), PlatformIcons.LIBRARY_ICON);
+    String text = ProjectBundle.message("library.unnamed.text", PathUtil.getFileName(url), files.length - 1);
+    return SimpleTextCellAppearance.regular(text, PlatformIcons.LIBRARY_ICON);
   }
 
   @NotNull
index 108eb7c9802585c4e71df492efe9eca686169695..e3b0a7aa085820644e6f7478ac0b0fee2c72def3 100644 (file)
@@ -17,7 +17,6 @@ package com.intellij.openapi.roots.ui.configuration.artifacts.actions;
 
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CustomShortcutSet;
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.keymap.KeymapManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorEx;
@@ -87,13 +86,7 @@ public class SurroundElementWithAction extends LayoutTreeActionBase {
 
         @Override
         public PopupStep onChosen(final CompositePackagingElementType selectedValue, boolean finalChoice) {
-          ApplicationManager.getApplication().invokeLater(new Runnable() {
-            @Override
-            public void run() {
-              surroundWith(selectedValue, parent, selected, treeComponent);
-            }
-          });
-          return FINAL_CHOICE;
+          return doFinalStep(() -> surroundWith(selectedValue, parent, selected, treeComponent));
         }
       }).showInBestPositionFor(e.getDataContext());
     }
index 8d0c17ce5492c88adf2af7198cc37bb613da2e96..43a9d0886fd6bd214d6c71abe43f55078498dc22 100644 (file)
@@ -30,13 +30,17 @@ import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil;
 import com.intellij.openapi.roots.ui.configuration.libraryEditor.DefaultLibraryRootsComponentDescriptor;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.ArrayUtil;
 import com.intellij.util.Function;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
 
 import javax.swing.*;
 import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static com.intellij.util.ArrayUtil.contains;
 
 /**
 * @author nik
@@ -78,12 +82,15 @@ public class CreateModuleLibraryChooser implements ClasspathElementChooser<Libra
     }
   }
 
-  private Library createLibraryFromRoots(List<OrderRoot> roots, @Nullable final LibraryType libraryType) {
+  private static Library createLibraryFromRoots(@NotNull List<OrderRoot> roots,
+                                                @Nullable final LibraryType libraryType,
+                                                @NotNull LibraryTable.ModifiableModel moduleLibrariesModel,
+                                                @Nullable Function<LibraryType, LibraryProperties> defaultPropertiesFactory) {
     final PersistentLibraryKind kind = libraryType == null ? null : libraryType.getKind();
-    final Library library = myModuleLibrariesModel.createLibrary(null, kind);
+    final Library library = moduleLibrariesModel.createLibrary(null, kind);
     final LibraryEx.ModifiableModelEx libModel = (LibraryEx.ModifiableModelEx)library.getModifiableModel();
-    if (myDefaultPropertiesFactory != null) {
-      libModel.setProperties(myDefaultPropertiesFactory.fun(libraryType));
+    if (defaultPropertiesFactory != null) {
+      libModel.setProperties(defaultPropertiesFactory.fun(libraryType));
     }
     for (OrderRoot root : roots) {
       if (root.isJarDirectory()) {
@@ -97,30 +104,21 @@ public class CreateModuleLibraryChooser implements ClasspathElementChooser<Libra
     return library;
   }
 
-  private List<OrderRoot> filterAlreadyAdded(final List<OrderRoot> roots) {
+  private static List<OrderRoot> filterAlreadyAdded(final List<OrderRoot> roots, LibraryTable.ModifiableModel moduleLibrariesModel) {
     if (roots == null || roots.isEmpty()) {
       return Collections.emptyList();
     }
 
     final List<OrderRoot> result = new ArrayList<OrderRoot>();
-    final Library[] libraries = myModuleLibrariesModel.getLibraries();
+    final Library[] libraries = moduleLibrariesModel.getLibraries();
     for (OrderRoot root : roots) {
-      if (!isIncluded(root, libraries)) {
+      if (!Arrays.stream(libraries).anyMatch(library -> contains(root.getFile(), library.getFiles(root.getType())))) {
         result.add(root);
       }
     }
     return result;
   }
 
-  private static boolean isIncluded(OrderRoot root, Library[] libraries) {
-    for (Library library : libraries) {
-      if (ArrayUtil.contains(root.getFile(), library.getFiles(root.getType()))) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   @Override
   @NotNull
   public List<Library> chooseElements() {
@@ -179,23 +177,35 @@ public class CreateModuleLibraryChooser implements ClasspathElementChooser<Libra
     }
     List<OrderRoot> chosenRoots = RootDetectionUtil.detectRoots(Arrays.asList(files), myParentComponent, project, rootsComponentDescriptor);
 
-    final List<OrderRoot> roots = filterAlreadyAdded(chosenRoots);
+    return createLibrariesFromRoots(chosenRoots, libraryType, myModuleLibrariesModel, myDefaultPropertiesFactory);
+  }
+
+  @TestOnly
+  @NotNull
+  public static List<Library> createLibrariesFromRoots(List<OrderRoot> chosenRoots, LibraryTable.ModifiableModel moduleLibrariesModel) {
+    return createLibrariesFromRoots(chosenRoots, null, moduleLibrariesModel, null);
+  }
+
+  @NotNull
+  private static List<Library> createLibrariesFromRoots(@NotNull List<OrderRoot> chosenRoots,
+                                                        @Nullable LibraryType libraryType,
+                                                        @NotNull LibraryTable.ModifiableModel moduleLibrariesModel,
+                                                        @Nullable Function<LibraryType, LibraryProperties> defaultPropertiesFactory) {
+    final List<OrderRoot> roots = filterAlreadyAdded(chosenRoots, moduleLibrariesModel);
     if (roots.isEmpty()) {
       return Collections.emptyList();
     }
 
     final List<Library> addedLibraries = new ArrayList<Library>();
-    boolean onlyClasses = true;
-    for (OrderRoot root : roots) {
-      onlyClasses &= root.getType() == OrderRootType.CLASSES;
-    }
-    if (onlyClasses) {
-      for (OrderRoot root : roots) {
-        addedLibraries.add(createLibraryFromRoots(Collections.singletonList(root), libraryType));
+    Map<VirtualFile, List<OrderRoot>> byFile = roots.stream().collect(Collectors.groupingBy(OrderRoot::getFile));
+    Predicate<List<OrderRoot>> containsClasses = it -> it.stream().anyMatch(root -> root.getType().equals(OrderRootType.CLASSES));
+    if (byFile.values().stream().allMatch(containsClasses)) {
+      for (List<OrderRoot> rootsForFile : byFile.values()) {
+        addedLibraries.add(createLibraryFromRoots(rootsForFile, libraryType, moduleLibrariesModel, defaultPropertiesFactory));
       }
     }
     else {
-      addedLibraries.add(createLibraryFromRoots(roots, libraryType));
+      addedLibraries.add(createLibraryFromRoots(roots, libraryType, moduleLibrariesModel, defaultPropertiesFactory));
     }
     return addedLibraries;
   }
index b1c858b0d9bbd6021b139fcf5beb33a1d78a79a0..a68f794c578ec33fb7fcf61be4095d98556a18f7 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.
@@ -240,28 +240,27 @@ public class UnusedSymbolUtil {
     }
     FindUsagesOptions options;
     if (member instanceof PsiPackage) {
-      options = new JavaPackageFindUsagesOptions(project);
+      options = new JavaPackageFindUsagesOptions(useScope);
       options.isSearchForTextOccurrences = true;
     }
     else if (member instanceof PsiClass) {
-      options = new JavaClassFindUsagesOptions(project);
+      options = new JavaClassFindUsagesOptions(useScope);
       options.isSearchForTextOccurrences = true;
     }
     else if (member instanceof PsiMethod) {
       PsiMethod method = (PsiMethod)member;
-      options = new JavaMethodFindUsagesOptions(project);
+      options = new JavaMethodFindUsagesOptions(useScope);
       options.isSearchForTextOccurrences = method.isConstructor();
     }
     else if (member instanceof PsiVariable) {
-      options = new JavaVariableFindUsagesOptions(project);
+      options = new JavaVariableFindUsagesOptions(useScope);
       options.isSearchForTextOccurrences = false;
     }
     else {
-      options = new FindUsagesOptions(project);
+      options = new FindUsagesOptions(useScope);
       options.isSearchForTextOccurrences = true;
     }
     options.isUsages = true;
-    options.searchScope = useScope;
     return JavaFindUsagesHelper.processElementUsages(member, options, usageInfoProcessor);
   }
 
index 485e5ff7530afc38ad6345b410d8744b4ed1ba87..d10efe58c2e6869f9847a4653fc3775fd3bec382 100644 (file)
@@ -436,8 +436,7 @@ public class HighlightUtil extends HighlightUtilBase {
     if (rExpression == null) return null;
     final PsiType rType = rExpression.getType();
     HighlightInfo errorResult = null;
-    if (!TypeConversionUtil.isBinaryOperatorApplicable(opSign, lType, rType, true) ||
-        PsiType.getJavaLangObject(containingFile.getManager(), assignment.getResolveScope()).equals(lType)) {
+    if (!TypeConversionUtil.isBinaryOperatorApplicable(opSign, lType, rType, true)) {
       String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1);
       String message = JavaErrorMessages.message("binary.operator.not.applicable", operatorText,
                                                  JavaHighlightUtil.formatType(lType),
index 68a3d8f413712f8f621b215d25cb0e1ff63849e4..e8bf7fcc0659393b8e9666e4e93557cea2c98e2d 100644 (file)
@@ -92,7 +92,12 @@ class PostHighlightingVisitor {
           }
         });
       };
-      Disposer.register((DaemonProgressIndicator)progress, invokeFixLater);
+      try {
+        Disposer.register((DaemonProgressIndicator)progress, invokeFixLater);
+      }
+      catch (Exception ignored) {
+        // suppress "parent already has been disposed" exception here
+      }
       if (progress.isCanceled()) {
         Disposer.dispose(invokeFixLater);
         Disposer.dispose((DaemonProgressIndicator)progress);
index 97577bcb2d4f484d7d4029847f89e4355a340928..ea006477bf16b6efdaa7cf2963192287ac775f37 100644 (file)
 package com.intellij.codeInspection.compiler;
 
 import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemHighlightType;
-import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
+import com.intellij.codeInspection.*;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import com.intellij.openapi.projectRoots.JavaVersionService;
 import com.intellij.patterns.ElementPattern;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.siyeh.ig.PsiReplacementUtil;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
 
 import static com.intellij.patterns.PsiJavaPatterns.psiElement;
 
@@ -73,6 +78,28 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor {
     }
   }
 
+  @Override
+  public void visitAssignmentExpression(PsiAssignmentExpression assignment) {
+    super.visitAssignmentExpression(assignment);
+    final PsiType lType = assignment.getLExpression().getType();
+    PsiJavaToken operationSign = assignment.getOperationSign();
+    IElementType eqOpSign = operationSign.getTokenType();
+    IElementType opSign = TypeConversionUtil.convertEQtoOperation(eqOpSign);
+    if (opSign == null) return;
+    final PsiExpression rExpression = assignment.getRExpression();
+    if (rExpression == null) return;
+    if (JavaSdkVersion.JDK_1_6.equals(JavaVersionService.getInstance().getJavaSdkVersion(assignment)) &&
+        PsiType.getJavaLangObject(assignment.getManager(), assignment.getResolveScope()).equals(lType)) {
+      String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1);
+      String message = JavaErrorMessages.message("binary.operator.not.applicable", operatorText,
+                                                 JavaHighlightUtil.formatType(lType),
+                                                 JavaHighlightUtil.formatType(rExpression.getType()));
+
+      myHolder.registerProblem(assignment, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                               new ReplaceAssignmentOperatorWithAssignmentFix(operationSign.getText()));
+    }
+  }
+
   @Override
   public void visitIdentifier(PsiIdentifier identifier) {
     super.visitIdentifier(identifier);
@@ -83,4 +110,34 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor {
       myHolder.registerProblem(identifier, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
     }
   }
+
+  private static class ReplaceAssignmentOperatorWithAssignmentFix implements LocalQuickFix {
+    private final String myOperationSign;
+
+    public ReplaceAssignmentOperatorWithAssignmentFix(String operationSign) {
+      myOperationSign = operationSign;
+    }
+
+    @Nls
+    @NotNull
+    @Override
+    public String getName() {
+      return "Replace ''" + myOperationSign + "'' with ''=''";
+    }
+
+    @Nls
+    @NotNull
+    @Override
+    public String getFamilyName() {
+      return "Replace Operator Assignment with Assignment";
+    }
+
+    @Override
+    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+      final PsiElement element = descriptor.getPsiElement();
+      if (element instanceof PsiAssignmentExpression) {
+        PsiReplacementUtil.replaceOperatorAssignmentWithAssignmentExpression((PsiAssignmentExpression)element);
+      }
+    }
+  }
 }
index aa260be52842a19e2943d335f21ee7dfd4c6d8d8..f3880bfef9904f92670d14598f7dd5e4a4af2531 100644 (file)
@@ -25,7 +25,6 @@ import com.intellij.util.containers.ContainerUtil;
 import gnu.trove.THashSet;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import javax.swing.event.ChangeEvent;
@@ -56,12 +55,6 @@ public class DefUseInspectionBase extends BaseJavaBatchLocalInspectionTool {
     };
   }
 
-  @Nullable
-  @Override
-  public String getAlternativeID() {
-    return "unused";
-  }
-
   private void checkCodeBlock(final PsiCodeBlock body,
                               final ProblemsHolder holder,
                               final boolean isOnTheFly) {
index 8a509ab05b4b586d3ec5ca73ad97283444e10743..4339d36ffb38fcafe09b8529f16382d133893bde 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.find.findUsages;
 
 import com.intellij.find.FindBundle;
 import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.SearchScope;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.LinkedHashSet;
@@ -37,6 +38,10 @@ public class JavaClassFindUsagesOptions extends JavaFindUsagesOptions {
     super(project);
   }
 
+  public JavaClassFindUsagesOptions(@NotNull SearchScope searchScope) {
+    super(searchScope);
+  }
+
   @Override
   protected void addUsageTypes(@NotNull LinkedHashSet<String> strings) {
     if (isUsages || isMethodsUsages || isFieldsUsages) {
index 7accfccd14b937a437872fa7acc525aeb2c19693..60b650ce293ac89ddc3d025bb0467762f5eeae25 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.find.findUsages;
 import com.intellij.find.FindBundle;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.search.SearchScope;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.LinkedHashSet;
@@ -34,6 +35,12 @@ public abstract class JavaFindUsagesOptions extends FindUsagesOptions {
     isUsages = true;
   }
 
+  public JavaFindUsagesOptions(@NotNull SearchScope searchScope) {
+    super(searchScope);
+
+    isUsages = true;
+  }
+
   @Override
   public boolean equals(final Object o) {
     if (this == o) return true;
index 575ea88d5f522f0291f1375307b3479d08bbc541..ab39b82d109f7d7cee2c2a6b182c43c2e2f61726 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.find.findUsages;
 
 import com.intellij.find.FindBundle;
 import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.SearchScope;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.LinkedHashSet;
@@ -36,6 +37,11 @@ public class JavaMethodFindUsagesOptions extends JavaFindUsagesOptions {
     isSearchForTextOccurrences = false;
   }
 
+  public JavaMethodFindUsagesOptions(@NotNull SearchScope searchScope) {
+    super(searchScope);
+    isSearchForTextOccurrences = false;
+  }
+
   public boolean equals(final Object o) {
     if (this == o) return true;
     if (!super.equals(this)) return false;
index 415e06b2c502e8da3b78dbd62e3665e40d38129d..93cc0db69e9e7415d6195b7ed1a7b03ac5966005 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.find.findUsages;
 
 import com.intellij.find.FindBundle;
 import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.SearchScope;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.LinkedHashSet;
@@ -33,6 +34,10 @@ public class JavaPackageFindUsagesOptions extends JavaFindUsagesOptions {
     super(project);
   }
 
+  public JavaPackageFindUsagesOptions(@NotNull SearchScope searchScope) {
+    super(searchScope);
+  }
+
   @Override
   protected void addUsageTypes(@NotNull LinkedHashSet<String> to) {
     if (this.isUsages || this.isClassesUsages) {
index 14d865280d3a75908863a7bc2521b67e75429e80..218525612d6aedfaf33d007f201cd22bf7274296 100644 (file)
@@ -16,6 +16,7 @@
 package com.intellij.find.findUsages;
 
 import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.SearchScope;
 import org.jetbrains.annotations.NotNull;
 
 /**
@@ -30,6 +31,11 @@ public class JavaVariableFindUsagesOptions extends JavaFindUsagesOptions {
     isSearchForTextOccurrences = false;
   }
 
+  public JavaVariableFindUsagesOptions(@NotNull SearchScope searchScope) {
+    super(searchScope);
+    isSearchForTextOccurrences = false;
+  }
+
   public boolean equals(final Object o) {
     if (this == o) return true;
     if (!super.equals(this)) return false;
index 440a3b38667c8954bf21aa59a9626eba9a40af25..37affd109b9fa8b305413b4799d9a48a1f5f1c16 100644 (file)
@@ -58,4 +58,9 @@ public class GenerateToStringQuickFix implements LocalQuickFix {
     GenerateToStringActionHandler handler = ServiceManager.getService(GenerateToStringActionHandler.class);
     handler.executeActionQuickFix(project, clazz);
   }
+
+  @Override
+  public boolean startInWriteAction() {
+    return false;
+  }
 }
index e5b726d5b74b779870106309b39915af76c72c69..7e7dfaba90806a73c110368e1731aa3d07f8c1a5 100644 (file)
@@ -979,17 +979,25 @@ public class ExpectedTypesProvider {
         PsiSubstitutor substitutor;
         if (candidateInfo instanceof MethodCandidateInfo) {
           final MethodCandidateInfo info = (MethodCandidateInfo)candidateInfo;
-          substitutor = info.inferTypeArguments(policy, args, true);
+          substitutor = MethodCandidateInfo.ourOverloadGuard
+            .doPreventingRecursion(argumentList, false, () -> info.inferTypeArguments(policy, args, true));
           if (!info.isStaticsScopeCorrect() && method != null && !method.hasModifierProperty(PsiModifier.STATIC)) continue;
         }
         else {
-          substitutor = candidateInfo.getSubstitutor();
+          substitutor = MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(argumentList, false, candidateInfo::getSubstitutor);
+        }
+        if (substitutor == null) {
+          return ExpectedTypeInfo.EMPTY_ARRAY;
         }
         inferMethodCallArgumentTypes(argument, forCompletion, args, index, method, substitutor, array);
 
         if (leftArgs != null && candidateInfo instanceof MethodCandidateInfo) {
-          substitutor = ((MethodCandidateInfo)candidateInfo).inferTypeArguments(policy, leftArgs, true);
-          inferMethodCallArgumentTypes(argument, forCompletion, leftArgs, index, method, substitutor, array);
+          substitutor = MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(argumentList, false,
+                                                                                   () -> ((MethodCandidateInfo)candidateInfo)
+                                                                                     .inferTypeArguments(policy, leftArgs, true));
+          if (substitutor != null) {
+            inferMethodCallArgumentTypes(argument, forCompletion, leftArgs, index, method, substitutor, array);
+          }
         }
       }
 
index b1c8991f973aed13ba188bbc1cf847201625cc27..a9bfa1de8716d36dd49e805381eeeb95ecad629f 100644 (file)
@@ -65,7 +65,9 @@ public class DeadHTMLComposer extends HTMLComposerImpl {
         appendHeading(buf, InspectionsBundle.message("inspection.problem.synopsis"));
         //noinspection HardCodedStringLiteral
         buf.append("<br>");
+        buf.append("<div class=\"problem-description\">");
         appendProblemSynopsis(refElement, buf);
+        buf.append("</div>");
 
         if (toExternalHtml) {
           buf.append("<br><br>");
@@ -100,7 +102,6 @@ public class DeadHTMLComposer extends HTMLComposerImpl {
   }
 
   public static void appendProblemSynopsis(final RefElement refElement, final StringBuffer buf) {
-    buf.append("<div class=\"problem-description\">");
     refElement.accept(new RefJavaVisitor() {
       @Override public void visitField(@NotNull RefField field) {
         if (field.isUsedForReading() && !field.isUsedForWriting()) {
@@ -217,7 +218,6 @@ public class DeadHTMLComposer extends HTMLComposerImpl {
         }
       }
     });
-    buf.append("</div>");
   }
 
   @Override
index 0afddffe27ce9e74b5076a6a583ee118a7b1f511..62f9752acc9dead1795c79ce616b5804a49c554e 100644 (file)
@@ -128,7 +128,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta
   @Override
   public void exportResults(@NotNull final Element parentNode,
                             @NotNull RefEntity refEntity,
-                            Set<CommonProblemDescriptor> excludedDescriptions) {
+                            @NotNull Set<CommonProblemDescriptor> excludedDescriptions) {
     if (!(refEntity instanceof RefJavaElement)) return;
     final RefFilter filter = getFilter();
     if (!getIgnoredRefElements().contains(refEntity) && filter.accepts((RefJavaElement)refEntity)) {
index dfe723269290088b6220d9c0040870deb5730b4e..5ebbb608bf1a640e8132134226380ee88eb10542 100644 (file)
@@ -275,7 +275,7 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
 
   protected void restartAnalysis(final Project project, final AnalysisScope scope) {
     TransactionGuard guard = TransactionGuard.getInstance();
-    TransactionId id = guard.getCurrentMergeableTransaction();
+    TransactionId id = guard.getContextTransaction();
     DumbService.getInstance(project).smartInvokeLater(
       () -> TransactionGuard.getInstance().submitMergeableTransaction(project, id, () -> {
         if (DumbService.isDumb(project)) {
index 2f5418631dae71715d073ddb5e763a25e7318be6..aa386e3f2aacce4b3cdc29e9e5eb4c1ee54a578e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 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.
@@ -28,14 +28,16 @@ import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.PsiShortNamesCache;
 import com.intellij.psi.util.ClassUtil;
 import com.intellij.util.ArrayUtil;
-import com.intellij.util.CommonProcessors;
 import com.intellij.util.Processor;
+import com.intellij.util.Processors;
 import com.intellij.util.indexing.FileBasedIndex;
 import com.intellij.util.indexing.FindSymbolParameters;
 import com.intellij.util.indexing.IdFilter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.regex.Matcher;
 
 public class DefaultClassNavigationContributor implements ChooseByNameContributorEx, GotoClassContributor {
@@ -44,10 +46,12 @@ public class DefaultClassNavigationContributor implements ChooseByNameContributo
   public String[] getNames(Project project, boolean includeNonProjectItems) {
     if (FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping) {
       GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project);
-      CommonProcessors.CollectProcessor<String> processor = new CommonProcessors.CollectProcessor<String>();
+      List<String> result = new ArrayList<>();
+      Processor<String> processor = Processors.cancelableCollectProcessor(result);
+
       processNames(processor, scope, IdFilter.getProjectIdFilter(project, includeNonProjectItems));
 
-      return ArrayUtil.toStringArray(processor.getResults());
+      return ArrayUtil.toStringArray(result);
     }
 
     return PsiShortNamesCache.getInstance(project).getAllClassNames();
@@ -56,10 +60,12 @@ public class DefaultClassNavigationContributor implements ChooseByNameContributo
   @Override
   @NotNull
   public NavigationItem[] getItemsByName(String name, final String pattern, Project project, boolean includeNonProjectItems) {
-    CommonProcessors.CollectProcessor<NavigationItem> processor = new CommonProcessors.CollectProcessor<NavigationItem>();
+    List<NavigationItem> result = new ArrayList<>();
+    Processor<NavigationItem> processor = Processors.cancelableCollectProcessor(result);
     processElementsWithName(name, processor, FindSymbolParameters.wrap(pattern, project, includeNonProjectItems));
 
-    return processor.toArray(new NavigationItem[processor.getResults().size()]);
+    return result.isEmpty() ? NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY :
+           result.toArray(new NavigationItem[result.size()]);
   }
 
   @Override
index 23f5cc8f5a0fb5de493af010bca63cd18a27ed8e..ad2a88c025a372f9ceb45c9e4f0431eafb7902f4 100644 (file)
@@ -15,8 +15,6 @@
  */
 package com.intellij.refactoring.anonymousToInner;
 
-import com.intellij.openapi.application.AcceptNestedTransactions;
-import com.intellij.openapi.application.TransactionKind;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.project.Project;
@@ -44,7 +42,7 @@ import javax.swing.*;
 import java.awt.*;
 import java.util.Map;
 
-@AcceptNestedTransactions(TransactionKind.Common.TEXT_EDITING)class AnonymousToInnerDialog extends DialogWrapper{
+class AnonymousToInnerDialog extends DialogWrapper{
   private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.anonymousToInner.AnonymousToInnerDialog");
 
   private final Project myProject;
index 8d351834091d8c00717780cc4e1569225bd8f6d3..f0a4fee2a0735231b196980812dba109b4339171 100644 (file)
@@ -15,8 +15,6 @@
  */
 package com.intellij.refactoring.copy;
 
-import com.intellij.openapi.application.AcceptNestedTransactions;
-import com.intellij.openapi.application.TransactionKind;
 import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.JavaProjectRootsUtil;
@@ -44,7 +42,6 @@ import org.jetbrains.annotations.NotNull;
 import javax.swing.*;
 import java.awt.*;
 
-@AcceptNestedTransactions(TransactionKind.Common.TEXT_EDITING)
 class CopyClassDialog extends DialogWrapper{
   @NonNls private static final String RECENTS_KEY = "CopyClassDialog.RECENTS_KEY";
   private final JLabel myInformationLabel = new JLabel();
index 1ff1bf2291f41708712055d13685d7c2a1db98b0..ef3df4acafc536b6ba4ae1468b39765564eb37f6 100644 (file)
@@ -19,8 +19,6 @@ import com.intellij.codeInsight.NullableNotNullManager;
 import com.intellij.codeInspection.dataFlow.Nullness;
 import com.intellij.ide.highlighter.JavaFileType;
 import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.application.AcceptNestedTransactions;
-import com.intellij.openapi.application.TransactionKind;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.ComboBox;
 import com.intellij.openapi.ui.DialogWrapper;
@@ -61,7 +59,6 @@ import java.awt.event.*;
 /**
  * @author Konstantin Bulenkov
  */
-@AcceptNestedTransactions(TransactionKind.Common.TEXT_EDITING)
 public class ExtractMethodDialog extends DialogWrapper implements AbstractExtractDialog {
   private static final String EXTRACT_METHOD_DEFAULT_VISIBILITY = "extract.method.default.visibility";
   public static final String EXTRACT_METHOD_GENERATE_ANNOTATIONS = "extractMethod.generateAnnotations";
index b7120141d00eb87365ff6a5b20d865636f8ef3f1..be4e56dc211950bf7c52e5c211ffe7eec56f23bb 100644 (file)
@@ -15,8 +15,6 @@
  */
 package com.intellij.refactoring.extractMethodObject;
 
-import com.intellij.openapi.application.AcceptNestedTransactions;
-import com.intellij.openapi.application.TransactionKind;
 import com.intellij.openapi.editor.event.DocumentAdapter;
 import com.intellij.openapi.editor.event.DocumentEvent;
 import com.intellij.openapi.help.HelpManager;
@@ -47,7 +45,6 @@ import java.awt.event.ActionListener;
 import java.util.Enumeration;
 
 
-@AcceptNestedTransactions(TransactionKind.Common.TEXT_EDITING)
 public class ExtractMethodObjectDialog extends DialogWrapper implements AbstractExtractDialog {
   private final Project myProject;
   private final PsiType myReturnType;
index 7a9cb013159a53d773c9c30593bb234e3c646410..338faaf7adf30ab7fc03d2ed183dcbf8c24e1049 100644 (file)
@@ -21,8 +21,6 @@ import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.ide.util.TreeClassChooser;
 import com.intellij.ide.util.TreeClassChooserFactory;
-import com.intellij.openapi.application.AcceptNestedTransactions;
-import com.intellij.openapi.application.TransactionKind;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.event.DocumentAdapter;
 import com.intellij.openapi.editor.event.DocumentEvent;
@@ -69,7 +67,6 @@ import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
-@AcceptNestedTransactions(TransactionKind.Common.TEXT_EDITING)
 class IntroduceConstantDialog extends DialogWrapper {
   private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.IntroduceConstantDialog");
   @NonNls private static final String RECENTS_KEY = "IntroduceConstantDialog.RECENTS_KEY";
index c732eafa820cf22803b51d6fd95e56734a266693..e71e6c3317ae9f7f1daf2a9ddc6f0ad15edfffda 100644 (file)
@@ -16,8 +16,6 @@
 package com.intellij.refactoring.introduceField;
 
 import com.intellij.codeInsight.completion.JavaCompletionUtil;
-import com.intellij.openapi.application.AcceptNestedTransactions;
-import com.intellij.openapi.application.TransactionKind;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.project.Project;
@@ -43,7 +41,6 @@ import org.jetbrains.annotations.Nullable;
 import javax.swing.*;
 import java.awt.*;
 
-@AcceptNestedTransactions(TransactionKind.Common.TEXT_EDITING)
 class IntroduceFieldDialog extends DialogWrapper {
 
 
index 2d1083f081d2b6ecce80d354d5d8512b7e8ee5a6..8d311229d6fa8aa1d9c534973a3dfa81f9415b57 100644 (file)
@@ -50,7 +50,6 @@ import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.Pass;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.wm.IdeFocusManager;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.codeStyle.SuggestedNameInfo;
@@ -267,12 +266,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase {
 
           final PsiMethod methodToSearchFor = superMethod.isEnabled() && superMethod.isSelected()
                                               ? methodToSearchIn.findDeepestSuperMethod() : methodToSearchIn;
-          Runnable runnable = new Runnable() {
-            public void run() {
-              consumer.consume(methodToSearchIn, methodToSearchFor);
-            }
-          };
-          IdeFocusManager.findInstance().doWhenFocusSettlesDown(runnable);
+          consumer.consume(methodToSearchIn, methodToSearchFor);
         }
       }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)));
     myEnclosingMethodsPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, list)
index a6bb4a5ae0c5ea77969ec3c855630123f739b9f5..6834a09693a89201d5b86b90594eb4787154a500 100644 (file)
@@ -18,8 +18,6 @@ package com.intellij.refactoring.migration;
 
 import com.intellij.lang.Language;
 import com.intellij.lang.java.JavaLanguage;
-import com.intellij.openapi.application.AcceptNestedTransactions;
-import com.intellij.openapi.application.TransactionKind;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.event.DocumentAdapter;
 import com.intellij.openapi.editor.event.DocumentEvent;
@@ -34,7 +32,6 @@ import org.jetbrains.annotations.Nullable;
 import javax.swing.*;
 import java.awt.*;
 
-@AcceptNestedTransactions(TransactionKind.Common.TEXT_EDITING)
 public class EditMigrationEntryDialog extends DialogWrapper{
   private JRadioButton myRbPackage;
   private JRadioButton myRbClass;
index 3c7798a4856bfdbd494cc4061fc7744da70ffeac..d5d14a33f2aa99db57d8fe3acbb035471ac9e51f 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.
@@ -26,8 +26,8 @@ import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiNamedElement;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.PsiShortNamesCache;
-import com.intellij.util.CommonProcessors;
 import com.intellij.util.Processor;
+import com.intellij.util.Processors;
 import com.intellij.util.containers.HashSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -97,8 +97,8 @@ public class JavaTestFinder implements TestFinder {
     if (klass == null) return Collections.emptySet();
 
     List<Pair<? extends PsiNamedElement, Integer>> classesWithProximities = new ArrayList<Pair<? extends PsiNamedElement, Integer>>();
-    final CommonProcessors.CollectProcessor<Pair<? extends PsiNamedElement, Integer>> processor =
-      new CommonProcessors.CollectProcessor<Pair<? extends PsiNamedElement, Integer>>(classesWithProximities);
+    Processor<Pair<? extends PsiNamedElement, Integer>> processor =
+      Processors.cancelableCollectProcessor(classesWithProximities);
     collectTests(klass, processor);
 
     return TestFinderHelper.getSortedElements(classesWithProximities, true);
index ca551b923d5b332cc768b7b166c5c5678d997965..20ad32e3e368135dd3551c0658df2afd69b0b379 100644 (file)
@@ -139,7 +139,7 @@ public class TestIntegrationUtils {
     return result;
   }
 
-  public static void runTestMethodTemplate(MethodKind methodKind,
+  public static void runTestMethodTemplate(@NotNull MethodKind methodKind,
                                            TestFramework framework,
                                            final Editor editor,
                                            final PsiClass targetClass,
@@ -149,15 +149,15 @@ public class TestIntegrationUtils {
     runTestMethodTemplate(methodKind, framework, editor, targetClass, null, method, name, automatic, existingNames);
   }
 
-  public static void runTestMethodTemplate(MethodKind methodKind,
+  public static void runTestMethodTemplate(@NotNull MethodKind methodKind,
                                            TestFramework framework,
                                            final Editor editor,
                                            final PsiClass targetClass,
                                            @Nullable PsiClass sourceClass,
                                            final PsiMethod method,
                                            @Nullable String name,
-    boolean automatic,
-    Set<String> existingNames) {
+                                           boolean automatic,
+                                           Set<String> existingNames) {
     runTestMethodTemplate(editor, targetClass, method, automatic,
                           createTestMethodTemplate(methodKind, framework, targetClass, sourceClass, name, automatic, existingNames));
   }
@@ -204,18 +204,18 @@ public class TestIntegrationUtils {
     TemplateManager.getInstance(project).startTemplate(editor, template, adapter);
   }
 
-  public static Template createTestMethodTemplate(MethodKind methodKind,
+  public static Template createTestMethodTemplate(@NotNull MethodKind methodKind,
                                                   TestFramework descriptor,
-                                                  PsiClass targetClass,
+                                                  @NotNull PsiClass targetClass,
                                                   @Nullable String name,
                                                   boolean automatic,
                                                   Set<String> existingNames) {
     return createTestMethodTemplate(methodKind, descriptor, targetClass, null, name, automatic, existingNames);
   }
 
-  public static Template createTestMethodTemplate(MethodKind methodKind,
+  public static Template createTestMethodTemplate(@NotNull MethodKind methodKind,
                                                   TestFramework descriptor,
-                                                  @NotNull PsiClass targetClass, 
+                                                  @NotNull PsiClass targetClass,
                                                   @Nullable PsiClass sourceClass,
                                                   @Nullable String name,
                                                   boolean automatic,
index 66ee2a6b6cf1dc4e324d0714566b0b3abd0a3ea9..6603e9b542a6b457d30a86a808271f36cd118a5b 100644 (file)
@@ -41,6 +41,7 @@ import com.intellij.testIntegration.TestIntegrationUtils;
 import com.intellij.util.Function;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collection;
@@ -223,7 +224,7 @@ public class JavaTestGenerator implements TestGenerator {
     });
   }
 
-  private static PsiMethod generateMethod(TestIntegrationUtils.MethodKind methodKind,
+  private static PsiMethod generateMethod(@NotNull TestIntegrationUtils.MethodKind methodKind,
                                           TestFramework descriptor,
                                           PsiClass targetClass,
                                           @Nullable PsiClass sourceClass,
index 5db4819a8d025d1f17267707e89017a05ff775db..90ebc0afcbf078ecd320db656f1f846786140834 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 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.
@@ -27,10 +27,7 @@ import com.intellij.psi.search.FilenameIndex;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.PsiShortNamesCache;
 import com.intellij.psi.stubs.StubIndex;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.CommonProcessors;
-import com.intellij.util.Processor;
-import com.intellij.util.SmartList;
+import com.intellij.util.*;
 import com.intellij.util.containers.HashSet;
 import com.intellij.util.indexing.IdFilter;
 import gnu.trove.THashMap;
@@ -120,7 +117,8 @@ public class PsiShortNamesCacheImpl extends PsiShortNamesCache {
 
   @Override
   public void getAllClassNames(@NotNull HashSet<String> set) {
-    processAllClassNames(new CommonProcessors.CollectProcessor<String>(set));
+    Processor<String> processor = Processors.cancelableCollectProcessor(set);
+    processAllClassNames(processor);
   }
 
   @Override
@@ -187,7 +185,7 @@ public class PsiShortNamesCacheImpl extends PsiShortNamesCache {
 
   @Override
   public void getAllMethodNames(@NotNull HashSet<String> set) {
-    JavaMethodNameIndex.getInstance().processAllKeys(myManager.getProject(), new CommonProcessors.CollectProcessor<String>(set));
+    JavaMethodNameIndex.getInstance().processAllKeys(myManager.getProject(), Processors.cancelableCollectProcessor(set));
   }
 
   @Override
@@ -226,7 +224,8 @@ public class PsiShortNamesCacheImpl extends PsiShortNamesCache {
 
   @Override
   public void getAllFieldNames(@NotNull HashSet<String> set) {
-    JavaFieldNameIndex.getInstance().processAllKeys(myManager.getProject(), new CommonProcessors.CollectProcessor<String>(set));
+    Processor<String> processor = Processors.cancelableCollectProcessor(set);
+    JavaFieldNameIndex.getInstance().processAllKeys(myManager.getProject(), processor);
   }
 
   @Override
index addd7cfd52daff0530babd876d3bb5408162792a..5b58fc7899b4305d3e433d98ed7a9208e2b5c72e 100644 (file)
@@ -34,11 +34,13 @@ import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
 import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.util.ConcurrencyUtil;
 import com.intellij.util.Processor;
-import com.intellij.util.containers.Stack;
-import gnu.trove.THashSet;
+import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.containers.HashSetQueue;
 import org.jetbrains.annotations.NotNull;
 
-import java.util.*;
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.concurrent.ConcurrentMap;
 
 public class JavaClassInheritorsSearcher extends QueryExecutorBase<PsiClass, ClassInheritorsSearch.SearchParameters> {
@@ -113,78 +115,8 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase<PsiClass, Cla
 
   @NotNull
   // returns lazy collection of subclasses. Each call to next() leads to calculation of next batch of subclasses.
-  // Candidates to subclasses are kept in 'stack'. Already computed inheritors are in 'subClasses' array.
   private static Collection<PsiClass> computeAllSubClasses(@NotNull Project project, @NotNull PsiClass baseClass) {
-    final Stack<PsiAnchor> stack = new Stack<>();
-    final Set<PsiAnchor> processed = new THashSet<>();
-    final List<PsiClass> subClasses = Collections.synchronizedList(new ArrayList<>());
-
-    ApplicationManager.getApplication().runReadAction(() -> {
-      stack.push(PsiAnchor.create(baseClass));
-    });
-    return new AbstractCollection<PsiClass>() {
-      {
-        checkNextCandidates(); // populate with at least one subclass
-      }
-
-      @NotNull
-      @Override
-      public Iterator<PsiClass> iterator() {
-        return new Iterator<PsiClass>() {
-          int index;
-
-          @Override
-          public boolean hasNext() {
-            if (index < subClasses.size()) return true;
-            checkNextCandidates();
-            return index < subClasses.size();
-          }
-
-          @Override
-          public PsiClass next() {
-            return subClasses.get(index++);
-          }
-        };
-      }
-
-      @Override
-      public int size() {
-        throw new UnsupportedOperationException();
-      }
-
-      private void checkNextCandidates() {
-        final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project);
-        synchronized (subClasses) { // this collection can be iterated from different threads concurrently
-          while (!stack.isEmpty()) {
-            ProgressManager.checkCanceled();
-
-            final PsiAnchor anchor = stack.pop();
-            if (!processed.add(anchor)) continue;
-
-            PsiClass psiClass = ApplicationManager.getApplication().runReadAction((Computable<PsiClass>)() -> (PsiClass)anchor.retrieve());
-            if (psiClass == null) continue;
-
-            if (!(psiClass instanceof PsiAnonymousClass) && !isFinal(psiClass)) {
-              DirectClassInheritorsSearch.search(psiClass, projectScope).forEach(
-                candidate -> {
-                  ProgressManager.checkCanceled();
-                  ApplicationManager.getApplication().runReadAction(() -> {
-                    stack.push(PsiAnchor.create(candidate));
-                  });
-
-                  return true;
-                });
-            }
-
-            if (psiClass != baseClass) {
-              subClasses.add(psiClass);
-              return; // just allow the iterator to move forward, rest elements will be added on the next call to .next()
-            }
-          }
-          processed.clear(); // prevent too many PsiAnchors retained by this anonymous class closure
-        }
-      }
-    };
+    return new AllSubClassesLazyCollection(project, baseClass);
   }
 
   private static boolean processLocalScope(@NotNull final Project project,
@@ -255,4 +187,103 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase<PsiClass, Cla
   private static boolean isFinal(@NotNull final PsiClass baseClass) {
     return ApplicationManager.getApplication().runReadAction((Computable<Boolean>)() -> baseClass.hasModifierProperty(PsiModifier.FINAL));
   }
+
+  private static class AllSubClassesLazyCollection extends AbstractCollection<PsiClass> {
+    // Computes all sub classes of the 'baseClass' transitively by calling DirectClassInheritorsSearch repeatedly.
+    // Already computed subclasses in this collection.
+    // There are two iterators maintained for this collection:
+    // - 'candidatesToFindSubclassesIterator' points to the next element for which direct inheritors haven't been searched yet.
+    // - 'subClassIterator' created in AllSubClassesLazyCollection.iterator() maintains state of the AllSubClassesLazyCollection iterator in a lazy fashion. If more elements requested for this iterator, the findNextSubclasses() is called which tries to populate 'subClasses' with more inheritors.
+    private final HashSetQueue<PsiClass> subClasses = new HashSetQueue<>();
+    private final Object lock = new Object();
+    private final GlobalSearchScope projectScope;
+    private final Semaphore currentlyProcessingClasses = new Semaphore();
+    private final PsiClass myBaseClass;
+
+    AllSubClassesLazyCollection(@NotNull Project project, @NotNull PsiClass baseClass) {
+      myBaseClass = baseClass;
+      projectScope = GlobalSearchScope.allScope(project);
+      // populate with at least one subclass
+      findNextSubclasses();
+    }
+
+    @NotNull
+    @Override
+    public Iterator<PsiClass> iterator() {
+      return new Iterator<PsiClass>() {
+        private final Iterator<PsiClass> subClassIterator = subClasses.iterator();
+
+        @Override
+        public boolean hasNext() {
+          synchronized (lock) {
+            if (subClassIterator.hasNext()) return true;
+          }
+
+          findNextSubclasses();
+
+          synchronized (lock) {
+            return subClassIterator.hasNext();
+          }
+        }
+
+        @Override
+        public PsiClass next() {
+          synchronized (lock) {
+            return subClassIterator.next();
+          }
+        }
+      };
+    }
+
+    @Override
+    public int size() {
+      throw new UnsupportedOperationException();
+    }
+
+    private Iterator<PsiClass> candidatesToFindSubclassesIterator; // guarded by lock
+
+    private void findNextSubclasses() {
+      while (true) {
+        ProgressManager.checkCanceled();
+
+        PsiClass candidate;
+        synchronized (lock) {
+          if (candidatesToFindSubclassesIterator == null) {
+            candidatesToFindSubclassesIterator = subClasses.iterator();
+            candidate = myBaseClass;
+          }
+          else {
+            if (!candidatesToFindSubclassesIterator.hasNext()) {
+              // no candidates left, exit
+              // but first, wait for other threads to process their candidates
+              break;
+            }
+            candidate = candidatesToFindSubclassesIterator.next();
+          }
+          currentlyProcessingClasses.down(); // tell other threads we are going to process this candidate
+        }
+
+        boolean added;
+        try {
+          if (candidate instanceof PsiAnonymousClass || isFinal(candidate)) {
+            added = false;
+          }
+          else {
+            Collection<PsiClass> foundSubClasses = DirectClassInheritorsSearch.search(candidate, projectScope).findAll();
+            synchronized (lock) {
+              added = subClasses.addAll(foundSubClasses);
+            }
+          }
+        }
+        finally {
+          currentlyProcessingClasses.up();
+        }
+        if (added) {
+          // just allow the iterator to move forward; more elements will be added on the next call to .next()
+          return;
+        }
+      }
+      currentlyProcessingClasses.waitFor(); // wait until other threads process their classes before giving up
+    }
+  }
 }
index d2482955e8a1bc52784731ec5e0b356b98168603..edf61fe9f9a52343fff88494b860b62d34260af1 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.
@@ -36,9 +36,9 @@ import com.intellij.psi.search.searches.ReferencesSearch;
 import com.intellij.psi.stubs.StubIndex;
 import com.intellij.psi.stubs.StubIndexKey;
 import com.intellij.psi.util.*;
-import com.intellij.util.CommonProcessors;
 import com.intellij.util.Function;
 import com.intellij.util.Processor;
+import com.intellij.util.Processors;
 import com.intellij.util.containers.HashSet;
 import com.intellij.util.indexing.FileBasedIndex;
 import org.jetbrains.annotations.NotNull;
@@ -174,7 +174,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
 
           final Set<String> usedMethodNames = newHashSet();
           FileBasedIndex.getInstance().processAllKeys(JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID,
-                                                      new CommonProcessors.CollectProcessor<String>(usedMethodNames), candidateScope, null);
+                                                      Processors.cancelableCollectProcessor(usedMethodNames), candidateScope, null);
 
           final LinkedHashSet<PsiMethod> methods = newLinkedHashSet();
           Processor<PsiMethod> methodProcessor = new Processor<PsiMethod>() {
@@ -200,12 +200,9 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
   @NotNull
   private static GlobalSearchScope combineResolveScopes(Project project, Set<VirtualFile> candidateFiles) {
     final PsiManager psiManager = PsiManager.getInstance(project);
-    LinkedHashSet<GlobalSearchScope> resolveScopes = newLinkedHashSet(mapNotNull(candidateFiles, new Function<VirtualFile, GlobalSearchScope>() {
-      @Override
-      public GlobalSearchScope fun(VirtualFile file) {
-        PsiFile psiFile = file.isValid() ? psiManager.findFile(file) : null;
-        return psiFile == null ? null : psiFile.getResolveScope();
-      }
+    Set<GlobalSearchScope> resolveScopes = newLinkedHashSet(mapNotNull(candidateFiles, file -> {
+      PsiFile psiFile = file.isValid() ? psiManager.findFile(file) : null;
+      return psiFile == null ? null : psiFile.getResolveScope();
     }));
     return GlobalSearchScope.union(resolveScopes.toArray(new GlobalSearchScope[resolveScopes.size()]));
   }
@@ -214,7 +211,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
   private static Set<VirtualFile> getFilesWithFunctionalExpressionsScope(Project project, GlobalSearchScope useScope) {
     final Set<VirtualFile> files = newLinkedHashSet();
     final PsiSearchHelperImpl helper = (PsiSearchHelperImpl)PsiSearchHelper.SERVICE.getInstance(project);
-    final CommonProcessors.CollectProcessor<VirtualFile> processor = new CommonProcessors.CollectProcessor<VirtualFile>(files);
+    Processor<VirtualFile> processor = Processors.cancelableCollectProcessor(files);
     helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "::", processor);
     helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "->", processor);
     return files;
index c66654661bc966757b5434609373c6d8faa75671..33817855456b6176fafb7652a540fe097f257717 100644 (file)
@@ -79,6 +79,8 @@ public class JavaOverridingMethodsSearcher implements QueryExecutor<PsiMethod, O
     // optimisation: in case of local scope it's considered cheaper to enumerate all scope files and check if there is an inheritor there,
     // instead of traversing the (potentially huge) class hierarchy and filter out almost everything by scope.
     VirtualFile[] virtualFiles = searchScope.getVirtualFiles();
+    final PsiClass methodContainingClass = ApplicationManager.getApplication().runReadAction((Computable<PsiClass>)method::getContainingClass);
+    if (methodContainingClass == null) return true;
 
     final boolean[] success = {true};
     for (VirtualFile virtualFile : virtualFiles) {
@@ -88,13 +90,12 @@ public class JavaOverridingMethodsSearcher implements QueryExecutor<PsiMethod, O
         public void run() {
           PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
           if (psiFile != null) {
-            final PsiClass containingClass = ApplicationManager.getApplication().runReadAction((Computable<PsiClass>)method::getContainingClass);
             psiFile.accept(new JavaRecursiveElementVisitor() {
               @Override
               public void visitClass(PsiClass candidate) {
                 ProgressManager.checkCanceled();
                 if (!success[0]) return;
-                PsiMethod overridingMethod = candidate == containingClass ? null : findOverridingMethod(project, candidate, method, containingClass);
+                PsiMethod overridingMethod = candidate == methodContainingClass ? null : findOverridingMethod(project, candidate, method, methodContainingClass);
                 if (overridingMethod != null && !consumer.process(overridingMethod)) {
                   success[0] = false;
                 }
index f63fcb976dd22a5d6ccf746bc90f239f79bbaee4..7dc93558ed09bf9970b74e67548d303c69ce3066 100644 (file)
@@ -19,7 +19,8 @@ import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.psi.util.*;
 import com.intellij.util.ArrayUtil;
-import com.intellij.util.CommonProcessors;
+import com.intellij.util.Processor;
+import com.intellij.util.Processors;
 import com.intellij.util.containers.ConcurrentFactoryMap;
 import com.intellij.util.containers.ContainerUtil;
 import gnu.trove.THashSet;
@@ -197,14 +198,16 @@ public class AnnotationUtil {
       @Nullable
       @Override
       public Result<List<T>> compute() {
-        LinkedHashSet<PsiModifierListOwner> result = ContainerUtil.newLinkedHashSet();
+        Set<PsiModifierListOwner> result = ContainerUtil.newLinkedHashSet();
         if (element instanceof PsiMethod) {
           collectSuperMethods(result, ((PsiMethod)element).getHierarchicalMethodSignature(), element,
                               JavaPsiFacade.getInstance(element.getProject()).getResolveHelper());
-        } else if (element instanceof PsiClass) {
+        }
+        else if (element instanceof PsiClass) {
           //noinspection unchecked
-          InheritanceUtil.processSupers((PsiClass)element, false, new CommonProcessors.CollectProcessor<PsiClass>((Set)result));
-        } else if (element instanceof PsiParameter) {
+          InheritanceUtil.processSupers((PsiClass)element, false, (Processor)Processors.cancelableCollectProcessor(result));
+        }
+        else if (element instanceof PsiParameter) {
           collectSuperParameters(result, (PsiParameter)element);
         }
 
@@ -249,7 +252,7 @@ public class AnnotationUtil {
     return map.get(annotationNames);
   }
 
-  private static void collectSuperParameters(LinkedHashSet<PsiModifierListOwner> result, @NotNull PsiParameter parameter) {
+  private static void collectSuperParameters(@NotNull Set<PsiModifierListOwner> result, @NotNull PsiParameter parameter) {
     PsiElement scope = parameter.getDeclarationScope();
     if (!(scope instanceof PsiMethod)) {
       return;
@@ -269,7 +272,7 @@ public class AnnotationUtil {
     }
   }
 
-  private static void collectSuperMethods(LinkedHashSet<PsiModifierListOwner> result,
+  private static void collectSuperMethods(@NotNull Set<PsiModifierListOwner> result,
                                           @NotNull HierarchicalMethodSignature signature,
                                           @NotNull PsiElement place,
                                           @NotNull PsiResolveHelper resolveHelper) {
index 415f32e86fd3c39702b758cd64b2988b09edce10..a8a48667b039bfea0d4944d31dc544ddc338c6be 100644 (file)
@@ -155,7 +155,7 @@ public class MethodCandidateInfo extends CandidateInfo{
         }
         return level;
       }
-    }, substitutor);
+    }, substitutor, isVarargs(), true);
     if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(new Computable<PsiSubstitutor>() {
       @Override
       public PsiSubstitutor compute() {
@@ -236,15 +236,17 @@ public class MethodCandidateInfo extends CandidateInfo{
     return true;
   }
 
-  private <T> T computeForOverloadedCandidate(final Computable<T> computable, final PsiSubstitutor substitutor) {
+  private <T> T computeForOverloadedCandidate(final Computable<T> computable,
+                                              final PsiSubstitutor substitutor,
+                                              boolean varargs, boolean applicabilityCheck) {
     Map<PsiElement, CurrentCandidateProperties> map = CURRENT_CANDIDATE.get();
     if (map == null) {
       map = ContainerUtil.createConcurrentWeakMap();
       CURRENT_CANDIDATE.set(map);
     }
     final PsiElement argumentList = getMarkerList();
-    final CurrentCandidateProperties alreadyThere = map.put(argumentList,
-                                                            new CurrentCandidateProperties(this, substitutor, isVarargs(), true));
+    final CurrentCandidateProperties alreadyThere =
+      map.put(argumentList, new CurrentCandidateProperties(this, substitutor, varargs, applicabilityCheck));
     try {
       return computable.compute();
     }
@@ -369,40 +371,32 @@ public class MethodCandidateInfo extends CandidateInfo{
     }
   }
 
+  /**
+   * If iterated through all candidates, should be called under {@link #ourOverloadGuard} guard so results won't be cached on the top level call
+   */
   @NotNull
-  public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy,
-                                           @NotNull PsiExpression[] arguments, 
+  public PsiSubstitutor inferTypeArguments(@NotNull final ParameterTypeInferencePolicy policy,
+                                           @NotNull final PsiExpression[] arguments,
                                            boolean includeReturnConstraint) {
-    Map<PsiElement, CurrentCandidateProperties> map = CURRENT_CANDIDATE.get();
-    if (map == null) {
-      map = ContainerUtil.createConcurrentWeakMap();
-      CURRENT_CANDIDATE.set(map);
-    }
-    final PsiMethod method = getElement();
-    final PsiElement argumentList = getMarkerList();
-    final CurrentCandidateProperties alreadyThere =
-      map.put(argumentList, new CurrentCandidateProperties(this, super.getSubstitutor(), policy.isVarargsIgnored() || isVarargs(), !includeReturnConstraint));
-    try {
-      PsiTypeParameter[] typeParameters = method.getTypeParameters();
+    return computeForOverloadedCandidate(new Computable<PsiSubstitutor>() {
+      @Override
+      public PsiSubstitutor compute() {
+        final PsiMethod method = MethodCandidateInfo.this.getElement();
+        PsiTypeParameter[] typeParameters = method.getTypeParameters();
 
-      if (isRawSubstitution()) {
-        return JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createRawSubstitutor(mySubstitutor, typeParameters);
-      }
+        if (MethodCandidateInfo.this.isRawSubstitution()) {
+          return JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createRawSubstitutor(mySubstitutor, typeParameters);
+        }
 
-      final PsiElement parent = getParent();
-      if (parent == null) return PsiSubstitutor.EMPTY;
-      Project project = method.getProject();
-      JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
-      return javaPsiFacade.getResolveHelper()
-        .inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, mySubstitutor, parent, policy, myLanguageLevel);
-    }
-    finally {
-      if (alreadyThere == null) {
-        map.remove(argumentList);
-      } else {
-        map.put(argumentList, alreadyThere);
+        final PsiElement parent = MethodCandidateInfo.this.getParent();
+        if (parent == null) return PsiSubstitutor.EMPTY;
+        Project project = method.getProject();
+        JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
+        return javaPsiFacade.getResolveHelper()
+          .inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, mySubstitutor, parent, policy,
+                              myLanguageLevel);
       }
-    }
+    }, super.getSubstitutor(), policy.isVarargsIgnored() || isVarargs(), !includeReturnConstraint);
   }
 
   private boolean isRawSubstitution() {
index 9e39182e8a533ab4a09954c25ff9bf0be7df7541..7ff44384c50d1e7dad68240e4e8b40082fd6e5c4 100644 (file)
@@ -28,6 +28,7 @@ import com.intellij.psi.impl.PsiManagerImpl;
 import com.intellij.psi.impl.compiled.ClsFileImpl;
 import com.intellij.psi.impl.file.PsiBinaryFileImpl;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.jetbrains.org.objectweb.asm.ClassReader;
 import org.jetbrains.org.objectweb.asm.ClassVisitor;
 import org.jetbrains.org.objectweb.asm.Opcodes;
@@ -59,7 +60,7 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider {
 
     // skip inner, anonymous, missing and corrupted classes
     try {
-      if (!isInnerClass(file, file.contentsToByteArray(false))) {
+      if (!isInnerClass(file)) {
         return new ClsFileImpl(this);
       }
     }
@@ -70,29 +71,31 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider {
     return null;
   }
 
-  /** @deprecated use {@link #isInnerClass(VirtualFile, byte[])} (to be removed in IDEA 17) */
-  @SuppressWarnings("unused")
   public static boolean isInnerClass(@NotNull VirtualFile file) {
-    try {
-      String name = file.getNameWithoutExtension();
-      int p = name.lastIndexOf('$', name.length() - 2);
-      return p > 0 && detectInnerClass(file, file.contentsToByteArray(false));
-    }
-    catch (IOException e) {
-      throw new RuntimeException(e);
-    }
+    return detectInnerClass(file, null);
   }
 
   public static boolean isInnerClass(@NotNull VirtualFile file, @NotNull byte[] content) {
+    return detectInnerClass(file, content);
+  }
+
+  private static boolean detectInnerClass(VirtualFile file, @Nullable byte[] content) {
     String name = file.getNameWithoutExtension();
     int p = name.lastIndexOf('$', name.length() - 2);
-    return p > 0 && detectInnerClass(file, content);
-  }
+    if (p <= 0) return false;
 
-  private static boolean detectInnerClass(VirtualFile file, byte[] content) {
     Boolean isInner = IS_INNER_CLASS.get(file);
     if (isInner != null) return isInner;
 
+    if (content == null) {
+      try {
+        content = file.contentsToByteArray(false);
+      }
+      catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+
     ClassReader reader = new ClassReader(content);
     final Ref<Boolean> ref = Ref.create(Boolean.FALSE);
     final String className = reader.getClassName();
index b69d5ccb98ebea9a16a9ff874687e7fac14a5950..2c861a6d34e2a828debaae28c40b65d540546cf5 100644 (file)
@@ -861,7 +861,7 @@ public class ControlFlowUtil {
 
   private static PsiReferenceExpression findReferenceTo(PsiElement element, PsiVariable variable) {
     if (element instanceof PsiReferenceExpression
-        && !((PsiReferenceExpression)element).isQualified()
+        && isUnqualified((PsiReferenceExpression)element)
         && ((PsiReferenceExpression)element).resolve() == variable) {
       return (PsiReferenceExpression)element;
     }
@@ -873,6 +873,14 @@ public class ControlFlowUtil {
     return null;
   }
 
+  private static boolean isUnqualified(PsiReferenceExpression element) {
+    if (element.isQualified()) {
+      final PsiExpression qualifierExpression = element.getQualifierExpression();
+      return qualifierExpression instanceof PsiThisExpression && ((PsiThisExpression)qualifierExpression).getQualifier() == null;
+    }
+    return true;
+  }
+
 
   public static boolean isVariableDefinitelyAssigned(@NotNull final PsiVariable variable, @NotNull final ControlFlow flow) {
     class MyVisitor extends InstructionClientVisitor<Boolean> {
index eb34fe1484d609494ae409406795bd232f5ae50c..9f346a14b0d98aee6916cbee33b5de02a4938fd7 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.
@@ -41,7 +41,8 @@ import com.intellij.psi.search.PsiSearchScopeUtil;
 import com.intellij.psi.util.*;
 import com.intellij.reference.SoftReference;
 import com.intellij.util.ArrayUtil;
-import com.intellij.util.CommonProcessors;
+import com.intellij.util.Processor;
+import com.intellij.util.Processors;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -84,10 +85,10 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
     return CachedValuesManager.getManager(myManager.getProject()).createCachedValue(new CachedValueProvider<Collection<PsiDirectory>>() {
       @Override
       public Result<Collection<PsiDirectory>> compute() {
-        final CommonProcessors.CollectProcessor<PsiDirectory> processor = new CommonProcessors.CollectProcessor<PsiDirectory>();
+        Collection<PsiDirectory> result = new ArrayList<PsiDirectory>();
+        Processor<PsiDirectory> processor = Processors.cancelableCollectProcessor(result);
         getFacade().processPackageDirectories(PsiPackageImpl.this, allScope(), processor, includeLibrarySources);
-        return Result.create(processor.getResults(), PsiPackageImplementationHelper.getInstance().getDirectoryCachedValueDependencies(
-          PsiPackageImpl.this));
+        return Result.create(result, PsiPackageImplementationHelper.getInstance().getDirectoryCachedValueDependencies(PsiPackageImpl.this));
       }
     }, false);
   }
index e7c83d772607523f3d25f418c79bfc031c7f3262..f86c266b385c2c2ab3f704899050b1e202c46e92 100644 (file)
@@ -75,4 +75,24 @@ public class PsiJavaFileStubImpl extends PsiFileStubImpl<PsiJavaFile> implements
   public String toString() {
     return "PsiJavaFileStub [" + myPackageName + "]";
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    PsiJavaFileStubImpl stub = (PsiJavaFileStubImpl)o;
+
+    if (myCompiled != stub.myCompiled) return false;
+    if (myPackageName != null ? !myPackageName.equals(stub.myPackageName) : stub.myPackageName != null) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = myPackageName != null ? myPackageName.hashCode() : 0;
+    result = 31 * result + (myCompiled ? 1 : 0);
+    return result;
+  }
 }
\ No newline at end of file
index 5b228b75114698cf5504561cf53660f1cd344b1d..50443509c106a02b8c0e9dbc6db8f659a7e253ae 100644 (file)
@@ -1298,6 +1298,9 @@ public class InferenceSession {
   }
 
   public GlobalSearchScope getScope() {
+    if (myContext != null) {
+      return myContext.getResolveScope();
+    }
     return GlobalSearchScope.allScope(myManager.getProject());
   }
 
index 6ccf25af7b26fc96f676deecea6b7b88b843cc9c..ebba9b0aae63ab89223167c7a360b87dbcb4b442 100644 (file)
@@ -79,7 +79,7 @@ public class InferenceSessionContainer {
                                                                                           });
         if (topLevelCall != null) {
 
-          final InferenceSession session;
+          InferenceSession session;
           if (MethodCandidateInfo.isOverloadCheck() || !PsiDiamondType.ourDiamondGuard.currentStack().isEmpty() || LambdaUtil.isLambdaParameterCheck()) {
             session = startTopLevelInference(topLevelCall);
           }
@@ -91,6 +91,22 @@ public class InferenceSessionContainer {
                 return new Result<InferenceSession>(startTopLevelInference(topLevelCall), PsiModificationTracker.MODIFICATION_COUNT);
               }
             });
+
+            if (session != null) {
+              //reject cached top level session if it was based on wrong candidate: check nested session if candidate (it's type parameters) are the same
+              //such situations are avoided when overload resolution is performed (MethodCandidateInfo.isOverloadCheck above)
+              //but situations when client code iterates through PsiResolveHelper.getReferencedMethodCandidates or similar are impossible to guess
+              final Map<PsiElement, InferenceSession> sessions = session.getInferenceSessionContainer().myNestedSessions;
+              final InferenceSession childSession = sessions.get(parent);
+              if (childSession != null) {
+                for (PsiTypeParameter parameter : typeParameters) {
+                  if (!childSession.getInferenceSubstitution().getSubstitutionMap().containsKey(parameter)) {
+                    session = startTopLevelInference(topLevelCall);
+                    break;
+                  }
+                }
+              }
+            }
           }
 
           if (session != null) {
index 0d27f47191628b680beff60daff3d02daa3584af..f78c1075a3e925105933a068628fc0bcbe3e2fa0 100644 (file)
@@ -117,8 +117,7 @@ public class PsiGraphInferenceHelper implements PsiInferenceHelper {
       leftTypes = new PsiType[] {arg};
       rightTypes = new PsiType[]{param};
     }
-    final PsiTypeParameterListOwner owner = typeParam.getOwner();
-    final PsiTypeParameter[] typeParams = owner != null ? owner.getTypeParameters() : new PsiTypeParameter[] {typeParam};
+    final PsiTypeParameter[] typeParams = new PsiTypeParameter[] {typeParam};
     final InferenceSession inferenceSession = new InferenceSession(typeParams, leftTypes, rightTypes, PsiSubstitutor.EMPTY, myManager, null);
     if (inferenceSession.isProperType(inferenceSession.substituteWithInferenceVariables(param)) &&
         inferenceSession.isProperType(inferenceSession.substituteWithInferenceVariables(arg))) {
index 555ebb946ef15500017a4a72737d7b800be7948d..4743d45c40612d92e0da60bc74496ed15ad20fc0 100644 (file)
@@ -101,9 +101,9 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
       if (callSession != session) {
         session.getInferenceSessionContainer().registerNestedSession(callSession);
         session.propagateVariables(callSession.getInferenceVariables(), callSession.getRestoreNameSubstitution());
-        if (callSession.isErased()) {
+/*        if (callSession.isErased()) {
           session.setErased();
-        }
+        }*/
       }
       return true;
     }
index 169aeeac6527a1451c97024ce204371c4041664d..d1d3b8054a5799a4f1662fe3904c9fa76d4cd5a6 100644 (file)
@@ -134,9 +134,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
     checkPrimitiveVarargs(conflicts, getActualParametersLength());
     if (conflicts.size() == 1) return conflicts.get(0);
 
-    checkAccessStaticLevels(conflicts, false);
-    if (conflicts.size() == 1) return conflicts.get(0);
-
     Set<CandidateInfo> uniques = new THashSet<CandidateInfo>(conflicts);
     if (uniques.size() == 1) return uniques.iterator().next();
     return null;
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SuggestMapInheritors-out.java b/java/java-tests/testData/codeInsight/completion/smartType/SuggestMapInheritors-out.java
new file mode 100644 (file)
index 0000000..11d19d0
--- /dev/null
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class A {
+  {
+    Map<String, String> m = new HashMap<>(<caret>);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SuggestMapInheritors.java b/java/java-tests/testData/codeInsight/completion/smartType/SuggestMapInheritors.java
new file mode 100644 (file)
index 0000000..83aca07
--- /dev/null
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class A {
+  {
+    Map<String, String> m = new HashM<caret>
+  }
+}
\ No newline at end of file
index e60c440b6f69fd975db35b9d0bbabb1ec04e935a..44ec29ac621d76e860d31954941edb5f07bd1b21 100644 (file)
@@ -44,7 +44,7 @@ public class a {
     ia[~i | (i+=(!b?2:i))] -= i + 3.3;
     
     // Object += String
-    <error descr="Operator '+' cannot be applied to 'java.lang.Object', 'java.lang.String'">o += o + "string"</error>;
+    o += o + "string";
 
     return 0;
   }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/AssignmentFromStringToObject.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/AssignmentFromStringToObject.java
new file mode 100644 (file)
index 0000000..d9daa31
--- /dev/null
@@ -0,0 +1,7 @@
+class Test {
+  {
+    Object o = "";
+    <warning descr="Operator '+' cannot be applied to 'java.lang.Object', 'java.lang.String'">o += ""</warning>;
+    System.out.println(o);
+  }
+}
\ No newline at end of file
index b924ad67598afed3c1f85adf8c5a90c243ce2be3..f9cad1c21ca3cf7bf5d3368cb4a866491ac9efb1 100644 (file)
@@ -89,3 +89,13 @@ class TestAnonymousWithRefToTheTopLevelUninitializedField {
 
 }
 
+class TestThisQualified {
+  final String s;
+
+  final Runnable r = () -> System.out.println(<error descr="Variable 'this.s' might not have been initialized">this.s</error>.length());
+  final Runnable r2 = () -> System.out.println(this.r2);
+
+  public TestThisQualified() {
+    s = "";
+  }
+}
\ No newline at end of file
index e7ad99c771d1ef3292aa208651671629ec2fe4c0..be295de6f509010cc31f11e5182ff46bd6edccda 100644 (file)
@@ -5,11 +5,11 @@ class Test {
     Result<String> r2 = Result.create<error descr="'create(K)' in 'Result' cannot be applied to '(Holder)'">(h)</error>;
 
     Holder dataHolder = null;
-    Result<String> r3 = new Result<>(new Holder<>(dataHolder));
-    Result<String> r4 = Result.create(new Holder<>(dataHolder));
+    Result<String> r3 = new Result<><error descr="'Result(D)' in 'Result' cannot be applied to '(Holder<E>)'">(new Holder<>(dataHolder))</error>;
+    Result<String> r4 = Result.create<error descr="'create(K)' in 'Result' cannot be applied to '(Holder<E>)'">(new Holder<>(dataHolder))</error>;
 
-    Result<String> r5 = new Result<>(Holder.create(dataHolder));
-    Result<String> r6 = Result.create(Holder.create(dataHolder));
+    Result<String> r5 = new Result<>(Holder.create<error descr="'create(Holder<M>)' in 'Holder' cannot be applied to '(Holder)'">(dataHolder)</error>);
+    Result<String> r6 = Result.create<error descr="'create(K)' in 'Result' cannot be applied to '(Holder)'">(Holder.create(dataHolder))</error>;
 
   }
 }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/NonCachingFolding.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/NonCachingFolding.java
new file mode 100644 (file)
index 0000000..abff7d3
--- /dev/null
@@ -0,0 +1,22 @@
+import java.util.function.Function;
+import java.util.*;
+
+class Test {
+  void m(Set<String> i) {
+    final List<String> getters = new ArrayList<String>(map(i, new Func<caret>tion<String, String>() {
+      @Override
+      public String apply(String propertyName) {
+        return propertyName;
+      }
+    }));
+  }
+
+
+  public static <T,V> List<V> map(Iterable<? extends T> iterable, Function<T, V> mapping) {
+    return null;
+  }
+
+  public static <T,V> List<V> map(Collection<? extends T> iterable, Function<T, V> mapping) {
+    return null;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/RejectCachedTopLevelSessionIfItCorrespondsToTheWrongOverload.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/RejectCachedTopLevelSessionIfItCorrespondsToTheWrongOverload.java
new file mode 100644 (file)
index 0000000..83a8ac7
--- /dev/null
@@ -0,0 +1,22 @@
+import java.util.function.Function;
+import java.util.*;
+
+class Test {
+  void m(Set<String> i) {
+    final List<String> getters = new ArrayList<String>(ma<caret>p(i, new Function<String, String>() {
+      @Override
+      public String apply(String propertyName) {
+        return propertyName;
+      }
+    }));
+  }
+
+
+  public static <T,V> List<V> map(Iterable<? extends T> iterable, Function<T, V> mapping) {
+    return null;
+  }
+
+  public static <T,V> List<V> map(Collection<? extends T> iterable, Function<T, V> mapping) {
+    return null;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IgnoreStaticCorrectnessDuringOverloadResolution.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IgnoreStaticCorrectnessDuringOverloadResolution.java
new file mode 100644 (file)
index 0000000..0dffd0e
--- /dev/null
@@ -0,0 +1,16 @@
+class A<T> {
+  public void testMethod(T... values) {}
+  public void testMethod1(T values) {}
+}
+
+class B extends A<Integer> {
+  public static void testMethod(String... values) {}
+  public static void testMethod1(String values) {}
+}
+
+class Test45 {
+  public static void main(String[] args) {
+    B.testMethod<error descr="Ambiguous method call: both 'B.testMethod(String...)' and 'A.testMethod(Integer...)' match">()</error>;
+    B.testMethod1<error descr="Ambiguous method call: both 'B.testMethod1(String)' and 'A.testMethod1(Integer)' match">(null)</error>;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/multipleJdks/java8/p/BoxedTypesWhenPreGenericJDKPresentInProject.java b/java/java-tests/testData/codeInsight/multipleJdks/java8/p/BoxedTypesWhenPreGenericJDKPresentInProject.java
new file mode 100644 (file)
index 0000000..2106209
--- /dev/null
@@ -0,0 +1,10 @@
+import java.io.File;
+import java.util.Arrays;
+import java.util.Comparator;
+
+class Test {
+  private static File findLastModified(final File[] files) {
+    return Arrays.stream(files).sorted(Comparator.comparing(File::lastModified).reversed())
+      .findFirst().orElse(null);
+  }
+}
\ No newline at end of file
index 5b0b6f47532e402ee93b5c90614f608a95dfbf60..508d8d5e99313204c64d64ef5d142b734aa58179 100644 (file)
@@ -57,10 +57,17 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase {
     myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
     myFixture.setTestDataPath(PathManagerEx.getTestDataPath() + "/codeInsight/multipleJdks");
     final JavaModuleFixtureBuilder[] builders = new JavaModuleFixtureBuilder[3];
+
     builders[0] = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
     builders[0].setLanguageLevel(LanguageLevel.JDK_1_3);
+    builders[0].addJdk(IdeaTestUtil.getMockJdk14Path().getPath());
+
     builders[1] = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
+    builders[1].addJdk(IdeaTestUtil.getMockJdk17Path().getPath());
+
     builders[2] = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
+    builders[2].addJdk(IdeaTestUtil.getMockJdk18Path().getPath());
+
     myFixture.setUp();
     myJava3Module = builders[0].getFixture().getModule();
     myJava7Module = builders[1].getFixture().getModule();
@@ -68,7 +75,6 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase {
     ModuleRootModificationUtil.updateModel(myJava3Module, new Consumer<ModifiableRootModel>() {
       @Override
       public void consume(ModifiableRootModel model) {
-        model.setSdk(IdeaTestUtil.getMockJdk14());
         String contentUrl = VfsUtilCore.pathToUrl(myFixture.getTempDirPath()) + "/java3";
         model.addContentEntry(contentUrl).addSourceFolder(contentUrl, false);
       }
@@ -77,7 +83,6 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase {
     ModuleRootModificationUtil.updateModel(myJava7Module, new Consumer<ModifiableRootModel>() {
       @Override
       public void consume(ModifiableRootModel model) {
-        model.setSdk(IdeaTestUtil.getMockJdk17());
         String contentUrl = VfsUtilCore.pathToUrl(myFixture.getTempDirPath()) + "/java7";
         model.addContentEntry(contentUrl).addSourceFolder(contentUrl, false);
       }
@@ -86,7 +91,6 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase {
     ModuleRootModificationUtil.updateModel(myJava8Module, new Consumer<ModifiableRootModel>() {
       @Override
       public void consume(ModifiableRootModel model) {
-        model.setSdk(IdeaTestUtil.getMockJdk18());
         String contentUrl = VfsUtilCore.pathToUrl(myFixture.getTempDirPath()) + "/java8";
         model.addContentEntry(contentUrl).addSourceFolder(contentUrl, false);
       }
@@ -169,6 +173,11 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase {
     doTest3Modules();
   }
 
+  public void testBoxedTypesWhenPreGenericJDKPresentInProject() throws Exception {
+    myFixture.configureByFiles("java8/p/" + getTestName(false) + ".java");
+    myFixture.checkHighlighting();
+  }
+
   public void testRawAssignmentToGenerics() throws Exception {
     ModuleRootModificationUtil.addDependency(myJava7Module, myJava3Module);
     final String name = getTestName(false);
index 523d490a7765c572f1edd3ab870c0c06828623cf..78f5bdff569fdd3be093ddec99fca59897385e0a 100644 (file)
@@ -17,9 +17,12 @@ package com.intellij.codeInsight.completion;
 
 import com.intellij.JavaTestUtil;
 import com.intellij.codeInsight.lookup.Lookup;
+import com.intellij.idea.Bombed;
 import com.intellij.testFramework.LightProjectDescriptor;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Calendar;
+
 public class SmartType18CompletionTest extends LightFixtureCompletionTestCase {
   @Override
   protected String getBasePath() {
@@ -183,8 +186,13 @@ public void testConvertToObjectStream() {
     checkResultByFile("/" + getTestName(false) + "-out.java");
   }
 
+  @Bombed(user = "anna/peter", month = Calendar.MAY, day = 4)
   public void testOnlyCompatibleTypes() {
     configureByTestName();
     assertOrderedEquals(myFixture.getLookupElementStrings(), "get2");
   }
+
+  public void testSuggestMapInheritors() { doTest(); }
+
+  public void testUnboundTypeArgs() { doTest(); }
 }
index 9eae0be5dfd4f2f58a30950ab7069aa12f7ffbe9..d95f19993027866c45c75cba035f08465fe66c2a 100644 (file)
@@ -61,4 +61,8 @@ public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase {
   public void testUnreachableAssignments() { doTest(false, false); }
   public void testCompileTypeConstantsAccessibleFromStaticFieldInitializers() { doTest(false, false);}
   public void testInheritUnrelatedConcreteMethodsWithSameSignature() { doTest(false, false);}
+
+  public void testAssignmentFromStringToObject() {
+    doTest(true, false);
+  }
 }
index 57d8965d132e784bda4a5efd211795225482b2ad..2dd5c03a7553cb6c664cce91909fa7f22fb1c713 100644 (file)
  */
 package com.intellij.codeInsight.daemon.lambda;
 
+import com.intellij.codeInsight.ExpectedTypeInfo;
+import com.intellij.codeInsight.ExpectedTypesProvider;
 import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.psi.*;
+import com.intellij.psi.infos.CandidateInfo;
+import com.intellij.psi.infos.MethodCandidateInfo;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.testFramework.IdeaTestUtil;
 import org.jetbrains.annotations.NonNls;
@@ -75,6 +79,35 @@ public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase {
     doTestAllMethodCallExpressions();
   }
 
+  public void testNonCachingFolding() throws Exception {
+    final String filePath = BASE_PATH + "/" + getTestName(false) + ".java";
+    configureByFile(filePath);
+    PsiNewExpression newWithAnonym =
+      PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiNewExpression.class);
+    ExpectedTypeInfo[] types = ExpectedTypesProvider.getExpectedTypes(newWithAnonym, false);
+    assertNotNull(types);
+
+    doTestConfiguredFile(false, false, filePath);
+  }
+
+  public void testRejectCachedTopLevelSessionIfItCorrespondsToTheWrongOverload() throws Exception {
+    final String filePath = BASE_PATH + "/" + getTestName(false) + ".java";
+    configureByFile(filePath);
+    PsiMethodCallExpression methodCall =
+      PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiMethodCallExpression.class);
+    assertNotNull(methodCall);
+    final PsiResolveHelper helper = JavaPsiFacade.getInstance(methodCall.getProject()).getResolveHelper();
+    CandidateInfo[] candidates = helper.getReferencedMethodCandidates(methodCall, false, true);
+    for (CandidateInfo candidate : candidates) {
+      if (candidate instanceof MethodCandidateInfo) {
+        //try to cache top level session
+        candidate.getSubstitutor();
+      }
+    }
+
+    doTestConfiguredFile(false, false, filePath);
+  }
+
   private void doTestCachedUnresolved() {
     configureByFile(BASE_PATH + "/" + getTestName(false) + ".java");
     PsiMethodCallExpression callExpression =
index 229c0d27662268cce5615683c6102a4101560557..56ecc91be0a5b012a4419bd04859afe8dde92370 100644 (file)
@@ -225,6 +225,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
     doTest();
   }
 
+  public void testIgnoreStaticCorrectnessDuringOverloadResolution() throws Exception {
+    doTest(false);
+  }
+
   private void doTest() {
     doTest(true);
   }
diff --git a/java/java-tests/testSrc/com/intellij/roots/libraries/CreateModuleLibraryFromFilesTest.java b/java/java-tests/testSrc/com/intellij/roots/libraries/CreateModuleLibraryFromFilesTest.java
new file mode 100644 (file)
index 0000000..9f26ce1
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * 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.roots.libraries;
+
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.roots.libraries.ui.OrderRoot;
+import com.intellij.openapi.roots.ui.configuration.classpath.CreateModuleLibraryChooser;
+import com.intellij.roots.ModuleRootManagerTestCase;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class CreateModuleLibraryFromFilesTest extends ModuleRootManagerTestCase {
+  private LibraryTable.ModifiableModel myModifiableModel;
+  private ModifiableRootModel myModifiableRootModel;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    myModifiableRootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
+    myModifiableModel = myModifiableRootModel.getModuleLibraryTable().getModifiableModel();
+  }
+
+  public void testSingleJar() {
+    Library library = assertOneElement(createLibraries(new OrderRoot(getJDomJar(), OrderRootType.CLASSES)));
+    assertNull(library.getName());
+    assertSameElements(library.getFiles(OrderRootType.CLASSES), getJDomJar());
+    assertEmpty(library.getFiles(OrderRootType.SOURCES));
+  }
+
+  public void testTwoJars() {
+    List<Library> libraries = createLibraries(new OrderRoot(getJDomJar(), OrderRootType.CLASSES),
+                                              new OrderRoot(getAsmJar(), OrderRootType.CLASSES));
+    assertEquals(2, libraries.size());
+    assertNull(libraries.get(0).getName());
+    assertSameElements(libraries.get(0).getFiles(OrderRootType.CLASSES), getJDomJar());
+    assertNull(libraries.get(1).getName());
+    assertSameElements(libraries.get(1).getFiles(OrderRootType.CLASSES), getAsmJar());
+  }
+
+  public void testJarAndSources() {
+    Library library = assertOneElement(createLibraries(new OrderRoot(getJDomJar(), OrderRootType.CLASSES),
+                                                       new OrderRoot(getJDomSources(), OrderRootType.SOURCES)));
+    assertNull(library.getName());
+    assertSameElements(library.getFiles(OrderRootType.CLASSES), getJDomJar());
+    assertSameElements(library.getFiles(OrderRootType.SOURCES), getJDomSources());
+  }
+
+  public void testJarWithSourcesInside() {
+    Library library = assertOneElement(createLibraries(new OrderRoot(getJDomJar(), OrderRootType.CLASSES),
+                                                       new OrderRoot(getJDomJar(), OrderRootType.SOURCES)));
+    assertNull(library.getName());
+    assertSameElements(library.getFiles(OrderRootType.CLASSES), getJDomJar());
+    assertSameElements(library.getFiles(OrderRootType.SOURCES), getJDomJar());
+  }
+
+  public void testTwoJarAndSources() {
+    List<Library> libraries = createLibraries(new OrderRoot(getJDomJar(), OrderRootType.CLASSES),
+                                              new OrderRoot(getAsmJar(), OrderRootType.CLASSES),
+                                              new OrderRoot(getJDomSources(), OrderRootType.SOURCES));
+    Library library = assertOneElement(libraries);
+    assertNull(library.getName());
+    assertSameElements(library.getFiles(OrderRootType.CLASSES), getJDomJar(), getAsmJar());
+    assertSameElements(library.getFiles(OrderRootType.SOURCES), getJDomSources());
+  }
+
+  public void testTwoJarWithSourcesInside() {
+    List<Library> libraries = createLibraries(new OrderRoot(getJDomJar(), OrderRootType.CLASSES),
+                                              new OrderRoot(getAsmJar(), OrderRootType.CLASSES),
+                                              new OrderRoot(getJDomJar(), OrderRootType.SOURCES),
+                                              new OrderRoot(getAsmJar(), OrderRootType.SOURCES));
+    assertEquals(2, libraries.size());
+    assertNull(libraries.get(0).getName());
+    assertSameElements(libraries.get(0).getFiles(OrderRootType.CLASSES), getJDomJar());
+    assertSameElements(libraries.get(0).getFiles(OrderRootType.SOURCES), getJDomJar());
+    assertNull(libraries.get(1).getName());
+    assertSameElements(libraries.get(1).getFiles(OrderRootType.CLASSES), getAsmJar());
+    assertSameElements(libraries.get(1).getFiles(OrderRootType.SOURCES), getAsmJar());
+  }
+
+  @NotNull
+  private List<Library> createLibraries(OrderRoot... roots) {
+    return CreateModuleLibraryChooser.createLibrariesFromRoots(Arrays.asList(roots), myModifiableModel);
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    try {
+      myModifiableRootModel.dispose();
+    }
+    finally {
+      super.tearDown();
+    }
+  }
+}
index 9e849862e25d4c9bb924e7f5732f4f017cdbef84..b302858af972d92b6448f278ec416d4bdfdad5eb 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.
@@ -24,6 +24,7 @@ import com.intellij.psi.*;
 import com.intellij.util.CommonProcessors;
 import com.intellij.util.Function;
 import com.intellij.util.Processor;
+import com.intellij.util.Processors;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.xml.ConvertContext;
 import com.intellij.util.xml.DomElement;
@@ -115,8 +116,8 @@ public abstract class AbstractMethodResolveConverter<ParentType extends DomEleme
 
   @NotNull
   public Collection<? extends PsiMethod> getVariants(final ConvertContext context) {
-    LinkedHashSet<PsiMethod> methodList = new LinkedHashSet<PsiMethod>();
-    Processor<PsiMethod> processor = CommonProcessors.notNullProcessor(new CommonProcessors.CollectProcessor<PsiMethod>(methodList));
+    Set<PsiMethod> methodList = new LinkedHashSet<PsiMethod>();
+    Processor<PsiMethod> processor = CommonProcessors.notNullProcessor(Processors.cancelableCollectProcessor(methodList));
     processMethods(context, processor, new Function<PsiClass, PsiMethod[]>() {
       public PsiMethod[] fun(final PsiClass s) {
         final List<PsiMethod> list = ContainerUtil.findAll(getVariants(s), new Condition<PsiMethod>() {
index 0afd2d66a48d06ba4a256184acfe75089cc0fe64..5c3060027f96b104aafa588d24bbd3e9876ed126 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.
@@ -192,20 +192,17 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
     final EditorInfo editorInfo = new EditorInfo(document.getText());
 
     final String newFileText = editorInfo.getNewFileText();
-    ApplicationManager.getApplication().runWriteAction(new Runnable() {
-      @Override
-      public void run() {
-        if (!document.getText().equals(newFileText)) {
-          document.setText(newFileText);
-        }
+    ApplicationManager.getApplication().runWriteAction(() -> {
+      if (!document.getText().equals(newFileText)) {
+        document.setText(newFileText);
+      }
 
-        PsiFile file = myPsiManager.findFile(virtualFile);
-        if (myFile == null) myFile = file;
+      PsiFile file = myPsiManager.findFile(virtualFile);
+      if (myFile == null) myFile = file;
 
-        if (myEditor == null) myEditor = editor;
+      if (myEditor == null) myEditor = editor;
 
-        editorInfo.applyToEditor(editor);
-      }
+      editorInfo.applyToEditor(editor);
     });
 
 
@@ -219,60 +216,57 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
     final File toDirIO = createTempDirectory();
     final VirtualFile toDir = getVirtualFile(toDirIO);
 
-    ApplicationManager.getApplication().runWriteAction(new Runnable() {
-      @Override
-      public void run() {
-        try {
-          final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule);
-          final ModifiableRootModel rootModel = rootManager.getModifiableModel();
-          if (clearModelBeforeConfiguring()) {
-            rootModel.clear();
-          }
+    ApplicationManager.getApplication().runWriteAction(() -> {
+      try {
+        final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule);
+        final ModifiableRootModel rootModel = rootManager.getModifiableModel();
+        if (clearModelBeforeConfiguring()) {
+          rootModel.clear();
+        }
 
-          // auxiliary files should be copied first
-          VirtualFile[] reversed = ArrayUtil.reverseArray(vFiles);
-          Map<VirtualFile, EditorInfo> editorInfos;
-          if (rawProjectRoot != null) {
-            final File projectRoot = rawProjectRoot.getCanonicalFile();
-            FileUtil.copyDir(projectRoot, toDirIO);
-            VirtualFile fromDir = getVirtualFile(projectRoot);
-            editorInfos =
-              copyFilesFillingEditorInfos(fromDir, toDir, ContainerUtil.map2Array(reversed, String.class, new Function<VirtualFile, String>() {
-                @Override
-                public String fun(final VirtualFile s) {
-                  return s.getPath().substring(projectRoot.getPath().length());
-                }
-              }));
-
-            toDir.refresh(false, true);
-          }
-          else {
-            editorInfos = new LinkedHashMap<VirtualFile, EditorInfo>();
-            for (final VirtualFile vFile : reversed) {
-              VirtualFile parent = vFile.getParent();
-              assert parent.isDirectory() : parent;
-              editorInfos.putAll(copyFilesFillingEditorInfos(parent, toDir, vFile.getName()));
-            }
+        // auxiliary files should be copied first
+        VirtualFile[] reversed = ArrayUtil.reverseArray(vFiles);
+        Map<VirtualFile, EditorInfo> editorInfos;
+        if (rawProjectRoot != null) {
+          final File projectRoot = rawProjectRoot.getCanonicalFile();
+          FileUtil.copyDir(projectRoot, toDirIO);
+          VirtualFile fromDir = getVirtualFile(projectRoot);
+          editorInfos =
+            copyFilesFillingEditorInfos(fromDir, toDir, ContainerUtil.map2Array(reversed, String.class, new Function<VirtualFile, String>() {
+              @Override
+              public String fun(final VirtualFile s) {
+                return s.getPath().substring(projectRoot.getPath().length());
+              }
+            }));
+
+          toDir.refresh(false, true);
+        }
+        else {
+          editorInfos = new LinkedHashMap<>();
+          for (final VirtualFile vFile : reversed) {
+            VirtualFile parent = vFile.getParent();
+            assert parent.isDirectory() : parent;
+            editorInfos.putAll(copyFilesFillingEditorInfos(parent, toDir, vFile.getName()));
           }
+        }
 
-          boolean sourceRootAdded = false;
-          if (isAddDirToContentRoot()) {
-            final ContentEntry contentEntry = rootModel.addContentEntry(toDir);
-            if (isAddDirToSource()) {
-              sourceRootAdded = true;
-              contentEntry.addSourceFolder(toDir, isAddDirToTests());
-            }
-          }
-          doCommitModel(rootModel);
-          if (sourceRootAdded) {
-            sourceRootAdded(toDir);
+        boolean sourceRootAdded = false;
+        if (isAddDirToContentRoot()) {
+          final ContentEntry contentEntry = rootModel.addContentEntry(toDir);
+          if (isAddDirToSource()) {
+            sourceRootAdded = true;
+            contentEntry.addSourceFolder(toDir, isAddDirToTests());
           }
-
-          openEditorsAndActivateLast(editorInfos);
         }
-        catch (IOException e) {
-          LOG.error(e);
+        doCommitModel(rootModel);
+        if (sourceRootAdded) {
+          sourceRootAdded(toDir);
         }
+
+        openEditorsAndActivateLast(editorInfos);
+      }
+      catch (IOException e) {
+        LOG.error(e);
       }
     });
 
@@ -303,9 +297,9 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
   protected Map<VirtualFile, EditorInfo> copyFilesFillingEditorInfos(@NotNull VirtualFile fromDir,
                                                                      @NotNull VirtualFile toDir,
                                                                      @NotNull String... relativePaths) throws IOException {
-    Map<VirtualFile, EditorInfo> editorInfos = new LinkedHashMap<VirtualFile, EditorInfo>();
+    Map<VirtualFile, EditorInfo> editorInfos = new LinkedHashMap<>();
 
-    List<OutputStream> streamsToClose = new ArrayList<OutputStream>();
+    List<OutputStream> streamsToClose = new ArrayList<>();
 
     for (String relativePath : relativePaths) {
       relativePath = StringUtil.trimStart(relativePath, "/");
@@ -352,21 +346,18 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
 
   @NotNull
   protected final List<Editor> openEditors(@NotNull final Map<VirtualFile, EditorInfo> editorInfos) {
-    return ContainerUtil.map(editorInfos.keySet(), new Function<VirtualFile, Editor>() {
-      @Override
-      public Editor fun(final VirtualFile newVFile) {
-        PsiFile file = myPsiManager.findFile(newVFile);
-        if (myFile == null) myFile = file;
+    return ContainerUtil.map(editorInfos.keySet(), newVFile -> {
+      PsiFile file = myPsiManager.findFile(newVFile);
+      if (myFile == null) myFile = file;
 
-        Editor editor = createEditor(newVFile);
-        if (myEditor == null) myEditor = editor;
+      Editor editor = createEditor(newVFile);
+      if (myEditor == null) myEditor = editor;
 
-        EditorInfo editorInfo = editorInfos.get(newVFile);
-        if (editorInfo != null) {
-          editorInfo.applyToEditor(editor);
-        }
-        return editor;
+      EditorInfo editorInfo = editorInfos.get(newVFile);
+      if (editorInfo != null) {
+        editorInfo.applyToEditor(editor);
       }
+      return editor;
     });
   }
 
index 3b92d873e8cabd3128592f572eba708f38697758..d7572b343209cdf3c1780fce41c12be02352b37d 100644 (file)
@@ -210,6 +210,16 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
   }
 
   public static void doAllTests(QuickFixTestCase testCase) {
+    final File[] files = getBeforeTestFiles(testCase);
+
+    for (File file : files) {
+      final String testName = file.getName().substring(BEFORE_PREFIX.length());
+      doTestFor(testName, testCase);
+    }
+  }
+
+  @NotNull
+  public static File[] getBeforeTestFiles(QuickFixTestCase testCase) {
     assertNotNull("getBasePath() should not return null!", testCase.getBasePath());
 
     final String testDirPath = testCase.getTestDataPath().replace(File.separatorChar, '/') + testCase.getBasePath();
@@ -224,11 +234,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
     if (files == null || files.length == 0) {
       fail("Test files not found in " + testDirPath);
     }
-
-    for (File file : files) {
-      final String testName = file.getName().substring(BEFORE_PREFIX.length());
-      doTestFor(testName, testCase);
-    }
+    return files;
   }
 
   protected void doSingleTest(String fileSuffix) {
index e3bc22b196f094bf6c1225eeb22e13bab13028dc..f3aa67a29a0f893f7fb6e8e7d0dd0709a3d0693f 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.
@@ -24,9 +24,9 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.PsiClass;
 import com.intellij.psi.impl.JavaPsiFacadeEx;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.Arrays;
-import java.util.Comparator;
 
 /**
  * @author mike
@@ -71,12 +71,7 @@ public abstract class IdeaTestCase extends PlatformTestCase {
   public static void initPlatformPrefix() {
   }
 
-  protected static void sortClassesByName(final PsiClass[] classes) {
-    Arrays.sort(classes, new Comparator<PsiClass>() {
-      @Override
-      public int compare(PsiClass o1, PsiClass o2) {
-        return o1.getName().compareTo(o2.getName());
-      }
-    });
+  protected static void sortClassesByName(@NotNull PsiClass[] classes) {
+    Arrays.sort(classes, (o1, o2) -> o1.getName().compareTo(o2.getName()));
   }
 }
index 604d4edec662a6304dd8d59bf7197f7b3e6dafb3..e3cea9296e315413bcdf80c53e7badcbc1edd748 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.
@@ -46,7 +46,7 @@ import java.util.Collection;
 import java.util.List;
 
 public abstract class ModuleTestCase extends IdeaTestCase {
-  protected final Collection<Module> myModulesToDispose = new ArrayList<Module>();
+  protected final Collection<Module> myModulesToDispose = new ArrayList<>();
 
   @Override
   protected void setUp() throws Exception {
@@ -70,7 +70,7 @@ public abstract class ModuleTestCase extends IdeaTestCase {
           }
           catch (Throwable e) {
             if (errors == null) {
-              errors = new SmartList<Throwable>();
+              errors = new SmartList<>();
             }
             errors.add(e);
           }
@@ -99,12 +99,7 @@ public abstract class ModuleTestCase extends IdeaTestCase {
 
   protected Module createModule(final String path, final ModuleType moduleType) {
     Module module = ApplicationManager.getApplication().runWriteAction(
-      new Computable<Module>() {
-        @Override
-        public Module compute() {
-          return ModuleManager.getInstance(myProject).newModule(path, moduleType.getId());
-        }
-      }
+      (Computable<Module>)() -> ModuleManager.getInstance(myProject).newModule(path, moduleType.getId())
     );
 
     myModulesToDispose.add(module);
@@ -118,12 +113,7 @@ public abstract class ModuleTestCase extends IdeaTestCase {
     final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
     Module module;
     try {
-    module = ApplicationManager.getApplication().runWriteAction(new ThrowableComputable<Module, Exception>() {
-      @Override
-      public Module compute() throws Exception {
-        return moduleManager.loadModule(normalizedPath);
-      }
-    });
+      module = ApplicationManager.getApplication().runWriteAction((ThrowableComputable<Module, Exception>)() -> moduleManager.loadModule(normalizedPath));
     }
     catch (Exception e) {
       LOG.error(e);
index 4c2abb08be7439ad24f119ea5eef89930c4a6aad..296d1f5afa503bb8a5e88e8f59f94345bc6e38e8 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.testFramework;
 import com.intellij.openapi.application.Result;
 import com.intellij.openapi.application.WriteAction;
 import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.fileTypes.FileTypeRegistry;
@@ -30,6 +31,7 @@ import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.PsiManagerImpl;
@@ -115,7 +117,7 @@ public abstract class PsiTestCase extends ModuleTestCase {
   protected PsiElement configureByFileWithMarker(String filePath, String marker) throws Exception{
     final VirtualFile vFile = VfsTestUtil.findFileByCaseSensitivePath(filePath);
 
-    String fileText = VfsUtil.loadText(vFile);
+    String fileText = VfsUtilCore.loadText(vFile);
     fileText = StringUtil.convertLineSeparators(fileText);
 
     int offset = fileText.indexOf(marker);
@@ -225,15 +227,15 @@ public abstract class PsiTestCase extends ModuleTestCase {
     return myFile;
   }
 
-  public com.intellij.openapi.editor.Document getDocument(PsiFile file) {
+  public Document getDocument(PsiFile file) {
     return PsiDocumentManager.getInstance(getProject()).getDocument(file);
   }
 
-  public com.intellij.openapi.editor.Document getDocument(VirtualFile file) {
+  public Document getDocument(VirtualFile file) {
     return FileDocumentManager.getInstance().getDocument(file);
   }
 
-  public void commitDocument(com.intellij.openapi.editor.Document document) {
+  public void commitDocument(Document document) {
     PsiDocumentManager.getInstance(getProject()).commitDocument(document);
   }
 }
index 269f2ca322cf252058f812edd428e6aa5b24357a..0e7e003033ec30fcf79c253050ff098ab2a9ccf6 100644 (file)
@@ -26,6 +26,8 @@ public interface GlobalOptions {
   String COMPILE_PARALLEL_MAX_THREADS_OPTION = "compile.parallel.max.threads";
   String REBUILD_ON_DEPENDENCY_CHANGE_OPTION = "rebuild.on.dependency.change";
   String LOG_DIR_OPTION = "jps.log.dir";
+  String FALLBACK_JDK_HOME = "jps.fallback.jdk.home";
+  String FALLBACK_JDK_VERSION = "jps.fallback.jdk.version";
 
   /**
    * Set this property to 'false' to disable default logging. By default the log is written to build.log file in the directory specified by {@link #LOG_DIR_OPTION}.
index bb4ce3509247894788e618b9e18edd8266e876fd..f77eeb2bbfb4ae561793e19bd13a9283c72f5250 100644 (file)
@@ -190,6 +190,13 @@ public class ClasspathBootstrap {
     if (optimizedFileManagerClass != null) {
       cp.add(getResourceFile(optimizedFileManagerClass));  // optimizedFileManager, if applicable
     }
+    else {
+      // last resort
+      final File f = new File(PathManager.getLibPath(), "optimizedFileManager.jar");
+      if (f.exists()) {
+        cp.add(f);
+      }
+    }
 
     try {
       final Class<?> cmdLineWrapper = Class.forName("com.intellij.rt.execution.CommandLineWrapper");
index fe74298cb85790a6d3d34ca82c91e15ad563dcec..142a3d0c923ae1c76ee73b8ce7c979c0cd79e2de 100644 (file)
@@ -31,10 +31,10 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.jps.ModuleChunk;
 import org.jetbrains.jps.ProjectPaths;
+import org.jetbrains.jps.api.GlobalOptions;
 import org.jetbrains.jps.builders.BuildRootIndex;
 import org.jetbrains.jps.builders.DirtyFilesHolder;
 import org.jetbrains.jps.builders.FileProcessor;
-import org.jetbrains.jps.builders.impl.java.JavacCompilerTool;
 import org.jetbrains.jps.builders.java.JavaBuilderExtension;
 import org.jetbrains.jps.builders.java.JavaBuilderUtil;
 import org.jetbrains.jps.builders.java.JavaCompilingTool;
@@ -352,14 +352,27 @@ public class JavaBuilder extends ModuleLevelBuilder {
     }
 
     final Map<File, Set<File>> outs = buildOutputDirectoriesMap(context, chunk);
-    final List<String> options = getCompilationOptions(context, chunk, profile, compilingTool);
-    final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink);
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Compiling chunk [" + chunk.getName() + "] with options: \"" + StringUtil.join(options, " ") + "\"");
-    }
     try {
-      final int chunkSdkVersion = getChunkSdkVersion(chunk);
+      final int targetLanguageLevel = convertToNumber(getLanguageLevel(chunk.getModules().iterator().next()));
+      final boolean shouldForkJavac = shouldForkCompilerProcess(context, targetLanguageLevel);
+
+      // when forking external javac, compilers from SDK 1.6 and higher are supported
+      Pair<String, Integer> forkSdk = null;
+      if (shouldForkJavac) {
+        forkSdk = getForkedJavacSdk(chunk, targetLanguageLevel);
+        if (forkSdk == null) {
+          diagnosticSink.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, "Cannot start javac process for " + chunk.getName() + ": unknown JDK home path.\nPlease check project configuration."));
+          return true;
+        }
+      }
       
+      final int compilerSdkVersion = forkSdk == null? getCompilerSdkVersion(context) : forkSdk.getSecond();
+      
+      final List<String> options = getCompilationOptions(compilerSdkVersion, context, chunk, profile, compilingTool);
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Compiling chunk [" + chunk.getName() + "] with options: \"" + StringUtil.join(options, " ") + "\"");
+      }
+
       Collection<File> _platformCp = calcEffectivePlatformCp(platformCp, options, compilingTool);
       if (_platformCp == null) {
         context.processMessage(
@@ -371,38 +384,50 @@ public class JavaBuilder extends ModuleLevelBuilder {
         return true;
       }
 
-      if (chunkSdkVersion >= 9 && !_platformCp.isEmpty()) {
-        // if chunk's SDK is 9 or higher, there is no way to specify full platform classpath
-        // because platform classes are stored in jimage binary files with unknown format.
-        // Because of this we are clearing platform classpath so that javac will resolve against its own bootclasspath
-        // and prepending additional jars from the JDK configuration to compilation classpath
-        final Collection<File> joined = new ArrayList<File>(_platformCp.size() + classpath.size());
-        joined.addAll(_platformCp);
-        joined.addAll(classpath);
-        classpath = joined;
-        _platformCp = Collections.emptyList();
+      if (!_platformCp.isEmpty()) {
+        final int chunkSdkVersion = getChunkSdkVersion(chunk);
+        if (chunkSdkVersion >= 9) {
+          // if chunk's SDK is 9 or higher, there is no way to specify full platform classpath
+          // because platform classes are stored in jimage binary files with unknown format.
+          // Because of this we are clearing platform classpath so that javac will resolve against its own bootclasspath
+          // and prepending additional jars from the JDK configuration to compilation classpath
+          final Collection<File> joined = new ArrayList<File>(_platformCp.size() + classpath.size());
+          joined.addAll(_platformCp);
+          joined.addAll(classpath);
+          classpath = joined;
+          _platformCp = Collections.emptyList();
+        }
+        else if (shouldUseReleaseOption(context, compilerSdkVersion, chunkSdkVersion, targetLanguageLevel)) {
+          final Collection<File> joined = new ArrayList<File>(classpath.size() + 1);
+          for (File file : _platformCp) {
+            // platform runtime classes will be handled by -release option
+            // include only additional jars from sdk distribution, e.g. tools.jar
+            if (!FileUtil.toSystemIndependentName(file.getAbsolutePath()).contains("/jre/")) {
+              joined.add(file);
+            }
+          }
+          joined.addAll(classpath);
+          classpath = joined;
+          _platformCp = Collections.emptyList();
+        }
       }
 
+      final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink);
       final boolean rc;
-      if (!shouldForkCompilerProcess(context, chunkSdkVersion, convertToNumber(getLanguageLevel(chunk.getModules().iterator().next())))) {
+      if (!shouldForkJavac) {
         rc = JavacMain.compile(
           options, files, classpath, _platformCp, sourcePath, outs, diagnosticSink, classesConsumer, context.getCancelStatus(), compilingTool
         );
       }
       else {
-        // fork external javac, compilers from SDK 1.6+ are supported
-        // todo: If chunkSDK is older than 1.6, we have to ask the user to specify a path to javac6+ to be used for compilation.
-        // todo: Add setting in compiler configuration for this.
-        final String sdkHome = getChunkSdkHome(chunk);
-        if (sdkHome == null) {
-          diagnosticSink.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, "Cannot start javac process for " + chunk.getName() + ": unknown JDK home path.\nPlease check project configuration."));
-          return true;
-        }
-
+        context.processMessage(new CompilerMessage("", BuildMessage.Kind.INFO, "Using javac "+ forkSdk.getSecond() + " to compile [" + chunk.getPresentableShortName() + "]"));
         final List<String> vmOptions = getCompilationVMOptions(context, compilingTool);
         final ExternalJavacManager server = ensureJavacServerStarted(context);
         rc = server.forkJavac(
-          sdkHome, getExternalJavacHeapSize(context), vmOptions, options, _platformCp, classpath, sourcePath, files, outs, diagnosticSink, classesConsumer, compilingTool, context.getCancelStatus()
+          forkSdk.getFirst(), 
+          getExternalJavacHeapSize(context), 
+          vmOptions, options, _platformCp, classpath, sourcePath, 
+          files, outs, diagnosticSink, classesConsumer, compilingTool, context.getCancelStatus()
         );
       }
       return rc;
@@ -451,32 +476,42 @@ public class JavaBuilder extends ModuleLevelBuilder {
     return null;
   }
 
-  private static boolean shouldForkCompilerProcess(CompileContext context, final int chunkSdkVersion, int chunkLanguageLevel) {
+  private static boolean shouldUseReleaseOption(CompileContext context, int compilerVersion, int chunkSdkVersion, int targetLanguageLevel) {
+    // -release option makes sense for javac only and is supported in java9+ and higher
+    if (compilerVersion >= 9 && chunkSdkVersion > 0 && targetLanguageLevel > 0 && isJavac(COMPILING_TOOL.get(context))) {
+      if (chunkSdkVersion < 9) {
+        // todo: this 'if' should be removed, if javac9+ drops support for '-source' and '-target' options
+        return targetLanguageLevel == chunkSdkVersion;
+      }
+      // chunkSdkVersion >= 9, so we have no rt.jar anymore and '-release' is the only cross-compilation option available
+      return true;
+    }
+    return false;
+  }
+
+  private static boolean shouldForkCompilerProcess(CompileContext context, int chunkLanguageLevel) {
+    if (!isJavac(COMPILING_TOOL.get(context))) {
+      return false;
+    }
     final int compilerSdkVersion = getCompilerSdkVersion(context);
-    if (compilerSdkVersion < 9 || chunkSdkVersion < 0) {
+    if (compilerSdkVersion < 9 || chunkLanguageLevel <= 0) {
       // javac up to version 9 supports all previous releases
       // or: was not able to determine jdk version, so assuming in-process compiler
       return false;
     }
-    if (chunkSdkVersion >= 9 && compilerSdkVersion != chunkSdkVersion) {
-      // For these SDK versions libraries are stored in jimage files with unknown format and currently
-      // there is no way to specify full platform classpath for cross-compilation purposes.
-      // We have for fork compiler process with corresponding SDK runtime to ensure that compiler resolves platform classes 
-      // against the SDK version specified for the given chunk.
-      // todo: if chunkSdkVersion complies to "one plus three back" rule, and "-release" option is supported, return false
-      return true;
-    }
-
     // compilerSdkVersion is 9+ here, so applying JEP 182 "Retiring javac 'one plus three back'" policy
-    final int requestedTargetPlatformVersion = chunkLanguageLevel > 0 ? chunkLanguageLevel : Math.min(chunkLanguageLevel, chunkSdkVersion);
-    return Math.abs(compilerSdkVersion - requestedTargetPlatformVersion) > 3;
+    return Math.abs(compilerSdkVersion - chunkLanguageLevel) > 3;
+  }
+  
+  private static boolean isJavac(final JavaCompilingTool compilingTool) {
+    return compilingTool != null && (compilingTool.getId() == JavaCompilers.JAVAC_ID || compilingTool.getId() == JavaCompilers.JAVAC_API_ID);
   }
 
   // If platformCp of the build process is the same as the target plafform, do not specify platformCp explicitly
   // this will allow javac to resolve against ct.sym file, which is required for the "compilation profiles" feature
   @Nullable
   private static Collection<File> calcEffectivePlatformCp(Collection<File> platformCp, List<String> options, JavaCompilingTool compilingTool) {
-    if (ourDefaultRtJar == null || !(compilingTool instanceof JavacCompilerTool)) {
+    if (ourDefaultRtJar == null || !isJavac(compilingTool)) {
       return platformCp;
     }
     boolean profileFeatureRequested = false;
@@ -622,10 +657,9 @@ public class JavaBuilder extends ModuleLevelBuilder {
     return cached;
   }
 
-  private static List<String> getCompilationOptions(CompileContext context,
-                                                    ModuleChunk chunk,
-                                                    @Nullable ProcessorConfigProfile profile,
-                                                    @NotNull JavaCompilingTool compilingTool) {
+  private static List<String> getCompilationOptions(
+    final int compilerSdkVersion, CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile, @NotNull JavaCompilingTool compilingTool) {
+    
     List<String> cached = JAVAC_OPTIONS.get(context);
     if (cached == null) {
       loadCommonJavacOptions(context, compilingTool);
@@ -648,11 +682,15 @@ public class JavaBuilder extends ModuleLevelBuilder {
     else {
       options.addAll(cached);
     }
-    addCompilationOptions(options, context, chunk, profile);
+    addCompilationOptions(compilerSdkVersion, options, context, chunk, profile);
     return options;
   }
 
   public static void addCompilationOptions(List<String> options, CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) {
+    addCompilationOptions(getCompilerSdkVersion(context), options, context, chunk, profile);
+  }
+  
+  public static void addCompilationOptions(final int compilerSdkVersion, List<String> options, CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) {
     if (!isEncodingSet(options)) {
       final CompilerEncodingConfiguration config = context.getProjectDescriptor().getEncodingConfiguration();
       final String encoding = config.getPreferredModuleChunkEncoding(chunk);
@@ -670,16 +708,60 @@ public class JavaBuilder extends ModuleLevelBuilder {
       }
     }
 
-    final String langLevel = getLanguageLevel(chunk.getModules().iterator().next());
-    if (!StringUtil.isEmpty(langLevel)) {
-      options.add("-source");
-      options.add(langLevel);
+    addCrossCompilationOptions(compilerSdkVersion, options, context, chunk);
+
+    if (profile != null && profile.isEnabled()) {
+      // configuring annotation processing
+      if (!profile.isObtainProcessorsFromClasspath()) {
+        final String processorsPath = profile.getProcessorPath();
+        options.add("-processorpath");
+        options.add(FileUtil.toSystemDependentName(processorsPath.trim()));
+      }
+
+      final Set<String> processors = profile.getProcessors();
+      if (!processors.isEmpty()) {
+        options.add("-processor");
+        options.add(StringUtil.join(processors, ","));
+      }
+
+      for (Map.Entry<String, String> optionEntry : profile.getProcessorOptions().entrySet()) {
+        options.add("-A" + optionEntry.getKey() + "=" + optionEntry.getValue());
+      }
+
+      final File srcOutput = ProjectPaths.getAnnotationProcessorGeneratedSourcesOutputDir(
+        chunk.getModules().iterator().next(), chunk.containsTests(), profile
+      );
+      if (srcOutput != null) {
+        srcOutput.mkdirs();
+        options.add("-s");
+        options.add(srcOutput.getPath());
+      }
+    }
+    else {
+      options.add("-proc:none");
     }
+  }
 
+  private static void addCrossCompilationOptions(final int compilerSdkVersion, final List<String> options, final CompileContext context, final ModuleChunk chunk) {
     final JpsJavaCompilerConfiguration compilerConfiguration = JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(
       context.getProjectDescriptor().getProject()
     );
 
+    final String langLevel = getLanguageLevel(chunk.getModules().iterator().next());
+    final int chunkSdkVersion = getChunkSdkVersion(chunk);
+
+    final int targetLanguageLevel = convertToNumber(langLevel);
+    if (shouldUseReleaseOption(context, compilerSdkVersion, chunkSdkVersion, targetLanguageLevel)) {
+      options.add("-release");
+      options.add(String.valueOf(targetLanguageLevel));
+      return;
+    }
+    // using older -source, -target and -bootclasspath options
+    if (!StringUtil.isEmpty(langLevel)) {
+      options.add("-source");
+      options.add(langLevel);
+    }
+
     String bytecodeTarget = null;
     for (JpsModule module : chunk.getModules()) {
       final String moduleTarget = compilerConfiguration.getByteCodeTargetLevel(module.getName());
@@ -695,7 +777,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
         }
       }
     }
-    
+
     if (bytecodeTarget == null) {
       if (!StringUtil.isEmpty(langLevel)) {
         // according to IDEA rule: if not specified explicitly, set target to be the same as source language level
@@ -708,9 +790,6 @@ public class JavaBuilder extends ModuleLevelBuilder {
       }
     }
 
-    final int compilerSdkVersion = getCompilerSdkVersion(context);
-    final int chunkSdkVersion = getChunkSdkVersion(chunk);
-    
     if (bytecodeTarget != null) {
       options.add("-target");
       if (chunkSdkVersion > 0 && compilerSdkVersion > chunkSdkVersion) { 
@@ -735,37 +814,6 @@ public class JavaBuilder extends ModuleLevelBuilder {
         options.add("1." + chunkSdkVersion);
       }
     }
-
-    if (profile != null && profile.isEnabled()) {
-      // configuring annotation processing
-      if (!profile.isObtainProcessorsFromClasspath()) {
-        final String processorsPath = profile.getProcessorPath();
-        options.add("-processorpath");
-        options.add(FileUtil.toSystemDependentName(processorsPath.trim()));
-      }
-
-      final Set<String> processors = profile.getProcessors();
-      if (!processors.isEmpty()) {
-        options.add("-processor");
-        options.add(StringUtil.join(processors, ","));
-      }
-
-      for (Map.Entry<String, String> optionEntry : profile.getProcessorOptions().entrySet()) {
-        options.add("-A" + optionEntry.getKey() + "=" + optionEntry.getValue());
-      }
-
-      final File srcOutput = ProjectPaths.getAnnotationProcessorGeneratedSourcesOutputDir(
-        chunk.getModules().iterator().next(), chunk.containsTests(), profile
-      );
-      if (srcOutput != null) {
-        srcOutput.mkdirs();
-        options.add("-s");
-        options.add(srcOutput.getPath());
-      }
-    }
-    else {
-      options.add("-proc:none");
-    }
   }
 
   private static String getLanguageLevel(JpsModule module) {
@@ -806,14 +854,36 @@ public class JavaBuilder extends ModuleLevelBuilder {
     return chunkSdkVersion;
   }
 
-  private static String getChunkSdkHome(ModuleChunk chunk) {
+  @Nullable
+  private static Pair<String, Integer> getForkedJavacSdk(ModuleChunk chunk, int targetLanguageLevel) {
     for (JpsModule module : chunk.getModules()) {
       final JpsSdk<JpsDummyElement> sdk = module.getSdk(JpsJavaSdkType.INSTANCE);
       if (sdk != null) {
-        return sdk.getHomePath();
+        final int version = convertToNumber(sdk.getVersionString());
+        if (version >= 6) {
+          if (version >= 9 && Math.abs(version - targetLanguageLevel) > 3) {
+            continue; // current javac compiler does not support required language level
+          }
+          return Pair.create(sdk.getHomePath(), version);
+        }
       }
     }
-    return null;
+    final String fallbackJdkHome = System.getProperty(GlobalOptions.FALLBACK_JDK_HOME, null);
+    if (fallbackJdkHome == null) {
+      LOG.info("Fallback JDK is not specified. (See " + GlobalOptions.FALLBACK_JDK_HOME + " option)");
+      return null;
+    }
+    final String fallbackJdkVersion = System.getProperty(GlobalOptions.FALLBACK_JDK_VERSION, null);
+    if (fallbackJdkVersion == null) {
+      LOG.info("Fallback JDK version is not specified. (See " + GlobalOptions.FALLBACK_JDK_VERSION + " option)");
+      return null;
+    }
+    final int fallbackVersion = convertToNumber(fallbackJdkVersion);
+    if (fallbackVersion < 6) {
+      LOG.info("Version string for fallback JDK is '" + fallbackJdkVersion + "' (recognized as version '" + fallbackJdkVersion + "'). At least version 6 is required.");
+      return null;
+    }
+    return Pair.create(fallbackJdkHome, fallbackVersion); 
   }
 
   private static void loadCommonJavacOptions(@NotNull CompileContext context, @NotNull JavaCompilingTool compilingTool) {
index c3867328a8757e34d89543e2ae905959cb3324e9..e47e78dac1839affe099a560a792f55896f44fa2 100644 (file)
@@ -25,6 +25,7 @@ import javax.tools.*;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.lang.reflect.Method;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -336,4 +337,21 @@ class JavacFileManager extends ForwardingJavaFileManager<StandardJavaFileManager
   public Context getContext() {
     return myContext;
   }
+
+  private static Map<Method, Boolean> ourImplStatus = Collections.synchronizedMap(new HashMap<Method, Boolean>());
+
+  JavaFileManager getApiCallHandler(Method method) {
+    Boolean isImplemented = ourImplStatus.get(method);
+    if (isImplemented == null) {
+      try {
+        JavacFileManager.class.getDeclaredMethod(method.getName(), method.getParameterTypes());
+        isImplemented = Boolean.TRUE;
+      }
+      catch (NoSuchMethodException e) {
+        isImplemented = Boolean.FALSE;
+      }
+      ourImplStatus.put(method, isImplemented);
+    }
+    return isImplemented? this : getStdManager();
+  }
 }
index c880924ea2326a01eecf10bec393e08fc7b832f5..840403e2d0a06401d3e030f33cb1f16121775e61 100644 (file)
@@ -30,9 +30,7 @@ import org.jetbrains.jps.incremental.LineOutputWriter;
 import javax.tools.*;
 import java.io.File;
 import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
+import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -155,7 +153,7 @@ public class JavacMain {
       };
 
       final JavaCompiler.CompilationTask task = compiler.getTask(
-        out, fileManager, diagnosticConsumer, _options, null, fileManager.getJavaFileObjectsFromFiles(sources)
+        out, wrapWithCallDispatcher(fileManager), diagnosticConsumer, _options, null, fileManager.getJavaFileObjectsFromFiles(sources)
       );
       compilingTool.prepareCompilationTask(task, _options);
 
@@ -191,6 +189,19 @@ public class JavacMain {
     return false;
   }
 
+  // methods added to newer versions of StandardJavaFileManager interfaces have default implementations that
+  // do not delegate to corresponding methods of FileManager's base implementation
+  // this proxy object makes sure the calls, not implemented in our file manager, are dispatched further to the base file manager implementation
+  private static StandardJavaFileManager wrapWithCallDispatcher(final JavacFileManager fileManager) {
+    //return fileManager;
+    return (StandardJavaFileManager)Proxy.newProxyInstance(fileManager.getClass().getClassLoader(), new Class[]{StandardJavaFileManager.class}, new InvocationHandler() {
+      @Override
+      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        return method.invoke(fileManager.getApiCallHandler(method), args);
+      }
+    });
+  }
+
   private static boolean canUseOptimizedFileManager(JavaCompilingTool compilingTool) {
     // since java 9 internal API's used by the optimizedFileManager have changed
     return compilingTool instanceof JavacCompilerTool && !SystemInfo.isJavaVersionAtLeast("1.9");
index e5bff0348bf050b1e7fc1bc1651354f33365bdc5..b5a96720afa96ace9b6c8f3bc772260d3ad2d25d 100644 (file)
@@ -7,7 +7,7 @@ import com.intellij.openapi.vfs.VfsUtilCore
 import com.intellij.openapi.vfs.VirtualFile
 import java.io.File
 
-class PathInfo(val ioFile: File?, val file: VirtualFile?, val root: VirtualFile, moduleName: String? = null, val isLibrary: Boolean = false) {
+class PathInfo(val ioFile: File?, val file: VirtualFile?, val root: VirtualFile, moduleName: String? = null, val isLibrary: Boolean = false, val isRootNameOptionalInPath: Boolean = false) {
   var moduleName: String? = moduleName
     set
 
@@ -15,6 +15,14 @@ class PathInfo(val ioFile: File?, val file: VirtualFile?, val root: VirtualFile,
    * URL path.
    */
   val path: String by lazy {
+    buildPath(true)
+  }
+
+  val rootLessPathIfPossible: String? by lazy {
+    if (isRootNameOptionalInPath) buildPath(false) else null
+  }
+
+  private fun buildPath(useRootName: Boolean): String {
     val builder = StringBuilder()
     if (moduleName != null) {
       builder.append(moduleName).append('/')
@@ -24,13 +32,14 @@ class PathInfo(val ioFile: File?, val file: VirtualFile?, val root: VirtualFile,
       builder.append(root.name).append('/')
     }
 
+    val relativeTo = if (useRootName) root else root.parent ?: root
     if (file == null) {
-      builder.append(FileUtilRt.getRelativePath(root.path, FileUtilRt.toSystemIndependentName(ioFile!!.path), '/'))
+      builder.append(FileUtilRt.getRelativePath(relativeTo.path, FileUtilRt.toSystemIndependentName(ioFile!!.path), '/'))
     }
     else {
-      builder.append(VfsUtilCore.getRelativePath(file, root, '/'))
+      builder.append(VfsUtilCore.getRelativePath(file, relativeTo, '/'))
     }
-    builder.toString()
+    return builder.toString()
   }
 
   /**
index 6c6e54de384bc4e6961ff590a41564bca2cb0b6c..1fa74d36be451589919320a42820f87e0e0e140a 100644 (file)
@@ -26,6 +26,7 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.impl.http.HttpVirtualFile;
 import com.intellij.psi.FileViewProvider;
 import com.intellij.testFramework.LightVirtualFile;
+import com.intellij.util.SmartList;
 import com.intellij.util.Url;
 import com.intellij.util.Urls;
 import com.intellij.util.containers.ContainerUtil;
@@ -33,7 +34,6 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.ide.BuiltInServerManager;
 
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -44,18 +44,32 @@ public class BuiltInWebBrowserUrlProvider extends WebBrowserUrlProvider implemen
       return Collections.emptyList();
     }
 
-    String path = WebServerPathToFileManager.getInstance(project).getPath(file);
-    if (path == null) {
+    PathInfo info = WebServerPathToFileManager.getInstance(project).getPathInfo(file);
+    if (info == null) {
       return Collections.emptyList();
     }
 
     int effectiveBuiltInServerPort = BuiltInServerOptions.getInstance().getEffectiveBuiltInServerPort();
-    Url url = Urls.newHttpUrl(currentAuthority == null ? "localhost:" + effectiveBuiltInServerPort : currentAuthority, '/' + project.getName() + '/' + path);
+    String path = info.getPath();
+
+    String authority = currentAuthority == null ? "localhost:" + effectiveBuiltInServerPort : currentAuthority;
+    List<Url> urls = new SmartList<>(Urls.newHttpUrl(authority, '/' + project.getName() + '/' + path));
+
+    String path2 = info.getRootLessPathIfPossible();
+    if (path2 != null) {
+      urls.add(Urls.newHttpUrl(authority, '/' + project.getName() + '/' + path2));
+    }
+
     int defaultPort = BuiltInServerManager.getInstance().getPort();
-    if (currentAuthority != null || defaultPort == effectiveBuiltInServerPort) {
-      return Collections.singletonList(url);
+    if (currentAuthority == null && defaultPort != effectiveBuiltInServerPort) {
+      String defaultAuthority = "localhost:" + defaultPort;
+      urls.add(Urls.newHttpUrl(defaultAuthority, '/' + project.getName() + '/' + path));
+      if (path2 != null) {
+        urls.add(Urls.newHttpUrl(defaultAuthority, '/' + project.getName() + '/' + path2));
+      }
     }
-    return Arrays.asList(url, Urls.newHttpUrl("localhost:" + defaultPort, '/' + project.getName() + '/' + path));
+
+    return urls;
   }
 
   public static boolean compareAuthority(@Nullable String currentAuthority) {
index ced4462721fa446cee12ce662b06cace38f0aa7a..feb29b80c168805cd026e08a3aaf7fba7fb533f3 100644 (file)
@@ -83,8 +83,10 @@ private class DefaultWebServerRootsProvider : WebServerRootsProvider() {
       }
 
       var root = info.sourceRoot
+      val isRootNameOptionalInPath: Boolean
       val isLibrary: Boolean
       if (root == null) {
+        isRootNameOptionalInPath = false
         root = info.contentRoot
         if (root == null) {
           root = info.libraryClassRoot
@@ -98,6 +100,7 @@ private class DefaultWebServerRootsProvider : WebServerRootsProvider() {
       }
       else {
         isLibrary = info.isInLibrarySource
+        isRootNameOptionalInPath = !isLibrary
       }
 
       var module = info.module
@@ -110,7 +113,7 @@ private class DefaultWebServerRootsProvider : WebServerRootsProvider() {
         }
       }
 
-      return PathInfo(null, file, root!!, getModuleNameQualifier(project, module), isLibrary)
+      return PathInfo(null, file, root!!, getModuleNameQualifier(project, module), isLibrary, isRootNameOptionalInPath = isRootNameOptionalInPath)
     }
   }
 }
index 43c402102c9527819cd708ee54ecdfcec5fc2241..6635066d66827a81c80e928c79b58123d757547e 100644 (file)
@@ -5,8 +5,8 @@ import com.intellij.ProjectTopics
 import com.intellij.openapi.application.Application
 import com.intellij.openapi.components.ServiceManager
 import com.intellij.openapi.project.Project
-import com.intellij.openapi.roots.ModuleRootAdapter
 import com.intellij.openapi.roots.ModuleRootEvent
+import com.intellij.openapi.roots.ModuleRootListener
 import com.intellij.openapi.vfs.LocalFileSystem
 import com.intellij.openapi.vfs.VirtualFile
 import com.intellij.openapi.vfs.VirtualFileManager
@@ -45,7 +45,7 @@ class WebServerPathToFileManager(application: Application, private val project:
         }
       }
     })
-    project.messageBus.connect().subscribe(ProjectTopics.PROJECT_ROOTS, object : ModuleRootAdapter() {
+    project.messageBus.connect().subscribe(ProjectTopics.PROJECT_ROOTS, object : ModuleRootListener {
       override fun rootsChanged(event: ModuleRootEvent) {
         clearCache()
       }
@@ -79,7 +79,7 @@ class WebServerPathToFileManager(application: Application, private val project:
 
   fun getPath(file: VirtualFile) = getPathInfo(file)?.path
 
-  private fun getPathInfo(child: VirtualFile): PathInfo? {
+  fun getPathInfo(child: VirtualFile): PathInfo? {
     var result = virtualFileToPathInfo.getIfPresent(child)
     if (result == null) {
       result = WebServerRootsProvider.EP_NAME.extensions.computeOrNull { it.getPathInfo(child, project) }
@@ -92,8 +92,8 @@ class WebServerPathToFileManager(application: Application, private val project:
 
   internal fun doFindByRelativePath(path: String): PathInfo? {
     val result = WebServerRootsProvider.EP_NAME.extensions.computeOrNull { it.resolve(path, project) } ?: return null
-    if (result.file != null) {
-      virtualFileToPathInfo.put(result.file, result)
+    result.file?.let {
+      virtualFileToPathInfo.put(it, result)
     }
     return result
   }
index 3cc4c4cdedfd2cfe06b364f12c713cfbbf62396d..27311648d09648fdc6964decb58482de98a18135 100644 (file)
@@ -1,41 +1,51 @@
 package com.intellij.configurationStore
 
-import com.intellij.util.containers.isNullOrEmpty
 import org.jdom.*
+import java.io.DataInputStream
 import java.io.DataOutputStream
+import java.io.InputStream
+import java.io.OutputStream
 
 private enum class TypeMarker {
   ELEMENT, CDATA, TEXT, ELEMENT_END
 }
 
-fun output(doc: Document, out: DataOutputStream) {
-  val content = doc.content
-  val size = content.size
-  for (i in 0..size - 1) {
-    val obj = content[i]
-    when (obj) {
-      is Element -> printElement(out, doc.rootElement)
-    }
-  }
+fun writeElement(element: Element, out: OutputStream) = writeElement(element, DataOutputStream(out))
 
-  out.flush()
+fun writeElement(element: Element, out: DataOutputStream) {
+  writeElement(out, element)
 }
 
-fun writeElement(element: Element, out: DataOutputStream) {
-  printElement(out, element)
-  out.flush()
+fun readElement(input: InputStream) = readElement(DataInputStream(input))
+
+fun readElement(input: DataInputStream): Element {
+  val element = Element(input.readUTF())
+  readAttributes(element, input)
+  readContent(element, input)
+  return element
+}
+
+private fun readContent(element: Element, input: DataInputStream) {
+  while (true) {
+    when (input.read()) {
+      TypeMarker.ELEMENT.ordinal -> element.addContent(readElement(input))
+      TypeMarker.TEXT.ordinal -> element.addContent(Text(input.readUTF()))
+      TypeMarker.CDATA.ordinal -> element.addContent(CDATA(input.readUTF()))
+      TypeMarker.ELEMENT_END.ordinal -> return
+    }
+  }
 }
 
-private fun printElement(out: DataOutputStream, element: Element) {
-  out.writeByte(TypeMarker.ELEMENT.ordinal)
+private fun writeElement(out: DataOutputStream, element: Element) {
   out.writeUTF(element.name)
 
-  val content = element.content
-  printAttributes(out, element.attributes)
+  writeAttributes(out, element.attributes)
 
+  val content = element.content
   for (item in content) {
     if (item is Element) {
-      printElement(out, item)
+      out.writeByte(TypeMarker.ELEMENT.ordinal)
+      writeElement(out, item)
     }
     else if (item is Text) {
       if (!isAllWhitespace(item)) {
@@ -51,19 +61,28 @@ private fun printElement(out: DataOutputStream, element: Element) {
   out.writeByte(TypeMarker.ELEMENT_END.ordinal)
 }
 
-private fun printAttributes(out: DataOutputStream, attributes: List<Attribute>?) {
-  if (attributes.isNullOrEmpty()) {
-    val size = attributes?.size ?: 0
-    if (size > 255) {
-      throw UnsupportedOperationException("attributes size > 255")
-    }
-    out.writeByte(size)
+private fun writeAttributes(out: DataOutputStream, attributes: List<Attribute>?) {
+  val size = attributes?.size ?: 0
+  out.write(size)
+  if (size == 0) {
     return
   }
 
-  for (attribute in attributes!!) {
-    out.writeUTF(attribute.name)
-    out.writeUTF(attribute.value)
+  if (size > 255) {
+    throw UnsupportedOperationException("attributes size > 255")
+  }
+  else {
+    for (attribute in attributes!!) {
+      out.writeUTF(attribute.name)
+      out.writeUTF(attribute.value)
+    }
+  }
+}
+
+private fun readAttributes(element: Element, input: DataInputStream) {
+  val size = input.readUnsignedByte()
+  for (i in 0..size - 1) {
+    element.setAttribute(Attribute(input.readUTF(), input.readUTF()))
   }
 }
 
index bde696b73914cbba8d6207f543361bc2103d9724..ce22668794644d8b635d729c56e0554c573e1ca8 100644 (file)
@@ -34,7 +34,6 @@ import com.intellij.openapi.util.InvalidDataException
 import com.intellij.openapi.util.JDOMExternalizable
 import com.intellij.openapi.util.JDOMUtil
 import com.intellij.openapi.util.NamedJDOMExternalizable
-import com.intellij.openapi.util.registry.Registry
 import com.intellij.openapi.vfs.VirtualFile
 import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
 import com.intellij.ui.AppUIUtil
@@ -126,7 +125,7 @@ abstract class ComponentStoreImpl : IComponentStore {
       var timeLog = if (LOG.isDebugEnabled) StringBuilder(timeLogPrefix) else null
       for (name in names) {
         val start = if (timeLog == null) 0 else System.currentTimeMillis()
-        commitComponent(externalizationSession, components[name]!!, name)
+        commitComponent(externalizationSession, components.get(name)!!, name)
         timeLog?.let {
           val duration = System.currentTimeMillis() - start
           if (duration > 10) {
@@ -268,7 +267,8 @@ abstract class ComponentStoreImpl : IComponentStore {
         }
 
         val storage = storageManager.getStateStorage(storageSpec)
-        var stateGetter = if (isUseLoadedStateAsExisting(storage) && (ApplicationManager.getApplication().isUnitTestMode || Registry.`is`("use.loaded.state.as.existing", false))) {
+        // todo "ProjectModuleManager" investigate why after loadState we get empty state on getState, test CMakeWorkspaceContentRootsTest
+        var stateGetter = if (isUseLoadedStateAsExisting(storage) && name != "ProjectModuleManager") {
           (storage as? StorageBaseEx<*>)?.createGetSession(component, name, stateClass)
         }
         else {
index 254085ea9bdd0befdd30f53785a5c42c21ddc1bb..6d8171a0a1b76d6624d3712629bc70ceb88a98c3 100644 (file)
@@ -18,56 +18,26 @@ package com.intellij.configurationStore
 import com.intellij.openapi.application.ApplicationManager
 import com.intellij.openapi.util.JDOMUtil
 import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
-import com.intellij.openapi.util.registry.Registry
 import com.intellij.openapi.util.text.StringUtil
-import com.intellij.openapi.vfs.CharsetToolkit
 import com.intellij.util.ArrayUtil
 import com.intellij.util.SystemProperties
-import com.intellij.util.loadElement
 import gnu.trove.THashMap
 import org.iq80.snappy.SnappyInputStream
 import org.iq80.snappy.SnappyOutputStream
 import org.jdom.Element
-import org.jdom.output.Format
 import java.io.ByteArrayInputStream
-import java.io.DataOutputStream
-import java.io.OutputStreamWriter
 import java.util.*
 import java.util.concurrent.atomic.AtomicReferenceArray
 
-private val XML_FORMAT = Format.getRawFormat().setTextMode(Format.TextMode.TRIM).setOmitEncoding(true).setOmitDeclaration(true)
-
-// must be mot modified during app life
-private val isUseNewSaving by lazy { ApplicationManager.getApplication().isUnitTestMode || Registry.`is`("configuration.saving.v3", false) }
-
-private fun archiveState(state: Element): BufferExposingByteArrayOutputStream {
-  if (isUseNewSaving) {
-    return archiveStateBinary(state)
-  }
-  else {
-    return archiveStateXml(state)
-  }
-}
-
-fun archiveStateBinary(state: Element): BufferExposingByteArrayOutputStream {
+fun archiveState(state: Element): BufferExposingByteArrayOutputStream {
   val byteOut = BufferExposingByteArrayOutputStream()
-  DataOutputStream(SnappyOutputStream(byteOut)).use {
+  SnappyOutputStream(byteOut).use {
     writeElement(state, it)
   }
   return byteOut
 }
 
-fun archiveStateXml(state: Element): BufferExposingByteArrayOutputStream {
-  val byteOut = BufferExposingByteArrayOutputStream()
-  OutputStreamWriter(SnappyOutputStream(byteOut), CharsetToolkit.UTF8_CHARSET).use {
-    val xmlOutputter = JDOMUtil.MyXMLOutputter()
-    xmlOutputter.format = XML_FORMAT
-    xmlOutputter.output(state, it)
-  }
-  return byteOut
-}
-
-private fun unarchiveState(state: ByteArray) = loadElement(SnappyInputStream(ByteArrayInputStream(state)).reader())
+private fun unarchiveState(state: ByteArray) = SnappyInputStream(ByteArrayInputStream(state)).use { readElement(it) }
 
 fun getNewByteIfDiffers(key: String, newState: Any, oldState: ByteArray): ByteArray? {
   val newBytes: ByteArray
@@ -86,15 +56,16 @@ fun getNewByteIfDiffers(key: String, newState: Any, oldState: ByteArray): ByteAr
     }
   }
 
-  if (SystemProperties.getBooleanProperty("idea.log.changed.components", false)) {
+  val logChangedComponents = SystemProperties.getBooleanProperty("idea.log.changed.components", false)
+  if (ApplicationManager.getApplication().isUnitTestMode || logChangedComponents ) {
     fun stateToString(state: Any) = JDOMUtil.writeParent(state as? Element ?: unarchiveState(state as ByteArray), "\n")
 
     val before = stateToString(oldState)
     val after = stateToString(newState)
     if (before == after) {
-      LOG.info("Serialization error: serialized are different, but unserialized are equal")
+      throw IllegalStateException("$key serialization error - serialized are different, but unserialized are equal")
     }
-    else {
+    else if (logChangedComponents) {
       LOG.info("$key ${StringUtil.repeat("=", 80 - key.length)}\nBefore:\n$before\nAfter:\n$after")
     }
   }
@@ -203,9 +174,7 @@ class StateMap private constructor(private val names: Array<String>, private val
       return
     }
 
-    val currentState = states.get(index)
-    LOG.assertTrue(currentState is Element, currentState?.let { it.javaClass.name } ?: "null")
-    states.set(index, if (state == null) null else archiveState(state).toByteArray())
+    states.set(index, state?.let { archiveState(state).toByteArray() })
   }
 }
 
index 7597be807f0e8b10626d48b78fa2488b7d5c945f..d0372b28055a0a7d3c89794d653da8ac161d49ab 100644 (file)
@@ -337,7 +337,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
   fun collapseMacros(path: String): String {
     var result = path
     for ((key, value) in macros) {
-      result = StringUtil.replace(result, value, key)
+      result = result.replace(value, key)
     }
     return normalizeFileSpec(result)
   }
@@ -364,7 +364,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
     }
 
     private fun getExternalizationSession(storage: StateStorage): StateStorage.ExternalizationSession? {
-      var session = sessions[storage]
+      var session = sessions.get(storage)
       if (session == null) {
         session = storage.startExternalization()
         if (session != null) {
@@ -393,7 +393,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
           saveSessions.add(saveSession)
         }
       }
-      return ContainerUtil.notNullize(saveSessions)
+      return saveSessions ?: emptyList()
     }
   }
 
index bdc7ce320f0370589b26a37ca0357cf9230e3ab6..44853deea182d37c9daaa13c17b915b886d01781 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.configurationStore
 
 import com.intellij.openapi.components.PersistentStateComponent
 import com.intellij.openapi.components.impl.stores.StateStorageBase
+import com.intellij.openapi.util.JDOMUtil
 import org.jdom.Element
 
 abstract class StorageBaseEx<T : Any> : StateStorageBase<T>() {
@@ -65,7 +66,9 @@ class StateGetter<S : Any, T : Any>(private val component: PersistentStateCompon
       serializedState
     }
     else {
-      serializeState(stateAfterLoad)?.normalizeRootName()
+      serializeState(stateAfterLoad)?.normalizeRootName().let {
+        if (JDOMUtil.isEmpty(it)) null else it
+      }
     }
 
     storage.archiveState(storageData, componentName, serializedStateAfterLoad)
diff --git a/platform/configuration-store-impl/testSrc/BinaryXmlOutputterTest.kt b/platform/configuration-store-impl/testSrc/BinaryXmlOutputterTest.kt
new file mode 100644 (file)
index 0000000..3e178ea
--- /dev/null
@@ -0,0 +1,28 @@
+package com.intellij.configurationStore
+
+import com.intellij.openapi.util.JDOMUtil
+import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
+import com.intellij.util.loadElement
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Test
+
+class BinaryXmlOutputterTest {
+  @Test fun noAttributes() {
+    test("""<foo />""")
+  }
+
+  @Test fun attributes() {
+    test("""<foo bar="1" />""")
+  }
+
+  private fun test(xml: String) {
+    val byteOut = BufferExposingByteArrayOutputStream()
+    byteOut.use {
+      writeElement(loadElement(xml), it)
+    }
+
+    val xmlAfter = JDOMUtil.writeElement(byteOut.toByteArray().inputStream().use { readElement(it) })
+
+    assertThat(xml.trimIndent()).isEqualTo(xmlAfter)
+  }
+}
\ No newline at end of file
index 0a4835cbcafd4c573cd71f5614c3f1497d5fdedb..46184d21863be44a0eb3048c4fbda543a6407f55 100644 (file)
@@ -37,11 +37,10 @@ import org.jetbrains.annotations.Nullable;
  * The recommended way to perform a transaction is to invoke {@link #submitTransaction(Disposable, Runnable)}. It either runs the transaction immediately
  * (if on UI thread and not inside invokeLater) or queues it to invoke at some later moment, when it becomes possible.<p/>
  *
- * Sometimes transactions need to be processed immediately, even if another transaction is already running. Example:
- * outer transaction has shown a dialog with an editor, and typing into that editor (which requires a transaction for changing document)
- * should be allowed. For such cases, the framework should be notified which transaction kinds are allowed to merged into
- * the main transaction and executed immediately. Use {@link #acceptNestedTransactions(TransactionKind...)} for that. Inner transactions
- * should be given some kind in such circumstances: {@link #submitMergeableTransaction(Disposable, TransactionKind, Runnable)}.
+ * Sometimes transactions need to be processed as soon as possible, even if another transaction is already running. Example:
+ * outer transaction has shown a dialog with a modal progress that performs a write action inside (which requires a transaction)
+ * and waits for it to be finished. For such cases, a context transaction id
+ * should be supplied to the nested transaction via {@link #submitMergeableTransaction(Disposable, TransactionId, Runnable)}.
  *
  * <p><h1>FAQ</h1></p>
  *
@@ -111,19 +110,6 @@ public abstract class TransactionGuard {
     getInstance().submitMergeableTransaction(parentDisposable, TransactionKind.ANY_CHANGE, transaction);
   }
 
-  /**
-   * Runs the given code synchronously inside a transaction. Fails if transactions of given kind are not allowed at this moment.
-   * @see #startSynchronousTransaction(TransactionKind)
-   */
-  public static void syncTransaction(@NotNull TransactionKind kind, @NotNull Runnable transaction) {
-    AccessToken token = getInstance().startSynchronousTransaction(kind);
-    try {
-      transaction.run();
-    } finally {
-      token.finish();
-    }
-  }
-
   /**
    * Schedules a given runnable to be executed inside a transaction later on Swing thread.
    * Same as {@link #submitTransaction(Disposable, Runnable)}, but the runnable is never executed immediately.
@@ -152,17 +138,7 @@ public abstract class TransactionGuard {
     submitMergeableTransaction(ApplicationManager.getApplication(), kind, transaction);
   }
 
-  /**
-   * When on UI thread and there's no other transaction running, executes the given runnable. If there is a transaction running,
-   * but the given {@code kind} is allowed via {@link #acceptNestedTransactions(TransactionKind...)}, merges two transactions
-   * and executes the provided code immediately. Otherwise
-   * adds the runnable to a queue. When all transactions scheduled before this one are finished, executes the given
-   * runnable under a transaction.
-   * @param parentDisposable an object whose disposing (via {@link com.intellij.openapi.util.Disposer} makes this transaction invalid,
-   *                         and so it won't be run after it has been disposed.
-   * @param kind a "kind" object for transaction merging
-   * @param transaction code to execute inside a transaction.
-   */
+  @Deprecated
   public abstract void submitMergeableTransaction(@NotNull Disposable parentDisposable, @NotNull TransactionKind kind, @NotNull Runnable transaction);
 
   /**
@@ -174,24 +150,10 @@ public abstract class TransactionGuard {
    *                         and so it won't be run after it has been disposed.
    * @param mergeInto an optional id of another transaction, to allow execution inside that transaction if it's still running
    * @param transaction code to execute inside a transaction.
-   * @see #getCurrentMergeableTransaction()
+   * @see #getContextTransaction()
    */
   public abstract void submitMergeableTransaction(@NotNull Disposable parentDisposable, @Nullable TransactionId mergeInto, @NotNull Runnable transaction);
 
-  /**
-   * Allow incoming transactions of the specified kinds to be executed immediately, instead of being queued until the current transaction is finished.<p/>
-   *
-   * Example: outer transaction has shown a dialog with an editor, and typing into that editor (which requires a transaction for changing document).
-   * should be allowed.<p/>
-   *
-   * For dialogs, consider using {@link AcceptNestedTransactions} annotation instead of explicit call to this method.
-   * @param kinds kinds of transactions to allow
-   * @return a token object for this session. Please call {@link AccessToken#finish()} (inside finally clause) when you don't want
-   * nested transactions anymore.
-   */
-  @NotNull
-  public abstract AccessToken acceptNestedTransactions(@NotNull TransactionKind... kinds);
-
   /**
    * Asserts that a transaction is currently running, or not. Callable only on Swing thread.
    * @param transactionRequired whether the assertion should check that the application is inside transaction or not
@@ -203,5 +165,5 @@ public abstract class TransactionGuard {
    * @return the id of the currently running transaction for using in {@link #submitMergeableTransaction(Disposable, TransactionId, Runnable)},
    * or null if there's no transaction running or merging is not allowed in the callee context (e.g. from invokeLater).
    */
-  public abstract TransactionId getCurrentMergeableTransaction();
+  public abstract TransactionId getContextTransaction();
 }
index c42233849a6f69ad90b56006407aa116f994b080..eefda0daddb00dbcd78b48c6b9cfc52aab61e794 100644 (file)
@@ -3,7 +3,7 @@ package com.intellij.openapi.application;
 import com.intellij.openapi.Disposable;
 
 /**
- * A unique object identifying each running transaction. Can be retrieved from {@link TransactionGuard#getCurrentMergeableTransaction()}
+ * A unique object identifying each running transaction. Can be retrieved from {@link TransactionGuard#getContextTransaction()}
  * while inside a transaction, and used to merge other transactions into it via
  * {@link TransactionGuard#submitMergeableTransaction(Disposable, TransactionId, Runnable)}.
  *
index dccdaf8056c8dc391664556d27d4293c7bb033e4..672728d00f34f47ac6de31818e45203b66cbdc8a 100644 (file)
@@ -19,8 +19,7 @@ import com.intellij.openapi.Disposable;
 import com.intellij.openapi.editor.Document;
 
 /**
- * A kind of transaction used in {@link TransactionGuard#submitMergeableTransaction(Disposable, TransactionKind, Runnable)},
- * {@link TransactionGuard#acceptNestedTransactions(TransactionKind...)}.
+ * A kind of transaction used in {@link TransactionGuard#submitMergeableTransaction(Disposable, TransactionKind, Runnable)}.
  */
 public interface TransactionKind {
   /**
index 75dad0c8e351d6d6d0da502e586b9beb9e5b3366..f113b93106373ae4af5c3d918788bccca3f0bc5f 100644 (file)
@@ -21,8 +21,10 @@ import com.intellij.openapi.application.ReadActionProcessor;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 
 /**
  * @author peter
@@ -34,9 +36,10 @@ public abstract class AbstractQuery<Result> implements Query<Result> {
   @NotNull
   public Collection<Result> findAll() {
     assertNotProcessing();
-    final CommonProcessors.CollectProcessor<Result> processor = new CommonProcessors.CollectProcessor<Result>();
+    List<Result> result = new ArrayList<Result>();
+    Processor<Result> processor = Processors.cancelableCollectProcessor(result);
     forEach(processor);
-    return processor.getResults();
+    return result;
   }
 
   @Override
index 6c01bbc7fbd585753a89f48ab083ab5fb681f405..082831b9cf9ced879e3132f3c30ef167dd9ccf2e 100644 (file)
@@ -20,8 +20,10 @@ import com.intellij.concurrency.AsyncFuture;
 import com.intellij.openapi.util.Condition;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 
 /**
  * @author max
@@ -57,9 +59,10 @@ public class FilteredQuery<T> implements Query<T> {
   @Override
   @NotNull
   public Collection<T> findAll() {
-    CommonProcessors.CollectProcessor<T> processor = new CommonProcessors.CollectProcessor<T>();
+    List<T> result = new ArrayList<T>();
+    Processor<T> processor = Processors.cancelableCollectProcessor(result);
     forEach(processor);
-    return processor.getResults();
+    return result;
   }
 
   @NotNull