Merge remote-tracking branch 'origin/master' into amakeev/gradle
authorAnton Makeev <Anton.Makeev@jetbrains.com>
Wed, 8 May 2019 15:34:35 +0000 (17:34 +0200)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Fri, 17 May 2019 16:07:41 +0000 (19:07 +0300)
GitOrigin-RevId: 47047f22e3c91c0029882f4b648bb92aa55db3ab

322 files changed:
.idea/artifacts/maven_event_listener.xml [new file with mode: 0644]
.idea/modules.xml
build/dependencies/setupJdk.gradle
java/debugger/impl/src/com/intellij/debugger/memory/ui/ExpressionEditorWithHistory.java
java/execution/impl/src/com/intellij/testIntegration/SelectTestStep.kt
java/execution/impl/src/com/intellij/testIntegration/ShowRecentTests.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FindUsagesInProjectStructureActionBase.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractValue.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/SpecialField.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardMethodContract.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingDfaMemoryState.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraint.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/inference/preContracts.kt
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/rangeSet/LongRangeSet.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java
java/java-impl/src/META-INF/JavaPlugin.xml
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/BringVariableIntoScopeFix.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodQuestionAction.java
java/java-impl/src/com/intellij/ide/actions/JavaVirtualFileQualifiedNameProvider.java
java/java-impl/src/com/intellij/internal/statistic/libraryJar/LibraryJarStatisticsService.java
java/java-impl/src/com/intellij/lang/jvm/actions/JvmClassIntentionActionGroup.kt
java/java-impl/src/com/intellij/psi/impl/source/tree/injected/JavaInjectedFileChangesHandler.kt
java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzerBase.java
java/java-impl/src/com/intellij/unscramble/UnscrambleAction.java
java/java-impl/src/inspectionDescriptions/ExplicitArrayFilling.html
java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
java/java-psi-api/src/com/intellij/psi/PsiDiamondType.java
java/java-psi-api/src/com/intellij/psi/PsiFunctionalExpression.java
java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceExpression.java
java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.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/constraints/ExpressionCompatibilityConstraint.java
java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
java/java-tests/testData/codeInsight/completion/keywords/indentDefaultInSwitch.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/completion/keywords/indentDefaultInSwitch_after.java [new file with mode: 0644]
java/java-tests/testData/inspection/dataFlow/tracker/AssignTernaryNumeric.java
java/java-tests/testData/inspection/dataFlow/tracker/CollectionSizeEquality.java [new file with mode: 0644]
java/java-tests/testData/inspection/dataFlow/tracker/EqualsContract.java [new file with mode: 0644]
java/java-tests/testData/inspection/dataFlow/tracker/FailingCall.java [new file with mode: 0644]
java/java-tests/testData/inspection/dataFlow/tracker/InstanceOfMethodReturn.java [new file with mode: 0644]
java/java-tests/testData/inspection/dataFlow/tracker/SimpleContract.java [new file with mode: 0644]
java/java-tests/testData/inspection/dataFlow/tracker/SimpleContract2.java [new file with mode: 0644]
java/java-tests/testData/inspection/explicitArrayFilling/afterConstantRhs.java
java/java-tests/testData/inspection/explicitArrayFilling/afterFieldComments.java
java/java-tests/testData/inspection/explicitArrayFilling/afterSimple.java
java/java-tests/testData/inspection/explicitArrayFilling/beforeConstantRhs.java
java/java-tests/testData/inspection/explicitArrayFilling/beforeFieldComments.java
java/java-tests/testData/inspection/explicitArrayFilling/beforeSimple.java
java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavadocCompletionTest.groovy
java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java
java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.groovy
java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java
jvm/jvm-analysis-api/src/com/intellij/codeInspection/NlsCapitalizationUtil.java
jvm/jvm-analysis-tests-api/src/com/intellij/codeInspection/tests/StringToUpperWithoutLocaleInspectionTestBase.java
jvm/jvm-analysis-tests-api/src/com/intellij/codeInspection/tests/UastCallMatcherTestBase.java
platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityRepositoryModules.groovy
platform/build-scripts/groovy/org/jetbrains/intellij/build/GradleRunner.groovy
platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/JpsCompilationRunner.groovy
platform/configuration-store-impl/testSrc/CodeStyleTest.kt
platform/configuration-store-impl/testSrc/xml/XmlSerializerTest.kt
platform/core-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesDescriptionLocation.java
platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffToolUtil.java
platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/ExternalSystemException.java
platform/lang-api/src/com/intellij/build/events/DuplicateMessageAware.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/build/issue/BuildIssue.kt [new file with mode: 0644]
platform/lang-api/src/com/intellij/build/issue/BuildIssueChecker.kt [new file with mode: 0644]
platform/lang-api/src/com/intellij/build/issue/BuildIssueData.kt [new file with mode: 0644]
platform/lang-api/src/com/intellij/build/issue/BuildIssueQuickFix.kt [new file with mode: 0644]
platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java
platform/lang-impl/src/com/intellij/build/BuildTextConsoleView.java
platform/lang-impl/src/com/intellij/build/BuildTreeConsoleView.java
platform/lang-impl/src/com/intellij/build/ExecutionNode.java
platform/lang-impl/src/com/intellij/build/events/impl/FailureResultImpl.java
platform/lang-impl/src/com/intellij/build/output/BuildOutputInstantReaderImpl.kt
platform/lang-impl/src/com/intellij/codeInsight/CodeInsightSettings.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArrangerImpl.java
platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoNextErrorAction.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/actions/GotoPreviousErrorAction.java
platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java
platform/lang-impl/src/com/intellij/codeInspection/naming/AbstractNamingConventionInspection.java
platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java
platform/lang-impl/src/com/intellij/execution/impl/RunDialog.java
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/JBRunnerTabs.java
platform/lang-impl/src/com/intellij/find/impl/FindPopupScopeUIImpl.java
platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceUtil.java
platform/lang-impl/src/com/intellij/ide/actions/VirtualFileQualifiedNameProvider.java [deleted file]
platform/lang-impl/src/com/intellij/ide/actions/runAnything/RunAnythingMore.java
platform/lang-impl/src/com/intellij/ide/actions/runAnything/RunAnythingPopupUI.java
platform/lang-impl/src/com/intellij/ide/actions/runAnything/RunAnythingSearchListModel.java
platform/lang-impl/src/com/intellij/ide/actions/runAnything/RunAnythingUtil.java
platform/lang-impl/src/com/intellij/ide/actions/runAnything/groups/RunAnythingGroup.java
platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/AbstractGotoSEContributor.java
platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java
platform/lang-impl/src/com/intellij/ide/util/DeleteNameDescriptionLocation.java
platform/lang-impl/src/com/intellij/ide/util/DeleteTypeDescriptionLocation.java
platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
platform/lang-impl/src/com/intellij/psi/util/psiTreeUtil.kt [moved from java/java-impl/src/com/intellij/psi/util/psiTreeUtil.kt with 100% similarity]
platform/lang-impl/src/com/intellij/refactoring/util/DefaultNonCodeSearchElementDescriptionProvider.java
platform/lang-impl/src/com/intellij/slicer/SliceLeafAnalyzer.java
platform/platform-api/src/com/intellij/ui/tabs/JBTabPainter.kt
platform/platform-api/src/com/intellij/ui/tabs/newImpl/JBEditorTabs.java
platform/platform-api/src/com/intellij/ui/tabs/newImpl/JBTabsImpl.java
platform/platform-api/src/com/intellij/ui/tabs/newImpl/SameHeightTabs.kt [new file with mode: 0644]
platform/platform-api/src/com/intellij/ui/tabs/newImpl/TabsHeightController.kt [moved from platform/platform-impl/src/com/intellij/openapi/wm/impl/TabsHeightController.kt with 97% similarity]
platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java
platform/platform-impl/src/com/intellij/diagnostic/IdeMessagePanel.java
platform/platform-impl/src/com/intellij/ide/actions/project/loadSaveModuleRenameMapping.kt
platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNewLayout.java
platform/platform-impl/src/com/intellij/ide/plugins/newui/NewListPluginComponent.java
platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginDetailsPageComponent.java
platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginLogo.java
platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java
platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaJBPopupComboPopup.java
platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJComboBoxUI.java
platform/platform-impl/src/com/intellij/idea/StartupUtil.java
platform/platform-impl/src/com/intellij/internal/statistic/actions/AddGroupToLocalWhitelistDialog.form [new file with mode: 0644]
platform/platform-impl/src/com/intellij/internal/statistic/actions/AddGroupToLocalWhitelistDialog.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/internal/statistic/actions/AddTestGroupToLocalWhitelistAction.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/SensitiveDataValidator.java
platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/persistence/FUSTestWhiteListPersistence.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/persistence/FUSWhiteListPersistence.java
platform/platform-impl/src/com/intellij/internal/statistic/service/fus/FUStatisticsWhiteListGroupsService.java
platform/platform-impl/src/com/intellij/openapi/command/impl/UpdatePluginsApp.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/GlobalMenuLinux.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameDecorator.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/content/TabContentLayout.java
platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java
platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
platform/platform-impl/src/com/intellij/ui/popup/async/AsyncPopupImpl.java
platform/platform-impl/src/com/intellij/ui/popup/async/AsyncPopupStep.java
platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java
platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupModel.java
platform/platform-impl/src/com/intellij/ui/popup/tree/TreePopupImpl.java
platform/platform-resources-en/src/inspectionDescriptions/IgnoreFileDuplicateEntry.html [moved from platform/platform-resources-en/src/inspectionDescriptions/IgnoreDuplicateEntry.html with 100% similarity]
platform/platform-resources-en/src/messages/ApplicationBundle.properties
platform/platform-resources-en/src/messages/InspectionsBundle.properties
platform/platform-resources-en/src/messages/VcsBundle.properties
platform/platform-resources/src/META-INF/LangExtensionPoints.xml
platform/platform-resources/src/brokenPlugins.txt
platform/platform-resources/src/componentSets/VCS.xml
platform/platform-resources/src/idea/PlatformActions.xml
platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.kt
platform/projectModel-api/src/com/intellij/configurationStore/KotlinAwareBeanBinding.kt
platform/projectModel-api/src/com/intellij/configurationStore/xmlSerializer.kt
platform/projectModel-api/src/com/intellij/openapi/components/BaseState.kt
platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java
platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/StructuralSearchDialog.java
platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/filters/FilterPanel.java
platform/tasks-platform-impl/src/com/intellij/tasks/impl/TaskManagerImpl.java
platform/testFramework/extensions/src/com/intellij/keymap/KeymapsTestCaseBase.java
platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
platform/util/resources/misc/registry.properties
platform/util/src/com/intellij/util/serialization/FieldAccessor.java [moved from platform/util/src/com/intellij/util/xmlb/FieldAccessor.java with 79% similarity]
platform/util/src/com/intellij/util/serialization/MutableAccessor.java [new file with mode: 0644]
platform/util/src/com/intellij/util/serialization/PropertyAccessor.java [moved from platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java with 76% similarity]
platform/util/src/com/intellij/util/serialization/PropertyCollector.java [new file with mode: 0644]
platform/util/src/com/intellij/util/serialization/SerializationException.java [new file with mode: 0644]
platform/util/src/com/intellij/util/ui/JBUI.java
platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java
platform/util/src/com/intellij/util/xmlb/Accessor.java
platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java
platform/util/src/com/intellij/util/xmlb/ArrayBinding.java
platform/util/src/com/intellij/util/xmlb/AttributeBinding.java
platform/util/src/com/intellij/util/xmlb/BasePrimitiveBinding.java
platform/util/src/com/intellij/util/xmlb/BeanBinding.java
platform/util/src/com/intellij/util/xmlb/Binding.java
platform/util/src/com/intellij/util/xmlb/CollectionBinding.java
platform/util/src/com/intellij/util/xmlb/CompactCollectionBinding.java
platform/util/src/com/intellij/util/xmlb/JDOMElementBinding.java
platform/util/src/com/intellij/util/xmlb/MapBinding.java
platform/util/src/com/intellij/util/xmlb/MutableAccessor.java [deleted file]
platform/util/src/com/intellij/util/xmlb/NotNullDeserializeBinding.java
platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java
platform/util/src/com/intellij/util/xmlb/Serializer.java
platform/util/src/com/intellij/util/xmlb/TagBinding.java
platform/util/src/com/intellij/util/xmlb/TextBinding.java
platform/util/src/com/intellij/util/xmlb/XmlSerializationException.java
platform/util/src/com/intellij/util/xmlb/XmlSerializer.java
platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java
platform/util/src/com/intellij/util/xmlb/XmlSerializerUtil.java
platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java
platform/util/testSrc/com/intellij/util/io/DecompressorTest.kt
platform/vcs-impl/src/com/intellij/openapi/vcs/ExternallyAddedFilesProcessorImpl.kt
platform/vcs-impl/src/com/intellij/openapi/vcs/ProjectConfigurationFilesProcessorImpl.kt
platform/vcs-impl/src/com/intellij/openapi/vcs/VcsVFSListener.java
platform/vcs-impl/src/com/intellij/openapi/vcs/actions/ShowBaseRevisionAction.java
platform/vcs-impl/src/com/intellij/openapi/vcs/actions/TabbedShowHistoryAction.java
platform/vcs-impl/src/com/intellij/openapi/vcs/actions/TabbedShowHistoryForRevisionAction.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ignore/IgnoreFilesProcessorImpl.kt
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ignore/codeInspection/IgnoreFileDuplicateEntryInspection.java [moved from platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ignore/codeInspection/IgnoreDuplicateEntryInspection.java with 96% similarity]
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ignore/codeInspection/IgnoreFileRemoveEntryFix.java [moved from platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ignore/codeInspection/IgnoreRemoveEntryFix.java with 92% similarity]
platform/vcs-impl/src/com/intellij/openapi/vcs/merge/MultipleFileMergeDialog.kt
platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsCustomizableActionGroupProvider.java
platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFileHistoryProvider.java
platform/vcs-log/impl/src/com/intellij/vcs/log/history/VcsLogFileHistoryProviderImpl.java [deleted file]
platform/vcs-log/impl/src/com/intellij/vcs/log/history/VcsLogFileHistoryProviderImpl.kt [new file with mode: 0644]
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogChangesBrowser.java
platform/vcs-log/impl/src/com/intellij/vcs/log/util/VcsLogUtil.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
plugins/IntelliLang/IntelliLang-tests/test/com/intellij/psi/impl/source/tree/injected/JavaInjectedFileChangesHandlerTest.kt
plugins/IntentionPowerPak/src/com/siyeh/ipp/collections/ImmutableCollectionModelUtils.java
plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/MapOfEntriesArrayAccess.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/MapOfEntriesTernary_after.java [deleted file]
plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/VarArgCall.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/collections/to_mutable_collection/VarArgCall_after.java [new file with mode: 0644]
plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/collections/ReplaceWithMutableCollectionIntentionTest.java
plugins/devkit/devkit-core/src/actions/MigrateModuleNamesInSourcesAction.kt
plugins/devkit/devkit-core/src/actions/ShowSerializedXmlAction.java
plugins/devkit/devkit-core/src/dom/Extension.java
plugins/devkit/devkit-core/src/dom/impl/ExtensionDomExtender.java
plugins/devkit/devkit-core/src/dom/impl/ExtensionPointImpl.java
plugins/git4idea/src/git4idea/GitVcs.java
plugins/git4idea/src/git4idea/checkin/GitCheckinHandlerFactory.java
plugins/git4idea/src/git4idea/i18n/GitBundle.properties
plugins/git4idea/src/git4idea/push/GitPushTargetPanel.java
plugins/git4idea/src/git4idea/rebase/GitRewordAction.kt
plugins/git4idea/src/git4idea/rebase/GitRewordOperation.kt
plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java
plugins/git4idea/src/git4idea/vfs/GitVFSListener.java
plugins/github/src/org/jetbrains/plugins/github/pullrequest/data/service/GithubPullRequestsMetadataServiceImpl.kt
plugins/github/src/org/jetbrains/plugins/github/pullrequest/data/service/GithubPullRequestsStateServiceImpl.kt
plugins/gradle/java/src/service/project/JavaGradleProjectResolver.java
plugins/gradle/src/org/jetbrains/plugins/gradle/execution/build/output/GradleBuildScriptErrorParser.kt
plugins/gradle/src/org/jetbrains/plugins/gradle/execution/build/output/GradleOutputDispatcherFactory.kt
plugins/gradle/src/org/jetbrains/plugins/gradle/issue/BuildIssueException.java [new file with mode: 0644]
plugins/gradle/src/org/jetbrains/plugins/gradle/issue/GradleIssueData.kt [new file with mode: 0644]
plugins/gradle/src/org/jetbrains/plugins/gradle/issue/IncompatibleGradleJdkIssueChecker.kt [new file with mode: 0644]
plugins/gradle/src/org/jetbrains/plugins/gradle/issue/quickfix/GradleSettingsQuickFix.kt [new file with mode: 0644]
plugins/gradle/src/org/jetbrains/plugins/gradle/issue/quickfix/GradleVersionQuickFix.kt [new file with mode: 0644]
plugins/gradle/src/org/jetbrains/plugins/gradle/issue/quickfix/GradleWrapperSettingsOpenQuickFix.kt [new file with mode: 0644]
plugins/gradle/src/org/jetbrains/plugins/gradle/issue/quickfix/ReimportQuickFix.kt [new file with mode: 0644]
plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleExecutionHelper.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/notification/GradleNotificationExtension.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectImportErrorHandler.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseProjectImportErrorHandler.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/DefaultProjectResolverContext.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java
plugins/gradle/testSources/org/jetbrains/plugins/gradle/service/project/BaseProjectImportErrorHandlerTest.java
plugins/groovy/src/org/jetbrains/plugins/groovy/util/moduleChooserUtil.kt
plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java
plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java
plugins/java-decompiler/plugin/test/org/jetbrains/java/decompiler/IdeaDecompilerTest.kt
plugins/java-i18n/src/com/intellij/codeInspection/capitalization/TitleCapitalizationInspection.java
plugins/maven/intellij.maven.iml
plugins/maven/maven-event-listener/intellij.maven.server.eventListener.iml [new file with mode: 0644]
plugins/maven/maven-event-listener/src/main/java/org/jetbrains/maven/server/EventInfoPrinter.java [new file with mode: 0644]
plugins/maven/maven-event-listener/src/main/java/org/jetbrains/maven/server/IntellijMavenSpy.java [new file with mode: 0644]
plugins/maven/maven-event-listener/src/main/java/org/jetbrains/maven/server/SpyConstants.java [new file with mode: 0644]
plugins/maven/maven-event-listener/src/main/resources/META-INF/MANIFEST.MF [new file with mode: 0644]
plugins/maven/maven-event-listener/src/main/resources/META-INF/sisu/javax.inject.Named [new file with mode: 0644]
plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/buildtool/BuildViewMavenConsole.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/buildtool/MavenBuildEventProcessor.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/buildtool/MavenSyncConsole.kt
plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalExecutor.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExternalParameters.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfiguration.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/LogMessageType.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenLogOutputParser.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenLoggedEventParser.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenOutputParserProvider.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenParsingContext.java [new file with mode: 0644]
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/ArtifactDownloadScanning.java [deleted file]
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/BuildErrorNotification.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/CommonErrorParser.java [deleted file]
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/MavenBadConfigEventParser.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/MavenSpyOutputParser.java [new file with mode: 0644]
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/ProjectScanning.java [deleted file]
plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/WarningNotifier.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigator.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerManager.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java
plugins/maven/src/main/resources/META-INF/plugin.xml
plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenBuildToolLogTestUtils.java
plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenSpyOutputParserTest.java [new file with mode: 0644]
plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/ArtifactDownloadScanningTest.java [deleted file]
plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/TestBuildErrorNotification.java
plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/parsers/WarningScanningTest.java
plugins/maven/src/test/resources/org/jetbrains/maven/buildlogs/Project2Modules.log [new file with mode: 0644]
plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.java
python/helpers/generator3.py
python/helpers/pycharm_generator_utils/util_methods.py
python/ide/src/com/jetbrains/python/PyCharmInitialConfigurator.java
python/src/com/jetbrains/python/codeInsight/editorActions/PyTripleQuoteBackspaceDelegate.java
python/src/com/jetbrains/python/editor/BaseQuoteHandler.java
python/src/com/jetbrains/python/editor/PythonQuoteHandler.java
python/src/com/jetbrains/python/refactoring/invertBoolean/PyInvertBooleanDelegate.java
python/testSrc/com/jetbrains/python/refactoring/PyInvertBooleanTest.java
resources-en/src/search/searchableOptions.xml
resources/src/idea/JavaActions.xml
xml/impl/src/com/intellij/codeInsight/daemon/impl/quickfix/FetchExtResourceAction.java
xml/tests/src/com/intellij/codeInsight/daemon/quickFix/RealFetchTest.java

diff --git a/.idea/artifacts/maven_event_listener.xml b/.idea/artifacts/maven_event_listener.xml
new file mode 100644 (file)
index 0000000..0810919
--- /dev/null
@@ -0,0 +1,8 @@
+<component name="ArtifactManager">
+  <artifact type="jar" name="maven-event-listener">
+    <output-path>$PROJECT_DIR$/out/artifacts/maven_event_listener</output-path>
+    <root id="archive" name="maven-event-listener.jar">
+      <element id="module-output" name="intellij.maven.server.eventListener" />
+    </root>
+  </artifact>
+</component>
\ No newline at end of file
index aa7251843c6f1e0f993bf10a5aa003bd5f04c9fc..92d90d3c9abda2600fcac294198d8df0b779d13b 100644 (file)
       <module fileurl="file://$PROJECT_DIR$/plugins/maven/error-prone-compiler/intellij.maven.errorProne.compiler.iml" filepath="$PROJECT_DIR$/plugins/maven/error-prone-compiler/intellij.maven.errorProne.compiler.iml" />
       <module fileurl="file://$PROJECT_DIR$/plugins/maven/jps-plugin/intellij.maven.jps.iml" filepath="$PROJECT_DIR$/plugins/maven/jps-plugin/intellij.maven.jps.iml" />
       <module fileurl="file://$PROJECT_DIR$/plugins/maven/maven-server-api/intellij.maven.server.iml" filepath="$PROJECT_DIR$/plugins/maven/maven-server-api/intellij.maven.server.iml" />
+      <module fileurl="file://$PROJECT_DIR$/plugins/maven/maven-event-listener/intellij.maven.server.eventListener.iml" filepath="$PROJECT_DIR$/plugins/maven/maven-event-listener/intellij.maven.server.eventListener.iml" />
       <module fileurl="file://$PROJECT_DIR$/plugins/maven/maven2-server-impl/intellij.maven.server.m2.impl.iml" filepath="$PROJECT_DIR$/plugins/maven/maven2-server-impl/intellij.maven.server.m2.impl.iml" />
       <module fileurl="file://$PROJECT_DIR$/plugins/maven/maven3-server-common/intellij.maven.server.m3.common.iml" filepath="$PROJECT_DIR$/plugins/maven/maven3-server-common/intellij.maven.server.m3.common.iml" />
       <module fileurl="file://$PROJECT_DIR$/plugins/maven/maven3-server-impl/intellij.maven.server.m3.impl.iml" filepath="$PROJECT_DIR$/plugins/maven/maven3-server-impl/intellij.maven.server.m3.impl.iml" />
index 46a828c079038429bd76833d3b77b69eb58107cd..b4f1c185de2581f725b5780d562aba5f602b5214 100644 (file)
@@ -11,6 +11,7 @@ cleanSetupJdks.dependsOn('cleanSetupJdk', 'cleanSetupJdk16', 'cleanDownloadJdk')
 project.ext.jdkRepo = 'https://cache-redirector.jetbrains.com/intellij-jbr'
 project.ext.jdkVersion = System.getProperty('intellij.build.jdk.version', '8').toInteger()
 def isModular = jdkVersion > 8
+project.ext.build = isModular ? secondJreBuild : jdkBuild
 project.ext.jdkArtifactPrefix = isModular ? 'jbr-' : 'jbrsdk-'
 
 def jdkDir = System.getProperty('intellij.build.jdks.target.dir')?.with {
@@ -48,12 +49,12 @@ task downloadJdk {
   def arch = jdkArch()
   def platform = currentPlatformName()
   def jdkUrl = jdkUrl()
-  def (update, buildNumber) = splitJdkBuild(jdkBuild.toString(), jdkVersion.toString())
+  def (update, buildNumber) = splitJdkBuild(build.toString(), jdkVersion.toString())
   def artifactName = "$jdkArtifactPrefix${update}-${platform}-${arch}-${buildNumber}.tar.gz"
   def outputFile = "$project.buildDir/jbsdk/${artifactName}"
 
   inputs.property('version', jdkVersion)
-  inputs.property('build', jdkBuild)
+  inputs.property('build', build)
   inputs.property('url', jdkUrl)
   outputs.file(outputFile)
   doLast {
@@ -133,7 +134,7 @@ static def jdkArch() {
 def jdkUrl() {
   def arch = jdkArch()
   def platform = currentPlatformName()
-  def (update, buildNumber) = splitJdkBuild(jdkBuild.toString(), jdkVersion.toString())
+  def (update, buildNumber) = splitJdkBuild(build.toString(), jdkVersion.toString())
   // base url of TeamCity build to download JDK from
   def teamCityBuild = System.getProperty('intellij.jdk.teamcity.build.url')
   "${teamCityBuild != null ? teamCityBuild : jdkRepo}/${jdkArtifactPrefix}${update}-${platform}-${arch}-${buildNumber}.tar.gz"
index 7136079e04d551f0f910623053a9c878e2553d3c..42061804d7559603e16c40c32efb5bc0d7a6564c 100644 (file)
@@ -65,7 +65,7 @@ class ExpressionEditorWithHistory extends XDebuggerExpressionEditor {
   private void showHistory() {
     List<XExpression> expressions = getRecentExpressions();
     if (!expressions.isEmpty()) {
-      ListPopupImpl historyPopup = new ListPopupImpl(new BaseListPopupStep<XExpression>(null, expressions) {
+      ListPopupImpl historyPopup = new ListPopupImpl(getProject(), new BaseListPopupStep<XExpression>(null, expressions) {
         @Override
         public PopupStep onChosen(XExpression selectedValue, boolean finalChoice) {
           setExpression(selectedValue);
index 83aa4ce53b7d065e134707e5cb5d2ed690e3456a..2a06767b40798fdc3eecc61443db175e8a7db715 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.testIntegration
 
 import com.intellij.icons.AllIcons
 import com.intellij.openapi.keymap.MacKeymapUtil
+import com.intellij.openapi.project.Project
 import com.intellij.openapi.ui.popup.ListPopupStep
 import com.intellij.openapi.ui.popup.PopupStep
 import com.intellij.openapi.ui.popup.util.BaseListPopupStep
@@ -32,9 +33,10 @@ import javax.swing.Icon
 import javax.swing.KeyStroke
 
 
-class RecentTestsListPopup(popupStep: ListPopupStep<RecentTestsPopupEntry>,
+class RecentTestsListPopup(project: Project,
+                           popupStep: ListPopupStep<RecentTestsPopupEntry>,
                            private val testRunner: RecentTestRunner,
-                           private val locator: TestLocator) : ListPopupImpl(popupStep) {
+                           private val locator: TestLocator) : ListPopupImpl(project, popupStep) {
 
   init {
     shiftReleased()
index 202ff5633c6837ce9394c72f8540eabfd776fed8..e25a34f983e8a889f0af19cf3bf4b6d790945421 100644 (file)
@@ -58,7 +58,7 @@ public class ShowRecentTests extends AnAction {
     
     SelectTestStep selectStepTest = new SelectTestStep("Debug Recent Tests", entries, testRunner);
 
-    RecentTestsListPopup popup = new RecentTestsListPopup(selectStepTest, testRunner, testLocator);
+    RecentTestsListPopup popup = new RecentTestsListPopup(project, selectStepTest, testRunner, testLocator);
     popup.showCenteredInCurrentWindow(project);
 
     cleanDeadTests(entries, testLocator, testStorage);
index 822a6f4d99877f0972db7ecb26d9bea6652ce3ff..1bd4c8c0e14370ae1c68b3f6b6e24a917caf39be 100644 (file)
@@ -105,7 +105,7 @@ public abstract class FindUsagesInProjectStructureActionBase extends AnAction im
           return true;
         }
       };
-    new ListPopupImpl(step) {
+    new ListPopupImpl(myProject, step) {
       @Override
       protected ListCellRenderer getListElementRenderer() {
         return new ListCellRendererWithRightAlignedComponent<ProjectStructureElementUsage>() {
index f68af8326297b57b973f098e361e7c6fbaef8eb2..6d74bc407f4dee7dda21b06c0d0f3806e48b10d2 100644 (file)
@@ -69,6 +69,10 @@ public abstract class ContractValue {
     return false;
   }
 
+  public ContractValue invert() {
+    return null;
+  }
+  
   /**
    * @return true if this contract value represents a bounds-checking condition
    */
@@ -88,6 +92,18 @@ public abstract class ContractValue {
     return OptionalInt.empty();
   }
 
+  public String getPresentationText(PsiMethod method) {
+    return toString();
+  }
+
+  public PsiExpression findLeftPlace(PsiCallExpression call) {
+    return null;
+  }
+
+  public PsiExpression findRightPlace(PsiCallExpression call) {
+    return null;
+  }
+
   public static ContractValue qualifier() {
     return Qualifier.INSTANCE;
   }
@@ -150,6 +166,18 @@ public abstract class ContractValue {
     }
 
     @Override
+    public String getPresentationText(PsiMethod method) {
+      PsiParameter[] params = method.getParameterList().getParameters();
+      if (myIndex == 0 && params.length == 1) {
+        return "parameter";
+      }
+      if (myIndex < params.length) {
+        return params[myIndex].getName();
+      }
+      return toString();
+    }
+
+    @Override
     public boolean equals(Object obj) {
       return obj == this || (obj instanceof Argument && myIndex == ((Argument)obj).myIndex);
     }
@@ -218,6 +246,11 @@ public abstract class ContractValue {
     }
 
     @Override
+    public String getPresentationText(PsiMethod method) {
+      return myQualifier.getPresentationText(method) + "." + myField + (myField == SpecialField.ARRAY_LENGTH ? "" : "()");
+    }
+
+    @Override
     public String toString() {
       return myQualifier + "." + myField + "()";
     }
@@ -317,6 +350,49 @@ public abstract class ContractValue {
     }
 
     @Override
+    public String getPresentationText(PsiMethod method) {
+      if (myLeft instanceof IndependentValue) {
+        return myRight.getPresentationText(method) + " " + myRelationType.getFlipped() + " " + myLeft.getPresentationText(method);
+      }
+      return myLeft.getPresentationText(method) + " " + myRelationType + " " + myRight.getPresentationText(method);
+    }
+
+    @Override
+    public PsiExpression findLeftPlace(PsiCallExpression call) {
+      return findPlace(call, myLeft);
+    }
+
+    @Override
+    public PsiExpression findRightPlace(PsiCallExpression call) {
+      return findPlace(call, myRight);
+    }
+
+    private static PsiExpression findPlace(PsiCallExpression call, ContractValue value) {
+      while (value instanceof Spec) {
+        value = ((Spec)value).myQualifier;
+      }
+      if (value instanceof Argument) {
+        PsiExpressionList list = call.getArgumentList();
+        if (list != null) {
+          PsiExpression[] args = list.getExpressions();
+          int index = ((Argument)value).myIndex;
+          if (index < args.length - 1 || (index == args.length - 1 && !MethodCallUtils.isVarArgCall(call))) {
+            return args[index];
+          }
+        }
+      }
+      if (value instanceof Qualifier && call instanceof PsiMethodCallExpression) {
+        return ((PsiMethodCallExpression)call).getMethodExpression().getQualifierExpression();
+      }
+      return null;
+    }
+
+    @Override
+    public ContractValue invert() {
+      return new Condition(myLeft, myRelationType.getNegated(), myRight);
+    }
+
+    @Override
     public String toString() {
       return myLeft + " " + myRelationType + " " + myRight;
     }
index 42b924125b246c89d073655879d2df3230b8b5b6..04f8c6e4cb12c8afa2db5a1d34c7ec744f02eee4 100644 (file)
@@ -591,10 +591,11 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool
     holder.registerProblem(annoName, msg, fixes);
   }
 
-  private static void reportAlwaysFailingCalls(ProblemReporter reporter, DataFlowInstructionVisitor visitor) {
+  private void reportAlwaysFailingCalls(ProblemReporter reporter, DataFlowInstructionVisitor visitor) {
     visitor.alwaysFailingCalls().remove(TestUtils::isExceptionExpected).forEach(call -> {
       String message = getContractMessage(JavaMethodContractUtil.getMethodCallContracts(call));
-      reporter.registerProblem(getElementToHighlight(call), message);
+      LocalQuickFix causeFix = reporter.isOnTheFly() ? createExplainFix(call, new TrackingRunner.FailingCallDfaProblemType()) : null;
+      reporter.registerProblem(getElementToHighlight(call), message, causeFix);
     });
   }
 
index a933665c067e101a1f1f5f24262a2f5fe7ff40d1..51cc547e0b45b4899ec29962843261bf860eb789 100644 (file)
@@ -16,7 +16,9 @@
 package com.intellij.codeInspection.dataFlow;
 
 import com.intellij.codeInspection.dataFlow.value.DfaRelationValue.RelationType;
+import org.jetbrains.annotations.NotNull;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -71,11 +73,16 @@ public abstract class MethodContract {
     };
   }
 
+  @NotNull
   public static MethodContract singleConditionContract(ContractValue left,
                                                        RelationType relationType,
                                                        ContractValue right,
                                                        ContractReturnValue returnValue) {
-    ContractValue condition = ContractValue.condition(left, relationType, right);
+    return singleConditionContract(ContractValue.condition(left, relationType, right), returnValue);
+  }
+
+  @NotNull
+  private static MethodContract singleConditionContract(ContractValue condition, ContractReturnValue returnValue) {
     return new MethodContract(returnValue) {
       @Override
       String getArgumentsPresentation() {
@@ -88,4 +95,26 @@ public abstract class MethodContract {
       }
     };
   }
+
+  public static List<? extends MethodContract> toNonIntersectingContracts(List<? extends MethodContract> contracts) {
+    if (contracts.size() == 1) return contracts;
+    if (contracts.stream().allMatch(StandardMethodContract.class::isInstance)) {
+      @SuppressWarnings("unchecked") List<StandardMethodContract> standardContracts = (List<StandardMethodContract>)contracts;
+      return StandardMethodContract.toNonIntersectingStandardContracts(standardContracts);
+    }
+    if (contracts.size() == 2 && contracts.get(1).isTrivial()) {
+      List<MethodContract> result = new ArrayList<>();
+      result.add(contracts.get(0));
+      List<ContractValue> conditions = contracts.get(0).getConditions();
+      for (ContractValue condition : conditions) {
+        ContractValue inverted = condition.invert();
+        if (inverted == null) {
+          return null;
+        }
+        result.add(singleConditionContract(inverted, contracts.get(1).getReturnValue()));
+      }
+      return result;
+    }
+    return null;
+  }
 }
index 8c06878f994e515b5fbbbe2d75f876aa9fa1479c..ee0b7876bec8f07fa1ed751980a293cdafb23f13 100644 (file)
@@ -354,8 +354,10 @@ public enum SpecialField implements VariableDescriptor {
    * @param type a qualifier type
    * @return a special field; null if no special field is available for given type
    */
+  @Contract("null -> null")
   @Nullable
   public static SpecialField fromQualifierType(PsiType type) {
+    if (type == null) return null;
     for (SpecialField value : VALUES) {
       if (value.isMyQualifierType(type)) {
         return value;
index bccc61a107d43a5b68ed9644a0d355db2f1f8c00..a863daacc16fc8d8db3c4ef022fb7bc6b9b32b17 100644 (file)
@@ -134,7 +134,7 @@ public final class StandardMethodContract extends MethodContract {
    * (e.g. contracts with different parameter count)
    */
   @Nullable("When result is too big or contracts are erroneous")
-  public static List<StandardMethodContract> toNonIntersectingContracts(List<StandardMethodContract> contracts) {
+  public static List<StandardMethodContract> toNonIntersectingStandardContracts(List<StandardMethodContract> contracts) {
     if (contracts.isEmpty()) return contracts;
     int paramCount = contracts.get(0).getParameterCount();
     List<StandardMethodContract> result = new ArrayList<>();
index f7cc28ea34a0a0832eff0cade95bf28be3318963..8cd4808c50131b4e9845508b43f7830fcb504ee3 100644 (file)
@@ -6,7 +6,6 @@ import com.intellij.codeInspection.dataFlow.instructions.ExpressionPushingInstru
 import com.intellij.codeInspection.dataFlow.instructions.Instruction;
 import com.intellij.codeInspection.dataFlow.value.*;
 import com.intellij.codeInspection.dataFlow.value.DfaRelationValue.RelationType;
-import com.intellij.openapi.util.Pair;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiExpression;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -340,30 +339,28 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
     }
     
     @NotNull
-    <T> Pair<MemoryStateChange, T> findFact(DfaValue value, DfaFactType<T> type) {
+    <T> FactDefinition<T> findFact(DfaValue value, DfaFactType<T> type) {
       if (value instanceof DfaVariableValue) {
         for (MemoryStateChange change = this; change != null; change = change.myPrevious) {
-          Pair<MemoryStateChange, T> factPair = factFromChange(type, change, change.myChanges.get(value));
+          FactDefinition<T> factPair = factFromChange(type, change, change.myChanges.get(value));
           if (factPair != null) return factPair;
           factPair = factFromChange(type, change, change.myBridgeChanges.get(value));
           if (factPair != null) return factPair;
         }
-        return Pair.create(null, ((DfaVariableValue)value).getInherentFacts().get(type));
+        return new FactDefinition<>(null, ((DfaVariableValue)value).getInherentFacts().get(type));
       }
-      return Pair.create(null, type.fromDfaValue(value));
+      return new FactDefinition<>(null, type.fromDfaValue(value));
     }
 
     @Nullable
-    private static <T> Pair<MemoryStateChange, T> factFromChange(DfaFactType<T> type,
-                                                                 MemoryStateChange change,
-                                                                 Change varChange) {
+    private static <T> FactDefinition<T> factFromChange(DfaFactType<T> type, MemoryStateChange change, Change varChange) {
       if (varChange != null) {
         T added = varChange.myAddedFacts.get(type);
         if (added != null) {
-          return Pair.create(change, added); 
+          return new FactDefinition<>(change, added); 
         }
         if (varChange.myRemovedFacts.get(type) != null) {
-          return Pair.create(change, null);
+          return new FactDefinition<>(change, null);
         }
       }
       return null;
@@ -496,4 +493,20 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
               "; Bridge changes: " + EntryStream.of(myBridgeChanges).join(": ", "\n\t", "").joining());
     }
   }
+
+  static class FactDefinition<T> {
+    final @Nullable MemoryStateChange myChange;
+    final @Nullable T myFact;
+
+    FactDefinition(@Nullable MemoryStateChange change, @Nullable T fact) {
+      myChange = change;
+      myFact = fact;
+    }
+
+    @Nullable
+    @Contract("!null -> !null")
+    T getFact(T defaultFact) {
+      return myFact == null ? defaultFact : myFact;
+    }
+  }
 }
index d7c1f9f7a8c5d5473c54d0cd564b1c690dd71d2e..25ca9c45782622233c098ac3c42804b72a38e6aa 100644 (file)
@@ -3,6 +3,7 @@ package com.intellij.codeInspection.dataFlow;
 
 import com.intellij.codeInsight.NullabilityAnnotationInfo;
 import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.codeInspection.dataFlow.TrackingDfaMemoryState.FactDefinition;
 import com.intellij.codeInspection.dataFlow.TrackingDfaMemoryState.MemoryStateChange;
 import com.intellij.codeInspection.dataFlow.TrackingDfaMemoryState.Relation;
 import com.intellij.codeInspection.dataFlow.instructions.*;
@@ -12,7 +13,6 @@ import com.intellij.codeInspection.dataFlow.value.DfaRelationValue.RelationType;
 import com.intellij.lang.ASTNode;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.Segment;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.text.StringUtil;
@@ -111,25 +111,55 @@ public class TrackingRunner extends StandardDataFlowRunner {
     StandardInstructionVisitor visitor = new StandardInstructionVisitor(true);
     RunnerResult result = runner.analyzeMethodRecursively(body, visitor, ignoreAssertions);
     if (result != RunnerResult.OK) return Collections.emptyList();
+    return ContainerUtil.createMaybeSingletonList(runner.findProblemCause(expression, type));
+  }
+
+  /*
+  TODO: 1. Find causes of other warnings:  
+            Cause for AIOOBE
+            Cause for "modifying an immutable collection"
+            Cause for "Collection is always empty" (separate inspection now)
+  TODO: 2. Describe causes in more cases:
+            Warning caused by contract
+            Warning caused by CustomMethodHandler
+            Warning caused by polyadic math
+            Warning caused by unary minus
+            Warning caused by final field initializer
+  TODO: 3. Check how it works with:
+            Inliners (notably: Stream API)
+            Boxed numbers
+  TODO: 4. Check for possible performance disasters (likely on some code patterns current algo might blow up)
+  TODO: 5. Problem when interesting state doesn't reach the current condition, need to do something with this    
+   */
+  @Nullable
+  private CauseItem findProblemCause(PsiExpression expression, DfaProblemType type) {
     CauseItem cause = null;
-    for (MemoryStateChange history : runner.myHistoryForContext) {
-      CauseItem root = findCauseChain(expression, history, type);
+    for (MemoryStateChange history : myHistoryForContext) {
+      CauseItem item = new CauseItem(type, expression);
+      if (history.getExpression() == expression) {
+        item.addChildren(type.findCauses(this, expression, history));
+      }
       if (cause == null) {
-        cause = root;
+        cause = item;
       } else {
-        cause = cause.merge(root);
-        if (cause == null) return Collections.emptyList();
+        cause = cause.merge(item);
+        if (cause == null) return null;
       }
     }
-    return Collections.singletonList(cause);
+    return cause;
   }
 
   public abstract static class DfaProblemType {
     public abstract String toString();
 
-    CauseItem[] findCauses(PsiExpression expression, MemoryStateChange history) {
+    CauseItem[] findCauses(TrackingRunner runner, PsiExpression expression, MemoryStateChange history) {
       return new CauseItem[0];
     }
+
+    @Nullable
+    DfaProblemType tryMerge(DfaProblemType other) {
+      return this.toString().equals(other.toString()) ? this : null; 
+    }
   }
 
   public static class CauseItem {
@@ -137,6 +167,12 @@ public class TrackingRunner extends StandardDataFlowRunner {
     final @NotNull DfaProblemType myProblem;
     final @Nullable SmartPsiFileRange myTarget;
 
+    private CauseItem(@NotNull List<CauseItem> children, @NotNull DfaProblemType problem, @Nullable SmartPsiFileRange target) {
+      myChildren = children;
+      myProblem = problem;
+      myTarget = target;
+    }
+    
     CauseItem(@NotNull String problem, @Nullable PsiElement target) {
       this(new CustomDfaProblemType(problem), target);
     }
@@ -244,9 +280,17 @@ public class TrackingRunner extends StandardDataFlowRunner {
 
     public CauseItem merge(CauseItem other) {
       if (this.equals(other)) return this;
-      if (Objects.equals(this.myTarget, other.myTarget) && getProblemName().equals(other.getProblemName())) {
-        if(tryMergeChildren(other.myChildren)) return this;
-        if(other.tryMergeChildren(this.myChildren)) return other;
+      if (Objects.equals(this.myTarget, other.myTarget)) {
+        if (myChildren.equals(other.myChildren)) {
+          DfaProblemType mergedProblem = myProblem.tryMerge(other.myProblem);
+          if (mergedProblem != null) {
+            return new CauseItem(myChildren, mergedProblem, myTarget);
+          }
+        }
+        if (getProblemName().equals(other.getProblemName())) {
+          if (tryMergeChildren(other.myChildren)) return this;
+          if (other.tryMergeChildren(this.myChildren)) return other;
+        }
       }
       return null;
     }
@@ -285,12 +329,12 @@ public class TrackingRunner extends StandardDataFlowRunner {
   
   public static class CastDfaProblemType extends DfaProblemType {
     @Override
-    public CauseItem[] findCauses(PsiExpression expression, MemoryStateChange history) {
+    public CauseItem[] findCauses(TrackingRunner runner, PsiExpression expression, MemoryStateChange history) {
       if (expression instanceof PsiTypeCastExpression) {
         PsiType expressionType = expression.getType();
         MemoryStateChange operandPush = history.findExpressionPush(((PsiTypeCastExpression)expression).getOperand());
         if (operandPush != null) {
-          return new CauseItem[]{findTypeCause(operandPush, expressionType, false)};
+          return new CauseItem[]{runner.findTypeCause(operandPush, expressionType, false)};
         }
       }
       return new CauseItem[0];
@@ -303,10 +347,10 @@ public class TrackingRunner extends StandardDataFlowRunner {
 
   public static class NullableDfaProblemType extends DfaProblemType {
     @Override
-    public CauseItem[] findCauses(PsiExpression expression, MemoryStateChange history) {
-      Pair<MemoryStateChange, DfaNullability> nullability = history.findFact(history.myTopOfStack, DfaFactType.NULLABILITY);
-      if (nullability.second == DfaNullability.NULLABLE || nullability.second == DfaNullability.NULL) {
-        return new CauseItem[]{findNullabilityCause(history, nullability.first, nullability.second)};
+    public CauseItem[] findCauses(TrackingRunner runner, PsiExpression expression, MemoryStateChange history) {
+      FactDefinition<DfaNullability> nullability = history.findFact(history.myTopOfStack, DfaFactType.NULLABILITY);
+      if (nullability.myFact == DfaNullability.NULLABLE || nullability.myFact == DfaNullability.NULL) {
+        return new CauseItem[]{runner.findNullabilityCause(history, nullability.myFact)};
       }
       return new CauseItem[0];
     }
@@ -316,6 +360,22 @@ public class TrackingRunner extends StandardDataFlowRunner {
     }
   }
 
+  public static class FailingCallDfaProblemType extends DfaProblemType {
+    @Override
+    CauseItem[] findCauses(TrackingRunner runner, PsiExpression expression, MemoryStateChange history) {
+      if (expression instanceof PsiCallExpression) {
+        return new CauseItem[]{runner.fromCallContract(history, (PsiCallExpression)expression, ContractReturnValue.fail())};
+      }
+      return super.findCauses(runner, expression, history);
+    }
+
+    @Override
+    public String toString() {
+      return "call always fails";
+    }
+  }
+  
+
   static class PossibleExecutionDfaProblemType extends DfaProblemType {
     boolean myComplete = true;
 
@@ -324,6 +384,35 @@ public class TrackingRunner extends StandardDataFlowRunner {
       return myComplete ? "one of the following happens:" : "an execution might exist where:";
     }
   }
+
+  static class RangeDfaProblemType extends DfaProblemType {
+    final @NotNull String myTemplate;
+    final @NotNull LongRangeSet myRangeSet;
+    final @Nullable PsiPrimitiveType myType;
+
+    RangeDfaProblemType(@NotNull String template, @NotNull LongRangeSet set, @Nullable PsiPrimitiveType type) {
+      myTemplate = template;
+      myRangeSet = set;
+      myType = type;
+    }
+
+    @Nullable
+    @Override
+    DfaProblemType tryMerge(DfaProblemType other) {
+      if (other instanceof RangeDfaProblemType) {
+        RangeDfaProblemType rangeProblem = (RangeDfaProblemType)other;
+        if (myTemplate.equals(rangeProblem.myTemplate) && Objects.equals(myType, rangeProblem.myType)) {
+          return new RangeDfaProblemType(myTemplate, myRangeSet.unite(((RangeDfaProblemType)other).myRangeSet), myType);
+        }
+      }
+      return super.tryMerge(other);
+    }
+
+    @Override
+    public String toString() {
+      return String.format(myTemplate, myRangeSet.getPresentationText(myType));
+    }
+  }
   
 
   public static class ValueDfaProblemType extends DfaProblemType {
@@ -334,8 +423,8 @@ public class TrackingRunner extends StandardDataFlowRunner {
     }
 
     @Override
-    public CauseItem[] findCauses(PsiExpression expression, MemoryStateChange history) {
-      return findConstantValueCause(expression, history, myValue);
+    public CauseItem[] findCauses(TrackingRunner runner, PsiExpression expression, MemoryStateChange history) {
+      return runner.findConstantValueCause(expression, history, myValue);
     }
 
     @Override
@@ -357,34 +446,8 @@ public class TrackingRunner extends StandardDataFlowRunner {
     }
   }
 
-  /*
-  TODO: 1. Find causes of other warnings:  
-            Cause for AIOOBE
-            Cause for "Contract always fails"
-            Cause for "modifying an immutable collection"
-            Cause for "Collection is always empty" (separate inspection now)
-  TODO: 2. Describe causes in more cases:
-            Warning caused by contract
-            Warning caused by CustomMethodHandler
-            Warning caused by polyadic math
-            Warning caused by unary minus
-            Warning caused by final field initializer
-  TODO: 3. Check how it works with:
-            Inliners (notably: Stream API)
-            Boxed numbers
-  TODO: 4. Check for possible performance disasters (likely on some code patterns current algo might blow up)
-  TODO: 5. Problem when interesting state doesn't reach the current condition, need to do something with this    
-   */
-  @NotNull
-  private static CauseItem findCauseChain(PsiExpression expression, MemoryStateChange history, DfaProblemType type) {
-    CauseItem root = new CauseItem(type, expression);
-    if (history.getExpression() != expression) return root;
-    root.addChildren(type.findCauses(expression, history));
-    return root;
-  }
-
   @NotNull
-  private static CauseItem[] findConstantValueCause(PsiExpression expression, MemoryStateChange history, Object expectedValue) {
+  private CauseItem[] findConstantValueCause(PsiExpression expression, MemoryStateChange history, Object expectedValue) {
     if (expression instanceof PsiLiteralExpression) return new CauseItem[0];
     Object constantExpressionValue = ExpressionUtils.computeConstantExpression(expression);
     DfaValue value = history.myTopOfStack;
@@ -449,9 +512,9 @@ public class TrackingRunner extends StandardDataFlowRunner {
     return new CauseItem("'" + target + "' was assigned" + suffix, anchor);
   }
 
-  private static CauseItem[] findBooleanResultCauses(PsiExpression expression,
-                                                     MemoryStateChange history,
-                                                     boolean value) {
+  private CauseItem[] findBooleanResultCauses(PsiExpression expression,
+                                              MemoryStateChange history,
+                                              boolean value) {
     if (BoolUtils.isNegation(expression)) {
       PsiExpression negated = BoolUtils.getNegated(expression);
       if (negated != null) {
@@ -522,8 +585,8 @@ public class TrackingRunner extends StandardDataFlowRunner {
       if (operandHistory != null) {
         DfaValue operandValue = operandHistory.myTopOfStack;
         if (!value) {
-          Pair<MemoryStateChange, DfaNullability> nullability = operandHistory.findFact(operandValue, DfaFactType.NULLABILITY);
-          if (nullability.second == DfaNullability.NULL) {
+          FactDefinition<DfaNullability> nullability = operandHistory.findFact(operandValue, DfaFactType.NULLABILITY);
+          if (nullability.myFact == DfaNullability.NULL) {
             CauseItem causeItem = new CauseItem("value '" + operand.getText() + "' is always 'null'", operand);
             causeItem.addChildren(findConstantValueCause(operand, operandHistory, null));
             return new CauseItem[]{causeItem};
@@ -544,23 +607,62 @@ public class TrackingRunner extends StandardDataFlowRunner {
   }
 
   @Nullable
-  private static CauseItem findTypeCause(MemoryStateChange operandHistory, PsiType type, boolean isInstance) {
+  private CauseItem findTypeCause(MemoryStateChange operandHistory, PsiType type, boolean isInstance) {
     PsiExpression operand = Objects.requireNonNull(operandHistory.getExpression());
+    DfaPsiType wanted = getFactory().createDfaType(type);
+    PsiType operandType = operand.getType();
+    if (operandType != null) {
+      DfaPsiType dfaType = getFactory().createDfaType(operandType);
+      TypeConstraint constraint = Objects.requireNonNull(TypeConstraint.empty().withInstanceofValue(dfaType));
+      String explanation = constraint.getAssignabilityExplanation(wanted, isInstance);
+      if (explanation != null) {
+        String name = "an expression";
+        if (operand instanceof PsiMethodCallExpression) {
+          name = "method return";
+        }
+        else if (operand instanceof PsiReferenceExpression) {
+          PsiElement target = ((PsiReferenceExpression)operand).resolve();
+          if (target instanceof PsiField) {
+            name = "field";
+          }
+          else if (target instanceof PsiParameter) {
+            name = "parameter";
+          }
+          else if (target instanceof PsiVariable) {
+            name = "variable";
+          }
+        }
+        if (dfaType == wanted) {
+          explanation = "type is " + dfaType;
+        }
+        return new CauseItem(name + " " + explanation, operand);
+      }
+    }
     DfaValue operandValue = operandHistory.myTopOfStack;
-    DfaPsiType wanted = operandValue.getFactory().createDfaType(type);
 
-    Pair<MemoryStateChange, TypeConstraint> fact = operandHistory.findFact(operandValue, DfaFactType.TYPE_CONSTRAINT);
-    String explanation = fact.second == null ? null : fact.second.getAssignabilityExplanation(wanted, isInstance);
+    FactDefinition<TypeConstraint> fact = operandHistory.findFact(operandValue, DfaFactType.TYPE_CONSTRAINT);
+    String explanation = fact.myFact == null ? null : fact.myFact.getAssignabilityExplanation(wanted, isInstance);
     while (explanation != null) {
-      MemoryStateChange causeLocation = fact.first;
+      MemoryStateChange causeLocation = fact.myChange;
       if (causeLocation == null) break;
       MemoryStateChange prevHistory = causeLocation.myPrevious;
       if (prevHistory == null) break;
       fact = prevHistory.findFact(operandValue, DfaFactType.TYPE_CONSTRAINT);
-      TypeConstraint prevConstraint = fact.second == null ? TypeConstraint.empty() : fact.second;
+      TypeConstraint prevConstraint = fact.getFact(TypeConstraint.empty());
       String prevExplanation = prevConstraint.getAssignabilityExplanation(wanted, isInstance);
       if (prevExplanation == null) {
-        CauseItem causeItem = new CauseItem(explanation, operand);
+        if (causeLocation.myInstruction instanceof AssignInstruction && causeLocation.myTopOfStack == operandValue) {
+          PsiExpression rExpression = ((AssignInstruction)causeLocation.myInstruction).getRExpression();
+          if (rExpression != null) {
+            MemoryStateChange rValuePush = causeLocation.findSubExpressionPush(rExpression);
+            if (rValuePush != null) {
+              CauseItem assignmentItem = createAssignmentCause((AssignInstruction)causeLocation.myInstruction, operandValue);
+              assignmentItem.addChildren(findTypeCause(rValuePush, type, isInstance));
+              return assignmentItem;
+            }
+          }
+        }
+        CauseItem causeItem = new CauseItem("an object " + explanation, operand);
         causeItem.addChildren(new CauseItem("type of '" + operand.getText() + "' is known from #ref", causeLocation));
         return causeItem;
       }
@@ -570,28 +672,32 @@ public class TrackingRunner extends StandardDataFlowRunner {
   }
 
   @NotNull
-  private static CauseItem[] findRelationCause(RelationType relationType,
-                                               MemoryStateChange leftChange,
-                                               MemoryStateChange rightChange) {
+  private CauseItem[] findRelationCause(RelationType relationType, MemoryStateChange leftChange, MemoryStateChange rightChange) {
+    return findRelationCause(relationType, leftChange, leftChange.myTopOfStack, rightChange, rightChange.myTopOfStack);
+  }
+
+  @NotNull
+  private CauseItem[] findRelationCause(RelationType relationType,
+                                        MemoryStateChange leftChange, DfaValue leftValue, 
+                                        MemoryStateChange rightChange, DfaValue rightValue) {
     ProgressManager.checkCanceled();
-    DfaValue leftValue = leftChange.myTopOfStack;
-    DfaValue rightValue = rightChange.myTopOfStack;
-    Pair<MemoryStateChange, DfaNullability> leftNullability = leftChange.findFact(leftValue, DfaFactType.NULLABILITY);
-    Pair<MemoryStateChange, DfaNullability> rightNullability = rightChange.findFact(rightValue, DfaFactType.NULLABILITY);
-    if ((leftNullability.second == DfaNullability.NULL && rightNullability.second == DfaNullability.NOT_NULL) ||
-        (rightNullability.second == DfaNullability.NULL && leftNullability.second == DfaNullability.NOT_NULL)) {
-      return new CauseItem[]{findNullabilityCause(leftChange, leftNullability.first, leftNullability.second),
-        findNullabilityCause(rightChange, rightNullability.first, rightNullability.second)};
-    }
-
-    Pair<MemoryStateChange, LongRangeSet> leftRange = leftChange.findFact(leftValue, DfaFactType.RANGE);
-    Pair<MemoryStateChange, LongRangeSet> rightRange = rightChange.findFact(rightValue, DfaFactType.RANGE);
-    if (leftRange.second != null && rightRange.second != null) {
-      LongRangeSet fromRelation = rightRange.second.fromRelation(relationType.getNegated());
-      if (fromRelation != null && !fromRelation.intersects(leftRange.second)) {
+    FactDefinition<DfaNullability> leftNullability = leftChange.findFact(leftValue, DfaFactType.NULLABILITY);
+    FactDefinition<DfaNullability> rightNullability = rightChange.findFact(rightValue, DfaFactType.NULLABILITY);
+    if ((leftNullability.myFact == DfaNullability.NULL && rightNullability.myFact == DfaNullability.NOT_NULL) ||
+        (rightNullability.myFact == DfaNullability.NULL && leftNullability.myFact == DfaNullability.NOT_NULL)) {
+      return new CauseItem[]{
+        findNullabilityCause(leftChange, leftNullability.myFact),
+        findNullabilityCause(rightChange, rightNullability.myFact)};
+    }
+
+    FactDefinition<LongRangeSet> leftRange = leftChange.findFact(leftValue, DfaFactType.RANGE);
+    FactDefinition<LongRangeSet> rightRange = rightChange.findFact(rightValue, DfaFactType.RANGE);
+    if (leftRange.myFact != null && rightRange.myFact != null) {
+      LongRangeSet fromRelation = rightRange.myFact.fromRelation(relationType.getNegated());
+      if (fromRelation != null && !fromRelation.intersects(leftRange.myFact)) {
         return new CauseItem[]{
-          findRangeCause(leftChange, leftRange.first, leftRange.second, "left operand is %s"),
-          findRangeCause(rightChange, rightRange.first, rightRange.second, "right operand is %s")};
+          findRangeCause(leftChange, leftValue, leftRange.myFact, "left operand is %s"),
+          findRangeCause(rightChange, rightValue, rightRange.myFact, "right operand is %s")};
       }
     }
     if (leftValue instanceof DfaVariableValue) {
@@ -623,12 +729,27 @@ public class TrackingRunner extends StandardDataFlowRunner {
         return new CauseItem[]{findRelationCause(change, (DfaVariableValue)rightValue, relation, leftChange)};
       }
     }
+    if (relationType == RelationType.NE) {
+      SpecialField leftField = SpecialField.fromQualifierType(leftValue.getType());
+      SpecialField rightField = SpecialField.fromQualifierType(leftValue.getType());
+      if (leftField != null && leftField == rightField) {
+        DfaValue leftSpecial = leftField.createValue(getFactory(), leftValue);
+        DfaValue rightSpecial = rightField.createValue(getFactory(), rightValue);
+        CauseItem[] specialCause = findRelationCause(relationType, leftChange, leftSpecial, rightChange, rightSpecial);
+        if (specialCause.length > 0) {
+          CauseItem item =
+            new CauseItem("Values cannot be equal because " + leftValue + "." + leftField + " != " + rightValue + "." + rightField,
+                          (PsiElement)null);
+          item.addChildren(specialCause);
+          return new CauseItem[]{item};
+        }
+      }
+    }
     return new CauseItem[0];
   }
 
-  private static CauseItem findRelationCause(MemoryStateChange change,
-                                             DfaVariableValue value,
-                                             Relation relation, MemoryStateChange counterPartChange) {
+  private CauseItem findRelationCause(MemoryStateChange change, DfaVariableValue value,
+                                      Relation relation, MemoryStateChange counterPartChange) {
     Instruction instruction = change.myInstruction;
     String condition = value + " " + relation;
     if (instruction instanceof AssignInstruction) {
@@ -667,12 +788,12 @@ public class TrackingRunner extends StandardDataFlowRunner {
     return null;
   }
 
-  private static CauseItem findNullabilityCause(MemoryStateChange factUse, MemoryStateChange factDef, DfaNullability nullability) {
+  private CauseItem findNullabilityCause(MemoryStateChange factUse, DfaNullability nullability) {
     PsiExpression expression = factUse.getExpression();
     if (expression instanceof PsiTypeCastExpression) {
       MemoryStateChange operandPush = factUse.findSubExpressionPush(((PsiTypeCastExpression)expression).getOperand());
       if (operandPush != null) {
-        return findNullabilityCause(operandPush, factDef, nullability);
+        return findNullabilityCause(operandPush, nullability);
       }
     }
     if (expression instanceof PsiMethodCallExpression) {
@@ -701,6 +822,8 @@ public class TrackingRunner extends StandardDataFlowRunner {
         }
       }
     }
+    FactDefinition<DfaNullability> info = factUse.findFact(factUse.myTopOfStack, DfaFactType.NULLABILITY);
+    MemoryStateChange factDef = info.myFact == nullability ? info.myChange : null;
     if (nullability == DfaNullability.NOT_NULL) {
       String explanation = getObviouslyNonNullExplanation(expression);
       if (explanation != null) {
@@ -726,8 +849,7 @@ public class TrackingRunner extends StandardDataFlowRunner {
           MemoryStateChange rValuePush = factDef.findSubExpressionPush(rExpression);
           if (rValuePush != null) {
             CauseItem assignmentItem = createAssignmentCause((AssignInstruction)factDef.myInstruction, value);
-            Pair<MemoryStateChange, DfaNullability> rValueFact = rValuePush.findFact(rValuePush.myTopOfStack, DfaFactType.NULLABILITY);
-            assignmentItem.addChildren(findNullabilityCause(rValuePush, rValueFact.first, nullability));
+            assignmentItem.addChildren(findNullabilityCause(rValuePush, nullability));
             return assignmentItem;
           }
         }
@@ -741,8 +863,7 @@ public class TrackingRunner extends StandardDataFlowRunner {
     return null;
   }
 
-  private static CauseItem fromMemberNullability(DfaNullability nullability,
-                                                 PsiModifierListOwner owner,
+  private static CauseItem fromMemberNullability(DfaNullability nullability, PsiModifierListOwner owner,
                                                  String memberName, PsiElement anchor) {
     if (owner != null) {
       NullabilityAnnotationInfo info = NullableNotNullManager.getInstance(owner.getProject()).findEffectiveNullabilityInfo(owner);
@@ -800,32 +921,78 @@ public class TrackingRunner extends StandardDataFlowRunner {
     return null;
   }
 
-  private static CauseItem fromCallContract(MemoryStateChange history, PsiCallExpression call, ContractReturnValue contractReturnValue) {
+  private CauseItem fromCallContract(MemoryStateChange history, PsiCallExpression call, ContractReturnValue contractReturnValue) {
     PsiMethod method = call.resolveMethod();
     if (method == null) return null;
-    List<? extends MethodContract> contracts =
-      ContainerUtil.filter(JavaMethodContractUtil.getMethodCallContracts(method, call),
-                           mc -> contractReturnValue.isSuperValueOf(mc.getReturnValue()));
-    boolean explicit = JavaMethodContractUtil.hasExplicitContractAnnotation(method);
+    List<? extends MethodContract> contracts = JavaMethodContractUtil.getMethodCallContracts(method, call);
+    if (contracts.isEmpty()) return null;
+    MethodContract contract = contracts.get(0);
+    String contractType = JavaMethodContractUtil.hasExplicitContractAnnotation(method) ? "" :
+                          contract instanceof StandardMethodContract ? "inferred " :
+                          "hard-coded ";
     if (call instanceof PsiMethodCallExpression) {
       PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)call).getMethodExpression();
       String name = methodExpression.getReferenceName();
-      for (MethodContract contract : contracts) {
-        if (contract.isTrivial()) {
-          return new CauseItem("according to " + (explicit ? "contract" : "inferred contract") +
-                               ", method '" + name + "' always returns '" + contract.getReturnValue() + "' value",
-                               methodExpression.getReferenceNameElement());
-        }
+      String prefix = "according to " + contractType + "contract, method '" + name + "'";
+      if (contracts.size() == 1 && contract.isTrivial() && contractReturnValue.isSuperValueOf(contract.getReturnValue())) {
+        return new CauseItem(prefix +
+                             " always returns '" + contract.getReturnValue() + "' value",
+                             methodExpression.getReferenceNameElement());
+      }
+      List<? extends MethodContract> nonIntersecting = MethodContract.toNonIntersectingContracts(contracts);
+      if (nonIntersecting != null) {
+        MethodContract onlyContract = ContainerUtil
+          .getOnlyItem(ContainerUtil.filter(nonIntersecting, mc -> contractReturnValue.isSuperValueOf(mc.getReturnValue())));
+        return fromSingleContract(history, (PsiMethodCallExpression)call, method, prefix, onlyContract);
       }
     }
     return null;
   }
 
-  private static CauseItem findRangeCause(MemoryStateChange factUse,
-                                          MemoryStateChange factDef,
-                                          LongRangeSet range,
-                                          String template) {
-    DfaValue value = factUse.myTopOfStack;
+  @Nullable
+  private CauseItem fromSingleContract(MemoryStateChange history, PsiMethodCallExpression call,
+                                       PsiMethod method, String prefix, MethodContract contract) {
+    if (contract == null) return null;
+    List<ContractValue> conditions = contract.getConditions();
+    String conditionsText = StringUtil.join(conditions, c -> c.getPresentationText(method), " and ");
+    String returnValueText = contract.getReturnValue().isFail() ? "throws exception" : "returns '" + contract.getReturnValue() + "' value";
+    CauseItem causeItem = new CauseItem(prefix + " " + returnValueText + " when " + conditionsText,
+      call.getMethodExpression().getReferenceNameElement());
+    for (ContractValue condition : conditions) {
+      DfaRelationValue relation = ObjectUtils.tryCast(condition.fromCall(getFactory(), call), DfaRelationValue.class);
+      PsiExpression leftPlace = condition.findLeftPlace(call);
+      MemoryStateChange leftPush = history.findExpressionPush(leftPlace);
+      PsiExpression rightPlace = condition.findRightPlace(call);
+      MemoryStateChange rightPush = history.findExpressionPush(rightPlace);
+      if (relation != null) {
+        DfaValue left = relation.getLeftOperand();
+        DfaValue right = relation.getRightOperand();
+        RelationType type = relation.getRelation();
+        MemoryStateChange leftChange = history;
+        MemoryStateChange rightChange = history;
+        if (leftPush != null) {
+          if (leftPush.myTopOfStack == left) {
+            leftChange = leftPush;
+          }
+          else if (leftPush.myTopOfStack == right) {
+            rightChange = leftPush;
+          }
+        }
+        if (rightPush != null) {
+          if (rightPush.myTopOfStack == right) {
+            rightChange = rightPush;
+          }
+          else if (rightPush.myTopOfStack == left) {
+            leftChange = rightPush;
+          }
+        }
+        causeItem.addChildren(findRelationCause(type, leftChange, left, rightChange, right));
+      }
+    }
+    return causeItem;
+  }
+
+  private static CauseItem findRangeCause(MemoryStateChange factUse, DfaValue value, LongRangeSet range, String template) {
     if (value instanceof DfaVariableValue) {
       VariableDescriptor descriptor = ((DfaVariableValue)value).getDescriptor();
       if (descriptor instanceof SpecialField && range.equals(LongRangeSet.indexRange())) {
@@ -840,7 +1007,7 @@ public class TrackingRunner extends StandardDataFlowRunner {
         }
       }
     }
-    PsiExpression expression = factUse.getExpression();
+    PsiExpression expression = factUse.myTopOfStack == value ? factUse.getExpression() : null;
     if (expression != null) {
       PsiType type = expression.getType();
       if (expression instanceof PsiLiteralExpression) {
@@ -861,15 +1028,16 @@ public class TrackingRunner extends StandardDataFlowRunner {
         PsiExpression operand = ((PsiTypeCastExpression)expression).getOperand();
         MemoryStateChange operandPush = factUse.findExpressionPush(operand);
         if (operandPush != null) {
-          Pair<MemoryStateChange, LongRangeSet> operandInfo = operandPush.findFact(operandPush.myTopOfStack, DfaFactType.RANGE);
-          LongRangeSet operandRange = operandInfo.second == null ? LongRangeSet.fromType(type) : operandInfo.second;
+          DfaValue castedValue = operandPush.myTopOfStack;
+          FactDefinition<LongRangeSet> operandInfo = operandPush.findFact(castedValue, DfaFactType.RANGE);
+          LongRangeSet operandRange = operandInfo.myFact == null ? LongRangeSet.fromType(type) : operandInfo.myFact;
           if (operandRange != null) {
             LongRangeSet result = operandRange.castTo((PsiPrimitiveType)type);
             if (range.equals(result)) {
               CauseItem cause =
-                new CauseItem("result of '(" + type.getCanonicalText() + ")' cast is " + range.getPresentationText(null), expression);
+                new CauseItem(new RangeDfaProblemType("result of '(" + type.getCanonicalText() + ")' cast is %s", range, null), expression);
               if (!operandRange.equals(LongRangeSet.fromType(operand.getType()))) {
-                cause.addChildren(findRangeCause(operandPush, operandInfo.first, operandRange, "cast operand is %s"));
+                cause.addChildren(findRangeCause(operandPush, castedValue, operandRange, "cast operand is %s"));
               }
               return cause;
             }
@@ -888,27 +1056,24 @@ public class TrackingRunner extends StandardDataFlowRunner {
           MemoryStateChange leftPush = factUse.findExpressionPush(left);
           MemoryStateChange rightPush = factUse.findExpressionPush(right);
           if (leftPush != null && rightPush != null) {
-            DfaValue leftValue = leftPush.myTopOfStack;
-            DfaValue rightValue = rightPush.myTopOfStack;
-            Pair<MemoryStateChange, LongRangeSet> leftSet = leftPush.findFact(leftValue, DfaFactType.RANGE);
-            Pair<MemoryStateChange, LongRangeSet> rightSet = rightPush.findFact(rightValue, DfaFactType.RANGE);
+            DfaValue leftVal = leftPush.myTopOfStack;
+            FactDefinition<LongRangeSet> leftSet = leftPush.findFact(leftVal, DfaFactType.RANGE);
+            DfaValue rightVal = rightPush.myTopOfStack;
+            FactDefinition<LongRangeSet> rightSet = rightPush.findFact(rightVal, DfaFactType.RANGE);
             LongRangeSet fromType = Objects.requireNonNull(LongRangeSet.fromType(type));
-            if (leftSet.second == null) {
-              leftSet = Pair.create(null, fromType);
-            }
-            if (rightSet.second == null) {
-              rightSet = Pair.create(null, fromType);
-            }
-            LongRangeSet result = leftSet.second.binOpFromToken(binOp.getOperationTokenType(), rightSet.second, isLong);
+            LongRangeSet leftRange = leftSet.getFact(fromType);
+            LongRangeSet rightRange = rightSet.getFact(fromType);
+            LongRangeSet result = leftRange.binOpFromToken(binOp.getOperationTokenType(), rightRange, isLong);
             if (range.equals(result)) {
-              CauseItem cause = new CauseItem("result of '" + binOp.getOperationSign().getText() +
-                                              "' is " + range.getPresentationText(type), factUse);
+              String sign = binOp.getOperationSign().getText();
+              CauseItem cause = new CauseItem(new RangeDfaProblemType("result of '" + (sign.equals("%")?"%%":sign) + "' is %s", 
+                                                                      range, ObjectUtils.tryCast(type, PsiPrimitiveType.class)), factUse);
               CauseItem leftCause = null, rightCause = null;
-              if (!leftSet.second.equals(fromType)) {
-                leftCause = findRangeCause(leftPush, leftSet.first, leftSet.second, "left operand is %s");
+              if (!leftRange.equals(fromType)) {
+                leftCause = findRangeCause(leftPush, leftVal, leftRange, "left operand is %s");
               }
-              if (!rightSet.second.equals(fromType)) {
-                rightCause = findRangeCause(rightPush, rightSet.first, rightSet.second, "right operand is %s");
+              if (!rightRange.equals(fromType)) {
+                rightCause = findRangeCause(rightPush, rightVal, rightRange, "right operand is %s");
               }
               cause.addChildren(leftCause, rightCause);
               return cause;
@@ -917,8 +1082,10 @@ public class TrackingRunner extends StandardDataFlowRunner {
         }
       }
     }
-    String rangeText = range.getPresentationText(expression != null ? expression.getType() : null);
-    CauseItem item = new CauseItem(String.format(template, rangeText), factUse);
+    PsiPrimitiveType type = expression != null ? ObjectUtils.tryCast(expression.getType(), PsiPrimitiveType.class) : null;
+    CauseItem item = new CauseItem(new RangeDfaProblemType(template, range, type), factUse);
+    FactDefinition<LongRangeSet> info = factUse.findFact(value, DfaFactType.RANGE);
+    MemoryStateChange factDef = range.equals(info.myFact) ? info.myChange : null;
     if (factDef != null) {
       if (factDef.myInstruction instanceof AssignInstruction && factDef.myTopOfStack == value) {
         PsiExpression rExpression = ((AssignInstruction)factDef.myInstruction).getRExpression();
@@ -926,8 +1093,7 @@ public class TrackingRunner extends StandardDataFlowRunner {
           MemoryStateChange rValuePush = factDef.findSubExpressionPush(rExpression);
           if (rValuePush != null) {
             CauseItem assignmentItem = createAssignmentCause((AssignInstruction)factDef.myInstruction, value);
-            Pair<MemoryStateChange, LongRangeSet> rValueFact = rValuePush.findFact(rValuePush.myTopOfStack, DfaFactType.RANGE);
-            assignmentItem.addChildren(findRangeCause(rValuePush, rValueFact.first, range, "Value is %s"));
+            assignmentItem.addChildren(findRangeCause(rValuePush, rValuePush.myTopOfStack, range, "Value is %s"));
             item.addChildren(assignmentItem);
             return item;
           }
index 81e5ef10645163e427753e5b7f8042b5f276a637..d68c3e85a6c5c0781b05b11d075153964f8ec68d 100644 (file)
@@ -88,12 +88,12 @@ public abstract class TypeConstraint {
       if (actual != expectedAssignable) return null;
       if (expectedAssignable) {
         if (myType == otherType) {
-          return "an object is already known to be " + myType;
+          return "is already known to be " + myType;
         }
-        return "an object type is exactly " + myType + " which is a subtype of " + otherType;
+        return "type is exactly " + myType + " which is a subtype of " + otherType;
       }
       else {
-        return "an object type is exactly " + myType + " which is not a subtype of " + otherType;
+        return "type is exactly " + myType + " which is not a subtype of " + otherType;
       }
     }
 
@@ -418,20 +418,20 @@ public abstract class TypeConstraint {
       if (expectedAssignable) {
         for (DfaPsiType dfaTypeValue : myInstanceofValues) {
           if (otherType.isAssignableFrom(dfaTypeValue)) {
-            return "an object is already known to be " + dfaTypeValue +
+            return "is already known to be " + dfaTypeValue +
                    (otherType == dfaTypeValue ? "" : " which is a subtype of " + otherType);
           }
         }
       } else {
         for (DfaPsiType dfaTypeValue : myNotInstanceofValues) {
           if (dfaTypeValue.isAssignableFrom(otherType)) {
-            return "an object is known to be not " + dfaTypeValue +
+            return "is known to be not " + dfaTypeValue +
                    (otherType == dfaTypeValue ? "" : " which is a supertype of " + otherType);
           }
         }
         for (DfaPsiType dfaTypeValue : myInstanceofValues) {
           if (!otherType.isConvertibleFrom(dfaTypeValue)) {
-            return "an object is known to be " + dfaTypeValue + " which is definitely incompatible with " + otherType;
+            return "is known to be " + dfaTypeValue + " which is definitely incompatible with " + otherType;
           }
         }
       }
index d4055c9250c5d1d22f23ae08640c3d17502aad13..48615b148ac24cc369b59c7321ce1609dead83b0 100644 (file)
@@ -38,7 +38,7 @@ internal data class DelegationContract(internal val expression: ExpressionRange,
     val arguments = call.argumentList.expressions
     val varArgCall = MethodCallInstruction.isVarArgCall(targetMethod, result.substitutor, arguments, parameters)
 
-    val methodContracts = StandardMethodContract.toNonIntersectingContracts(JavaMethodContractUtil.getMethodContracts(targetMethod))
+    val methodContracts = StandardMethodContract.toNonIntersectingStandardContracts(JavaMethodContractUtil.getMethodContracts(targetMethod))
                           ?: return emptyList()
     var fromDelegate = methodContracts.mapNotNull { dc ->
       convertDelegatedMethodContract(method, parameters, arguments, varArgCall, dc)
@@ -47,7 +47,7 @@ internal data class DelegationContract(internal val expression: ExpressionRange,
       fromDelegate = fromDelegate.map(this::returnNotNull) + listOf(
         StandardMethodContract(emptyConstraints(method), ContractReturnValue.returnNotNull()))
     }
-    return StandardMethodContract.toNonIntersectingContracts(fromDelegate) ?: emptyList()
+    return StandardMethodContract.toNonIntersectingStandardContracts(fromDelegate) ?: emptyList()
   }
 
   private fun convertDelegatedMethodContract(callerMethod: PsiMethod,
index 44026674570c69abcd66754819705aaab32a473c..a117e2317ea26bb237f5389d6f417829b5e1573f 100644 (file)
@@ -1258,6 +1258,9 @@ public abstract class LongRangeSet {
           return ">= " + LongRangeSet.formatNumber(myFrom);
         }
       }
+      if (myTo - myFrom == 1) {
+        return myFrom + " or " + myTo;
+      }
       return "in " + toString();
     }
 
@@ -2006,6 +2009,9 @@ public abstract class LongRangeSet {
           return "!= " + diff.min();
         }
       }
+      if (myRanges.length == 4 && myRanges[0] == myRanges[1] && myRanges[2] == myRanges[3]) {
+        return myRanges[0] + " or " + myRanges[2];
+      }
       return "in " + toString();
     }
 
index 3ec5622c99ec12e90753c28f7c3b69f9abc6f868..f654c67e7e2d88d7f6f1d191d89ad77dce166de1 100644 (file)
@@ -3,6 +3,7 @@
 package com.intellij.codeInspection.dataFlow.value;
 
 import com.intellij.codeInspection.dataFlow.DfaUtil;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTypesUtil;
 import com.intellij.psi.util.PsiUtil;
@@ -152,6 +153,7 @@ public class DfaConstValue extends DfaValue {
 
   public String toString() {
     if (myValue == null) return "null";
+    if (myValue instanceof String) return '"' + StringUtil.escapeStringCharacters((String)myValue) + '"';
     return myValue.toString();
   }
 
index a7565232cc20e6444b2daf7d26973c53b04af508..29015a1c8f1b409aa2c2594bcf1a57a57a6dfc40 100644 (file)
@@ -84,6 +84,7 @@
     </component>
     <component>
       <implementation-class>com.intellij.execution.testDiscovery.AffectedTestsInChangeListPainter</implementation-class>
+      <headless-implementation-class/>
     </component>
 
   </project-components>
index a50a9ea98f8cfaad88e9a4b513f0440a8c7525e9..7ca867463543015bfdf8c7457ed40142a93bfe8c 100644 (file)
@@ -317,7 +317,7 @@ public class JavaCompletionUtil {
 
     if (javaReference instanceof PsiJavaCodeReferenceElement) {
       PsiElement refQualifier = ((PsiJavaCodeReferenceElement)javaReference).getQualifier();
-      if (refQualifier == null && PsiTreeUtil.getParentOfType(element, PsiPackageStatement.class) == null) {
+      if (refQualifier == null && PsiTreeUtil.getParentOfType(element, PsiPackageStatement.class, PsiImportStatementBase.class) == null) {
         final StaticMemberProcessor memberProcessor = new JavaStaticMemberProcessor(parameters);
         memberProcessor.processMembersOfRegisteredClasses(matcher, (member, psiClass) -> {
           if (!mentioned.contains(member) && processor.satisfies(member, ResolveState.initial())) {
index a28c5685751157d127ca84109eef932e61f9a80d..2437fe3266974f5b1cdb6e52fa3b8ce9c460a2c4 100644 (file)
@@ -7,6 +7,9 @@ import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
 import com.intellij.codeInsight.editorActions.wordSelection.DocTagSelectioner;
 import com.intellij.codeInsight.javadoc.JavaDocUtil;
 import com.intellij.codeInsight.lookup.*;
+import com.intellij.codeInsight.template.TemplateManager;
+import com.intellij.codeInsight.template.impl.ConstantNode;
+import com.intellij.codeInsight.template.impl.TemplateImpl;
 import com.intellij.codeInspection.InspectionProfile;
 import com.intellij.codeInspection.SuppressionUtilCore;
 import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection;
@@ -17,6 +20,7 @@ import com.intellij.openapi.editor.*;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Conditions;
+import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.patterns.PsiElementPattern;
 import com.intellij.patterns.PsiJavaPatterns;
@@ -414,10 +418,8 @@ public class JavaDocCompletionContributor extends CompletionContributor {
       final Editor editor = context.getEditor();
       final PsiMethod method = item.getObject();
 
-      final PsiParameter[] parameters = method.getParameterList().getParameters();
-      final StringBuilder buffer = new StringBuilder();
-
-      final CharSequence chars = editor.getDocument().getCharsSequence();
+      Document document = editor.getDocument();
+      final CharSequence chars = document.getCharsSequence();
       int endOffset = editor.getCaretModel().getOffset();
       final Project project = context.getProject();
       int afterSharp = CharArrayUtil.shiftBackwardUntil(chars, endOffset - 1, "#") + 1;
@@ -434,41 +436,68 @@ public class JavaDocCompletionContributor extends CompletionContributor {
           context.setTailOffset(endOffset);
         }
       }
-      editor.getDocument().deleteString(afterSharp, endOffset);
+      document.deleteString(afterSharp, endOffset);
       editor.getCaretModel().moveToOffset(signatureOffset);
       editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
       editor.getSelectionModel().removeSelection();
-      buffer.append(method.getName()).append("(");
-      final int afterParenth = afterSharp + buffer.length();
-      for (int i = 0; i < parameters.length; i++) {
-        final PsiType type = TypeConversionUtil.erasure(parameters[i].getType());
-        buffer.append(type.getCanonicalText());
-
-        if (i < parameters.length - 1) {
-          buffer.append(",");
-          if (styleSettings.getCommonSettings(JavaLanguage.INSTANCE).SPACE_AFTER_COMMA) buffer.append(" ");
-        }
-      }
-      buffer.append(")");
+
+      String methodName = method.getName();
+      int beforeParenth = signatureOffset + methodName.length();
+      PsiParameter[] parameters = method.getParameterList().getParameters();
+      String signature = "(" +
+                         StringUtil.join(parameters,
+                                         p -> TypeConversionUtil.erasure(p.getType()).getCanonicalText(),
+                                         "," + (styleSettings.getCommonSettings(JavaLanguage.INSTANCE).SPACE_AFTER_COMMA ? " " : "")) +
+                         ")";
+      String insertString = methodName + signature;
       if (!(tag instanceof PsiInlineDocTag)) {
-        buffer.append(" ");
+        insertString += " ";
       }
       else {
-        final int currentOffset = editor.getCaretModel().getOffset();
-        if (chars.charAt(currentOffset) == '}') {
+        if (chars.charAt(signatureOffset) == '}') {
           afterSharp++;
         }
         else {
-          buffer.append("} ");
+          insertString += "} ";
         }
       }
-      String insertString = buffer.toString();
-      EditorModificationUtil.insertStringAtCaret(editor, insertString);
-      editor.getCaretModel().moveToOffset(afterSharp + buffer.length());
+
+      document.insertString(signatureOffset, insertString);
+      RangeMarker paramListMarker = document.createRangeMarker(TextRange.from(beforeParenth, signature.length()));
+      editor.getCaretModel().moveToOffset(afterSharp + insertString.length());
       editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
-      PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
+      PsiDocumentManager.getInstance(project).commitDocument(document);
 
-      shortenReferences(project, editor, context, afterParenth);
+      shortenReferences(project, editor, context, beforeParenth + 1);
+
+      if (parameters.length > 0) {
+        startParameterListTemplate(context, editor, document, project, paramListMarker);
+      }
+    }
+
+    private static void startParameterListTemplate(@NotNull InsertionContext context,
+                                                   Editor editor,
+                                                   Document document,
+                                                   Project project, RangeMarker paramListMarker) {
+      PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
+      int tail = editor.getCaretModel().getOffset();
+      if (paramListMarker.isValid() && tail >= paramListMarker.getEndOffset()) {
+        PsiDocComment docComment =
+          PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), paramListMarker.getStartOffset(), PsiDocComment.class, false);
+        if (docComment != null) {
+          TemplateImpl template = new TemplateImpl("", "");
+          ConstantNode node = new ConstantNode(document.getText(TextRange.create(paramListMarker)));
+          template.addVariable("PARAMETERS", node, node, true);
+          template.addTextSegment(document.getText(TextRange.create(paramListMarker.getEndOffset(), tail)));
+          template.addEndVariable();
+          template.setToShortenLongNames(false);
+
+          editor.getCaretModel().moveToOffset(paramListMarker.getStartOffset());
+          document.deleteString(paramListMarker.getStartOffset(), tail);
+
+          TemplateManager.getInstance(project).startTemplate(editor, template);
+        }
+      }
     }
 
     private static void shortenReferences(final Project project, final Editor editor, InsertionContext context, int offset) {
index 9736fde30da11b5c7445f1e3fa12453518ca8013..3a7643c15eeadb9c1623bc63bae9ecff33fa481b 100644 (file)
@@ -13,6 +13,7 @@ import com.intellij.patterns.ElementPattern;
 import com.intellij.patterns.PsiElementPattern;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.filters.FilterPositionUtil;
 import com.intellij.psi.templateLanguages.OuterLanguageElement;
 import com.intellij.psi.util.InheritanceUtil;
@@ -43,6 +44,11 @@ public class JavaKeywordCompletion {
       psiElement(PsiJavaCodeReferenceElement.class).insideStarting(
         psiElement().withTreeParent(
           psiElement(PsiParameterList.class).andNot(psiElement(PsiAnnotationParameterList.class)))));
+  private static final InsertHandler<LookupElementDecorator<?>> ADJUST_LINE_OFFSET = (context, item) -> {
+    item.getDelegate().handleInsert(context);
+    context.commitDocument();
+    CodeStyleManager.getInstance(context.getProject()).adjustLineIndent(context.getFile(), context.getStartOffset());
+  };
 
   private static boolean isStatementCodeFragment(PsiFile file) {
     return file instanceof JavaCodeFragment &&
@@ -307,7 +313,9 @@ public class JavaKeywordCompletion {
     PsiSwitchBlock switchBlock = getSwitchFromLabelPosition(myPosition);
     if (switchBlock != null) {
       addKeyword(new OverridableSpace(createKeyword(PsiKeyword.CASE), TailType.INSERT_SPACE));
-      addKeyword(new OverridableSpace(createKeyword(PsiKeyword.DEFAULT), TailTypes.forSwitchLabel(switchBlock)));
+      addKeyword(LookupElementDecorator.withInsertHandler(
+        new OverridableSpace(createKeyword(PsiKeyword.DEFAULT), TailTypes.forSwitchLabel(switchBlock)),
+        ADJUST_LINE_OFFSET));
     }
   }
 
index ece610ea3467918e6265e9e27208429321eae8fa..faebdf75e87ce0c0349262ce6338d557b7c8b48d 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.filters.ElementFilter;
 import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.CollectConsumer;
 import com.intellij.util.Consumer;
 import org.jetbrains.annotations.NotNull;
@@ -105,7 +106,7 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
 
   private static void suggestChainedCalls(CompletionParameters parameters, CompletionResultSet result, PsiElement position) {
     PsiElement parent = position.getParent();
-    if (!(parent instanceof PsiJavaCodeReferenceElement) || parent.getParent() instanceof PsiImportStatementBase) {
+    if (!(parent instanceof PsiJavaCodeReferenceElement) || PsiTreeUtil.getParentOfType(parent, PsiImportStatementBase.class) != null) {
       return;
     }
     PsiElement qualifier = ((PsiJavaCodeReferenceElement)parent).getQualifier();
index d2e358bfbd09d16fece282a45f0088c8a38acd5e..1948158196ed18a157672459e252fed203107ddc 100644 (file)
@@ -129,7 +129,7 @@ public class AddImportAction implements QuestionAction {
           return aValue.getIcon(0);
         }
       };
-    ListPopupImpl popup = new ListPopupImpl(step) {
+    ListPopupImpl popup = new ListPopupImpl(myProject, step) {
       @Override
       protected ListCellRenderer getListElementRenderer() {
         final PopupListElementRenderer baseRenderer = (PopupListElementRenderer)super.getListElementRenderer();
index 9408d4e637d883df6c9d62f9fefde2bd0bac0f54..778a216b7d467927729ceb0beada17c544d741a8 100644 (file)
@@ -131,7 +131,7 @@ public class AddMethodQualifierFix implements IntentionAction {
       qualify(candidates.get(0), editor);
     }
     else {
-      chooseAndQualify(editor, candidates);
+      chooseAndQualify(project, editor, candidates);
     }
   }
 
@@ -140,7 +140,7 @@ public class AddMethodQualifierFix implements IntentionAction {
     return false;
   }
 
-  private void chooseAndQualify(Editor editor, List<PsiVariable> candidates) {
+  private void chooseAndQualify(Project project, Editor editor, List<PsiVariable> candidates) {
     final BaseListPopupStep<PsiVariable> step =
       new BaseListPopupStep<PsiVariable>(QuickFixBundle.message("add.qualifier"), candidates) {
         @Override
@@ -163,7 +163,7 @@ public class AddMethodQualifierFix implements IntentionAction {
         }
       };
 
-    final ListPopupImpl popup = new ListPopupImpl(step);
+    ListPopupImpl popup = new ListPopupImpl(project, step);
     popup.showInBestPositionFor(editor);
   }
 
index 38d27d3ce011a08486fd505992fd9db94139cfda..65dc61e8c544d71a3832bc12ae08782fedbe74bb 100644 (file)
@@ -29,13 +29,15 @@ import com.intellij.util.IncorrectOperationException;
 import gnu.trove.THashMap;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Objects;
+
 /**
  * @author ven
  */
 public class BringVariableIntoScopeFix implements IntentionAction {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.BringVariableIntoScopeFix");
   private final PsiReferenceExpression myUnresolvedReference;
-  private PsiLocalVariable myOutOfScopeVariable;
+  private volatile PsiLocalVariable myOutOfScopeVariable;
 
   BringVariableIntoScopeFix(@NotNull PsiReferenceExpression unresolvedReference) {
     myUnresolvedReference = unresolvedReference;
@@ -61,7 +63,8 @@ public class BringVariableIntoScopeFix implements IntentionAction {
   public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
     if (!(file instanceof PsiJavaFile)) return false;
     if (!myUnresolvedReference.isValid() || !BaseIntentionAction.canModify(myUnresolvedReference)) return false;
-    if (myOutOfScopeVariable != null && !myOutOfScopeVariable.isValid()) return false;
+    PsiLocalVariable variable = myOutOfScopeVariable;
+    if (variable != null && !variable.isValid()) return false;
     if (myUnresolvedReference.isQualified()) return false;
 
     final String referenceName = myUnresolvedReference.getReferenceName();
@@ -71,9 +74,11 @@ public class BringVariableIntoScopeFix implements IntentionAction {
     PsiElement container = PsiTreeUtil.getParentOfType(myUnresolvedReference, PsiCodeBlock.class, PsiClass.class);
     if (!(container instanceof PsiCodeBlock)) return false;
 
-    myOutOfScopeVariable = null;
     while(container.getParent() instanceof PsiStatement || container.getParent() instanceof PsiCatchSection) container = container.getParent();
-    container.accept(new JavaRecursiveElementWalkingVisitor() {
+
+    class Visitor extends JavaRecursiveElementWalkingVisitor {
+      PsiLocalVariable myOutOfScopeVariable;
+      
       @Override
       public void visitReferenceExpression(PsiReferenceExpression expression) {}
 
@@ -93,25 +98,30 @@ public class BringVariableIntoScopeFix implements IntentionAction {
           }
         }
       }
-    });
+    }
+    Visitor visitor = new Visitor();
+    container.accept(visitor);
+    
+    myOutOfScopeVariable = variable = visitor.myOutOfScopeVariable;
 
-    return myOutOfScopeVariable != null && !(myOutOfScopeVariable instanceof PsiResourceVariable);
+    return variable != null && !(variable instanceof PsiResourceVariable);
   }
 
   @Override
   public void invoke(@NotNull Project project, Editor editor, @NotNull PsiFile file) throws IncorrectOperationException {
-    LOG.assertTrue(myOutOfScopeVariable != null);
+    PsiLocalVariable outOfScopeVariable = myOutOfScopeVariable;
+    LOG.assertTrue(outOfScopeVariable != null);
     PsiManager manager = file.getManager();
-    myOutOfScopeVariable.normalizeDeclaration();
-    PsiUtil.setModifierProperty(myOutOfScopeVariable, PsiModifier.FINAL, false);
-    PsiElement commonParent = PsiTreeUtil.findCommonParent(myOutOfScopeVariable, myUnresolvedReference);
+    outOfScopeVariable.normalizeDeclaration();
+    PsiUtil.setModifierProperty(outOfScopeVariable, PsiModifier.FINAL, false);
+    PsiElement commonParent = PsiTreeUtil.findCommonParent(outOfScopeVariable, myUnresolvedReference);
     LOG.assertTrue(commonParent != null);
-    PsiElement child = myOutOfScopeVariable.getTextRange().getStartOffset() < myUnresolvedReference.getTextRange().getStartOffset() ? myOutOfScopeVariable
-                       : myUnresolvedReference;
+    PsiElement child = outOfScopeVariable.getTextRange().getStartOffset() < myUnresolvedReference.getTextRange().getStartOffset() ? 
+                       outOfScopeVariable : myUnresolvedReference;
 
     while(child.getParent() != commonParent) child = child.getParent();
     PsiDeclarationStatement newDeclaration = (PsiDeclarationStatement)JavaPsiFacade.getElementFactory(manager.getProject()).createStatementFromText("int i = 0", null);
-    PsiVariable variable = (PsiVariable)newDeclaration.getDeclaredElements()[0].replace(myOutOfScopeVariable);
+    PsiVariable variable = (PsiVariable)newDeclaration.getDeclaredElements()[0].replace(outOfScopeVariable);
     if (variable.getInitializer() != null) {
       variable.getInitializer().delete();
     }
@@ -129,13 +139,13 @@ public class BringVariableIntoScopeFix implements IntentionAction {
     CodeStyleManager.getInstance(manager.getProject()).reformat(commonParent);
 
     //Leave initializer assignment
-    PsiExpression initializer = myOutOfScopeVariable.getInitializer();
+    PsiExpression initializer = outOfScopeVariable.getInitializer();
     if (initializer != null) {
-      PsiExpressionStatement assignment = (PsiExpressionStatement)JavaPsiFacade.getElementFactory(manager.getProject()).createStatementFromText(myOutOfScopeVariable
-        .getName() + "= e;", null);
-      ((PsiAssignmentExpression)assignment.getExpression()).getRExpression().replace(initializer);
+      PsiExpressionStatement assignment = (PsiExpressionStatement)JavaPsiFacade.getElementFactory(manager.getProject()).createStatementFromText(
+        outOfScopeVariable.getName() + "= e;", null);
+      Objects.requireNonNull(((PsiAssignmentExpression)assignment.getExpression()).getRExpression()).replace(initializer);
       assignment = (PsiExpressionStatement)CodeStyleManager.getInstance(manager.getProject()).reformat(assignment);
-      PsiDeclarationStatement declStatement = PsiTreeUtil.getParentOfType(myOutOfScopeVariable, PsiDeclarationStatement.class);
+      PsiDeclarationStatement declStatement = PsiTreeUtil.getParentOfType(outOfScopeVariable, PsiDeclarationStatement.class);
       LOG.assertTrue(declStatement != null);
       PsiElement parent = declStatement.getParent();
       if (parent instanceof PsiForStatement) {
@@ -146,8 +156,8 @@ public class BringVariableIntoScopeFix implements IntentionAction {
       }
     }
 
-    if (myOutOfScopeVariable.isValid()) {
-      myOutOfScopeVariable.delete();
+    if (outOfScopeVariable.isValid()) {
+      outOfScopeVariable.delete();
     }
 
     if (HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(myUnresolvedReference, addedVar, new THashMap<>(), file) != null) {
index 7e9c3c4763ec4ae8833663358ded0dbac6ade11a..e569f497da0eef4b82c6811f99a016082ac37266 100644 (file)
@@ -150,7 +150,7 @@ public class StaticImportMethodQuestionAction<T extends PsiMember> implements Qu
         }
       };
 
-    final ListPopupImpl popup = new ListPopupImpl(step) {
+    final ListPopupImpl popup = new ListPopupImpl(project, step) {
       final PopupListElementRenderer rightArrow = new PopupListElementRenderer(this);
       @Override
       protected ListCellRenderer getListElementRenderer() {
index 6a9c8e13dc97ced84ad71ac0724e902c1c8c86d1..803af7368f9f33464a96bda2338a2b779009fd1e 100644 (file)
@@ -15,7 +15,7 @@ import com.intellij.util.ObjectUtils;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public class JavaVirtualFileQualifiedNameProvider implements VirtualFileQualifiedNameProvider {
+public class JavaVirtualFileQualifiedNameProvider implements CopyReferenceAction.VirtualFileQualifiedNameProvider {
   @Nullable
   @Override
   public String getQualifiedName(@NotNull Project project, @NotNull VirtualFile virtualFile) {
index 75ddc4ce89058bad26778ca9055b6d2aa16b3ca7..fc533afb8631456a2c832e8327ece239488a9574 100644 (file)
@@ -1,30 +1,12 @@
-/*
- * Copyright 2000-2017 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.internal.statistic.libraryJar;
 
 import com.intellij.facet.frameworks.LibrariesDownloadConnectionService;
 import com.intellij.internal.statistic.utils.StatisticsUploadAssistant;
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.startup.StartupActivity;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.net.HttpConfigurable;
-import com.intellij.util.xmlb.XmlSerializationException;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.XmlSerializer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -67,7 +49,7 @@ public class LibraryJarStatisticsService implements DumbAware {
     try {
       libraryJarDescriptors = XmlSerializer.deserialize(url, LibraryJarDescriptors.class);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException ignored) {
       //
     }
     return libraryJarDescriptors;
index 803816d990232e91a52717ef8f46fd93b7e0384d..f83d08d44612be016102394844615c0ef4b056fa 100644 (file)
@@ -48,10 +48,10 @@ open class JvmClassIntentionActionGroup(
                             file: PsiFile,
                             actions: List<JvmGroupIntentionAction>,
                             invokeAction: (JvmGroupIntentionAction) -> Unit) {
-    createPopup(actions, invokeAction).showInBestPositionFor(editor)
+    createPopup(project, actions, invokeAction).showInBestPositionFor(editor)
   }
 
-  protected fun createPopup(actions: List<JvmGroupIntentionAction>, invokeAction: (JvmGroupIntentionAction) -> Unit): ListPopup {
+  protected fun createPopup(project: Project, actions: List<JvmGroupIntentionAction>, invokeAction: (JvmGroupIntentionAction) -> Unit): ListPopup {
     val targetActions = actions.groupByTo(LinkedHashMap()) { it.target }.mapValues { (_, actions) -> actions.single() }
 
     val step = object : BaseListPopupStep<JvmClass>(message("target.class.chooser.title"), targetActions.keys.toList()) {
@@ -61,7 +61,7 @@ open class JvmClassIntentionActionGroup(
       }
     }
 
-    return object : ListPopupImpl(step) {
+    return object : ListPopupImpl(project, step) {
       // TODO JvmClass renderer
       override fun getListElementRenderer() = PsiClassListCellRenderer()
     }
index 3c2233fecc830f1bfd8f341e79f019af2a9a8d93..532eec00ab92789de8212e49ad1b9b4a02bb59b2 100644 (file)
@@ -14,7 +14,9 @@ import com.intellij.psi.*
 import com.intellij.psi.PsiLanguageInjectionHost.Shred
 import com.intellij.psi.codeStyle.CodeStyleManager
 import com.intellij.psi.impl.PsiDocumentManagerBase
+import com.intellij.psi.impl.source.resolve.FileContextUtil
 import com.intellij.psi.impl.source.tree.injected.changesHandler.*
+import com.intellij.psi.util.createSmartPointer
 import com.intellij.util.SmartList
 import com.intellij.util.containers.ContainerUtil
 import kotlin.math.max
@@ -92,6 +94,18 @@ internal class JavaInjectedFileChangesHandler(shreds: List<Shred>, editor: Edito
       hostPsiFile, workingRange.startOffset, workingRange.endOffset, true)
 
     rebuildMarkers(workingRange)
+
+    updateFileContextElementIfNeeded(hostPsiFile, workingRange)
+  }
+
+  private fun updateFileContextElementIfNeeded(hostPsiFile: PsiFile, workingRange: TextRange) {
+    val fragmentPsiFile = PsiDocumentManager.getInstance(myProject).getCachedPsiFile(myFragmentDocument) ?: return
+
+    val injectedPointer = fragmentPsiFile.getUserData(FileContextUtil.INJECTED_IN_ELEMENT) ?: return
+    if (injectedPointer.element != null) return // still valid no need to update
+
+    val newHost = getInjectionHostAtRange(hostPsiFile, workingRange) ?: return
+    fragmentPsiFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, newHost.createSmartPointer())
   }
 
   private var myInvalidated = false
@@ -175,6 +189,8 @@ internal class JavaInjectedFileChangesHandler(shreds: List<Shred>, editor: Edito
   }
 
   private fun removeHostsFromConcatenation(hostsToRemove: List<MarkersMapping>): TextRange? {
+    val psiPolyadicExpression = hostsToRemove.asSequence().mapNotNull { it.host?.parent as? PsiPolyadicExpression }.distinct().singleOrNull()
+
     for (marker in hostsToRemove.reversed()) {
       val host = marker.host ?: continue
       val relatedElements = getFollowingElements(host) ?: host.prevSiblings.takeWhile(::intermediateElement).toList()
@@ -189,9 +205,9 @@ internal class JavaInjectedFileChangesHandler(shreds: List<Shred>, editor: Edito
       }
     }
 
-    val psiPolyadicExpression = hostsToRemove.asSequence().mapNotNull { it.host?.parent as? PsiPolyadicExpression }.distinct().singleOrNull()
     if (psiPolyadicExpression != null) {
-      psiPolyadicExpression.operands.singleOrNull()?.let { onlyRemaining ->
+      // distinct because Java could duplicate operands sometimes (EA-142380), mb something is wrong with the removal code upper ?
+      psiPolyadicExpression.operands.distinct().singleOrNull()?.let { onlyRemaining ->
         return psiPolyadicExpression.replace(onlyRemaining).textRange
       }
     }
index 8b2b4a7a3458ad576043eb40922d001a4ea435ff..91151075e0a66c96854d0fafda1ec08cda392ff7 100644 (file)
@@ -119,7 +119,9 @@ public abstract class SliceNullnessAnalyzerBase {
     final Ref<NullAnalysisResult> leafExpressions = Ref.create(null);
     final Map<SliceNode, NullAnalysisResult> map = createMap();
 
-    ProgressManager.getInstance().run(new Task.Backgroundable(root.getProject(), "Expanding all nodes... (may very well take the whole day)", true) {
+    String encouragementPiece = " (may very well take the whole day)";
+    ProgressManager.getInstance().run(new Task.Backgroundable(
+      root.getProject(), "Expanding All Nodes..." + encouragementPiece, true) {
       @Override
       public void run(@NotNull final ProgressIndicator indicator) {
         NullAnalysisResult l = calcNullableLeaves(root, treeStructure, map);
index 999b2abb8d91aaa273c621c0a97d8292a747e8bd..38dad2ef2ac0563759d13c71033339389df6d2f9 100644 (file)
@@ -19,7 +19,6 @@ import com.intellij.diagnostic.IdeErrorsDialog;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.application.ApplicationActivationListener;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.DumbAware;
@@ -36,6 +35,10 @@ public final class UnscrambleAction extends AnAction implements DumbAware {
                                                                             new UnscrambleListener());
   }
 
+  public UnscrambleAction() {
+    super("Analyze _Stack Trace or Thread Dump...", "Open console with the navigatable stack trace or a thread dump", null);
+  }
+
   @Override
   public void actionPerformed(@NotNull AnActionEvent e) {
     Project project = e.getRequiredData(CommonDataKeys.PROJECT);
@@ -49,9 +52,6 @@ public final class UnscrambleAction extends AnAction implements DumbAware {
 
   @Override
   public void update(@NotNull AnActionEvent event) {
-    Presentation presentation = event.getPresentation();
-    presentation.setEnabled(event.getProject() != null);
-    presentation.setText("Analyze _Stack Trace or Thread Dump...");
-    presentation.setDescription("Open console with the navigatable stack trace or a thread dump");
+    event.getPresentation().setEnabled(event.getProject() != null);
   }
 }
index f5033bf79eb57e6a153dfac311abad4ab6762b45..8d34b60b222d3ef659d6ffcbf70e8c365fb1736f 100644 (file)
@@ -1,6 +1,8 @@
 <html>
 <body>
 Reports loops which could be replaced with <code>Arrays.setAll()</code> or <code>Arrays.fill()</code> calls.
+Only reports code replaceable with <code>Arrays.setAll()</code> when the project or module is configured to use a language level of 8 or
+higher.
 <p>For example:</p>
 <pre>
   for (int i=0; i&lt;array.length; i++) {
index 68106662cb50a45888a0c7d295c243f3b4cfcb2f..29f8ee1bfb31e61cb45c1beb6b5b20ed1d045f4b 100644 (file)
@@ -404,8 +404,8 @@ public class LambdaUtil {
 
         if (gParent instanceof PsiCall) {
           final PsiCall contextCall = (PsiCall)gParent;
-          final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(contextCall.getArgumentList());
-          JavaResolveResult resolveResult = currentMethod != null ? currentMethod : PsiDiamondType.getDiamondsAwareResolveResult(contextCall);
+          LOG.assertTrue(!MethodCandidateInfo.isOverloadCheck(contextCall.getArgumentList()));
+          JavaResolveResult resolveResult = PsiDiamondType.getDiamondsAwareResolveResult(contextCall);
           return getSubstitutedType(expression, tryToSubstitute, lambdaIdx, resolveResult);
         }
       }
@@ -775,12 +775,9 @@ public class LambdaUtil {
       if (psiCall == null) {
         break;
       }
-      PsiExpressionList argumentList = psiCall.getArgumentList();
-      final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(argumentList);
-      if (currentMethod != null) {
-        if (MethodCandidateInfo.isOverloadCheck(argumentList) || lambdaExpression != null) {
-          break;
-        }
+      if (MethodCandidateInfo.isOverloadCheck(psiCall.getArgumentList()) ||
+          lambdaExpression != null && getFunctionalTypeMap().containsKey(lambdaExpression)) {
+        break;
       }
 
       top = psiCall;
@@ -801,7 +798,7 @@ public class LambdaUtil {
       return null;
     }
 
-    LOG.assertTrue(MethodCandidateInfo.getCurrentMethod(argumentList) == null);
+    LOG.assertTrue(!MethodCandidateInfo.isOverloadCheck(argumentList));
     return top;
   }
 
index f6d035c277e7383aae856ac6ce3e3c37e2a99b17..8c2b9958a293118e1019a3b72be5bbe7dfc7686c 100644 (file)
@@ -189,6 +189,17 @@ public abstract class PsiDiamondType extends PsiType {
         return factory != null ? factory : JavaResolveResult.EMPTY;
       }
     }
+    
+    if (expression instanceof PsiEnumConstant) {
+      final PsiEnumConstant enumConstant = (PsiEnumConstant)expression;
+      PsiClass containingClass = enumConstant.getContainingClass();
+      if (containingClass == null) return JavaResolveResult.EMPTY;
+      final JavaPsiFacade facade = JavaPsiFacade.getInstance(enumConstant.getProject());
+      final PsiClassType type = facade.getElementFactory().createType(containingClass);
+      PsiExpressionList argumentList = enumConstant.getArgumentList();
+      if (argumentList == null) return JavaResolveResult.EMPTY;
+      return facade.getResolveHelper().resolveConstructor(type, argumentList, enumConstant);
+    }
 
     return expression.resolveMethodGenerics();
   }
index 48d80d3f083ac3f16a6e93139444517f64e12ecb..4754dc5abdb2f31469ea16ef627504e1eca4e61a 100644 (file)
@@ -30,7 +30,15 @@ public interface PsiFunctionalExpression extends PsiExpression, Iconable, Naviga
   /**
    * @return true if assignment SAM s = expr is correctly shaped
    */
-  boolean isAcceptable(PsiType left);
+  default boolean isAcceptable(PsiType left) {
+    return isAcceptable(left, null);
+  }
+
+  /**
+   * @param method 
+   * @return true if assignment SAM s = expr is correctly shaped
+   */
+  boolean isAcceptable(PsiType left, @Nullable PsiMethod method);
 
   /**
    * Potentially compatible check takes into account the presence and "shape" of functional interface target types.
index 10fab60573bdca78b988645ca5ec72a7a5f6f644..bfbba1af9e741a358877a94e0a0244cbfd537900 100644 (file)
@@ -63,5 +63,5 @@ public interface PsiMethodReferenceExpression extends PsiReferenceExpression, Ps
    * Potentially compatible, and if exact - congruent
    */
   @Override
-  boolean isAcceptable(PsiType left);
+  boolean isAcceptable(PsiType left, PsiMethod method);
 }
\ No newline at end of file
index b2d579862d9ae41705be465becdb08eb5c72979d..7b5bdd0f8a28e6c6a4f1131a2636e8d1e40ce1cc 100644 (file)
@@ -26,6 +26,7 @@ import com.intellij.psi.*;
 import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
 import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
 import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
 import com.intellij.util.ThreeState;
 import org.intellij.lang.annotations.MagicConstant;
 import org.jetbrains.annotations.NotNull;
@@ -159,7 +160,8 @@ public class MethodCandidateInfo extends CandidateInfo{
         return ApplicabilityLevel.NOT_APPLICABLE;
       }
 
-      int level1 = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel);
+      int level1 = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel, true, true,
+                                                 (left, right, allowUncheckedConversion, argId) -> checkFunctionalInterfaceAcceptance(method, left, right, allowUncheckedConversion));
       if (!isVarargs() && level1 < ApplicabilityLevel.FIXED_ARITY) {
         return ApplicabilityLevel.NOT_APPLICABLE;
       }
@@ -171,6 +173,19 @@ public class MethodCandidateInfo extends CandidateInfo{
     return level;
   }
 
+  private static boolean checkFunctionalInterfaceAcceptance(PsiMethod method, PsiType left, PsiType right, boolean allowUncheckedConversion) {
+    PsiFunctionalExpression fun = null;
+    if (right instanceof PsiLambdaExpressionType) {
+      fun = ((PsiLambdaExpressionType)right).getExpression();
+    }
+    else if (right instanceof PsiMethodReferenceType) {
+      fun = ((PsiMethodReferenceType)right).getExpression();
+    }
+    return fun != null
+           ? !(left instanceof PsiArrayType) && fun.isAcceptable(left, method)
+           : TypeConversionUtil.isAssignable(left, right, allowUncheckedConversion);
+  }
+
   //If m is a generic method and the method invocation does not provide explicit type
   //arguments, then the applicability of the method is inferred as specified in p18.5.1
   public boolean isToInferApplicability() {
index 6bdc42ca619a90a2d22ca5d89796e1b241b3099c..11b2417089ce416df125a8c8144dc5befd77f759 100644 (file)
@@ -447,8 +447,7 @@ public class ExceptionUtil {
     if (MethodCandidateInfo.isOverloadCheck()) {
       return Collections.emptyList();
     }
-    final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(methodCall.getArgumentList());
-    final JavaResolveResult result = currentMethod != null ? currentMethod : PsiDiamondType.getDiamondsAwareResolveResult(methodCall);
+    final JavaResolveResult result = PsiDiamondType.getDiamondsAwareResolveResult(methodCall);
     final PsiElement element = result.getElement();
     final PsiMethod method = element instanceof PsiMethod ? (PsiMethod)element : null;
     if (method == null) {
@@ -458,10 +457,6 @@ public class ExceptionUtil {
       return Collections.emptyList();
     }
 
-    if (currentMethod != null) {
-      PsiUtilCore.ensureValid(method);
-    }
-
     final PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes();
     if (thrownExceptions.length == 0) {
       return Collections.emptyList();
index 7ba84a9f344ab305c8aa1fc6b61a5a34b0f2ed7f..097fb6cf06cf524e7114ea8a3ca73ae07f97f0f3 100644 (file)
@@ -154,7 +154,7 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
   }
 
   private static JavaResolveResult getStaticFactory(final PsiNewExpression newExpression, final PsiElement context) {
-    return context == newExpression && !MethodCandidateInfo.isOverloadCheck()
+    return context == newExpression && !MethodCandidateInfo.isOverloadCheck(newExpression.getArgumentList())
            ? CachedValuesManager.getCachedValue(newExpression,
                                                 () -> new CachedValueProvider.Result<>(
                                                   getStaticFactoryCandidateInfo(newExpression, newExpression),
index 81c29da384cc566985d19bb7e3e995caa161b29a..d3a105b3670d443366a208bc440f4a317950f924 100644 (file)
@@ -128,21 +128,16 @@ public class InferenceSession {
   }
 
   void initExpressionConstraints(PsiParameter[] parameters, PsiExpression[] args, PsiElement parent) {
-    final MethodCandidateInfo currentMethod = getCurrentProperties(parent);
-    initExpressionConstraints(parameters, args, parent, null, currentMethod != null && currentMethod.isVarargs());
+    final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(getArgumentList(parent));
+    initExpressionConstraints(parameters, args,
+                              currentMethod != null ? currentMethod.getElement() : null, 
+                              currentMethod != null && currentMethod.isVarargs());
   }
 
   public void initExpressionConstraints(PsiParameter[] parameters,
                                         PsiExpression[] args,
-                                        PsiElement parent,
                                         PsiMethod method,
                                         boolean varargs) {
-    final MethodCandidateInfo currentMethod = getCurrentProperties(parent);
-    if (method == null) {
-      if (currentMethod != null) {
-        method = currentMethod.getElement();
-      }
-    }
     if (method != null) {
       initThrowsConstraints(method);
     }
@@ -180,11 +175,6 @@ public class InferenceSession {
     return null;
   }
 
-  private static MethodCandidateInfo getCurrentProperties(PsiElement parent) {
-    PsiExpressionList argumentList = getArgumentList(parent);
-    return argumentList != null ? MethodCandidateInfo.getCurrentMethod(argumentList) : null;
-  }
-
   /**
    * Definition from 15.12.2.2 Phase 1: Identify Matching Arity Methods Applicable by Subtyping Strict Invocation
    * An argument expression is considered pertinent to applicability for a potentially-applicable method m unless it has one of the following forms:
@@ -298,7 +288,7 @@ public class InferenceSession {
   public PsiSubstitutor infer(@Nullable PsiParameter[] parameters,
                               @Nullable PsiExpression[] args,
                               @Nullable PsiElement parent) {
-    return infer(parameters, args, parent, getCurrentProperties(parent));
+    return infer(parameters, args, parent, MethodCandidateInfo.getCurrentMethod(getArgumentList(parent)));
   }
 
   @NotNull
@@ -374,7 +364,7 @@ public class InferenceSession {
       else if (parameters != null && parameters.length > 0 && args != null && !isOverloadCheck()) {//todo
         final Set<ConstraintFormula> additionalConstraints = new LinkedHashSet<>();
         final HashSet<ConstraintFormula> ignoredConstraints = new HashSet<>();
-        collectAdditionalConstraints(parameters, args, properties.getElement(), mySiteSubstitutor, additionalConstraints,
+        collectAdditionalConstraints(parameters, args, method, mySiteSubstitutor, additionalConstraints,
                                      ignoredConstraints, properties.isVarargs(), initialSubstitutor);
 
         proceedWithAdditionalConstraints(additionalConstraints, ignoredConstraints);
@@ -428,7 +418,8 @@ public class InferenceSession {
         if (arg instanceof PsiCall) {
           //If the expression is a poly class instance creation expression (15.9) or a poly method invocation expression (15.12), 
           //the set contains all constraint formulas that would appear in the set C when determining the poly expression's invocation type.
-          final PsiMethod calledMethod = getCalledMethod((PsiCall)arg);
+          final JavaResolveResult resolveResult = PsiDiamondType.getDiamondsAwareResolveResult((PsiCall)arg);
+          final PsiMethod calledMethod = resolveResult instanceof MethodCandidateInfo ? (PsiMethod)resolveResult.getElement() : null;
           if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(arg, calledMethod)) {
             collectAdditionalConstraints(additionalConstraints, ignoredConstraints, (PsiCall)arg, initialSubstitutor);
           }
@@ -476,23 +467,6 @@ public class InferenceSession {
     return false;
   }
 
-  private static PsiMethod getCalledMethod(PsiCall arg) {
-    final PsiExpressionList argumentList = arg.getArgumentList();
-    if (argumentList == null) {
-      return null;
-    }
-
-    MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(argumentList);
-    if (currentMethod != null) {
-      return currentMethod.getElement();
-    }
-    final JavaResolveResult resolveResult = PsiDiamondType.getDiamondsAwareResolveResult(arg);
-    if (resolveResult instanceof MethodCandidateInfo) {
-      return (PsiMethod)resolveResult.getElement();
-    }
-    return null;
-  }
-
   private void collectLambdaReturnExpression(Set<ConstraintFormula> additionalConstraints,
                                              Set<ConstraintFormula> ignoredConstraints, 
                                              PsiLambdaExpression lambdaExpression,
@@ -516,8 +490,9 @@ public class InferenceSession {
                                        PsiSubstitutor initialSubstitutor) {
     if (returnExpression instanceof PsiCallExpression) {
       if (addConstraint) {
-        final PsiMethod calledMethod = getCalledMethod((PsiCallExpression)returnExpression);
-        if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(returnExpression, calledMethod)) {
+        final JavaResolveResult resolveResult = PsiDiamondType.getDiamondsAwareResolveResult((PsiCallExpression)returnExpression);
+        if (resolveResult instanceof MethodCandidateInfo && 
+            PsiPolyExpressionUtil.isMethodCallPolyExpression(returnExpression, ((MethodCandidateInfo)resolveResult).getElement())) {
           collectAdditionalConstraints(additionalConstraints, ignoredConstraints, (PsiCallExpression)returnExpression, initialSubstitutor);
         }
       }
@@ -548,15 +523,14 @@ public class InferenceSession {
                                             PsiSubstitutor initialSubstitutor) {
     PsiExpressionList argumentList = callExpression.getArgumentList();
     if (argumentList != null) {
-      MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(argumentList);
-      final JavaResolveResult result = currentMethod != null ? null : PsiDiamondType.getDiamondsAwareResolveResult(callExpression);
-      final PsiMethod method = currentMethod != null ? currentMethod.getElement() : result instanceof MethodCandidateInfo ? ((MethodCandidateInfo)result).getElement() :  null;
+      final JavaResolveResult result = PsiDiamondType.getDiamondsAwareResolveResult(callExpression);
+      final PsiMethod method = result instanceof MethodCandidateInfo ? ((MethodCandidateInfo)result).getElement() :  null;
       if (method != null) {
         final PsiExpression[] newArgs = argumentList.getExpressions();
         final PsiParameter[] newParams = method.getParameterList().getParameters();
         if (newParams.length > 0) {
-          collectAdditionalConstraints(newParams, newArgs, method, chooseSiteSubstitutor(currentMethod, result, method), additionalConstraints,
-                                       ignoredConstraints, chooseVarargsMode(currentMethod, result), initialSubstitutor);
+          collectAdditionalConstraints(newParams, newArgs, method, chooseSiteSubstitutor(null, result, method), additionalConstraints,
+                                       ignoredConstraints, chooseVarargsMode(null, result), initialSubstitutor);
         }
       }
     }
@@ -835,8 +809,9 @@ public class InferenceSession {
       if (gParent instanceof PsiCall) {
         final PsiExpressionList argumentList = ((PsiCall)gParent).getArgumentList();
         if (argumentList != null) {
-          final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(argumentList);
-          if (currentMethod != null && MethodCandidateInfo.isOverloadCheck(argumentList)) {
+          if (MethodCandidateInfo.isOverloadCheck(argumentList)) {//todo overload resolution on method without type parameters: infer argument type
+            final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(argumentList);
+            LOG.assertTrue(currentMethod != null);
             return getTypeByMethod(context, argumentList, currentMethod.getElement(), currentMethod.isVarargs(), currentMethod.getSiteSubstitutor(), inferParent);
           }
 
index 5f985f6c75c4d19e61d0473ddf37dd8347b0cbe2..146a1c92f460364504a831ca4d1747d6dd426a62 100644 (file)
@@ -54,7 +54,6 @@ public class InferenceSessionContainer {
                               @NotNull final ParameterTypeInferencePolicy policy) {
     if (parent instanceof PsiCall) {
       final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList();
-      final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(argumentList);
       //overload resolution can't depend on outer call => should not traverse to top
       if (//in order to to avoid caching of candidates's errors on parent (!) , so check for overload resolution is left here
           //But overload resolution can depend on type of lambda parameter. As it can't depend on lambda body,
@@ -98,6 +97,7 @@ public class InferenceSessionContainer {
           }
 
           if (session != null) {
+            final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(argumentList);
             final PsiSubstitutor childSubstitutor = inferNested(parameters, arguments, (PsiCall)parent, currentMethod, session);
             if (childSubstitutor != null) return childSubstitutor;
           }
@@ -233,7 +233,7 @@ public class InferenceSessionContainer {
       return PsiResolveHelper.ourGraphGuard.doPreventingRecursion(topLevelCall, true, () -> {
         final InferenceSession topLevelSession =
           new InferenceSession(method.getTypeParameters(), ((MethodCandidateInfo)result).getSiteSubstitutor(), topLevelCall.getManager(), topLevelCall, policy);
-        topLevelSession.initExpressionConstraints(topLevelParameters, topLevelArguments, topLevelCall, method, ((MethodCandidateInfo)result).isVarargs());
+        topLevelSession.initExpressionConstraints(topLevelParameters, topLevelArguments, method, ((MethodCandidateInfo)result).isVarargs());
         topLevelSession.infer(topLevelParameters, topLevelArguments, topLevelCall, ((MethodCandidateInfo)result));
         return topLevelSession;
       });
index 3b4767f7ac45004c96279d5cabc29d99a5251222..b9e32abebec30742f38b60320ea74e7ef9672fc5 100644 (file)
@@ -161,8 +161,7 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
         if (method != null) {
           final PsiExpression[] args = argumentList.getExpressions();
           final PsiParameter[] parameters = method.getParameterList().getParameters();
-          callSession.initExpressionConstraints(parameters, args, expression, method, InferenceSession
-            .chooseVarargsMode(currentMethod, resolveResult));
+          callSession.initExpressionConstraints(parameters, args, method, InferenceSession.chooseVarargsMode(currentMethod, resolveResult));
         }
         if (callSession.repeatInferencePhases()) {
 
index 8311ad46eb5c9067a3869e362fee82ff6f89c705..647605b0f8f672d35fc483a35b6619a3de0a1d1f 100644 (file)
@@ -167,7 +167,7 @@ public class PsiLambdaExpressionImpl extends JavaStubPsiElement<FunctionalExpres
   }
 
   @Override
-  public boolean isAcceptable(PsiType leftType) {
+  public boolean isAcceptable(PsiType leftType, @Nullable PsiMethod method) {
     if (leftType instanceof PsiIntersectionType) {
       for (PsiType conjunctType : ((PsiIntersectionType)leftType).getConjuncts()) {
         if (isAcceptable(conjunctType)) return true;
@@ -176,17 +176,13 @@ public class PsiLambdaExpressionImpl extends JavaStubPsiElement<FunctionalExpres
     }
     final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
 
-    if (MethodCandidateInfo.isOverloadCheck(argsList)) {
-      final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(argsList);
-      if (currentMethod != null) {
-        final PsiMethod method = currentMethod.getElement();
-        if (hasFormalParameterTypes() && !InferenceSession.isPertinentToApplicability(this, method)) {
-          return true;
-        }
+    if (MethodCandidateInfo.isOverloadCheck(argsList) && method != null) {
+      if (hasFormalParameterTypes() && !InferenceSession.isPertinentToApplicability(this, method)) {
+        return true;
+      }
 
-        if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) {
-          return true;
-        }
+      if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) {
+        return true;
       }
     }
 
index 610776d0c2a38385a9cba230f8e227a9599502a3..c2a187c3b68cf20d9b651d998ad343b475b6a7ca 100644 (file)
@@ -372,7 +372,7 @@ public class PsiMethodReferenceExpressionImpl extends JavaStubPsiElement<Functio
   }
 
   @Override
-  public boolean isAcceptable(PsiType left) {
+  public boolean isAcceptable(PsiType left, PsiMethod method) {
     if (left instanceof PsiIntersectionType) {
       for (PsiType conjunct : ((PsiIntersectionType)left).getConjuncts()) {
         if (isAcceptable(conjunct)) return true;
@@ -382,17 +382,13 @@ public class PsiMethodReferenceExpressionImpl extends JavaStubPsiElement<Functio
 
     final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
     final boolean isExact = isExact();
-    if (MethodCandidateInfo.isOverloadCheck(argsList)) {
-      final MethodCandidateInfo currentMethod = MethodCandidateInfo.getCurrentMethod(argsList);
-      if (currentMethod != null) {
-        final PsiMethod method = currentMethod.getElement();
-        if (isExact && !InferenceSession.isPertinentToApplicability(this, method)) {
-          return true;
-        }
+    if (method != null && MethodCandidateInfo.isOverloadCheck(argsList)) {
+      if (isExact && !InferenceSession.isPertinentToApplicability(this, method)) {
+        return true;
+      }
 
-        if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) {
-          return true;
-        }
+      if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) {
+        return true;
       }
     }
 
diff --git a/java/java-tests/testData/codeInsight/completion/keywords/indentDefaultInSwitch.java b/java/java-tests/testData/codeInsight/completion/keywords/indentDefaultInSwitch.java
new file mode 100644 (file)
index 0000000..b21af10
--- /dev/null
@@ -0,0 +1,8 @@
+public class StructuredConfigKey {
+  {
+    switch (x) {
+        case 2:
+           def<caret>
+    }
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/completion/keywords/indentDefaultInSwitch_after.java b/java/java-tests/testData/codeInsight/completion/keywords/indentDefaultInSwitch_after.java
new file mode 100644 (file)
index 0000000..cbecd48
--- /dev/null
@@ -0,0 +1,8 @@
+public class StructuredConfigKey {
+  {
+    switch (x) {
+        case 2:
+        default:<caret>
+    }
+  }
+}
index 40ca65a09ae6f98b17a9205077b9cb94d2efa12a..c4cb1e127cd326ba6960ecbd4a76ab91505e0ec0 100644 (file)
@@ -1,10 +1,7 @@
 /*
-Value is always false (foo > 3; line#16)
-  One of the following happens:
-    Left operand is 1 (foo; line#16)
-      'foo' was assigned (=; line#15)
-    or left operand is 2 (foo; line#16)
-      'foo' was assigned (=; line#15)
+Value is always false (foo > 3; line#13)
+  Left operand is 1 or 2 (foo; line#13)
+    'foo' was assigned (=; line#12)
  */
 
 import org.jetbrains.annotations.Nullable;
diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/CollectionSizeEquality.java b/java/java-tests/testData/inspection/dataFlow/tracker/CollectionSizeEquality.java
new file mode 100644 (file)
index 0000000..f2c2cd8
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+Value is always false (l1 == l2; line#16)
+  Values cannot be equal because l1.size != l2.size
+    Left operand is 0 (l1; line#16)
+      Range is known from line #14 (!l1.isEmpty(); line#14)
+    and right operand is in {3..Integer.MAX_VALUE} (l2; line#16)
+      Range is known from line #15 (l2.size() < 3; line#15)
+ */
+
+import java.util.List;
+
+class Test {
+  void test(List<String> l1, List<String> l2) {
+    if (!l1.isEmpty()) return;
+    if (l2.size() < 3) return;
+    if (<selection>l1 == l2</selection>) {
+      
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/EqualsContract.java b/java/java-tests/testData/inspection/dataFlow/tracker/EqualsContract.java
new file mode 100644 (file)
index 0000000..78cf4e1
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+Value is always false (s.equals("."); line#14)
+  According to hard-coded contract, method 'equals' returns 'false' value when this != parameter (equals; line#14)
+    Values cannot be equal because s.length != ".".length
+      Left operand is in {2..Integer.MAX_VALUE} (s; line#14)
+        Range is known from line #14 (s.startsWith("--"); line#14)
+      and right operand is 1 ("."; line#14)
+ */
+
+import java.util.Objects;
+
+class Test {
+  void test(String s) {
+    if (s.startsWith("--") && <selection>s.equals(".")</selection>) {
+      
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/FailingCall.java b/java/java-tests/testData/inspection/dataFlow/tracker/FailingCall.java
new file mode 100644 (file)
index 0000000..99d8081
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+Call always fails (foo(s, "checked"); line#12)
+  According to inferred contract, method 'foo' throws exception when obj == null (foo; line#12)
+    Condition 's == null' was checked before (s == null; line#11)
+ */
+
+import java.util.Objects;
+
+class Test {
+  void test(String s) {
+    if (s == null) {
+      <selection>foo(s, "checked")</selection>;
+    }
+  }
+  
+  static void foo(Object obj, String message) {
+    if(obj == null) {
+      throw new RuntimeException(message);
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/InstanceOfMethodReturn.java b/java/java-tests/testData/inspection/dataFlow/tracker/InstanceOfMethodReturn.java
new file mode 100644 (file)
index 0000000..f1552d9
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+Value is always true (x instanceof String; line#15)
+  'x' was assigned (=; line#13)
+    Method return type is String (str(); line#13)
+ */
+
+import java.util.Objects;
+
+class Test {
+  String str() {return "foo";}
+  
+  void test() {
+    Object x = str();
+    System.out.println(x.hashCode());
+    if(<selection>x instanceof String</selection>) {
+      
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/SimpleContract.java b/java/java-tests/testData/inspection/dataFlow/tracker/SimpleContract.java
new file mode 100644 (file)
index 0000000..9285724
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+Value is always false (Objects.isNull(s); line#12)
+  According to inferred contract, method 'isNull' returns 'false' value when parameter != null (isNull; line#12)
+    's' was dereferenced (s; line#11)
+ */
+
+import java.util.Objects;
+
+class Test {
+  void test(String s) {
+    System.out.println(s.trim());
+    if (<selection>Objects.isNull(s)</selection>) {
+      
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/SimpleContract2.java b/java/java-tests/testData/inspection/dataFlow/tracker/SimpleContract2.java
new file mode 100644 (file)
index 0000000..23d433d
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+Value is always false (Objects.isNull(s.trim()); line#11)
+  According to inferred contract, method 'isNull' returns 'false' value when parameter != null (isNull; line#11)
+    Method 'trim' is externally annotated as 'non-null' (trim; line#11)
+ */
+
+import java.util.Objects;
+
+class Test {
+  void test(String s) {
+    if (<selection>Objects.isNull(s.trim())</selection>) {
+      
+    }
+  }
+}
\ No newline at end of file
index d785d05ba357f95a34cdd972fc6e5d383df30194..6a0a3d65e2ad6dcaa4d3c15c91e64947e893069a 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace loop with 'Arrays.fill' method call" "true"
+// "Replace loop with 'Arrays.fill()' method call" "true"
 import java.util.Arrays;
 import java.util.List;
 
index f6244ae7b80ce48f09d2315b855c4c7788f33ef3..d7c961e6bbd1bc4711f899f0663f12b2e532d59c 100644 (file)
@@ -1,6 +1,6 @@
 import java.util.Arrays;
 
-// "Replace loop with 'Arrays.setAll' method call" "true"
+// "Replace loop with 'Arrays.setAll()' method call" "true"
 public class Test {
     private Object[] data;
 
index 9b20af4876e8a225cb9d3fa6d709b4294dcdeab5..30a02c6459b20b94ca9d85a7c28ade13a295e387 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace loop with 'Arrays.setAll' method call" "true"
+// "Replace loop with 'Arrays.setAll()' method call" "true"
 import java.util.Arrays;
 import java.util.List;
 
index e0498b478352949062a3658dc2671c60aef18522..5b9c968e412fc129f0473c23b4eb8dbe504071aa 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace loop with 'Arrays.fill' method call" "true"
+// "Replace loop with 'Arrays.fill()' method call" "true"
 import java.util.Arrays;
 import java.util.List;
 
index 30c9ac4e1a160e4686308f83c2f417d2e737f180..1e699628effb53b8d408ce7026a8981c6291aa53 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace loop with 'Arrays.setAll' method call" "true"
+// "Replace loop with 'Arrays.setAll()' method call" "true"
 public class Test {
     private Object[] data;
 
index f9c9f323a844d79e24cca478ce1a74f8196b1c6c..8003ead3daabd534b1eac809705f2b43d51ccaa9 100644 (file)
@@ -1,4 +1,4 @@
-// "Replace loop with 'Arrays.setAll' method call" "true"
+// "Replace loop with 'Arrays.setAll()' method call" "true"
 import java.util.Arrays;
 import java.util.List;
 
index d73687c377d64244e588f7ff9dcd5a229a1b55d0..0932c7f52d008b317bf6b7919343c6403b0c6411 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.CodeInsightSettings
 import com.intellij.codeInsight.completion.CompletionType
 import com.intellij.codeInsight.completion.LightFixtureCompletionTestCase
 import com.intellij.codeInsight.lookup.LookupElement
+import com.intellij.codeInsight.template.impl.TemplateManagerImpl
 import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection
 import com.intellij.lang.java.JavaLanguage
 import com.intellij.patterns.PlatformPatterns
@@ -638,10 +639,17 @@ class Foo {
   }
 
   void "test insert link to method"() {
+    TemplateManagerImpl.setTemplateTesting(myFixture.getTestRootDisposable())
     myFixture.configureByText 'a.java', "/** a. #fo<caret> */ interface Foo { void foo(int a); }}"
     myFixture.completeBasic()
     myFixture.type('\n')
+
+    myFixture.checkResult "/** a. {@link #foo<selection>(int)<caret></selection>} */ interface Foo { void foo(int a); }}"
+    assert TemplateManagerImpl.getTemplateState(myFixture.editor)
+
+    myFixture.type('\t')
     myFixture.checkResult "/** a. {@link #foo(int)}<caret> */ interface Foo { void foo(int a); }}"
+    assert !TemplateManagerImpl.getTemplateState(myFixture.editor)
   }
 
   void "test insert link to field"() {
@@ -692,4 +700,18 @@ interface Bar<T> extends Foo<T> {
     myFixture.completeBasic()
     myFixture.assertPreferredCompletionItems 0, 'foo', 'finalize'
   }
+
+  void "test allow to easily omit method parameters"() {
+    TemplateManagerImpl.setTemplateTesting(myFixture.getTestRootDisposable())
+    myFixture.configureByText 'a.java', "/** {@link #fo<caret>} */ interface Foo { void foo(int a); }}"
+    myFixture.completeBasic()
+
+    myFixture.checkResult "/** {@link #foo<selection>(int)<caret></selection>} */ interface Foo { void foo(int a); }}"
+    assert TemplateManagerImpl.getTemplateState(myFixture.editor)
+
+    myFixture.type('\b\n')
+    myFixture.checkResult "/** {@link #foo}<caret> */ interface Foo { void foo(int a); }}"
+    assert !TemplateManagerImpl.getTemplateState(myFixture.editor)
+  }
+
 }
\ No newline at end of file
index 1042e858b473ec3134bd8d4854e67dd2afaf7a60..89e970fd1d9864f49bf4f3aff9046506fbee3767 100644 (file)
@@ -144,6 +144,7 @@ public class KeywordCompletionTest extends LightCompletionTestCase {
   public void testFinalAfterParameterAnno2() { doTest(2, "final", "float", "class"); }
   public void testFinalAfterCase() { doTest(3, "final", "float", "class"); }
   public void testNoCaseInsideWhileInSwitch() { doTest(0, "case", "default"); }
+  public void testIndentDefaultInSwitch() { doTest(); }
   public void testFinalInCatch() { doTest(1, "final"); }
   public void testFinalInIncompleteCatch() { doTest(1, "final"); }
   public void testFinalInCompleteCatch() { doTest(1, "final"); }
index ac95bd50e3b41cf248f75ab3cbd934524ece1c1f..d2192fefa83429dc86652def325e2c5a714489b7 100644 (file)
@@ -392,4 +392,12 @@ class Test88 {
     assert !('finalize' in myFixture.lookupElementStrings)
   }
 
+  void "test only importable suggestions in import"() {
+    CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE
+    myFixture.addClass("package com.foo; public class Comments { public static final int B = 2; }")
+    myFixture.configureByText("a.java", "import com.<caret>x.y;\n" +
+                                        "import static java.util.stream.Collectors.joining;")
+    myFixture.completeBasic()
+    assert myFixture.lookupElementStrings == ['foo']
+  }
 }
\ No newline at end of file
index 851c37f1fcc08745e545c53616ad024bcc3f2a07..b8a2ef574abc9366e15db4172d242b1b5129a330 100644 (file)
@@ -100,6 +100,9 @@ public class DataFlowInspectionTrackerTest extends LightCodeInsightFixtureTestCa
       return new TrackingRunner.NullableDfaProblemType();
     }
     CommonDataflow.DataflowResult result = CommonDataflow.getDataflowResult(expression);
+    if (expression instanceof PsiCallExpression && !result.cannotFailByContract((PsiCallExpression)expression)) {
+      return new TrackingRunner.FailingCallDfaProblemType();
+    }
     assertNotNull("No common dataflow result for expression: " + selectedText, result);
     Set<Object> values = result.getExpressionValues(expression);
     assertEquals("No single value for expression: "+selectedText, 1, values.size());
@@ -161,4 +164,10 @@ public class DataFlowInspectionTrackerTest extends LightCodeInsightFixtureTestCa
   public void testNumericCast() { doTest(); }
   public void testNumericCast2() { doTest(); }
   public void testNumericWidening() { doTest(); }
+  public void testSimpleContract() { doTest(); }
+  public void testSimpleContract2() { doTest(); }
+  public void testEqualsContract() { doTest(); }
+  public void testCollectionSizeEquality() { doTest(); }
+  public void testFailingCall() { doTest(); }
+  public void testInstanceOfMethodReturn() { doTest(); }
 }
index 42e9f78520316ed60e64b80799dce0c7bc75d988..ecd6231590ae8f29ee8058ff64cde2837feefa31 100644 (file)
@@ -1,10 +1,16 @@
 // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.codeInspection;
 
+import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiAnnotation;
+import com.intellij.psi.PsiAnnotationMemberValue;
+import com.intellij.psi.PsiModifierListOwner;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Collections;
 import java.util.List;
 
 public class NlsCapitalizationUtil {
@@ -56,4 +62,14 @@ public class NlsCapitalizationUtil {
            ? StringUtil.wordsToBeginFromUpperCase(string)
            : StringUtil.capitalize(StringUtil.wordsToBeginFromLowerCase(string));
   }
+
+  @NotNull
+  public static Nls.Capitalization getCapitalizationFromAnno(PsiModifierListOwner modifierListOwner) {
+    PsiAnnotation nls = AnnotationUtil.findAnnotationInHierarchy(modifierListOwner, Collections.singleton(Nls.class.getName()));
+    if (nls == null) return Nls.Capitalization.NotSpecified;
+    PsiAnnotationMemberValue capitalization = nls.findAttributeValue("capitalization");
+    Object cap = JavaPsiFacade
+      .getInstance(modifierListOwner.getProject()).getConstantEvaluationHelper().computeConstantExpression(capitalization);
+    return cap instanceof Nls.Capitalization ? (Nls.Capitalization)cap : Nls.Capitalization.NotSpecified;
+  }
 }
index 0c89edbab5e4ec406b39ab307024a012f259e019..6e35124e1ea6f4319a38f2e061f37eae3c07e8d3 100644 (file)
@@ -8,8 +8,6 @@ import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
 import com.intellij.util.PathUtil;
 import org.jetbrains.annotations.NonNls;
 
-import java.util.stream.Stream;
-
 public abstract class StringToUpperWithoutLocaleInspectionTestBase extends JavaCodeInsightFixtureTestCase {
   @Override
   protected void setUp() throws Exception {
@@ -22,6 +20,5 @@ public abstract class StringToUpperWithoutLocaleInspectionTestBase extends JavaC
     moduleBuilder.setLanguageLevel(LanguageLevel.JDK_1_8);
     moduleBuilder.addJdk(IdeaTestUtil.getMockJdk18Path().getPath());
     moduleBuilder.addLibrary("annotations", PathUtil.getJarPathForClass(NonNls.class));
-    moduleBuilder.addLibrary("javaUtil", PathUtil.getJarPathForClass(Stream.class));
   }
 }
index 1d4b88fbd6d87b0ea5861113aa48a73168b4f013..1e83389c4565cd954451316ed65c5bbd777b850a 100644 (file)
@@ -6,13 +6,11 @@ import com.intellij.testFramework.IdeaTestUtil;
 import com.intellij.testFramework.TestDataFile;
 import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
 import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
-import com.intellij.util.PathUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.uast.UCallExpression;
 import org.jetbrains.uast.UCallableReferenceExpression;
 import org.jetbrains.uast.UastCallKind;
 
-import java.util.Locale;
 import java.util.Set;
 
 import static com.intellij.codeInspection.UastCallMatcher.builder;
@@ -22,7 +20,6 @@ public abstract class UastCallMatcherTestBase extends JavaCodeInsightFixtureTest
   @Override
   protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) {
     moduleBuilder.addJdk(IdeaTestUtil.getMockJdk18Path().getPath());
-    moduleBuilder.addLibrary("javaUtil", PathUtil.getJarPathForClass(Locale.class));
   }
 
   protected static int matchCallExpression(UastCallMatcher matcher, Set<? extends UCallExpression> expressions) {
index 6f82beff340429ddf09d7f62bf78e5b6a5e4c724..4d8526bd784894fb4026c53ee403d3ba8aa7e25b 100644 (file)
@@ -18,8 +18,8 @@ import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
 import com.intellij.util.ResourceUtil;
 import com.intellij.util.ThreeState;
 import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.SerializationFilter;
-import com.intellij.util.xmlb.XmlSerializationException;
 import com.intellij.util.xmlb.annotations.Property;
 import gnu.trove.THashSet;
 import gnu.trove.TObjectHashingStrategy;
@@ -307,7 +307,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool {
       try {
         XmlSerializer.deserializeInto(node, this);
       }
-      catch (XmlSerializationException e) {
+      catch (SerializationException e) {
         throw new InvalidDataException(e);
       }
     }
index bbe754eb7c43e2ecb049b16342ee3b3e48b64d9e..83700eb9d0733e8785ca80cb5557b793b4c4f6be 100644 (file)
@@ -158,6 +158,7 @@ class CommunityRepositoryModules {
       withModule("intellij.maven.artifactResolver.common", "artifact-resolver-m3.jar")
       withModule("intellij.maven.artifactResolver.m31", "artifact-resolver-m31.jar")
       withModule("intellij.maven.artifactResolver.common", "artifact-resolver-m31.jar")
+      withArtifact("maven-event-listener", "")
       withResource("maven36-server-impl/lib/maven3", "lib/maven3")
       withResource("maven3-server-common/lib", "lib/maven3-server-lib")
       withResource("maven2-server-impl/lib/maven2", "lib/maven2")
index 6f225ab1a141757c5de8f49d043b01a2d4c93c0b..10d772a2b5cde6288fe662b6bc2f8f92c4c71d6f 100644 (file)
@@ -76,7 +76,7 @@ class GradleRunner {
     } else {
       command.add('--no-daemon')
     }
-    def additionalParams = System.getProperty('intellij.build.additional.gradle.parameters')
+    def additionalParams = System.getProperty('intellij.gradle.jdk.build.parameters')
     if (additionalParams != null && !additionalParams.isEmpty()) {
       command.addAll(additionalParams.split(" "))
     }
index e399747df077bea2565b1c62e2ee19001753daea..f7a80b67a93e2b8745c3fd5ec2830663789be979 100644 (file)
@@ -152,7 +152,7 @@ class JpsCompilationRunner {
 
   private void runBuild(final Set<String> modulesSet, final boolean allModules, Collection<String> artifactNames, boolean includeTests,
                         boolean resolveProjectDependencies) {
-    if (!modulesSet.isEmpty() || allModules) {
+    if (context.options.jdkVersion < 9 && (!modulesSet.isEmpty() || allModules)) {
       addToolsJarToSystemClasspath(context.paths.jdkHome, context.messages)
     }
     System.setProperty(GlobalOptions.USE_DEFAULT_FILE_LOGGING_OPTION, "false")
index 4ac5701eabe5eb2f96e4525e9c3d1c932f95e21e..e03c5a1a3191f95e9dfd35d051275a6f1dae29b9 100644 (file)
@@ -37,11 +37,23 @@ internal class CodeStyleTest {
       <codeStyleSettings language="CoffeeScript">
         <option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
       </codeStyleSettings>
+      <codeStyleSettings language="DB2">
+        <option name="KEEP_LINE_BREAKS" value="false" />
+      </codeStyleSettings>
+      <codeStyleSettings language="Derby">
+        <option name="KEEP_LINE_BREAKS" value="false" />
+      </codeStyleSettings>
       <codeStyleSettings language="Gherkin">
         <indentOptions>
           <option name="USE_TAB_CHARACTER" value="true" />
         </indentOptions>
       </codeStyleSettings>
+      <codeStyleSettings language="H2">
+        <option name="KEEP_LINE_BREAKS" value="false" />
+      </codeStyleSettings>
+      <codeStyleSettings language="HSQLDB">
+        <option name="KEEP_LINE_BREAKS" value="false" />
+      </codeStyleSettings>
       <codeStyleSettings language="MySQL">
         <option name="KEEP_LINE_BREAKS" value="false" />
       </codeStyleSettings>
@@ -54,6 +66,12 @@ internal class CodeStyleTest {
       <codeStyleSettings language="SQL">
         <option name="KEEP_LINE_BREAKS" value="false" />
       </codeStyleSettings>
+      <codeStyleSettings language="SQLite">
+        <option name="KEEP_LINE_BREAKS" value="false" />
+      </codeStyleSettings>
+      <codeStyleSettings language="Sybase">
+        <option name="KEEP_LINE_BREAKS" value="false" />
+      </codeStyleSettings>
       <codeStyleSettings language="TSQL">
         <option name="KEEP_LINE_BREAKS" value="false" />
       </codeStyleSettings>
@@ -117,11 +135,23 @@ internal class CodeStyleTest {
         <codeStyleSettings language="CoffeeScript">
           <option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
         </codeStyleSettings>
+        <codeStyleSettings language="DB2">
+          <option name="KEEP_LINE_BREAKS" value="false" />
+        </codeStyleSettings>
+        <codeStyleSettings language="Derby">
+          <option name="KEEP_LINE_BREAKS" value="false" />
+        </codeStyleSettings>
         <codeStyleSettings language="Gherkin">
           <indentOptions>
             <option name="USE_TAB_CHARACTER" value="true" />
           </indentOptions>
         </codeStyleSettings>
+        <codeStyleSettings language="H2">
+          <option name="KEEP_LINE_BREAKS" value="false" />
+        </codeStyleSettings>
+        <codeStyleSettings language="HSQLDB">
+          <option name="KEEP_LINE_BREAKS" value="false" />
+        </codeStyleSettings>
         <codeStyleSettings language="MySQL">
           <option name="KEEP_LINE_BREAKS" value="false" />
         </codeStyleSettings>
@@ -134,6 +164,12 @@ internal class CodeStyleTest {
         <codeStyleSettings language="SQL">
           <option name="KEEP_LINE_BREAKS" value="false" />
         </codeStyleSettings>
+        <codeStyleSettings language="SQLite">
+          <option name="KEEP_LINE_BREAKS" value="false" />
+        </codeStyleSettings>
+        <codeStyleSettings language="Sybase">
+          <option name="KEEP_LINE_BREAKS" value="false" />
+        </codeStyleSettings>
         <codeStyleSettings language="TSQL">
           <option name="KEEP_LINE_BREAKS" value="false" />
         </codeStyleSettings>
index 249861906651b29cfc769e372ed4bddcefe0b7b9..08499c4eb5d4d39ee838387cca55d4ea07cbf300 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 @file:Suppress("PropertyName")
 
 package com.intellij.configurationStore.xml
@@ -12,7 +12,11 @@ import com.intellij.openapi.util.text.StringUtil
 import com.intellij.testFramework.UsefulTestCase
 import com.intellij.testFramework.assertConcurrent
 import com.intellij.testFramework.assertions.Assertions.assertThat
-import com.intellij.util.xmlb.*
+import com.intellij.util.serialization.SerializationException
+import com.intellij.util.xmlb.Accessor
+import com.intellij.util.xmlb.SerializationFilter
+import com.intellij.util.xmlb.SkipDefaultsSerializationFilter
+import com.intellij.util.xmlb.XmlSerializer
 import com.intellij.util.xmlb.annotations.*
 import junit.framework.TestCase
 import org.intellij.lang.annotations.Language
@@ -326,7 +330,7 @@ internal class XmlSerializerTest {
     try {
       testSerializer("<BeanWithPropertyWithoutTagOnPrimitiveValue><name>hello</name></BeanWithPropertyWithoutTagOnPrimitiveValue>", bean)
     }
-    catch (e: XmlSerializationException) {
+    catch (e: SerializationException) {
       return
     }
 
index a9671defef2baf1c468aa4ca29e27680f88c96cc..5735ddcc399225226bd40ee29cf74d1d9519de77 100644 (file)
@@ -1,24 +1,8 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.codeInsight.highlighting;
 
 import com.intellij.psi.ElementDescriptionLocation;
 import com.intellij.psi.ElementDescriptionProvider;
-import com.intellij.psi.PsiElement;
 import com.intellij.psi.meta.PsiPresentableMetaData;
 import org.jetbrains.annotations.NotNull;
 
@@ -26,23 +10,22 @@ import org.jetbrains.annotations.NotNull;
  * @author yole
  */
 public class HighlightUsagesDescriptionLocation extends ElementDescriptionLocation {
+
+  private static final ElementDescriptionProvider ourDefaultProvider = (element, location) -> {
+    if (element instanceof PsiPresentableMetaData) {
+      return ((PsiPresentableMetaData)element).getTypeName();
+    }
+    return null;
+  };
+
   private HighlightUsagesDescriptionLocation() {
   }
 
   @NotNull
   @Override
   public ElementDescriptionProvider getDefaultProvider() {
-    return new ElementDescriptionProvider() {
-      @Override
-      public String getElementDescription(@NotNull PsiElement element, @NotNull ElementDescriptionLocation location) {
-        if (element instanceof PsiPresentableMetaData) {
-          return ((PsiPresentableMetaData)element).getTypeName();
-        }
-        return null;
-      }
-    };
+    return ourDefaultProvider;
   }
 
-  public static HighlightUsagesDescriptionLocation INSTANCE = new HighlightUsagesDescriptionLocation();
-
+  public static final HighlightUsagesDescriptionLocation INSTANCE = new HighlightUsagesDescriptionLocation();
 }
index 541fa4552f349f197bae6f7450ece18103b5df0d..753e7fe48b98a262cbad21a5af22afd8a884fcc5 100644 (file)
@@ -35,9 +35,9 @@ import com.intellij.util.execution.ParametersListUtil;
 import com.intellij.util.graph.*;
 import com.intellij.util.io.URLUtil;
 import com.intellij.util.lang.UrlClassLoader;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.text.VersionComparatorUtil;
 import com.intellij.util.xmlb.JDOMXIncluder;
-import com.intellij.util.xmlb.XmlSerializationException;
 import gnu.trove.THashMap;
 import gnu.trove.THashSet;
 import gnu.trove.TObjectIntHashMap;
@@ -688,7 +688,7 @@ public class PluginManagerCore {
       descriptor.loadFromFile(descriptorFile, loadingContext.getXmlFactory());
       return descriptor;
     }
-    catch (XmlSerializationException | JDOMException | IOException e) {
+    catch (SerializationException | JDOMException | IOException e) {
       if (loadingContext.isEssential) ExceptionUtil.rethrow(e);
       getLogger().warn("Cannot load " + descriptorFile, e);
       prepareLoadingPluginsErrorMessage(Collections.singletonList("File '" + file.getName() + "' contains invalid plugin descriptor."));
@@ -721,7 +721,7 @@ public class PluginManagerCore {
         return descriptor;
       }
     }
-    catch (XmlSerializationException | InvalidDataException e) {
+    catch (SerializationException | InvalidDataException e) {
       if (context.isEssential) ExceptionUtil.rethrow(e);
       getLogger().info("Cannot load " + file + "!/META-INF/" + fileName, e);
       prepareLoadingPluginsErrorMessage(Collections.singletonList("File '" + file.getName() + "' contains invalid plugin descriptor."));
index 9784cda3895a4a347aeb6e3fce8d09a54e2f1d65..4560ad053f46ca06c03e4ebe70fcc08123be567d 100644 (file)
@@ -237,7 +237,7 @@ public class ExternalDiffToolUtil {
       if (settings.isMergeTrustExitCode()) {
         final Ref<Boolean> resultRef = new Ref<>();
 
-        ProgressManager.getInstance().run(new Task.Modal(project, "Waiting for External Tool", true) {
+        ProgressManager.getInstance().run(new Task.Modal(project, "Waiting for External Tool...", true) {
           @Override
           public void run(@NotNull ProgressIndicator indicator) {
             final Semaphore semaphore = new Semaphore(0);
@@ -274,7 +274,7 @@ public class ExternalDiffToolUtil {
         success = resultRef.get() == Boolean.TRUE;
       }
       else {
-        ProgressManager.getInstance().run(new Task.Modal(project, "Launching External Tool", false) {
+        ProgressManager.getInstance().run(new Task.Modal(project, "Launching External Tool...", false) {
           @Override
           public void run(@NotNull ProgressIndicator indicator) {
             indicator.setIndeterminate(true);
index d379696cfa5716fbf0b33262ed478a38771e3c84..427144cadf899ae68096ed057c12486eff495733 100644 (file)
@@ -25,6 +25,7 @@ public class ExternalSystemException extends RuntimeException {
 
   @NotNull
   private final String[] myQuickFixes;
+  private boolean myCauseInitialized;
 
   public ExternalSystemException() {
     this(null, (Throwable)null);
@@ -88,6 +89,16 @@ public ExternalSystemException(@Nullable String message, @Nullable Throwable cau
     s.println(myOriginalReason);
   }
 
+  public synchronized boolean isCauseInitialized() {
+    return myCauseInitialized;
+  }
+
+  @Override
+  public synchronized Throwable initCause(Throwable cause) {
+    myCauseInitialized = true;
+    return super.initCause(cause);
+  }
+
   @Nullable
   private static String extractMessage(@Nullable String message, @Nullable Throwable cause) {
     StringBuilder buffer = new StringBuilder();
diff --git a/platform/lang-api/src/com/intellij/build/events/DuplicateMessageAware.java b/platform/lang-api/src/com/intellij/build/events/DuplicateMessageAware.java
new file mode 100644 (file)
index 0000000..19ab224
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.build.events;
+
+import org.jetbrains.annotations.ApiStatus;
+
+/**
+ * @author Vladislav.Soroka
+ */
+@ApiStatus.Experimental
+public interface DuplicateMessageAware {
+}
diff --git a/platform/lang-api/src/com/intellij/build/issue/BuildIssue.kt b/platform/lang-api/src/com/intellij/build/issue/BuildIssue.kt
new file mode 100644 (file)
index 0000000..99a7208
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.build.issue
+
+import org.jetbrains.annotations.ApiStatus
+
+/**
+ * @author Vladislav.Soroka
+ */
+@ApiStatus.Experimental
+interface BuildIssue {
+  val description: String
+  val quickFixes: List<BuildIssueQuickFix>
+}
diff --git a/platform/lang-api/src/com/intellij/build/issue/BuildIssueChecker.kt b/platform/lang-api/src/com/intellij/build/issue/BuildIssueChecker.kt
new file mode 100644 (file)
index 0000000..a295335
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.build.issue
+
+import org.jetbrains.annotations.ApiStatus
+
+/**
+ * @author Vladislav.Soroka
+ */
+@ApiStatus.Experimental
+interface BuildIssueChecker<T : BuildIssueData> {
+  fun check(issueData: T): BuildIssue?
+}
diff --git a/platform/lang-api/src/com/intellij/build/issue/BuildIssueData.kt b/platform/lang-api/src/com/intellij/build/issue/BuildIssueData.kt
new file mode 100644 (file)
index 0000000..0371256
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.build.issue
+
+import org.jetbrains.annotations.ApiStatus
+
+/**
+ * @author Vladislav.Soroka
+ */
+@ApiStatus.Experimental
+interface BuildIssueData
diff --git a/platform/lang-api/src/com/intellij/build/issue/BuildIssueQuickFix.kt b/platform/lang-api/src/com/intellij/build/issue/BuildIssueQuickFix.kt
new file mode 100644 (file)
index 0000000..9a6f4d2
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.build.issue
+
+import com.intellij.openapi.project.Project
+import org.jetbrains.annotations.ApiStatus
+
+import java.util.concurrent.CompletableFuture
+
+/**
+ * @author Vladislav.Soroka
+ */
+@ApiStatus.Experimental
+interface BuildIssueQuickFix {
+  val id: String
+  fun runQuickFix(project: Project): CompletableFuture<*>
+}
index 3b280ab37a875bb8811e786b5ff4aa23e06d2e22..c8ef4e1d0d53bdc8c8cef84de563d5032a315084 100644 (file)
@@ -1,3 +1,4 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.facet.frameworks;
 
 import com.intellij.facet.frameworks.beans.Artifact;
@@ -8,9 +9,8 @@ import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.containers.ContainerUtil;
-import java.util.HashSet;
 import com.intellij.util.net.HttpConfigurable;
-import com.intellij.util.xmlb.XmlSerializationException;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.XmlSerializer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -19,6 +19,7 @@ import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -93,7 +94,7 @@ public class LibrariesDownloadAssistant {
     try {
       allArtifacts = XmlSerializer.deserialize(url, Artifacts.class);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       final Throwable cause = e.getCause();
       if (!(cause instanceof IOException)) {
         LOG.error(e);
index fc8fc90a91e3d29e8f5a15c630be0713278516ee..149b69eb487b4ef7441dd859cd3ee540f22cdc44 100644 (file)
@@ -23,13 +23,14 @@ import com.intellij.execution.process.ProcessOutputTypes;
 import com.intellij.execution.ui.ConsoleViewContentType;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Key;
-import com.intellij.util.ObjectUtils;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Iterator;
 import java.util.List;
 
+import static com.intellij.util.ObjectUtils.chooseNotNull;
+
 /**
  * @author Vladislav.Soroka
  */
@@ -46,24 +47,27 @@ public class BuildTextConsoleView extends ConsoleViewImpl implements BuildConsol
 
   @Override
   public void onEvent(@NotNull BuildEvent event) {
-    String description = event.getDescription();
-    if (description != null) {
-      append(description, true);
-    }
-    else if (event instanceof FileMessageEvent) {
-      FilePosition position = ((FileMessageEvent)event).getFilePosition();
-      StringBuilder fileLink = new StringBuilder();
-      fileLink.append(position.getFile().getName());
-      if (position.getStartLine() > 0) {
-        fileLink.append(":").append(position.getStartLine() + 1);
+    if (event instanceof FileMessageEvent) {
+      boolean isStdOut = ((FileMessageEvent)event).getResult().getKind() != MessageEvent.Kind.ERROR;
+      String description = event.getDescription();
+      if (description != null) {
+        append(description, isStdOut);
       }
-      if (position.getStartColumn() > 0) {
-        fileLink.append(":").append(position.getStartColumn() + 1);
+      else {
+        FilePosition position = ((FileMessageEvent)event).getFilePosition();
+        StringBuilder fileLink = new StringBuilder();
+        fileLink.append(position.getFile().getName());
+        if (position.getStartLine() > 0) {
+          fileLink.append(":").append(position.getStartLine() + 1);
+        }
+        if (position.getStartColumn() > 0) {
+          fileLink.append(":").append(position.getStartColumn() + 1);
+        }
+        print(fileLink.toString(), ConsoleViewContentType.NORMAL_OUTPUT,
+              new LazyFileHyperlinkInfo(getProject(), position.getFile().getPath(), position.getStartLine(), position.getStartColumn()));
+        print(": ", ConsoleViewContentType.NORMAL_OUTPUT);
+        append(event.getMessage(), isStdOut);
       }
-      print(fileLink.toString(), ConsoleViewContentType.NORMAL_OUTPUT,
-            new LazyFileHyperlinkInfo(getProject(), position.getFile().getPath(), position.getStartLine(), position.getStartColumn()));
-      print(": ", ConsoleViewContentType.NORMAL_OUTPUT);
-      append(event.getMessage(), true);
     }
     else if (event instanceof MessageEvent) {
       appendEventResult(((MessageEvent)event).getResult());
@@ -75,7 +79,7 @@ public class BuildTextConsoleView extends ConsoleViewImpl implements BuildConsol
       onEvent((OutputBuildEvent)event);
     }
     else {
-      append(event.getMessage(), true);
+      append(chooseNotNull(event.getDescription(), event.getMessage()), true);
     }
   }
 
@@ -114,7 +118,7 @@ public class BuildTextConsoleView extends ConsoleViewImpl implements BuildConsol
   }
 
   public boolean append(@NotNull Failure failure) {
-    String text = ObjectUtils.chooseNotNull(failure.getDescription(), failure.getMessage());
+    String text = chooseNotNull(failure.getDescription(), failure.getMessage());
     if (text == null && failure.getError() != null) {
       text = failure.getError().getMessage();
     }
index 2ae521469c7ebb22137b40ac78ac552ff462e546..4062964521351b9f8428a390234cfc5da1ac3cd7 100644 (file)
@@ -99,6 +99,7 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
   private final Project myProject;
   private final ConsoleViewHandler myConsoleViewHandler;
   private final String myWorkingDir;
+  private final AtomicBoolean myFinishedBuildEventReceived = new AtomicBoolean();
   private final AtomicBoolean myDisposed = new AtomicBoolean();
   private final AtomicBoolean myShownFirstError = new AtomicBoolean();
   private final StructureTreeModel<SimpleTreeStructure> myTreeModel;
@@ -107,6 +108,7 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
   private final ExecutionNode myBuildProgressRootNode;
   private final Set<Predicate<ExecutionNode>> myNodeFilters;
   private final ProblemOccurrenceNavigatorSupport myOccurrenceNavigatorSupport;
+  private final Set<BuildEvent> myDeferredEvents = ContainerUtil.newConcurrentSet();
 
   public BuildTreeConsoleView(Project project,
                               BuildDescriptor buildDescriptor,
@@ -243,6 +245,18 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
     ExecutionNode buildProgressRootNode = getBuildProgressRootNode();
     if (event instanceof StartEvent || event instanceof MessageEvent) {
       if (currentNode == null) {
+        if (event instanceof DuplicateMessageAware) {
+          if (myFinishedBuildEventReceived.get()) {
+            if (parentNode != null &&
+                parentNode.findFirstChild(node -> event.getMessage().equals(node.getName())) != null) {
+              return;
+            }
+          }
+          else {
+            myDeferredEvents.add(event);
+            return;
+          }
+        }
         if (event instanceof StartBuildEvent) {
           currentNode = buildProgressRootNode;
           installContextMenu((StartBuildEvent)event);
@@ -329,10 +343,12 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
     }
 
     if (event instanceof FinishBuildEvent) {
+      myFinishedBuildEventReceived.set(true);
       String aHint = event.getHint();
       String time = DateFormatUtil.formatDateTime(event.getEventTime());
       aHint = aHint == null ? "at " + time : aHint + " at " + time;
       currentNode.setHint(aHint);
+      myDeferredEvents.forEach(this::onEventInternal);
       if (myConsoleViewHandler.myExecutionNode == null) {
         ApplicationManager.getApplication().invokeLater(() -> myConsoleViewHandler.setNode(buildProgressRootNode));
       }
@@ -393,10 +409,6 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
   }
 
   private void addChildFailureNode(@NotNull ExecutionNode parentNode, @NotNull Failure failure, @NotNull String defaultFailureMessage) {
-    ExecutionNode failureNode = new ExecutionNode(myProject, parentNode);
-    parentNode.add(failureNode);
-    failureNode.setNavigatable(failure.getNavigatable());
-    failureNode.setResult(new FailureResultImpl(Collections.singletonList(failure)));
     String text = chooseNotNull(failure.getDescription(), failure.getMessage());
     if (text == null && failure.getError() != null) {
       text = failure.getError().getMessage();
@@ -412,8 +424,28 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
     if (sepIndex > 0) {
       text = text.substring(0, sepIndex);
     }
-    text = StringUtil.trimEnd(text, '.');
-    failureNode.setName(text);
+    String failureNodeName = StringUtil.trimEnd(text, '.');
+    ExecutionNode failureNode = parentNode.findFirstChild(executionNode -> failureNodeName.equals(executionNode.getName()));
+    if (failureNode == null) {
+      failureNode = new ExecutionNode(myProject, parentNode);
+      failureNode.setName(failureNodeName);
+      parentNode.add(failureNode);
+    }
+    if (failure.getNavigatable() == null) {
+      failureNode.setNavigatable(failure.getNavigatable());
+    }
+
+    List<Failure> failures;
+    EventResult result = failureNode.getResult();
+    if (result instanceof FailureResult) {
+      failures = ContainerUtil.newArrayList();
+      failures.addAll(((FailureResult)result).getFailures());
+      failures.add(failure);
+    }
+    else {
+      failures = Collections.singletonList(failure);
+    }
+    failureNode.setResult(new FailureResultImpl(failures));
     myConsoleViewHandler.addOutput(failureNode, failure);
     showErrorIfFirst(failureNode, failure.getNavigatable());
   }
index 5c30d416bb2086820c653656edc042ca14d4fd4b..8e64887bfeb8d5ec2842ee2e147ebf941bddad53 100644 (file)
@@ -28,6 +28,7 @@ import com.intellij.ui.treeStructure.CachingSimpleNode;
 import com.intellij.ui.treeStructure.SimpleNode;
 import com.intellij.util.SmartList;
 import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -310,6 +311,12 @@ public class ExecutionNode extends CachingSimpleNode {
     }
   }
 
+  @Nullable
+  @ApiStatus.Experimental
+  ExecutionNode findFirstChild(@NotNull Predicate<ExecutionNode> filter) {
+    return myChildrenList.stream().filter(filter).findFirst().orElse(null);
+  }
+
   private String getCurrentHint() {
     String hint = myHint;
     int warnings = myWarnings.get();
index 41e5fa2fa3a2b4026be34b94520db9da736c5626..d9e64c4ea116f7543d5eac4d1d9d2c7a977e6e91 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.build.events.impl;
 
 import com.intellij.build.events.Failure;
 import com.intellij.build.events.FailureResult;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
@@ -44,7 +45,7 @@ public class FailureResultImpl implements FailureResult {
     }
   }
 
-  public FailureResultImpl(List<Failure> failures) {
+  public FailureResultImpl(@NotNull List<Failure> failures) {
     myFailures = failures;
   }
   
index 96947c0390c3add60df0d1fbf01800a700320a20..ec30d805b28dbd4557503fd9391a6bd8344b5851 100644 (file)
@@ -12,7 +12,7 @@ import org.jetbrains.annotations.ApiStatus
 import org.jetbrains.annotations.TestOnly
 import java.io.Closeable
 import java.util.*
-import java.util.concurrent.Future
+import java.util.concurrent.CompletableFuture
 
 /**
  * @author Vladislav.Soroka
@@ -83,7 +83,7 @@ open class BuildOutputInstantReaderImpl(private val parentEventId: Any,
     closeAndGetFuture()
   }
 
-  fun closeAndGetFuture(): Future<Unit> {
+  fun closeAndGetFuture(): CompletableFuture<Unit> {
     appendedLineProcessor.close()
     outputLinesChannel.close()
     return CoroutineScope(Dispatchers.Default).future {
index c53f0072828ed9659eaf7080453b7626a1227583..ac070941139b0b7c9173969942af9f016427b2ec 100644 (file)
@@ -16,7 +16,7 @@ import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.ReflectionUtil;
-import com.intellij.util.xmlb.XmlSerializationException;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.xmlb.annotations.OptionTag;
 import com.intellij.util.xmlb.annotations.Property;
 import com.intellij.util.xmlb.annotations.Transient;
@@ -198,7 +198,7 @@ public class CodeInsightSettings implements PersistentStateComponent<Element>, C
     try {
       XmlSerializer.deserializeInto(state, this);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       LOG.info(e);
     }
   }
@@ -231,7 +231,7 @@ public class CodeInsightSettings implements PersistentStateComponent<Element>, C
     try {
       XmlSerializer.serializeObjectInto(this, element);
     }
-    catch (XmlSerializationException e) {
+    catch (SerializationException e) {
       LOG.info(e);
     }
   }
index 93703d278cb19857d25f54896544c08c09f9f08c..f8880716db93945c33a650a40346ca701b3c958c 100644 (file)
@@ -11,10 +11,7 @@ import com.intellij.codeInsight.template.impl.LiveTemplateLookupElement;
 import com.intellij.ide.ui.UISettings;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.*;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.patterns.StandardPatterns;
 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
@@ -54,29 +51,10 @@ public class CompletionLookupArrangerImpl extends LookupArranger implements Comp
 
   private String myLastLookupPrefix;
 
-  /**
-   * If false, the lookup arranger will generate enough items to fill the visible area of the list and fill the rest with "Loading..."
-   * items. If true, it will produce up to {@link #myLimit} items and truncate the list afterwards.
-   */
-  private boolean myConsiderAllItemsVisible = ApplicationManager.getApplication().isUnitTestMode();
-
   public CompletionLookupArrangerImpl(CompletionProcessEx process) {
     myProcess = process;
   }
 
-  public CompletionLookupArrangerImpl(CompletionParameters parameters) {
-    myProcess = (CompletionProcessEx) parameters.getProcess();
-  }
-
-  public CompletionLookupArrangerImpl withAllItemsVisible() {
-    myConsiderAllItemsVisible = true;
-    return this;
-  }
-
-  public void setConsiderAllItemsVisible() {
-    myConsiderAllItemsVisible = true;
-  }
-
   private MultiMap<CompletionSorterImpl, LookupElement> groupItemsBySorter(Iterable<LookupElement> source) {
     MultiMap<CompletionSorterImpl, LookupElement> inputBySorter = MultiMap.createLinked();
     for (LookupElement element : source) {
@@ -319,18 +297,9 @@ public class CompletionLookupArrangerImpl extends LookupArranger implements Comp
     int toSelect = getItemToSelect(lookup, listModel, onExplicitAction, relevantSelection);
     LOG.assertTrue(toSelect >= 0);
 
-    addDummyItems(items.size() - listModel.size(), listModel);
-
     return new Pair<>(listModel, toSelect);
   }
 
-  private static void addDummyItems(int count, List<? super LookupElement> listModel) {
-    EmptyLookupItem dummy = new EmptyLookupItem("loading...", true);
-    for (int i = count; i > 0; i--) {
-      listModel.add(dummy);
-    }
-  }
-
   private List<LookupElement> fillModelByRelevance(LookupElementListPresenter lookup,
                                                    Set<LookupElement> items,
                                                    Iterable<LookupElement> sortedElements,
@@ -350,16 +319,11 @@ public class CompletionLookupArrangerImpl extends LookupArranger implements Comp
 
     ensureItemAdded(items, model, byRelevance, lookup.getCurrentItem());
     ensureItemAdded(items, model, byRelevance, relevantSelection);
-    ensureEverythingVisibleAdded(lookup, model, byRelevance);
+    ContainerUtil.addAll(model, byRelevance);
 
     return new ArrayList<>(model);
   }
 
-  private void ensureEverythingVisibleAdded(LookupElementListPresenter lookup, final LinkedHashSet<LookupElement> model, Iterator<LookupElement> byRelevance) {
-    final int limit = Math.max(lookup.getLastVisibleIndex(), model.size()) + ourUISettings.getMaxLookupListHeight() * 3;
-    addSomeItems(model, byRelevance, lastAdded -> !myConsiderAllItemsVisible && model.size() >= limit);
-  }
-
   private static void ensureItemAdded(Set<LookupElement> items,
                                       LinkedHashSet<? super LookupElement> model,
                                       Iterator<? extends LookupElement> byRelevance, @Nullable final LookupElement item) {
index 097988835f5e6ad56c8f6711c35411c7c1e39650..710130e7c64538e36279dd0b5c241ff38ef76fe8 100644 (file)
@@ -140,9 +140,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
     myAdvertiserChanges.offer(() -> myLookup.getAdvertiser().clearAdvertisements());
 
     myArranger = new CompletionLookupArrangerImpl(this);
-    if (handler.isTestingMode()) {
-      myArranger.setConsiderAllItemsVisible();
-    }
     myLookup.setArranger(myArranger);
 
     myLookup.addLookupListener(myLookupListener);
index b99f6b5efec09a24e7c95a4d88fd6c91c5cfd494..7989d6dcf0e1ea9b2b4b8977a2c83155e6912350 100644 (file)
@@ -30,6 +30,11 @@ public class GotoNextErrorAction extends BaseCodeInsightAction implements DumbAw
     super(false);
   }
 
+  @Override
+  protected boolean isValidForLookup() {
+    return true;
+  }
+
   @NotNull
   @Override
   protected CodeInsightActionHandler getHandler() {
index 04fba0f60788cb787166fd3a09c1dd3b958a4029..0625b9a80309501c3c795cd02f08fcd509efc3cb 100644 (file)
@@ -32,6 +32,11 @@ public class GotoPreviousErrorAction extends BaseCodeInsightAction implements Du
     super(false);
   }
 
+  @Override
+  protected boolean isValidForLookup() {
+    return true;
+  }
+
   @NotNull
   @Override
   protected CodeInsightActionHandler getHandler() {
index 7d90b0c8de0f0a1b9829e86c29d419b97bc3b11d..353d05a2d24f7da36e2dbdc41a6dd53595cc8a04 100644 (file)
@@ -121,15 +121,6 @@ class LookupUi {
         }
       }
     });
-
-    final Alarm alarm = new Alarm(myLookup);
-    myScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
-      @Override
-      public void adjustmentValueChanged(AdjustmentEvent e) {
-        if (myLookup.myUpdating || myLookup.isLookupDisposed()) return;
-        alarm.addRequest(() -> myLookup.refreshUi(false, false), 300, myModalityState);
-      }
-    });
   }
 
   private void updateScrollbarVisibility() {
index 56f814508dbd6f799363a58ce5f7604a76f88f21..f0644167b015579f0d25987f184805cd3b3e8d45 100644 (file)
@@ -1,6 +1,4 @@
-// Copyright 2000-2017 JetBrains s.r.o.
-// Use of this source code is governed by the Apache 2.0 license that can be
-// found in the LICENSE file.
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.codeInspection.naming;
 
 import com.intellij.codeInspection.LocalInspectionTool;
@@ -15,9 +13,9 @@ import com.intellij.ui.CheckBoxList;
 import com.intellij.ui.CheckBoxListListener;
 import com.intellij.ui.components.JBScrollPane;
 import com.intellij.util.ObjectUtils;
+import com.intellij.util.serialization.SerializationException;
 import com.intellij.util.ui.JBUI;
 import com.intellij.util.ui.UIUtil;
-import com.intellij.util.xmlb.XmlSerializationException;
 import com.intellij.util.xmlb.XmlSerializer;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
@@ -25,8 +23,8 @@ import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
-import java.util.*;
 import java.util.List;
+import java.util.*;
 import java.util.function.Consumer;
 
 /**
@@ -98,7 +96,7 @@ public abstract class AbstractNamingConventionInspection<T extends PsiNameIdenti
         XmlSerializer.deserializeInto(conventionBean, extension);
         conventionBean.initPattern();
       }
-      catch (XmlSerializationException e) {
+      catch (SerializationException e) {
         throw new InvalidDataException(e);
       }
       String enabled = extension.getAttributeValue("enabled");
index a3852d4ca0b70478063d50afc91e7f06a07f458c..41f694166d264b28a2d81b3e273434efbe87c8da 100644 (file)
@@ -70,7 +70,7 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider {
     myDefaultExecutor = defaultExecutor;
     myAlternativeExecutor = alternativeExecutor;
 
-    myPopup = new RunListPopup(new ConfigurationListPopupStep(this, myProject, this, myDefaultExecutor.getActionName()));
+    myPopup = new RunListPopup(project, null, new ConfigurationListPopupStep(this, myProject, this, myDefaultExecutor.getActionName()), null);
   }
 
   public void show() {
@@ -768,12 +768,18 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider {
   }
 
   private class RunListPopup extends ListPopupImpl {
-    RunListPopup(ListPopupStep step) {
-      super(step);
+
+    RunListPopup(Project project, WizardPopup aParent, ListPopupStep aStep, Object parentValue) {
+      super(project, aParent, aStep, parentValue);
       registerActions(this);
     }
 
     @Override
+    protected WizardPopup createPopup(WizardPopup parent, PopupStep step, Object parentValue) {
+      return new RunListPopup(getProject(), parent, (ListPopupStep)step, parentValue);
+    }
+
+    @Override
     public boolean shouldBeShowing(Object value) {
       if (super.shouldBeShowing(value)) {
         return true;
@@ -789,16 +795,6 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider {
       return false;
     }
 
-    protected RunListPopup(WizardPopup aParent, ListPopupStep aStep, Object parentValue) {
-      super(aParent, aStep, parentValue);
-      registerActions(this);
-    }
-
-    @Override
-    protected WizardPopup createPopup(WizardPopup parent, PopupStep step, Object parentValue) {
-      return new RunListPopup(parent, (ListPopupStep)step, parentValue);
-    }
-
     @Override
     public void handleSelect(boolean handleFinalChoices, InputEvent e) {
       if (e instanceof MouseEvent && e.isShiftDown()) {
index 926a091e06216e5611434a3bc2d554b5f5a9b4dd..39dd501cbc27c82465f97d369ea172535442308e 100644 (file)
@@ -38,7 +38,7 @@ public class RunDialog extends DialogWrapper implements RunDialogBase {
     setTitle(executor.getId());
 
     setOKButtonText(executor.getActionName());
-    setOKButtonIcon(executor.getIcon());
+    //setOKButtonIcon(executor.getIcon());
 
     myConfigurable = new ProjectRunConfigurationConfigurable(project, this);
     init();
@@ -105,7 +105,7 @@ public class RunDialog extends DialogWrapper implements RunDialogBase {
       {
         if (executor != null) {
           setOKButtonText(executor.getActionName());
-          setOKButtonIcon(executor.getIcon());
+          //setOKButtonIcon(executor.getIcon());
         }
       }
     };
index b0eb7d79b6503c7efb912ae0c332410b77b21939..9c017240c20f7f1d21704beee6eda95285cb5c00 100644 (file)
@@ -11,14 +11,13 @@ import com.intellij.openapi.ui.popup.JBPopup;
 import com.intellij.openapi.util.ActionCallback;
 import com.intellij.openapi.util.DimensionService;
 import com.intellij.openapi.util.MutualMap;
-import com.intellij.openapi.wm.impl.TabsHeightController;
 import com.intellij.ui.JBColor;
 import com.intellij.ui.awt.RelativePoint;
 import com.intellij.ui.components.panels.NonOpaquePanel;
 import com.intellij.ui.content.Content;
 import com.intellij.ui.content.ContentManager;
 import com.intellij.ui.tabs.*;
-import com.intellij.ui.tabs.newImpl.JBEditorTabs;
+import com.intellij.ui.tabs.newImpl.SameHeightTabs;
 import com.intellij.ui.tabs.newImpl.TabLabel;
 import com.intellij.ui.tabs.newImpl.singleRow.ScrollableSingleRowLayout;
 import com.intellij.ui.tabs.newImpl.singleRow.SingleRowLayout;
@@ -449,9 +448,14 @@ public class GridCellImpl implements GridCell {
     return ActionCallback.DONE;
   }
 
-  private static class GridCellTabs extends JBEditorTabs {
+  private static class GridCellTabs extends SameHeightTabs {
     private final ViewContextEx myContext;
 
+    @Override
+    protected JBTabPainter createTabPainter() {
+      return JBTabPainter.getDEBUGGER();
+    }
+
     private GridCellTabs(ViewContextEx context, GridImpl container) {
       super(context.getProject(), context.getActionManager(), context.getFocusManager(), container);
       myContext = context;
@@ -489,19 +493,17 @@ public class GridCellImpl implements GridCell {
 
     @Override
     protected TabLabel createTabLabel(TabInfo info) {
-      return new TabLabel(this, info) {
-        @Override
-        public void setAlignmentToCenter(boolean toCenter) {
-          super.setAlignmentToCenter(false);
-        }
+      return new SameHeightTabs.SingleHeightLabel(this, info) {
 
+        @NotNull
         @Override
         public Dimension getPreferredSize() {
-          Dimension size = super.getPreferredSize();
-
-          Insets insets = getInsets();
+          return super.getPreferredSize();
+        }
 
-          return new Dimension(size.width, TabsHeightController.getToolWindowHeight().getValue() - insets.top - insets.bottom);
+        @Override
+        public void setAlignmentToCenter(boolean toCenter) {
+          super.setAlignmentToCenter(false);
         }
       };
     }
index 7a35b8b702441f2c4ed8d6c1e8e6a348685adbf3..e1a06e98a9dbc55bf694eea540292ea616f0bc49 100644 (file)
@@ -6,17 +6,13 @@ import com.intellij.openapi.actionSystem.ActionGroup;
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.wm.IdeFocusManager;
-import com.intellij.openapi.wm.impl.TabsHeightController;
 import com.intellij.ui.awt.RelativePoint;
-import com.intellij.ui.tabs.JBTabsBackgroundAndBorder;
-import com.intellij.ui.tabs.JBTabsFactory;
-import com.intellij.ui.tabs.TabInfo;
-import com.intellij.ui.tabs.UiDecorator;
-import com.intellij.ui.tabs.newImpl.JBEditorTabs;
+import com.intellij.ui.tabs.*;
+import com.intellij.ui.tabs.newImpl.SameHeightTabs;
 import com.intellij.ui.tabs.newImpl.TabLabel;
-import com.intellij.util.ui.JBUI;
 import com.intellij.ui.tabs.newImpl.singleRow.ScrollableSingleRowLayout;
 import com.intellij.ui.tabs.newImpl.singleRow.SingleRowLayout;
+import com.intellij.util.ui.JBUI;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -27,7 +23,7 @@ import java.util.Map;
 /**
  * @author Dennis.Ushakov
  */
-public class JBRunnerTabs extends JBEditorTabs implements JBRunnerTabsBase {
+public class JBRunnerTabs extends SameHeightTabs implements JBRunnerTabsBase {
   public static JBRunnerTabsBase create(@Nullable Project project, @NotNull Disposable parentDisposable) {
     IdeFocusManager focusManager = project != null ? IdeFocusManager.getInstance(project) : null;
     return JBTabsFactory.getUseNewTabs()
@@ -35,6 +31,10 @@ public class JBRunnerTabs extends JBEditorTabs implements JBRunnerTabsBase {
            : new JBRunnerTabsOld(project, ActionManager.getInstance(), focusManager, parentDisposable);
   }
 
+  @Override
+  protected JBTabPainter createTabPainter() {
+    return JBTabPainter.getDEBUGGER();
+  }
 
   public JBRunnerTabs(@Nullable Project project, @NotNull ActionManager actionManager, IdeFocusManager focusManager, @NotNull Disposable parent) {
     super(project, actionManager, focusManager, parent);
@@ -112,7 +112,7 @@ public class JBRunnerTabs extends JBEditorTabs implements JBRunnerTabsBase {
 
   @Override
   protected TabLabel createTabLabel(TabInfo info) {
-    return new TabLabel(this, info) {
+    return new SingleHeightLabel(this, info) {
       @Override
       public void setTabActionsAutoHide(boolean autoHide) {
         super.setTabActionsAutoHide(autoHide);
@@ -120,15 +120,6 @@ public class JBRunnerTabs extends JBEditorTabs implements JBRunnerTabsBase {
       }
 
       @Override
-      public Dimension getPreferredSize() {
-        Dimension size = super.getPreferredSize();
-
-        Insets insets = getInsets();
-
-        return new Dimension(size.width, TabsHeightController.getToolWindowHeight().getValue() - insets.top - insets.bottom);
-      }
-
-      @Override
       public void setTabActions(ActionGroup group) {
         super.setTabActions(group);
         if (myActionPanel != null) {
index 93ec0818583ec135dd0c6386c218d470515ffc45..2024a8b27b777b91c67164473f5dc68947e2de25 100644 (file)
@@ -20,12 +20,13 @@ import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiBundle;
 import com.intellij.psi.search.SearchScope;
-import com.intellij.ui.ComboboxSpeedSearch;
+import com.intellij.ui.SimpleListCellRenderer;
+import com.intellij.util.Functions;
 import com.intellij.util.ObjectUtils;
 import com.intellij.util.PlatformUtils;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ui.EmptyIcon;
-import com.intellij.util.ui.SwingHelper;
+import com.intellij.util.ui.JBUI;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -75,12 +76,10 @@ class FindPopupScopeUIImpl implements FindPopupScopeUI {
 
     Arrays.sort(names, String.CASE_INSENSITIVE_ORDER);
     myModuleComboBox = new ComboBox<>(names);
-    new ComboboxSpeedSearch(myModuleComboBox);
+    myModuleComboBox.setSwingPopup(false);
+    myModuleComboBox.setMinimumAndPreferredWidth(JBUI.scale(300)); // as ScopeChooser
+    myModuleComboBox.setRenderer(SimpleListCellRenderer.create("", Functions.id()));
 
-    SwingHelper.setLongestAsPrototype(myModuleComboBox, Arrays.asList(names));
-    if (myModuleComboBox.getPrototypeDisplayValue() != null) {
-      myModuleComboBox.setMinLength(myModuleComboBox.getPrototypeDisplayValue().length());
-    }
     ActionListener restartSearchListener = e -> scheduleResultsUpdate();
     myModuleComboBox.addActionListener(restartSearchListener);
 
index d261f5a918f3d7f93d054d71ae9d42502a3a6b8b..2a1900a89e606884016965d7d64198a58ea8b745 100644 (file)
@@ -9,10 +9,12 @@ import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.ExtensionPointName;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.ide.CopyPasteManager;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiDocumentManager;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
@@ -110,4 +112,15 @@ public class CopyReferenceAction extends DumbAwareAction {
   public static String elementToFqn(@Nullable final PsiElement element) {
     return CopyReferenceUtil.elementToFqn(element, null);
   }
+
+  public interface VirtualFileQualifiedNameProvider {
+    ExtensionPointName<VirtualFileQualifiedNameProvider> EP_NAME =
+      ExtensionPointName.create("com.intellij.virtualFileQualifiedNameProvider");
+
+    /**
+     * @return {@code virtualFile} fqn (relative path for example) or null if not handled by this provider
+     */
+    @Nullable
+    String getQualifiedName(@NotNull Project project, @NotNull VirtualFile virtualFile);
+  }
 }
index e60956a81260434283756125c0a0b56c154c0898..dd9f39f5ac3d14fa48a30450a2f1b479ea0a0566 100644 (file)
@@ -165,7 +165,7 @@ public class CopyReferenceUtil {
 
   @NotNull
   private static String getVirtualFileFqn(@NotNull VirtualFile virtualFile, @NotNull Project project) {
-    for (VirtualFileQualifiedNameProvider provider : VirtualFileQualifiedNameProvider.EP_NAME.getExtensionList()) {
+    for (CopyReferenceAction.VirtualFileQualifiedNameProvider provider : CopyReferenceAction.VirtualFileQualifiedNameProvider.EP_NAME.getExtensionList()) {
       String qualifiedName = provider.getQualifiedName(project, virtualFile);
       if (qualifiedName != null) {
         return qualifiedName;
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/VirtualFileQualifiedNameProvider.java b/platform/lang-impl/src/com/intellij/ide/actions/VirtualFileQualifiedNameProvider.java
deleted file mode 100644 (file)
index 517039a..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
-package com.intellij.ide.actions;
-
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public interface VirtualFileQualifiedNameProvider {
-  ExtensionPointName<VirtualFileQualifiedNameProvider> EP_NAME =
-    ExtensionPointName.create("com.intellij.virtualFileQualifiedNameProvider");
-
-  /**
-   * @return {@code virtualFile} fqn (relative path for example) or null if not handled by this provider
-   */
-  @Nullable
-  String getQualifiedName(@NotNull Project project, @NotNull VirtualFile virtualFile);
-}
\ No newline at end of file
index ff6507b3ec251002965621da49907b95a14cdbf6..3a8da86751846285888c688eff4d1628320581d8 100644 (file)
@@ -1,6 +1,7 @@
 // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.ide.actions.runAnything;
 
+import com.intellij.util.ui.JBUI;
 import com.intellij.util.ui.UIUtil;
 
 import javax.swing.*;
@@ -20,6 +21,7 @@ class RunAnythingMore extends JPanel {
     instance.label.setForeground(UIUtil.getLabelDisabledForeground());
     instance.label.setFont(RunAnythingUtil.getTitleFont());
     instance.label.setBackground(UIUtil.getListBackground(isSelected, true));
+    instance.label.setBorder(JBUI.Borders.emptyLeft(1));
     return instance;
   }
 }
\ No newline at end of file
index d75bf1b85a7b344b64fbd61707e56d33b0deda05..ef9bba8c9f60677a11dc8d746d9bd516ddb90ae3 100644 (file)
@@ -80,7 +80,7 @@ public class RunAnythingPopupUI extends BigPopupUI {
   private static final Logger LOG = Logger.getInstance(RunAnythingPopupUI.class);
   private static final Border RENDERER_BORDER = JBUI.Borders.empty(1, 0);
   private static final String HELP_PLACEHOLDER = "?";
-  private static final int LIST_REBUILD_DELAY = 200;
+  private static final int LIST_REBUILD_DELAY = 100;
   private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, ApplicationManager.getApplication());
   private final AnActionEvent myActionEvent;
   private boolean myIsUsedTrigger;
@@ -571,7 +571,7 @@ public class RunAnythingPopupUI extends BigPopupUI {
       if (model != null) {
         String title = model.getTitle(index);
         if (title != null) {
-          myMainPanel.add(RunAnythingUtil.createTitle(" " + title, model.getIcon(index)), BorderLayout.NORTH);
+          myMainPanel.add(RunAnythingUtil.createTitle(" " + title), BorderLayout.NORTH);
         }
       }
       JPanel wrapped = new JPanel(new BorderLayout());
index a3f2841e317d37e087f6ba3ff06e36fae8e4edf4..dd4999c1c10405b1c35458d4ce4b119a984c93ae 100644 (file)
@@ -48,11 +48,6 @@ public abstract class RunAnythingSearchListModel extends DefaultListModel<Object
   }
 
   @Nullable
-  Icon getIcon(int titleIndex) {
-    return RunAnythingGroup.getIcon(getGroups(), titleIndex);
-  }
-
-  @Nullable
   RunAnythingGroup findItemGroup(int titleIndex) {
     return RunAnythingGroup.findItemGroup(getGroups(), titleIndex);
   }
index ea908dd1f7555d48387e1525ff13dbc6571e49e7..b9f50db36d497a579fc83c120dd7458b5f92e9de 100644 (file)
@@ -49,14 +49,10 @@ public class RunAnythingUtil {
     return UIUtil.getLabelFont().deriveFont(UIUtil.getFontSize(UIUtil.FontSize.SMALL));
   }
 
-  static JComponent createTitle(@NotNull String titleText, @Nullable Icon icon) {
+  static JComponent createTitle(@NotNull String titleText) {
     JLabel titleLabel = new JLabel(titleText);
     titleLabel.setFont(getTitleFont());
     titleLabel.setForeground(UIUtil.getLabelDisabledForeground());
-    if (icon != null) {
-      titleLabel.setIcon(icon);
-      titleLabel.setIconTextGap(0);
-    }
 
     SeparatorComponent separatorComponent =
       new SeparatorComponent(titleLabel.getPreferredSize().height / 2, new JBColor(Gray._220, Gray._80), null);
index 3f1f4914df5ae81e0dff766154b4d3d7deea2bcd..2c3d609feb33a7339c9e0e38c3b4163948c48963 100644 (file)
@@ -104,17 +104,6 @@ public abstract class RunAnythingGroup {
   }
 
   /**
-   * Finds group icon by {@code titleIndex}.
-   *
-   * @return group icon if {@code titleIndex} is equals to group {@link #myTitleIndex} and {@code null} if nothing found
-   */
-  @Nullable
-  public static Icon getIcon(@NotNull Collection<RunAnythingGroup> groups, int titleIndex) {
-    return Optional.ofNullable(findGroup(groups, titleIndex)).map(RunAnythingGroup::getIcon).orElse(null);
-  }
-
-
-  /**
    * Finds group by {@code titleIndex}.
    *
    * @return group if {@code titleIndex} is equals to group {@link #myTitleIndex} and {@code null} if nothing found
index 4f3e9b53fbf5eac77565b3df48a51bbcdba8266d..e9d00def29e59edef809f5fa7fc7d20add30fe2c 100644 (file)
@@ -437,7 +437,8 @@ public abstract class AbstractGotoSEContributor implements SearchEverywhereContr
       ScopeDescriptor selection = getSelectedScope();
       step.setDefaultOptionIndex(ContainerUtil.indexOf(items, o ->
         Comparing.equal(o.getDisplayName(), selection.getDisplayName())));
-      ListPopupImpl popup = new ListPopupImpl(step, 10);
+      ListPopupImpl popup = new ListPopupImpl(e.getProject(), step);
+      popup.setMaxRowCount(10);
       //noinspection unchecked
       popup.getList().setCellRenderer(renderer);
       popup.showUnderneathOf(button);
index 72daf255bdf2a791354807bec7493ec13c0c8a0b..4a1356c4b32bc6fea8458b91c30676e69d29aa88 100644 (file)
@@ -25,6 +25,7 @@ import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
 import com.intellij.util.ObjectUtils;
 import com.intellij.util.PairFunction;
 import com.intellij.util.containers.JBIterable;
+import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -38,7 +39,8 @@ import java.util.List;
 public abstract class TemplateLanguageStructureViewBuilder extends TreeBasedStructureViewBuilder {
 
   @NotNull
-  public static TemplateLanguageStructureViewBuilder create(@NotNull PsiFile psiFile, @Nullable PairFunction<? super PsiFile, ? super Editor, ? extends StructureViewModel> modelFactory) {
+  public static TemplateLanguageStructureViewBuilder create(@NotNull PsiFile psiFile,
+                                                            @Nullable PairFunction<? super PsiFile, ? super Editor, ? extends StructureViewModel> modelFactory) {
     return new TemplateLanguageStructureViewBuilder(psiFile) {
       @Override
       protected TreeBasedStructureViewBuilder createMainBuilder(@NotNull PsiFile psi) {
@@ -93,16 +95,8 @@ public abstract class TemplateLanguageStructureViewBuilder extends TreeBasedStru
         VirtualFile file = fileEditor == null ? null : fileEditor.getFile();
         PsiFile psiFile = file == null || !file.isValid() ? null : PsiManager.getInstance(project).findFile(file);
         List<Language> newLanguages = getLanguages(psiFile).toList();
-        if (!Comparing.equal(languages, newLanguages)) return true;
-        if (psiFile == null) return true;
-        FileViewProvider viewProvider = psiFile.getViewProvider();
-        Language baseLanguage = viewProvider.getBaseLanguage();
-        StructureViewDescriptor[] views = getStructureViews();
-        boolean hasMainView = views.length > 0 && Comparing.equal(views[0].title, baseLanguage.getDisplayName());
-        JBIterable<Language> newAcceptedLanguages = JBIterable.from(newLanguages)
-          .filter(o -> o == baseLanguage && hasMainView ||
-                       o != baseLanguage && isAcceptableBaseLanguageFile(viewProvider.getPsi(o)));
-        return views.length != newAcceptedLanguages.size();
+        // think views count depends only on acceptable languages
+        return !Comparing.equal(languages, newLanguages);
       }
     };
   }
@@ -124,16 +118,21 @@ public abstract class TemplateLanguageStructureViewBuilder extends TreeBasedStru
   }
 
   @NotNull
-  private static JBIterable<Language> getLanguages(@Nullable PsiFile psiFile) {
+  private JBIterable<Language> getLanguages(@Nullable PsiFile psiFile) {
     if (psiFile == null) return JBIterable.empty();
-    FileViewProvider provider = psiFile.getViewProvider();
+    FileViewProvider viewProvider = psiFile.getViewProvider();
 
-    Language baseLanguage = provider.getBaseLanguage();
-    Language dataLanguage = provider instanceof TemplateLanguageFileViewProvider
-                            ? ((TemplateLanguageFileViewProvider)provider).getTemplateDataLanguage() : null;
+    Language baseLanguage = viewProvider.getBaseLanguage();
+    Language dataLanguage = viewProvider instanceof TemplateLanguageFileViewProvider
+                            ? ((TemplateLanguageFileViewProvider)viewProvider).getTemplateDataLanguage() : null;
     return JBIterable.of(baseLanguage)
       .append(dataLanguage)
-      .append(JBIterable.from(provider.getLanguages()).filter(o -> o != baseLanguage && o != dataLanguage));
+      .append(viewProvider.getLanguages())
+      .unique()
+      .filter(language -> {
+        PsiFile psi = viewProvider.getPsi(language);
+        return psi != null && (language == baseLanguage || isAcceptableBaseLanguageFile(psi));
+      });
   }
 
   @Nullable
@@ -143,7 +142,6 @@ public abstract class TemplateLanguageStructureViewBuilder extends TreeBasedStru
     PsiFile psi = viewProvider.getPsi(language);
     if (psi == null) return null;
     if (language == baseLanguage) return createMainBuilder(psi);
-    if (!isAcceptableBaseLanguageFile(psi)) return null;
     PsiStructureViewFactory factory = LanguageStructureViewBuilder.INSTANCE.forLanguage(language);
     return factory == null ? null : factory.getStructureViewBuilder(psi);
   }
@@ -174,6 +172,7 @@ public abstract class TemplateLanguageStructureViewBuilder extends TreeBasedStru
   }
 
   /** @deprecated override {@link #createMainBuilder(PsiFile)} instead */
+  @ApiStatus.ScheduledForRemoval
   @Deprecated
   protected StructureViewComposite.StructureViewDescriptor createMainView(FileEditor fileEditor, PsiFile mainFile) {
     throw new AssertionError();
index cd06ba0f465f0802773054add9e74a70c7d8f666..d29a2a80446448601d08935e4130916b12271c58 100644 (file)
@@ -1,19 +1,4 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package com.intellij.ide.util;