Merge remote-tracking branch 'origin/liana/PY-20932'
authorLiana.Bakradze <liana.bakradze@jetbrains.com>
Wed, 5 Oct 2016 08:40:17 +0000 (11:40 +0300)
committerLiana.Bakradze <liana.bakradze@jetbrains.com>
Wed, 5 Oct 2016 08:40:17 +0000 (11:40 +0300)
312 files changed:
.idea/inspectionProfiles/idea_default.xml
build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy
build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy
build/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy
images/src/org/intellij/images/icons/ThumbnailBlank_dark.png [new file with mode: 0644]
java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java
java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java
java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java
java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java
java/debugger/impl/src/com/intellij/debugger/impl/HotSwapManager.java
java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java
java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java
java/debugger/impl/src/com/intellij/debugger/ui/RunHotswapDialog.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java
java/debugger/impl/src/com/intellij/debugger/ui/impl/ThreadsDebuggerTree.java
java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java
java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java
java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressByJavaCommentFix.java
java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
java/java-analysis-impl/src/com/intellij/codeInspection/ComparatorCombinatorsInspection.java
java/java-analysis-impl/src/com/intellij/codeInspection/JavaSuppressionUtil.java
java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
java/java-analysis-impl/src/com/intellij/codeInspection/SimplifyStreamApiCallChainsInspection.java
java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8CollectionRemoveIfInspection.java [new file with mode: 0644]
java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8CollectionsApiInspection.java
java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8ListSortInspection.java [new file with mode: 0644]
java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8ReplaceMapGetInspection.java [new file with mode: 0644]
java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithCollectFix.java
java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithMatchFix.java
java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java
java/java-analysis-impl/src/com/intellij/ide/highlighter/JavaHighlightingColors.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/ParameterHintsPassFactory.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/ParameterNameHintsManager.java
java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java
java/java-impl/src/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java
java/java-impl/src/com/intellij/psi/util/ProjectIconsAccessor.java
java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java
java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java
java/java-runtime/src/com/intellij/rt/execution/testFrameworks/ChildVMStarter.java [deleted file]
java/java-runtime/src/com/intellij/rt/execution/testFrameworks/ForkedByModuleSplitter.java
java/java-runtime/src/com/intellij/rt/execution/testFrameworks/ForkedSplitter.java
java/java-runtime/src/com/intellij/rt/execution/testFrameworks/ForkedVMWrapper.java [deleted file]
java/java-structure-view/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElementBase.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedWarningIDEA60166.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaContext.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/redundantCast/InvalidConditional.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAllMatchChain.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchChain.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchCompoundAssignment.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchExtends.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchReturn.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSorted.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSortedNatural.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstField.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstIfPresentWithReturn.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstStaticField.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAllMatchChain.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchCompoundAssignment.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchExtends.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchReturn.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchReturnDifferent.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchReturnInterrupted.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSorted.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSortedNatural.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstIfPresentWithReturn.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/afterForeachParameter.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/afterTryWithResources.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/beforeForeachParameter.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/beforeTryWithResources.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/template/postfix/templates/stream/expressionContext.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/template/postfix/templates/stream/expressionContext_after.java [new file with mode: 0644]
java/java-tests/testData/inspection/java8CollectionRemoveIf/afterIteratorRemoveFor.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/afterIteratorRemoveFor.java with 100% similarity]
java/java-tests/testData/inspection/java8CollectionRemoveIf/afterIteratorRemoveInline.java [new file with mode: 0644]
java/java-tests/testData/inspection/java8CollectionRemoveIf/afterIteratorRemoveWhile.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/afterIteratorRemoveWhile.java with 100% similarity]
java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveFor.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeIteratorRemoveFor.java with 100% similarity]
java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveInline.java [new file with mode: 0644]
java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveInlineShortCircuit.java [new file with mode: 0644]
java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveInlineTwice.java [new file with mode: 0644]
java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveWhile.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeIteratorRemoveWhile.java with 100% similarity]
java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveWhileReused.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeIteratorRemoveWhileReused.java with 100% similarity]
java/java-tests/testData/inspection/java8ListSort/afterSort.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/afterSort.java with 100% similarity]
java/java-tests/testData/inspection/java8ListSort/afterSortExpression.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/afterSortExpression.java with 100% similarity]
java/java-tests/testData/inspection/java8ListSort/beforeSort.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeSort.java with 100% similarity]
java/java-tests/testData/inspection/java8ListSort/beforeSortExpression.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeSortExpression.java with 100% similarity]
java/java-tests/testData/inspection/java8ListSort/beforeSortSingleArg.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeSortSingleArg.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/afterComputeIfAbsent.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/afterComputeIfAbsent.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/afterComputeIfAbsentVarConflict.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/afterComputeIfAbsentVarConflict.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/afterGetOrDefaultAssignment.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/afterGetOrDefaultAssignment.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/afterGetOrDefaultField.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/afterGetOrDefaultField.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/afterGetOrDefaultLocal.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/afterGetOrDefaultLocal.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/beforeComputeIfAbsent.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeComputeIfAbsent.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/beforeComputeIfAbsentChecked.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeComputeIfAbsentChecked.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/beforeComputeIfAbsentNonFinal.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeComputeIfAbsentNonFinal.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/beforeComputeIfAbsentVarConflict.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeComputeIfAbsentVarConflict.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/beforeGetOrDefaultAssignment.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeGetOrDefaultAssignment.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/beforeGetOrDefaultField.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeGetOrDefaultField.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/beforeGetOrDefaultFieldOther.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeGetOrDefaultFieldOther.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/beforeGetOrDefaultFieldOther2.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeGetOrDefaultFieldOther2.java with 100% similarity]
java/java-tests/testData/inspection/java8MapGet/beforeGetOrDefaultLocal.java [moved from java/java-tests/testData/inspection/java8CollectionsApi/beforeGetOrDefaultLocal.java with 100% similarity]
java/java-tests/testData/inspection/redundantCast/lambda/CastToRawType.java [new file with mode: 0644]
java/java-tests/testData/inspection/redundantCast/lambda/Conditional.java [moved from java/java-tests/testData/inspection/redundantCast/lambda/Conditional/src/Test.java with 100% similarity]
java/java-tests/testData/inspection/redundantCast/lambda/Conditional/expected.xml [deleted file]
java/java-tests/testData/inspection/redundantCast/lambda/ExpectedSupertype.java [new file with mode: 0644]
java/java-tests/testData/inspection/redundantCast/lambda/ExpectedSupertype/expected.xml [deleted file]
java/java-tests/testData/inspection/redundantCast/lambda/ExpectedSupertype/src/Test.java [deleted file]
java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue.java [moved from java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/src/Test.java with 58% similarity]
java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/expected.xml [deleted file]
java/java-tests/testData/inspection/redundantCast/lambda/InferApplicabilityError.java [moved from java/java-tests/testData/inspection/redundantCast/lambda/InferApplicabilityError/src/Test.java with 100% similarity]
java/java-tests/testData/inspection/redundantCast/lambda/InferApplicabilityError/expected.xml [deleted file]
java/java-tests/testData/inspection/redundantCast/lambda/LambdaContext.java [new file with mode: 0644]
java/java-tests/testData/inspection/redundantCast/lambda/LambdaContext/expected.xml [deleted file]
java/java-tests/testData/inspection/redundantCast/lambda/LambdaContext/src/Test.java [deleted file]
java/java-tests/testData/inspection/redundantCast/lambda/MethodRefContext.java [moved from java/java-tests/testData/inspection/redundantCast/lambda/MethodRefContext/src/Test.java with 80% similarity]
java/java-tests/testData/inspection/redundantCast/lambda/MethodRefContext/expected.xml [deleted file]
java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedLambda.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedLambdaTwice.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegated.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegatedLambdaTwice.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegated.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegatedLambda.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegated.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedLambda.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedLambdaTwice.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegated.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedLambda.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedLambdaTwice.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegated.java [new file with mode: 0644]
java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegatedLambda.java [new file with mode: 0644]
java/java-tests/testData/refactoring/inlineLocal/AvoidTypeSpecificationWhenPossibleToAvoid.java [new file with mode: 0644]
java/java-tests/testData/refactoring/inlineLocal/AvoidTypeSpecificationWhenPossibleToAvoid.java.after [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
java/java-tests/testSrc/com/intellij/codeInsight/daemon/inlays/InlayParameterHintsTest.kt
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java
java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplateTest.java
java/java-tests/testSrc/com/intellij/codeInspection/Java8CollectionRemoveIfInspectionTest.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInspection/Java8ListSortInspectionTest.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInspection/Java8ReplaceMapGetInspectionTest.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java
java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java
jps/jps-builders/src/org/jetbrains/jps/incremental/ExternalProcessUtil.java
platform/diff-api/src/com/intellij/diff/DiffContentFactory.java
platform/diff-api/src/com/intellij/diff/contents/DiffContent.java
platform/diff-api/src/com/intellij/diff/contents/DiffContentBase.java
platform/diff-api/src/com/intellij/diff/contents/DocumentContent.java
platform/diff-api/src/com/intellij/ide/diff/DiffElement.java
platform/diff-impl/src/com/intellij/diff/DiffContentFactoryEx.java [new file with mode: 0644]
platform/diff-impl/src/com/intellij/diff/DiffContentFactoryImpl.java
platform/diff-impl/src/com/intellij/diff/DiffRequestFactoryImpl.java
platform/diff-impl/src/com/intellij/diff/actions/CompareClipboardWithSelectionAction.java
platform/diff-impl/src/com/intellij/diff/actions/DocumentFragmentContent.java
platform/diff-impl/src/com/intellij/diff/contents/DocumentContentImpl.java
platform/diff-impl/src/com/intellij/diff/contents/FileAwareDocumentContent.java
platform/diff-impl/src/com/intellij/diff/contents/FileDocumentContentImpl.java
platform/diff-impl/src/com/intellij/diff/merge/MergeWindow.java
platform/diff-impl/src/com/intellij/diff/merge/TextMergeChange.java
platform/diff-impl/src/com/intellij/diff/tools/external/ExternalDiffToolUtil.java
platform/diff-impl/src/com/intellij/diff/tools/util/base/TextDiffViewerUtil.java
platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java
platform/editor-ui-api/src/com/intellij/openapi/editor/DefaultLanguageHighlighterColors.java
platform/editor-ui-api/src/com/intellij/openapi/editor/Inlay.java
platform/editor-ui-api/src/com/intellij/openapi/editor/InlayModel.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/task/ToggleBeforeRunTaskAction.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/task/ToggleTaskActivationAction.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalSystemTaskActivator.java
platform/icons/src/debugger/explosion.png
platform/icons/src/diff/magicResolve.png [new file with mode: 0644]
platform/icons/src/diff/magicResolve@2x.png [new file with mode: 0644]
platform/icons/src/diff/magicResolve@2x_dark.png [new file with mode: 0644]
platform/icons/src/diff/magicResolve_dark.png [new file with mode: 0644]
platform/icons/src/icon_CE.png
platform/icons/src/icon_CEsmall.png
platform/icons/src/icon_CEsmall@2x.png
platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInComments.java
platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.java
platform/lang-impl/src/com/intellij/application/options/colors/highlighting/HighlightData.java
platform/lang-impl/src/com/intellij/application/options/colors/highlighting/HighlightsExtractor.java
platform/lang-impl/src/com/intellij/application/options/colors/highlighting/InlineElementData.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ParameterHintsPresentationManager.java [moved from java/java-impl/src/com/intellij/codeInsight/daemon/impl/ParameterHintsPresentationManager.java with 98% similarity]
platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java
platform/lang-impl/src/com/intellij/ide/macro/FileDirPathFromParentMacro.java
platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java
platform/lang-impl/src/com/intellij/injected/editor/InlayModelWindow.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/openapi/editor/richcopy/view/RtfTransferableData.java
platform/lang-impl/src/com/intellij/openapi/options/colors/pages/DefaultLanguageColorsPage.java
platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java
platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButton.java
platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButtonBuilder.java
platform/lang-impl/testSources/com/intellij/ide/macro/MacroManagerTest.java
platform/platform-api/src/com/intellij/execution/util/ExecUtil.java
platform/platform-api/src/com/intellij/ui/table/JBTable.java
platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java
platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java
platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java
platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftOrRightHandler.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTree.java
platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java
platform/platform-impl/src/com/intellij/util/Restarter.java
platform/platform-resources-en/src/messages/OptionsBundle.properties
platform/platform-resources/src/META-INF/LangExtensions.xml
platform/platform-tests/testData/editor/richcopy/BlockSelection.rtf
platform/platform-tests/testData/editor/richcopy/BlockSelection.rtf.mac
platform/platform-tests/testData/editor/richcopy/NormalSelection.rtf
platform/platform-tests/testData/editor/richcopy/NormalSelection.rtf.mac
platform/platform-tests/testSrc/com/intellij/history/integration/patches/PatchCreatorTest.java
platform/platform-tests/testSrc/com/intellij/openapi/project/impl/ProjectOpeningTest.java
platform/projectModel-impl/src/com/intellij/openapi/roots/AdditionalLibraryRootsProvider.java
platform/testRunner/src/com/intellij/execution/testframework/actions/TestDiffRequestProcessor.java
platform/testRunner/src/com/intellij/execution/testframework/ui/TestStatusLine.java
platform/util/resources/misc/registry.properties
platform/util/src/com/intellij/icons/AllIcons.java
platform/util/src/com/intellij/openapi/vfs/CharsetToolkit.java
platform/util/src/com/intellij/util/ui/JBUI.java
platform/util/src/com/intellij/util/ui/components/ComboBoxCompositeEditor.java [new file with mode: 0644]
platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
platform/util/src/org/jetbrains/annotations/ApiStatus.java
platform/vcs-impl/src/com/intellij/openapi/vcs/actions/DiffActionExecutor.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/diff/ChangeDiffRequestProducer.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/migrate/MigrateToNewDiffUtil.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchDiffRequestFactory.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/tool/ApplyPatchViewer.java
platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryUtil.java
platform/vcs-impl/src/com/intellij/openapi/vcs/update/ShowUpdatedDiffAction.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogData.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiPropertiesImpl.java
platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/RefreshLogAction.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/BranchFilterPopupComponent.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/FilterModel.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultilinePopupBuilder.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/MultipleValueFilterPopupComponent.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/UserFilterPopupComponent.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
platform/xdebugger-impl/src/com/intellij/xdebugger/attach/XLocalAttachGroup.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerHistoryManager.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerInlayUtil.java [new file with mode: 0644]
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/AttachToLocalProcessAction.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointManagerImpl.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsDialog.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XCopyValueAction.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java
platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ControlFlowUtils.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java
plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java
plugins/commander/src/com/intellij/ide/commander/PsiDiffContentFactory.java
plugins/generate-tostring/src/org/jetbrains/java/generate/GenerateToStringActionHandlerImpl.java
plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java
plugins/junit_rt/src/com/intellij/junit4/IdeaSuite.java
plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedSplitter.java
plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java
plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java
plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenModel.java
plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServer.java
plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerExecutionResult.java
plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/Maven2ServerImpl.java
plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ModelConverter.java
plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java
plugins/maven/maven3-server-common/src/org/jetbrains/idea/maven/server/MavenModelConverter.java
plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3AetherModelConverter.java
plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java
plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerImpl.java
plugins/maven/maven30-server-impl/src/org/jetbrains/idea/maven/server/Maven30AetherModelConverter.java
plugins/maven/maven30-server-impl/src/org/jetbrains/idea/maven/server/Maven30ServerEmbedderImpl.java
plugins/maven/maven30-server-impl/src/org/jetbrains/idea/maven/server/Maven30ServerImpl.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectReader.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectReaderResult.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/OpenOrCreateProfilesXmlAction.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/svn4idea/src/org/jetbrains/idea/svn/diff/FileWithBranchComparer.java
plugins/testng/testSources/com/theoryinpractice/testng/configuration/TestNGForkTest.java
plugins/testng_rt/src/org/testng/RemoteTestNGStarter.java
plugins/testng_rt/src/org/testng/TestNGForkedSplitter.java
plugins/testng_rt/src/org/testng/TestNGForkedStarter.java
python/helpers/pycharm/django_test_manage.py
python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java
python/src/com/jetbrains/python/psi/impl/PyConstantExpressionEvaluator.java
python/testData/inspections/PyUnboundLocalVariableInspection/WhileOneBreak.py [new file with mode: 0644]
python/testData/inspections/PyUnboundLocalVariableInspection/WhileTrueBreak.py [new file with mode: 0644]
python/testData/refactoring/inlinelocal/doubleDefinition.before.py
python/testData/refactoring/inlinelocal/noDominator.before.py
python/testSrc/com/jetbrains/env/PyEnvSufficiencyTest.java
python/testSrc/com/jetbrains/env/PyEnvTestCase.java
python/testSrc/com/jetbrains/python/inspections/PyUnboundLocalVariableInspectionTest.java
resources-en/src/inspectionDescriptions/Java8CollectionRemoveIf.html [new file with mode: 0644]
resources-en/src/inspectionDescriptions/Java8CollectionsApi.html
resources-en/src/inspectionDescriptions/Java8ListSort.html [new file with mode: 0644]
resources-en/src/inspectionDescriptions/Java8ReplaceMapGet.html [new file with mode: 0644]
resources-en/src/inspectionDescriptions/SimplifyStreamApiCallChains.html
resources-en/src/messages/QuickFixBundle.properties
resources/src/META-INF/IdeaPlugin.xml

index 0ce93dbd0261b45f3cc8a644c85e8b4998bbd9d7..615c0d1e859f94ec6c51163e85b343cbc9d56e30 100644 (file)
       <option name="m_minLength" value="8" />
       <option name="m_maxLength" value="64" />
     </inspection_tool>
+    <inspection_tool class="Java8CollectionRemoveIf" enabled="true" level="INFORMATION" enabled_by_default="true" />
     <inspection_tool class="Java8CollectionsApi" enabled="true" level="INFORMATION" enabled_by_default="true" />
+    <inspection_tool class="Java8ListSort" enabled="true" level="INFORMATION" enabled_by_default="true" />
+    <inspection_tool class="Java8ReplaceMapGet" enabled="true" level="INFORMATION" enabled_by_default="true" />
     <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="false">
       <scope name="Tests" level="WARNING" enabled="false">
         <option name="TOP_LEVEL_CLASS_OPTIONS">
index 6442c79f88b10794326780befaf94f2bc38ac056..4820fd9a18625763bef8ab7912ddc747607ac16b 100644 (file)
@@ -108,6 +108,9 @@ abstract class BaseIdeaProperties extends ProductProperties {
         withoutProjectLibrary("com.twelvemonkeys.imageio:imageio-tiff:3.2.1")
       }
     } as Consumer<PlatformLayout>
+
+    additionalModulesToCompile = ["jps-standalone-builder"]
+    modulesToCompileTests = ["jps-builders"]
   }
 
   @Override
index 9bf3be887b622380bf56e87ef1c0876e5f279e7c..f31af3af78803b262bf568b7bb4ea84e6b4b0e12 100644 (file)
@@ -156,6 +156,18 @@ abstract class ProductProperties {
 
   List<String> excludedPlugins = []
 
+  /**
+   * Specified additional modules (not included into the product layout) which need to be compiled when product is built.
+   * todo[nik] get rid of this
+   */
+  List<String> additionalModulesToCompile = []
+
+  /**
+   * Specified modules which tests need to be compiled when product is built.
+   * todo[nik] get rid of this
+   */
+  List<String> modulesToCompileTests = []
+
   /**
    * Prefix for names of environment variables used by Windows and Linux distributions to allow users customize location of the product JDK
    * (&lt;PRODUCT&gt;_JDK variable), *.vmoptions file (&lt;PRODUCT&gt;_VM_OPTIONS variable), idea.properties file (&lt;PRODUCT&gt;_PROPERTIES variable)
index 348293b3bf365c3528b020c028d8318843807379..30c5745633137b9e4539eb407bcabad725f39018 100644 (file)
@@ -282,7 +282,8 @@ idea.fatal.error.notification=disabled
   void compileModulesAndBuildDistributions() {
     checkProductProperties()
     def distributionJARsBuilder = new DistributionJARsBuilder(buildContext)
-    compileModules(buildContext.productProperties.productLayout.includedPluginModules + distributionJARsBuilder.platformModules)
+    compileModules(buildContext.productProperties.productLayout.includedPluginModules + distributionJARsBuilder.platformModules +
+                   buildContext.productProperties.additionalModulesToCompile, buildContext.productProperties.modulesToCompileTests)
     buildContext.messages.block("Build platform and plugin JARs") {
       distributionJARsBuilder.buildJARs()
       distributionJARsBuilder.buildAdditionalArtifacts()
diff --git a/images/src/org/intellij/images/icons/ThumbnailBlank_dark.png b/images/src/org/intellij/images/icons/ThumbnailBlank_dark.png
new file mode 100644 (file)
index 0000000..0e2d0ef
Binary files /dev/null and b/images/src/org/intellij/images/icons/ThumbnailBlank_dark.png differ
index 47e29af1c5e83bac9f55f22be6250546f302516a..18ee002394a0b38633e6b5f25c29acc28fd647d2 100644 (file)
@@ -81,8 +81,7 @@ public class ForceEarlyReturnAction extends DebuggerAction {
           forceEarlyReturnWithFinally(thread.getVirtualMachine().mirrorOfVoid(), stackFrame, debugProcess, null);
         }
         else {
-          //noinspection SSBasedInspection
-          SwingUtilities.invokeLater(
+          ApplicationManager.getApplication().invokeLater(
             () -> new ReturnExpressionDialog(project, debugProcess.getXdebugProcess().getEditorsProvider(), debugProcess, stackFrame).show());
         }
       }
index fc09b147c279738c5b61b4d59f2a402139177eea..50336f6bb012edc443e4fc60d722f0aa7e2b8811 100644 (file)
@@ -203,7 +203,7 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
         });
       if (lambdas.size() > 1) {
         ArrayList<Method> lambdasList = new ArrayList<>(lambdas);
-        Collections.sort(lambdasList, DebuggerUtilsEx.LAMBDA_ORDINAL_COMPARATOR);
+        lambdasList.sort(DebuggerUtilsEx.LAMBDA_ORDINAL_COMPARATOR);
         lambdaOrdinal = lambdasList.indexOf(method);
       }
     }
index a9a5de7d2225cf03256b9ad03b8bc7177c4bede9..1461bf2ff7a66f766526f284f2ca28bfbc7405b0 100644 (file)
@@ -257,7 +257,7 @@ public abstract class SuspendContextImpl extends XSuspendContext implements Susp
             currentStack = stack;
           }
         }
-        Collections.sort(res, THREADS_COMPARATOR);
+        res.sort(THREADS_COMPARATOR);
         if (currentStack != null) {
           res.add(0, currentStack);
         }
index 2e8f075d584d16730a75c0032a6b351452fdc8cb..bd47b8918fd9209e70e1958fb649d8dfbadaaadd 100644 (file)
@@ -949,7 +949,7 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
   }
 
   public static final Comparator<Method> LAMBDA_ORDINAL_COMPARATOR =
-    (m1, m2) -> LambdaMethodFilter.getLambdaOrdinal(m1.name()) - LambdaMethodFilter.getLambdaOrdinal(m2.name());
+    Comparator.comparingInt(m -> LambdaMethodFilter.getLambdaOrdinal(m.name()));
 
   public static void disableCollection(ObjectReference reference) {
     try {
index f1a7e7e43e3ef2a631c6c5a83b5d54da9d8361a6..6cf0bf5220881b8c457a6f16f5e2c2f8e29374f0 100644 (file)
@@ -145,12 +145,7 @@ public class HotSwapManager extends AbstractProjectComponent {
           for (Pair<DebuggerSession, Long> pair : sessionWithStamps) {
             final DebuggerSession session = pair.first;
             if (fileStamp > pair.second) {
-              Map<String, HotSwapFile> container = result.get(session);
-              if (container == null) {
-                container = new java.util.HashMap<>();
-                result.put(session, container);
-              }
-              container.put(qualifiedName, hotswapFile);
+              result.computeIfAbsent(session, k -> new java.util.HashMap<>()).put(qualifiedName, hotswapFile);
             }
           }
         }
index 31bd539868bc5ef53cb8e051d4de880b76360b17..d56d4374f5e01f830d9ca28089194b5c95274b3d 100644 (file)
@@ -34,8 +34,6 @@ import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 import javax.swing.event.DocumentEvent;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
 import java.awt.*;
 import java.util.ArrayList;
 import java.util.List;
@@ -101,19 +99,11 @@ public final class UserRenderersConfigurable extends JPanel implements Configura
   private void setupRenderersList() {
     myRendererChooser.getEmptyText().setText(DebuggerBundle.message("text.user.renderers.configurable.no.renderers"));
 
-    myRendererChooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener<NodeRenderer>() {
-      @Override
-      public void elementMarkChanged(final NodeRenderer element, final boolean isMarked) {
-        element.setEnabled(isMarked);
-      }
-    });
-    myRendererChooser.addListSelectionListener(new ListSelectionListener() {
-      @Override
-      public void valueChanged(@NotNull ListSelectionEvent e) {
+    myRendererChooser.addElementsMarkListener((ElementsChooser.ElementsMarkListener<NodeRenderer>)NodeRenderer::setEnabled);
+    myRendererChooser.addListSelectionListener(e -> {
       if (!e.getValueIsAdjusting()) {
         updateCurrentRenderer(myRendererChooser.getSelectedElements());
       }
-      }
     });
   }
 
index e5e1a0c2b6ee4520d29c9fcef53495f145e799ea..fbb9a5459a8d649f536ed50e1416071da1e27d37 100644 (file)
@@ -298,13 +298,7 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent {
     public void fileGenerated(String outputRoot, String relativePath) {
       if (StringUtil.endsWith(relativePath, ".class") && JpsPathUtil.isUnder(myOutputRoots, new File(outputRoot))) {
         // collect only classes
-        final Map<String, List<String>> map = myGeneratedPaths.get();
-        List<String> paths = map.get(outputRoot);
-        if (paths == null) {
-          paths = new ArrayList<>();
-          map.put(outputRoot, paths);
-        }
-        paths.add(relativePath);
+        myGeneratedPaths.get().computeIfAbsent(outputRoot, k -> new ArrayList<>()).add(relativePath);
       }
     }
 
index 29a362802a765d658573b5c45ad0192c2ecf86c6..f05acd887a9d67d148355fb881e2df32543aa289 100644 (file)
@@ -53,7 +53,7 @@ public class RunHotswapDialog extends OptionsDialog {
     for (DebuggerSession session : sessions) {
       items.add(new SessionItem(session));
     }
-    Collections.sort(items, (debuggerSession, debuggerSession1) -> debuggerSession.getSession().getSessionName().compareTo(debuggerSession1.getSession().getSessionName()));
+    items.sort(Comparator.comparing(debuggerSession -> debuggerSession.getSession().getSessionName()));
     myElementsChooser = new ElementsChooser<>(items, true);
     myPanel.setBorder(IdeBorderFactory.createEmptyBorder(10, 0, 5, 0));
     //myElementsChooser.setBorder(IdeBorderFactory.createEmptyBorder(5, 0, 0, 0));
index 1e8c5c8fc73bf55692718ce55cb7c1d1f86364b4..be97b24719cc95e3dd1e13f7b040a43a8e7041e1 100644 (file)
@@ -47,7 +47,6 @@ import com.intellij.openapi.util.Key;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileManager;
 import com.intellij.psi.PsiField;
-import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.xdebugger.XDebuggerManager;
 import com.intellij.xdebugger.XDebuggerUtil;
@@ -494,12 +493,8 @@ public class BreakpointManager {
 
   @NotNull
   public List<Breakpoint> getBreakpoints() {
-    return ApplicationManager.getApplication().runReadAction((Computable<List<Breakpoint>>)() -> ContainerUtil.mapNotNull(getXBreakpointManager().getAllBreakpoints(), new Function<XBreakpoint<?>, Breakpoint>() {
-      @Override
-      public Breakpoint fun(XBreakpoint<?> xBreakpoint) {
-        return getJavaBreakpoint(xBreakpoint);
-      }
-    }));
+    return ApplicationManager.getApplication().runReadAction((Computable<List<Breakpoint>>)() ->
+      ContainerUtil.mapNotNull(getXBreakpointManager().getAllBreakpoints(), BreakpointManager::getJavaBreakpoint));
   }
 
   @Nullable
index 196f354f722e436cbf7441de6ff012f0f9e50e37..0acacde8c0f24e84cfe28d748336e6e9dac8015a 100644 (file)
@@ -185,7 +185,7 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
     private final PsiElement myElement;
     private final Integer myLambdaOrdinal;
 
-    public ExactJavaBreakpointVariant(@NotNull XSourcePosition position, @NotNull PsiElement element, Integer lambdaOrdinal) {
+    public ExactJavaBreakpointVariant(@NotNull XSourcePosition position, @Nullable PsiElement element, Integer lambdaOrdinal) {
       super(position);
       myElement = element;
       myLambdaOrdinal = lambdaOrdinal;
@@ -193,17 +193,17 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
 
     @Override
     public Icon getIcon() {
-      return myElement.getIcon(0);
+      return myElement != null ? myElement.getIcon(0) : AllIcons.Debugger.Db_set_breakpoint;
     }
 
     @Override
     public String getText() {
-      return StringUtil.shortenTextWithEllipsis(myElement.getText(), 100, 0);
+      return myElement != null ? StringUtil.shortenTextWithEllipsis(myElement.getText(), 100, 0) : "Line";
     }
 
     @Override
     public TextRange getHighlightRange() {
-      return myElement.getTextRange();
+      return myElement != null ? myElement.getTextRange() : null;
     }
 
     @NotNull
@@ -217,7 +217,7 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
   }
 
   public class LineJavaBreakpointVariant extends ExactJavaBreakpointVariant {
-    public LineJavaBreakpointVariant(@NotNull XSourcePosition position, @NotNull PsiElement element, Integer lambdaOrdinal) {
+    public LineJavaBreakpointVariant(@NotNull XSourcePosition position, @Nullable PsiElement element, Integer lambdaOrdinal) {
       super(position, element, lambdaOrdinal);
     }
 
index 43d3941b1c10c34491b7d7e3c115aa1e848c9fa8..6909776f517da633597c0647cc6fe95a22a44f1e 100644 (file)
@@ -144,7 +144,7 @@ public class ThreadsDebuggerTree extends DebuggerTree {
             root.insert(nodeManager.createNode(nodeManager.getThreadDescriptor(null, currentThread), evaluationContext), 0);
           }
           List<ThreadReferenceProxyImpl> allThreads = new ArrayList<>(vm.allThreads());
-          Collections.sort(allThreads, ThreadReferenceProxyImpl.ourComparator);
+          allThreads.sort(ThreadReferenceProxyImpl.ourComparator);
 
           for (ThreadReferenceProxyImpl threadProxy : allThreads) {
             if (threadProxy.equals(currentThread)) {
index f73350ab0bb13c3ed0e3f59fa0d43e30298f6ea1..e006530b6145daa52d9733cd35db779b3702b326 100644 (file)
@@ -491,7 +491,7 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi
         try {
           buildVariables(stackDescriptor, evaluationContext);
           if (XDebuggerSettingsManager.getInstance().getDataViewSettings().isSortValues()) {
-            Collections.sort(myChildren, NodeManagerImpl.getNodeComparator());
+            myChildren.sort(NodeManagerImpl.getNodeComparator());
           }
         }
         catch (EvaluateException e) {
@@ -686,7 +686,7 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi
       ThreadGroupReferenceProxyImpl threadGroup = groupDescriptor.getThreadGroupReference();
 
       List<ThreadReferenceProxyImpl> threads = new ArrayList<>(threadGroup.threads());
-      Collections.sort(threads, ThreadReferenceProxyImpl.ourComparator);
+      threads.sort(ThreadReferenceProxyImpl.ourComparator);
 
       final DebuggerContextImpl debuggerContext = getDebuggerContext();
       final SuspendContextImpl suspendContext = debuggerContext.getSuspendContext();
index bb252531eadf736b66a26cd4584950ca2f0a40fe..baf30cbc5455c995c73db642425c7c86b6c38aa2 100644 (file)
@@ -76,7 +76,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
         }
         LOG.info(e);
       }
-      myMethodOccurrence = tracker.getMethodOccurrence(myUiIndex, myLocation.method());
+      myMethodOccurrence = tracker.getMethodOccurrence(myUiIndex, getMethod(myLocation));
       myIsSynthetic = DebuggerUtils.isSynthetic(myMethodOccurrence.getMethod());
       mySourcePosition = ContextUtil.getSourcePosition(this);
       ApplicationManager.getApplication().runReadAction(() -> {
@@ -101,6 +101,17 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
     }
   }
 
+  @Nullable
+  private static Method getMethod(Location location) {
+    try {
+      return location.method();
+    }
+    catch (IllegalArgumentException e) { // Invalid method id
+      LOG.info(e);
+    }
+    return null;
+  }
+
   public int getUiIndex() {
     return myUiIndex;
   }
index f7e96758b2bf57532956273fe08a7ed0c352c2a6..3650a0f1f91fd9383a4b96c09eb738ced34716d5 100644 (file)
@@ -48,7 +48,6 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -178,7 +177,7 @@ public class ClassRenderer extends NodeRendererImpl{
           children.add(nodeManager.createMessageNode(DebuggerBundle.message("message.node.class.no.fields.to.display")));
         }
         else if (XDebuggerSettingsManager.getInstance().getDataViewSettings().isSortValues()) {
-          Collections.sort(children, NodeManagerImpl.getNodeComparator());
+          children.sort(NodeManagerImpl.getNodeComparator());
         }
       }
       else {
index c42422f963100e238720d9f60db449433e9b777f..c1b194ae7a9aff4d8f7af99eee19a600fcc11831 100644 (file)
@@ -57,7 +57,7 @@ public class SuppressByJavaCommentFix extends SuppressByCommentFix {
       suppressWithComment(project, element, container);
     }
     else {
-      JavaSuppressionUtil.addSuppressAnnotation(project, container, (PsiLocalVariable)declaredElement, myID);
+      JavaSuppressionUtil.addSuppressAnnotation(project, container, (PsiVariable)declaredElement, myID);
     }
   }
 
index 448c427c445c9463bad6e211d6cd15bd51959436..1a648d2a1aed2753bcbd32c829b09803c66b502c 100644 (file)
@@ -323,8 +323,10 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
   @Override
   public void visitLambdaExpression(PsiLambdaExpression expression) {
     myHolder.add(checkFeature(expression, Feature.LAMBDA_EXPRESSIONS));
+    final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
+    if (parent instanceof PsiExpressionStatement) return;
     if (!myHolder.hasErrorResults()) {
-      if (LambdaUtil.isValidLambdaContext(expression.getParent())) {
+      if (LambdaUtil.isValidLambdaContext(parent)) {
         final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
         if (functionalInterfaceType != null) {
           final String notFunctionalMessage = LambdaHighlightingUtil.checkInterfaceFunctional(functionalInterfaceType);
@@ -335,7 +337,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
             myHolder.add(result);
           }
           else {
-            final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
             final PsiCallExpression callExpression = parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression ?
                                                      (PsiCallExpression)parent.getParent() : null;
             final JavaResolveResult containingCallResolveResult = callExpression != null ? callExpression.resolveMethodGenerics() : null;
@@ -1294,6 +1295,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
   @Override
   public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
     myHolder.add(checkFeature(expression, Feature.METHOD_REFERENCES));
+    final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
+    if (parent instanceof PsiExpressionStatement) return;
 
     final JavaResolveResult result;
     final JavaResolveResult[] results;
@@ -1324,7 +1327,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
       myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(expression, colorsScheme));
     }
 
-    if (!LambdaUtil.isValidLambdaContext(expression.getParent())) {
+    if (!LambdaUtil.isValidLambdaContext(parent)) {
       String description = "Method reference expression is not expected here";
       myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create());
     }
index bd62579397adba9f043a7bd99e83f422ee6d8eb0..fd8056a9fe1228c98e9947c60605ce786a147b59 100644 (file)
@@ -232,7 +232,7 @@ public class ComparatorCombinatorsInspection extends BaseJavaBatchLocalInspectio
       PsiParameter[] parameters = lambda.getParameterList().getParameters();
       PsiElement body = lambda.getBody();
       if (body == null) return;
-      if (LambdaCanBeMethodReferenceInspection.replaceLambdaWithMethodReference(factory, lambda) == lambda) {
+      if (LambdaCanBeMethodReferenceInspection.replaceLambdaWithMethodReference(lambda) == lambda) {
         PsiParameter parameter = parameters[0];
         String name = parameter.getName();
         SuggestedNameInfo nameCandidate = null;
index c3933012733d71f2ec35174cadfe02b8acb083dc..2d0a6549eec25746f859ec87a160921ae5091fc7 100644 (file)
@@ -330,14 +330,38 @@ public class JavaSuppressionUtil {
 
   @Nullable
   public static PsiElement getElementToAnnotate(PsiElement element, PsiElement container) {
-    if (container instanceof PsiDeclarationStatement && canHave15Suppressions(element)) {
-      final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)container;
-      final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
-      for (PsiElement declaredElement : declaredElements) {
-        if (declaredElement instanceof PsiLocalVariable) {
-          final PsiModifierList modifierList = ((PsiLocalVariable)declaredElement).getModifierList();
-          if (modifierList != null) {
-            return declaredElement;
+    if (container instanceof PsiDeclarationStatement) {
+      if (canHave15Suppressions(element)) {
+        final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)container;
+        final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
+        for (PsiElement declaredElement : declaredElements) {
+          if (declaredElement instanceof PsiLocalVariable) {
+            final PsiModifierList modifierList = ((PsiLocalVariable)declaredElement).getModifierList();
+            if (modifierList != null) {
+              return declaredElement;
+            }
+          }
+        }
+      }
+    }
+    else if (container instanceof PsiForeachStatement) {
+      if (canHave15Suppressions(element)) {
+        final PsiParameter parameter = ((PsiForeachStatement)container).getIterationParameter();
+        final PsiModifierList modifierList = element.getParent() == parameter ? parameter.getModifierList() : null;
+        if (modifierList != null) {
+          return parameter;
+        }
+      }
+    }
+    else if (container instanceof PsiTryStatement) {
+      final PsiResourceList resourceList = ((PsiTryStatement)container).getResourceList();
+      if (resourceList != null) {
+        for (PsiResourceListElement listElement : resourceList) {
+          if (listElement instanceof PsiResourceVariable && listElement == element.getParent()) {
+            final PsiModifierList modifierList = ((PsiResourceVariable)listElement).getModifierList();
+            if (modifierList != null) {
+              return listElement;
+            }
           }
         }
       }
index c86d71191de25755ec2ad436704e5f149d6929d1..17bd630a15286542929dca708190daeafe4d8c73 100644 (file)
@@ -308,27 +308,18 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
   public static void replaceAllLambdasWithMethodReferences(PsiElement root) {
     Collection<PsiLambdaExpression> lambdas = PsiTreeUtil.findChildrenOfType(root, PsiLambdaExpression.class);
     if(!lambdas.isEmpty()) {
-      PsiElementFactory factory = JavaPsiFacade.getElementFactory(root.getProject());
       for(PsiLambdaExpression lambda : lambdas) {
-        replaceLambdaWithMethodReference(factory, lambda);
+        replaceLambdaWithMethodReference(lambda);
       }
     }
   }
 
-  public static PsiExpression replaceLambdaWithMethodReference(PsiElementFactory factory, PsiLambdaExpression lambda) {
-    PsiType type = lambda.getFunctionalInterfaceType();
-    if(type == null) return lambda;
-    String methodReference =
-      convertToMethodReference(lambda.getBody(), lambda.getParameterList().getParameters(), type, lambda);
-    if(methodReference == null) return lambda;
-    PsiTypeCastExpression replacement = (PsiTypeCastExpression)lambda.replace(
-      factory.createExpressionFromText("(" + lambda.getFunctionalInterfaceType().getCanonicalText() + ")" + methodReference, lambda));
-    if (RedundantCastUtil.isCastRedundant(replacement)) {
-      final PsiExpression operand = replacement.getOperand();
-      LOG.assertTrue(operand != null);
-      return (PsiExpression)replacement.replace(operand);
-    }
-    return replacement;
+  @NotNull
+  public static PsiExpression replaceLambdaWithMethodReference(@NotNull PsiLambdaExpression lambda) {
+    PsiElement body = LambdaUtil.extractSingleExpressionFromBody(lambda.getBody());
+    final PsiExpression candidate = new LambdaCanBeMethodReferenceInspection()
+      .canBeMethodReferenceProblem(body, lambda.getParameterList().getParameters(), lambda.getFunctionalInterfaceType(), lambda);
+    return tryConvertToMethodReference(lambda, candidate);
   }
 
   private static boolean checkQualifier(PsiElement qualifier) {
@@ -599,34 +590,46 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
       if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
       final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
       if (lambdaExpression == null) return;
-      PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
-      if (functionalInterfaceType == null || !functionalInterfaceType.isValid()) return;
-      final PsiType denotableFunctionalInterfaceType = RefactoringChangeUtil.getTypeByExpression(lambdaExpression);
-      if (denotableFunctionalInterfaceType == null) return;
-
-      Collection<PsiComment> comments = ContainerUtil.map(PsiTreeUtil.findChildrenOfType(lambdaExpression, PsiComment.class),
-                                                          (comment) -> (PsiComment)comment.copy());
-
-      final String methodRefText = createMethodReferenceText(element, functionalInterfaceType,
-                                                             lambdaExpression.getParameterList().getParameters());
-
-      if (methodRefText != null) {
-        final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
-        final PsiExpression psiExpression = factory.createExpressionFromText(methodRefText, lambdaExpression);
-        final SmartTypePointer typePointer = SmartTypePointerManager.getInstance(project).createSmartTypePointer(denotableFunctionalInterfaceType);
-        PsiElement replace = lambdaExpression.replace(psiExpression);
-        final PsiType functionalTypeAfterReplacement = GenericsUtil.getVariableTypeByExpressionType(((PsiMethodReferenceExpression)replace).getFunctionalInterfaceType());
-        functionalInterfaceType = typePointer.getType();
-        if (functionalTypeAfterReplacement == null || functionalInterfaceType != null && !functionalTypeAfterReplacement.equals(functionalInterfaceType)) { //ambiguity
-          final PsiTypeCastExpression cast = (PsiTypeCastExpression)factory.createExpressionFromText("(A)a", replace);
-          cast.getCastType().replace(factory.createTypeElement(functionalInterfaceType));
-          cast.getOperand().replace(replace);
-          replace = replace.replace(cast);
-        }
+      tryConvertToMethodReference(lambdaExpression, element);
+    }
+  }
 
-        AnonymousCanBeLambdaInspection.restoreComments(comments, replace);
-        JavaCodeStyleManager.getInstance(project).shortenClassReferences(replace);
+  @NotNull
+  static PsiExpression tryConvertToMethodReference(@NotNull PsiLambdaExpression lambda, PsiElement body) {
+    Project project = lambda.getProject();
+    PsiType functionalInterfaceType = lambda.getFunctionalInterfaceType();
+    if (functionalInterfaceType == null || !functionalInterfaceType.isValid()) return lambda;
+    final PsiType denotableFunctionalInterfaceType = RefactoringChangeUtil.getTypeByExpression(lambda);
+    if (denotableFunctionalInterfaceType == null) return lambda;
+
+    Collection<PsiComment> comments = ContainerUtil.map(PsiTreeUtil.findChildrenOfType(lambda, PsiComment.class),
+                                                        (comment) -> (PsiComment)comment.copy());
+
+    final String methodRefText = createMethodReferenceText(body, functionalInterfaceType, lambda.getParameterList().getParameters());
+
+    if (methodRefText != null) {
+      final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+      final PsiExpression psiExpression = factory.createExpressionFromText(methodRefText, lambda);
+      final SmartTypePointer typePointer = SmartTypePointerManager.getInstance(project).createSmartTypePointer(denotableFunctionalInterfaceType);
+      PsiExpression replace = (PsiExpression)lambda.replace(psiExpression);
+      final PsiType functionalTypeAfterReplacement = GenericsUtil.getVariableTypeByExpressionType(((PsiMethodReferenceExpression)replace).getFunctionalInterfaceType());
+      functionalInterfaceType = typePointer.getType();
+      if (functionalInterfaceType != null && (functionalTypeAfterReplacement == null ||
+          !functionalTypeAfterReplacement.equals(functionalInterfaceType))) { //ambiguity
+        final PsiTypeCastExpression cast = (PsiTypeCastExpression)factory.createExpressionFromText("(A)a", replace);
+        PsiTypeElement castType = cast.getCastType();
+        LOG.assertTrue(castType != null);
+        castType.replace(factory.createTypeElement(functionalInterfaceType));
+        PsiExpression castOperand = cast.getOperand();
+        LOG.assertTrue(castOperand != null);
+        castOperand.replace(replace);
+        replace = (PsiExpression)replace.replace(cast);
       }
+
+      AnonymousCanBeLambdaInspection.restoreComments(comments, replace);
+      JavaCodeStyleManager.getInstance(project).shortenClassReferences(replace);
+      return replace;
     }
+    return lambda;
   }
 }
index 5bc775d6751a3bcc54ee264c2dd8a805f7db32a2..dcb6b192a3afd030827c5aaab1c5301839421ec5 100644 (file)
@@ -21,10 +21,8 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.util.ClassUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.RedundantCastUtil;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.psi.util.*;
+import com.siyeh.ig.psiutils.BoolUtils;
 import org.jetbrains.annotations.Contract;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
@@ -55,6 +53,8 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
   private static final String FIND_FIRST_METHOD = "findFirst";
   private static final String FILTER_METHOD = "filter";
   private static final String ANY_MATCH_METHOD = "anyMatch";
+  private static final String NONE_MATCH_METHOD = "noneMatch";
+  private static final String ALL_MATCH_METHOD = "allMatch";
 
   private static final String COUNTING_COLLECTOR = "counting";
   private static final String MIN_BY_COLLECTOR = "minBy";
@@ -90,11 +90,42 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
         else if (isCallOf(method, CommonClassNames.JAVA_UTIL_OPTIONAL, IS_PRESENT_METHOD, 0)) {
           handleOptionalIsPresent(methodCall);
         }
+        else if (isCallOf(method, CommonClassNames.JAVA_UTIL_STREAM_STREAM, ANY_MATCH_METHOD, 1)) {
+          if(isParentNegated(methodCall)) {
+            boolean argNegated = isArgumentLambdaNegated(methodCall);
+            registerMatchFix(methodCall,
+                             new SimplifyMatchNegationFix(argNegated ? "!Stream.anyMatch(x -> !(...))" : "!Stream.anyMatch(...)",
+                                                          argNegated ? ALL_MATCH_METHOD : NONE_MATCH_METHOD));
+          }
+        }
+        else if (isCallOf(method, CommonClassNames.JAVA_UTIL_STREAM_STREAM, NONE_MATCH_METHOD, 1)) {
+          if(isParentNegated(methodCall)) {
+            registerMatchFix(methodCall, new SimplifyMatchNegationFix("!Stream.noneMatch(...)", ANY_MATCH_METHOD));
+          }
+          if(isArgumentLambdaNegated(methodCall)) {
+            registerMatchFix(methodCall, new SimplifyMatchNegationFix("Stream.noneMatch(x -> !(...))", ALL_MATCH_METHOD));
+          }
+        }
+        else if (isCallOf(method, CommonClassNames.JAVA_UTIL_STREAM_STREAM, ALL_MATCH_METHOD, 1)) {
+          if(isArgumentLambdaNegated(methodCall)) {
+            boolean parentNegated = isParentNegated(methodCall);
+            registerMatchFix(methodCall,
+                             new SimplifyMatchNegationFix(parentNegated ? "!Stream.allMatch(x -> !(...))" : "Stream.allMatch(x -> !(...))",
+                                                          parentNegated ? ANY_MATCH_METHOD : NONE_MATCH_METHOD));
+          }
+        }
         else {
           handleStreamForEach(methodCall, method);
         }
       }
 
+      void registerMatchFix(PsiMethodCallExpression methodCall, SimplifyMatchNegationFix fix) {
+        PsiElement nameElement = methodCall.getMethodExpression().getReferenceNameElement();
+        if(nameElement != null) {
+          holder.registerProblem(nameElement, fix.getMessage(), new SimplifyCallChainFix(fix));
+        }
+      }
+
       private void handleOptionalIsPresent(PsiMethodCallExpression methodCall) {
         PsiExpression optionalQualifier = methodCall.getMethodExpression().getQualifierExpression();
         if(optionalQualifier instanceof PsiMethodCallExpression) {
@@ -212,6 +243,20 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
     };
   }
 
+  static boolean isParentNegated(PsiMethodCallExpression methodCall) {
+    PsiElement parent = PsiUtil.skipParenthesizedExprUp(methodCall.getParent());
+    return parent instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)parent);
+  }
+
+  static boolean isArgumentLambdaNegated(PsiMethodCallExpression methodCall) {
+    PsiExpression[] expressions = methodCall.getArgumentList().getExpressions();
+    if(expressions.length != 1) return false;
+    PsiExpression arg = expressions[0];
+    if(!(arg instanceof PsiLambdaExpression)) return false;
+    PsiElement body = ((PsiLambdaExpression)arg).getBody();
+    return body instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)body);
+  }
+
   static boolean hasSingleArrayArgument(PsiMethodCallExpression qualifierCall) {
     final PsiExpression[] argumentExpressions = qualifierCall.getArgumentList().getExpressions();
     if (argumentExpressions.length == 1) {
@@ -571,4 +616,65 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
       return "Stream.filter()." + myFindMethodName + "().isPresent() can be replaced with Stream.anyMatch()";
     }
   }
+
+  private static class SimplifyMatchNegationFix implements CallChainFix {
+    private final String myFrom, myTo;
+
+    private SimplifyMatchNegationFix(String from, String to) {
+      myFrom = from;
+      myTo = to;
+    }
+
+    @Override
+    public String getName() {
+      return "Replace "+myFrom+" with Stream."+myTo+"(...)";
+    }
+
+    public String getMessage() {
+      return myFrom+" can be replaced with Stream."+myTo+"(...)";
+    }
+
+    @Override
+    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+      PsiElement element = descriptor.getStartElement();
+      if(element instanceof PsiIdentifier) {
+        String from = element.getText();
+        boolean removeParentNegation;
+        boolean removeLambdaNegation;
+        switch(from) {
+          case ALL_MATCH_METHOD:
+            removeLambdaNegation = true;
+            removeParentNegation = myTo.equals(ANY_MATCH_METHOD);
+            break;
+          case ANY_MATCH_METHOD:
+            removeParentNegation = true;
+            removeLambdaNegation = myTo.equals(ALL_MATCH_METHOD);
+            break;
+          case NONE_MATCH_METHOD:
+            removeParentNegation = myTo.equals(ANY_MATCH_METHOD);
+            removeLambdaNegation = myTo.equals(ALL_MATCH_METHOD);
+            break;
+          default:
+            return;
+        }
+        PsiMethodCallExpression methodCall = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
+        if (methodCall == null) return;
+        if (removeParentNegation && !isParentNegated(methodCall)) return;
+        if (removeLambdaNegation && !isArgumentLambdaNegated(methodCall)) return;
+        if (!FileModificationService.getInstance().preparePsiElementForWrite(element.getContainingFile())) return;
+        PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+        element.replace(factory.createIdentifier(myTo));
+        if (removeLambdaNegation) {
+          // Casts and array bounds already checked in isArgumentLambdaNegated
+          PsiExpression body = (PsiExpression)((PsiLambdaExpression)methodCall.getArgumentList().getExpressions()[0]).getBody();
+          PsiExpression negated = BoolUtils.getNegated(body);
+          LOG.assertTrue(negated != null);
+          body.replace(negated);
+        }
+        if (removeParentNegation) {
+          PsiUtil.skipParenthesizedExprUp(methodCall.getParent()).replace(methodCall);
+        }
+      }
+    }
+  }
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8CollectionRemoveIfInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8CollectionRemoveIfInspection.java
new file mode 100644 (file)
index 0000000..1d26b61
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.java18api;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.daemon.QuickFixBundle;
+import com.intellij.codeInspection.*;
+import com.intellij.codeInspection.util.LambdaGenerationUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.codeStyle.SuggestedNameInfo;
+import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.controlFlow.DefUseUtil;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.siyeh.ig.psiutils.ControlFlowUtils;
+import one.util.streamex.MoreCollectors;
+import one.util.streamex.StreamEx;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * @author Tagir Valeev
+ */
+public class Java8CollectionRemoveIfInspection extends BaseJavaBatchLocalInspectionTool {
+  @NotNull
+  @Override
+  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+    if (!PsiUtil.isLanguageLevel8OrHigher(holder.getFile())) {
+      return PsiElementVisitor.EMPTY_VISITOR;
+    }
+    return new JavaElementVisitor() {
+      void handleIteratorLoop(PsiLoopStatement statement, PsiJavaToken endToken, IteratorDeclaration declaration) {
+        if (endToken == null) return;
+        PsiStatement body = statement.getBody();
+        if(!(body instanceof PsiBlockStatement)) return;
+        PsiStatement[] statements = ((PsiBlockStatement)body).getCodeBlock().getStatements();
+        if (statements.length == 2 && statements[1] instanceof PsiIfStatement) {
+          PsiVariable element = declaration.getNextElementVariable(statements[0]);
+          if (element == null) return;
+          PsiIfStatement ifStatement = (PsiIfStatement)statements[1];
+          if(checkAndExtractCondition(declaration, ifStatement) == null) return;
+          registerProblem(statement, endToken);
+        }
+        else if (statements.length == 1 && statements[0] instanceof PsiIfStatement){
+          PsiIfStatement ifStatement = (PsiIfStatement)statements[0];
+          PsiExpression condition = checkAndExtractCondition(declaration, ifStatement);
+          if (condition == null) return;
+          declaration.iteratorRefs(condition).collect(MoreCollectors.onlyOne()).ifPresent(ref -> {
+            if(declaration.isIteratorMethodCall(ref.getParent().getParent(), "next") && isAlwaysExecuted(condition, ref)) {
+              registerProblem(statement, endToken);
+            }
+          });
+        }
+      }
+
+      private boolean isAlwaysExecuted(PsiExpression condition, PsiElement ref) {
+        while(ref != condition) {
+          PsiElement parent = ref.getParent();
+          if(parent instanceof PsiPolyadicExpression) {
+            PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)parent;
+            IElementType type = polyadicExpression.getOperationTokenType();
+            if ((type.equals(JavaTokenType.ANDAND) || type.equals(JavaTokenType.OROR)) && polyadicExpression.getOperands()[0] != ref) {
+              return false;
+            }
+          }
+          if(parent instanceof PsiConditionalExpression && ((PsiConditionalExpression)parent).getCondition() != ref) {
+            return false;
+          }
+          ref = parent;
+        }
+        return true;
+      }
+
+      private void registerProblem(PsiLoopStatement statement, PsiJavaToken endToken) {
+        //noinspection DialogTitleCapitalization
+        holder.registerProblem(statement, new TextRange(0, endToken.getTextOffset() - statement.getTextOffset() + 1),
+                               QuickFixBundle.message("java.8.collection.removeif.inspection.description"),
+                               new ReplaceWithRemoveIfQuickFix());
+      }
+
+      @Nullable
+      private PsiExpression checkAndExtractCondition(IteratorDeclaration declaration,
+                                                     PsiIfStatement ifStatement) {
+        PsiExpression condition = ifStatement.getCondition();
+        if (condition == null || ifStatement.getElseBranch() != null) return null;
+        PsiStatement thenStatement = ControlFlowUtils.stripBraces(ifStatement.getThenBranch());
+        if (!(thenStatement instanceof PsiExpressionStatement)) return null;
+        if (!declaration.isIteratorMethodCall(((PsiExpressionStatement)thenStatement).getExpression(), "remove")) return null;
+        if (!LambdaGenerationUtil.canBeUncheckedLambda(condition)) return null;
+        return condition;
+      }
+
+      @Override
+      public void visitForStatement(PsiForStatement statement) {
+        super.visitForStatement(statement);
+        PsiStatement initialization = statement.getInitialization();
+        IteratorDeclaration declaration = IteratorDeclaration.extract(initialization);
+        if(declaration == null) return;
+        if(statement.getUpdate() != null) return;
+        if(!declaration.isHasNextCall(statement.getCondition())) return;
+        handleIteratorLoop(statement, statement.getRParenth(), declaration);
+      }
+
+      @Override
+      public void visitWhileStatement(PsiWhileStatement statement) {
+        super.visitWhileStatement(statement);
+        PsiElement previous = PsiTreeUtil.skipSiblingsBackward(statement, PsiComment.class, PsiWhiteSpace.class);
+        if(!(previous instanceof PsiDeclarationStatement)) return;
+        IteratorDeclaration declaration = IteratorDeclaration.extract((PsiStatement)previous);
+        if(declaration == null || !declaration.isHasNextCall(statement.getCondition())) return;
+        if(!ReferencesSearch.search(declaration.myIterator, declaration.myIterator.getUseScope()).forEach(ref -> {
+          return PsiTreeUtil.isAncestor(statement, ref.getElement(), true);
+        })) return;
+        handleIteratorLoop(statement, statement.getRParenth(), declaration);
+      }
+    };
+  }
+
+  private static class ReplaceWithRemoveIfQuickFix implements LocalQuickFix {
+    @Nls
+    @NotNull
+    @Override
+    public String getFamilyName() {
+      return QuickFixBundle.message("java.8.collection.removeif.inspection.fix.name");
+    }
+
+    @Override
+    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+      PsiElement element = descriptor.getStartElement();
+      if(!(element instanceof PsiLoopStatement)) return;
+      PsiLoopStatement loop = (PsiLoopStatement)element;
+      IteratorDeclaration declaration;
+      PsiElement previous = null;
+      if(loop instanceof PsiForStatement) {
+        declaration = IteratorDeclaration.extract(((PsiForStatement)loop).getInitialization());
+      } else if(loop instanceof PsiWhileStatement) {
+        previous = PsiTreeUtil.skipSiblingsBackward(loop, PsiComment.class, PsiWhiteSpace.class);
+        if(!(previous instanceof PsiDeclarationStatement)) return;
+        declaration = IteratorDeclaration.extract((PsiStatement)previous);
+      } else return;
+      if(declaration == null) return;
+      PsiStatement body = loop.getBody();
+      if(!(body instanceof PsiBlockStatement)) return;
+      PsiStatement[] statements = ((PsiBlockStatement)body).getCodeBlock().getStatements();
+      PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+      String replacement = null;
+      if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
+      if (statements.length == 2 && statements[1] instanceof PsiIfStatement) {
+        PsiVariable variable = declaration.getNextElementVariable(statements[0]);
+        if (variable == null) return;
+        PsiExpression condition = ((PsiIfStatement)statements[1]).getCondition();
+        if (condition == null) return;
+        replacement = (declaration.myCollection == null ? "" : declaration.myCollection.getText() + ".") +
+                             "removeIf(" + LambdaUtil.createLambda(variable, condition) + ");";
+      }
+      else if (statements.length == 1 && statements[0] instanceof PsiIfStatement){
+        PsiExpression condition = ((PsiIfStatement)statements[0]).getCondition();
+        if (condition == null) return;
+        Optional<PsiElement> iteratorRef = declaration.iteratorRefs(condition).collect(MoreCollectors.onlyOne());
+        if(iteratorRef.isPresent()) {
+          PsiElement call = iteratorRef.get().getParent().getParent();
+          if(!declaration.isIteratorMethodCall(call, "next")) return;
+          PsiType type = ((PsiExpression)call).getType();
+          JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
+          SuggestedNameInfo info = javaCodeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, type);
+          if(info.names.length == 0) {
+            info = javaCodeStyleManager.suggestVariableName(VariableKind.PARAMETER, "value", null, type);
+          }
+          String paramName = javaCodeStyleManager.suggestUniqueVariableName(info, condition, true).names[0];
+          call.replace(factory.createIdentifier(paramName));
+          replacement = (declaration.myCollection == null ? "" : declaration.myCollection.getText() + ".") +
+                        "removeIf(" + paramName + "->"+condition.getText() + ");";
+        }
+      }
+      if(replacement == null) return;
+      Collection<PsiComment> comments = ContainerUtil.map(PsiTreeUtil.findChildrenOfType(loop, PsiComment.class),
+                                                          comment -> (PsiComment)comment.copy());
+      PsiElement result = loop.replace(factory.createStatementFromText(replacement, loop));
+      if (previous != null) previous.delete();
+      LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result);
+      CodeStyleManager.getInstance(project).reformat(result);
+      comments.forEach(comment -> result.getParent().addBefore(comment, result));
+    }
+  }
+
+  private static class IteratorDeclaration {
+    private final @NotNull PsiLocalVariable myIterator;
+    private final @Nullable PsiExpression myCollection;
+
+    private IteratorDeclaration(@NotNull PsiLocalVariable iterator, @Nullable PsiExpression collection) {
+      myIterator = iterator;
+      myCollection = collection;
+    }
+
+    public boolean isHasNextCall(PsiExpression condition) {
+      return isIteratorMethodCall(condition, "hasNext");
+    }
+
+    public StreamEx<PsiElement> iteratorRefs(PsiExpression parent) {
+      PsiElement element = PsiUtil.getVariableCodeBlock(myIterator, null);
+      PsiCodeBlock block =
+        element instanceof PsiCodeBlock ? (PsiCodeBlock)element : PsiTreeUtil.getParentOfType(element, PsiCodeBlock.class);
+      if(block == null) return StreamEx.empty();
+      return StreamEx.of(DefUseUtil.getRefs(block, myIterator, myIterator.getInitializer()))
+                  .filter(e -> PsiTreeUtil.isAncestor(parent, e, false));
+    }
+
+    boolean isIteratorMethodCall(PsiElement candidate, String method) {
+      if(!(candidate instanceof PsiMethodCallExpression)) return false;
+      PsiMethodCallExpression call = (PsiMethodCallExpression)candidate;
+      if(call.getArgumentList().getExpressions().length != 0) return false;
+      PsiReferenceExpression expression = call.getMethodExpression();
+      if(!method.equals(expression.getReferenceName())) return false;
+      PsiExpression qualifier = expression.getQualifierExpression();
+      if(!(qualifier instanceof PsiReferenceExpression)) return false;
+      return ((PsiReferenceExpression)qualifier).resolve() == myIterator;
+    }
+
+    public PsiVariable getNextElementVariable(PsiStatement statement) {
+      if(!(statement instanceof PsiDeclarationStatement)) return null;
+      PsiDeclarationStatement declaration = (PsiDeclarationStatement)statement;
+      if(declaration.getDeclaredElements().length != 1) return null;
+      PsiElement element = declaration.getDeclaredElements()[0];
+      if(!(element instanceof PsiLocalVariable)) return null;
+      PsiLocalVariable var = (PsiLocalVariable)element;
+      if(!isIteratorMethodCall(var.getInitializer(), "next")) return null;
+      return var;
+    }
+
+    @Contract("null -> null")
+    static IteratorDeclaration extract(PsiStatement statement) {
+      if(!(statement instanceof PsiDeclarationStatement)) return null;
+      PsiDeclarationStatement declaration = (PsiDeclarationStatement)statement;
+      if(declaration.getDeclaredElements().length != 1) return null;
+      PsiElement element = declaration.getDeclaredElements()[0];
+      if(!(element instanceof PsiLocalVariable)) return null;
+      PsiLocalVariable variable = (PsiLocalVariable)element;
+      PsiExpression initializer = variable.getInitializer();
+      if(!(initializer instanceof PsiMethodCallExpression)) return null;
+      PsiMethodCallExpression call = (PsiMethodCallExpression)initializer;
+      if(call.getArgumentList().getExpressions().length != 0) return null;
+      PsiReferenceExpression methodExpression = call.getMethodExpression();
+      if(!"iterator".equals(methodExpression.getReferenceName())) return null;
+      PsiMethod method = call.resolveMethod();
+      if(method == null || !InheritanceUtil.isInheritor(method.getContainingClass(), CommonClassNames.JAVA_UTIL_COLLECTION)) return null;
+      PsiType type = variable.getType();
+      if(!(type instanceof PsiClassType) || !((PsiClassType)type).rawType().equalsToText(CommonClassNames.JAVA_UTIL_ITERATOR)) return null;
+      return new IteratorDeclaration(variable, methodExpression.getQualifierExpression());
+    }
+  }
+}
\ No newline at end of file
index 74720065ea1e6af9b5e9f1ba8e35dd5e82e669d4..9f902c43cb9d967e4c2adc83a67f1667ba9675e1 100644 (file)
  */
 package com.intellij.codeInspection.java18api;
 
-import com.intellij.codeInsight.ExceptionUtil;
-import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
-import com.intellij.codeInspection.*;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
+import com.intellij.codeInspection.ProblemsHolder;
 import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
-import com.intellij.codeInspection.util.LambdaGenerationUtil;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
-import com.intellij.util.containers.ContainerUtil;
-import com.siyeh.ig.psiutils.ControlFlowUtils;
 import com.siyeh.ig.psiutils.EquivalenceChecker;
 import com.siyeh.ig.psiutils.ExpressionUtils;
-import com.siyeh.ig.psiutils.ParenthesesUtils;
 import one.util.streamex.StreamEx;
-import org.jetbrains.annotations.Contract;
-import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
-import java.util.Collection;
 
 /**
  * @author Dmitry Batkovich
@@ -53,21 +37,11 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
   private static final Logger LOG = Logger.getInstance(Java8CollectionsApiInspection.class);
 
   public boolean myReportContainsCondition;
-  public boolean mySuggestCollectionRemoveIf = true;
-  public boolean mySuggestListSort = true;
-  public boolean mySuggestMapGetOrDefault = true;
-  public boolean mySuggestMapPutIfAbsent = true;
-  public boolean mySuggestMapComputeIfAbsent = true;
 
   @Nullable
   @Override
   public JComponent createOptionsPanel() {
     MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this);
-    panel.addCheckbox("Suggest conversion to Collection.removeIf", "mySuggestCollectionRemoveIf");
-    panel.addCheckbox("Suggest conversion to List.sort", "mySuggestListSort");
-    panel.addCheckbox("Suggest conversion to Map.computeIfAbsent", "mySuggestMapComputeIfAbsent");
-    panel.addCheckbox("Suggest conversion to Map.getOrDefault", "mySuggestMapGetOrDefault");
-    panel.addCheckbox("Suggest conversion to Map.putIfAbsent", "mySuggestMapPutIfAbsent");
     panel.addCheckbox("Report when \'containsKey\' is used in condition (may change semantics)", "myReportContainsCondition");
     return panel;
   }
@@ -79,70 +53,6 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
       return PsiElementVisitor.EMPTY_VISITOR;
     }
     return new JavaElementVisitor() {
-      @Override
-      public void visitMethodCallExpression(PsiMethodCallExpression expression) {
-        super.visitMethodCallExpression(expression);
-        if (!mySuggestListSort) return;
-        PsiElement nameElement = expression.getMethodExpression().getReferenceNameElement();
-        if(nameElement != null && expression.getArgumentList().getExpressions().length == 2 &&
-          "sort".equals(nameElement.getText())) {
-          PsiMethod method = expression.resolveMethod();
-          if(method != null) {
-            PsiClass containingClass = method.getContainingClass();
-            if(containingClass != null && CommonClassNames.JAVA_UTIL_COLLECTIONS.equals(containingClass.getQualifiedName())) {
-              //noinspection DialogTitleCapitalization
-              holder.registerProblem(nameElement, QuickFixBundle.message("java.8.collections.api.inspection.sort.description"),
-                                     new ReplaceWithListSortFix());
-            }
-          }
-        }
-      }
-
-      void handleIteratorLoop(PsiLoopStatement statement, PsiJavaToken endToken, IteratorDeclaration declaration) {
-        if (!mySuggestCollectionRemoveIf || endToken == null) return;
-        PsiStatement body = statement.getBody();
-        if(!(body instanceof PsiBlockStatement)) return;
-        PsiStatement[] statements = ((PsiBlockStatement)body).getCodeBlock().getStatements();
-        if(statements.length != 2 || !(statements[1] instanceof PsiIfStatement)) return;
-        PsiVariable element = declaration.getNextElementVariable(statements[0]);
-        if(element == null) return;
-        PsiIfStatement ifStatement = (PsiIfStatement)statements[1];
-        PsiExpression condition = ifStatement.getCondition();
-        if(condition == null || ifStatement.getElseBranch() != null) return;
-        PsiStatement thenStatement = ControlFlowUtils.stripBraces(ifStatement.getThenBranch());
-        if(!(thenStatement instanceof PsiExpressionStatement)) return;
-        if(!declaration.isIteratorMethodCall(((PsiExpressionStatement)thenStatement).getExpression(), "remove")) return;
-        if(!LambdaGenerationUtil.canBeUncheckedLambda(condition)) return;
-        //noinspection DialogTitleCapitalization
-        holder.registerProblem(statement, new TextRange(0, endToken.getTextOffset() - statement.getTextOffset() + 1),
-                               QuickFixBundle.message("java.8.collections.api.inspection.remove.description"),
-                               new ReplaceWithRemoveIfQuickFix());
-      }
-
-      @Override
-      public void visitForStatement(PsiForStatement statement) {
-        super.visitForStatement(statement);
-        PsiStatement initialization = statement.getInitialization();
-        IteratorDeclaration declaration = IteratorDeclaration.extract(initialization);
-        if(declaration == null) return;
-        if(statement.getUpdate() != null) return;
-        if(!declaration.isHasNextCall(statement.getCondition())) return;
-        handleIteratorLoop(statement, statement.getRParenth(), declaration);
-      }
-
-      @Override
-      public void visitWhileStatement(PsiWhileStatement statement) {
-        super.visitWhileStatement(statement);
-        PsiElement previous = PsiTreeUtil.skipSiblingsBackward(statement, PsiComment.class, PsiWhiteSpace.class);
-        if(!(previous instanceof PsiDeclarationStatement)) return;
-        IteratorDeclaration declaration = IteratorDeclaration.extract((PsiStatement)previous);
-        if(declaration == null || !declaration.isHasNextCall(statement.getCondition())) return;
-        if(!ReferencesSearch.search(declaration.myIterator, declaration.myIterator.getUseScope()).forEach(ref -> {
-          return PsiTreeUtil.isAncestor(statement, ref.getElement(), true);
-        })) return;
-        handleIteratorLoop(statement, statement.getRParenth(), declaration);
-      }
-
       @Override
       public void visitConditionalExpression(PsiConditionalExpression expression) {
         final ConditionInfo conditionInfo = extractConditionInfo(expression.getCondition());
@@ -158,7 +68,6 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
 
       @Override
       public void visitIfStatement(PsiIfStatement statement) {
-        handleGetWithVariable(holder, statement);
         final PsiExpression condition = statement.getCondition();
         final ConditionInfo conditionInfo = extractConditionInfo(condition);
         if (conditionInfo == null) return;
@@ -183,123 +92,9 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
                                            holder, statement);
         }
       }
-
-      private void handleGetWithVariable(ProblemsHolder holder, PsiIfStatement statement) {
-        if(statement.getElseBranch() != null) return;
-        PsiExpression condition = statement.getCondition();
-        PsiReferenceExpression value = getReferenceComparedWithNull(condition);
-        if (value == null) return;
-        PsiElement previous = PsiTreeUtil.skipSiblingsBackward(statement, PsiWhiteSpace.class, PsiComment.class);
-        PsiMethodCallExpression getCall = tryExtractMapGetCall(value, previous);
-        if(getCall == null) return;
-        PsiExpression[] getArguments = getCall.getArgumentList().getExpressions();
-        if(getArguments.length != 1) return;
-        PsiStatement thenBranch = ControlFlowUtils.stripBraces(statement.getThenBranch());
-        PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(thenBranch);
-        EquivalenceChecker equivalence = EquivalenceChecker.getCanonicalPsiEquivalence();
-        if(assignment != null) {
-          /*
-            value = map.get(key);
-            if(value == null) {
-              value = ...
-            }
-           */
-          if (!mySuggestMapGetOrDefault) return;
-          if (ExpressionUtils.isSimpleExpression(assignment.getRExpression()) &&
-              equivalence.expressionsAreEquivalent(assignment.getLExpression(), value)) {
-            holder.registerProblem(condition, QuickFixBundle.message("java.8.collections.api.inspection.description"),
-                                   new ReplaceGetNullCheck("getOrDefault"));
-          }
-        } else if(thenBranch instanceof PsiBlockStatement) {
-          /*
-            value = map.get(key);
-            if(value == null) {
-              value = ...
-              map.put(key, value);
-            }
-           */
-          if (!mySuggestMapComputeIfAbsent) return;
-          PsiExpression key = getArguments[0];
-          PsiStatement[] statements = ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements();
-          if(statements.length != 2) return;
-          assignment = ExpressionUtils.getAssignment(statements[0]);
-          if(assignment == null) return;
-          PsiExpression lambdaCandidate = assignment.getRExpression();
-          if (lambdaCandidate == null ||
-              !equivalence.expressionsAreEquivalent(assignment.getLExpression(), value) ||
-              !(statements[1] instanceof PsiExpressionStatement)) {
-            return;
-          }
-          PsiExpression expression = ((PsiExpressionStatement)statements[1]).getExpression();
-          if(!(expression instanceof PsiMethodCallExpression)) return;
-          PsiMethodCallExpression putCall = (PsiMethodCallExpression)expression;
-          if(!isJavaUtilMapMethodWithName(putCall, "put")) return;
-          PsiExpression[] putArguments = putCall.getArgumentList().getExpressions();
-          if (putArguments.length != 2 ||
-              !equivalence.expressionsAreEquivalent(putCall.getMethodExpression().getQualifierExpression(),
-                                                    getCall.getMethodExpression().getQualifierExpression()) ||
-              !equivalence.expressionsAreEquivalent(key, putArguments[0]) ||
-              !equivalence.expressionsAreEquivalent(value, putArguments[1])) {
-            return;
-          }
-          if(!ExceptionUtil.getThrownCheckedExceptions(lambdaCandidate).isEmpty()) return;
-          if(!PsiTreeUtil.processElements(lambdaCandidate, e -> {
-            if(!(e instanceof PsiReferenceExpression)) return true;
-            PsiElement element = ((PsiReferenceExpression)e).resolve();
-            if(!(element instanceof PsiVariable)) return true;
-            return HighlightControlFlowUtil.isEffectivelyFinal((PsiVariable)element, lambdaCandidate, null);
-          })) {
-            return;
-          }
-          holder.registerProblem(condition, QuickFixBundle.message("java.8.collections.api.inspection.description"),
-                                 new ReplaceGetNullCheck("computeIfAbsent"));
-        }
-      }
     };
   }
 
-  @Nullable
-  private static PsiReferenceExpression getReferenceComparedWithNull(PsiExpression condition) {
-    if(!(condition instanceof PsiBinaryExpression)) return null;
-    PsiBinaryExpression binOp = (PsiBinaryExpression)condition;
-    if(!binOp.getOperationTokenType().equals(JavaTokenType.EQEQ)) return null;
-    PsiExpression value = getValueComparedWithNull(binOp);
-    if(!(value instanceof PsiReferenceExpression)) return null;
-    return (PsiReferenceExpression)value;
-  }
-
-  @Nullable
-  @Contract("_, null -> null")
-  static PsiMethodCallExpression tryExtractMapGetCall(PsiReferenceExpression target, PsiElement element) {
-    if(element instanceof PsiDeclarationStatement) {
-      PsiDeclarationStatement declaration = (PsiDeclarationStatement)element;
-      PsiElement[] elements = declaration.getDeclaredElements();
-      if(elements.length > 0) {
-        PsiElement lastDeclaration = elements[elements.length - 1];
-        if(lastDeclaration instanceof PsiLocalVariable && lastDeclaration == target.resolve()) {
-          PsiLocalVariable var = (PsiLocalVariable)lastDeclaration;
-          PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(var.getInitializer());
-          if (initializer instanceof PsiMethodCallExpression &&
-              isJavaUtilMapMethodWithName((PsiMethodCallExpression)initializer, "get")) {
-            return (PsiMethodCallExpression)initializer;
-          }
-        }
-      }
-    }
-    PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(element);
-    if(assignment != null) {
-      PsiExpression lValue = assignment.getLExpression();
-      if (lValue instanceof PsiReferenceExpression &&
-          EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(target, lValue)) {
-        PsiExpression rValue = PsiUtil.skipParenthesizedExprDown(assignment.getRExpression());
-        if (rValue instanceof PsiMethodCallExpression && isJavaUtilMapMethodWithName((PsiMethodCallExpression)rValue, "get")) {
-          return (PsiMethodCallExpression)rValue;
-        }
-      }
-    }
-    return null;
-  }
-
   @Nullable
   private ConditionInfo extractConditionInfo(PsiExpression condition) {
     final ConditionInfo info = extractConditionInfoIfGet(condition);
@@ -310,7 +105,7 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
   }
 
   @Nullable
-  private static PsiExpression getValueComparedWithNull(PsiBinaryExpression binOp) {
+  static PsiExpression getValueComparedWithNull(PsiBinaryExpression binOp) {
     if(!binOp.getOperationTokenType().equals(JavaTokenType.EQEQ) &&
       !binOp.getOperationTokenType().equals(JavaTokenType.NE)) return null;
     PsiExpression left = binOp.getLOperand();
@@ -371,7 +166,7 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
     return new ConditionInfo(containsQualifier, containsKey, inverted);
   }
 
-  private void analyzeCorrespondenceOfPutAndGet(@NotNull PsiElement adjustedElseBranch,
+  private static void analyzeCorrespondenceOfPutAndGet(@NotNull PsiElement adjustedElseBranch,
                                                        @Nullable PsiElement adjustedThenBranch,
                                                        @Nullable PsiExpression containsQualifier,
                                                        @Nullable PsiExpression containsKey,
@@ -379,7 +174,6 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
                                                        @NotNull PsiElement context) {
     final PsiElement maybePutMethodCall;
     final PsiElement maybeGetMethodCall;
-    if (!mySuggestMapPutIfAbsent) return;
     if (adjustedThenBranch == null) {
       maybeGetMethodCall = null;
       if (adjustedElseBranch instanceof PsiExpressionStatement) {
@@ -445,7 +239,7 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
     }
   }
 
-  private static boolean isJavaUtilMapMethodWithName(@NotNull PsiMethodCallExpression methodCallExpression, @NotNull String expectedName) {
+  static boolean isJavaUtilMapMethodWithName(@NotNull PsiMethodCallExpression methodCallExpression, @NotNull String expectedName) {
     if (!expectedName.equals(methodCallExpression.getMethodExpression().getReferenceName())) {
       return false;
     }
@@ -482,198 +276,4 @@ public class Java8CollectionsApiInspection extends BaseJavaBatchLocalInspectionT
       return myInverted;
     }
   }
-
-  private static class ReplaceWithListSortFix implements LocalQuickFix {
-    @Nls
-    @NotNull
-    @Override
-    public String getFamilyName() {
-      return QuickFixBundle.message("java.8.collections.api.inspection.sort.fix.name");
-    }
-
-    @Override
-    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
-      PsiElement element = descriptor.getStartElement();
-      PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
-      if(methodCallExpression != null) {
-        PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions();
-        if(args.length == 2) {
-          PsiExpression list = args[0];
-          PsiExpression comparator = args[1];
-          String replacement =
-            ParenthesesUtils.getText(list, ParenthesesUtils.METHOD_CALL_PRECEDENCE) + ".sort(" + comparator.getText() + ")";
-          if (!FileModificationService.getInstance().preparePsiElementForWrite(element.getContainingFile())) return;
-          methodCallExpression
-            .replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(replacement, methodCallExpression));
-        }
-      }
-    }
-  }
-
-  private static class ReplaceGetNullCheck implements LocalQuickFix {
-    private final String myMethodName;
-
-    ReplaceGetNullCheck(String methodName) {
-      myMethodName = methodName;
-    }
-
-    @Nls
-    @NotNull
-    @Override
-    public String getName() {
-      return QuickFixBundle.message("java.8.collections.api.inspection.fix.text", myMethodName);
-    }
-
-    @Nls
-    @NotNull
-    @Override
-    public String getFamilyName() {
-      return QuickFixBundle.message("java.8.collections.api.inspection.get.fix.family.name");
-    }
-
-    @Override
-    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
-      PsiElement element = descriptor.getStartElement();
-      PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class);
-      if(ifStatement == null) return;
-      PsiReferenceExpression value = getReferenceComparedWithNull(ifStatement.getCondition());
-      if(value == null) return;
-      PsiElement statement = PsiTreeUtil.skipSiblingsBackward(ifStatement, PsiWhiteSpace.class, PsiComment.class);
-      PsiMethodCallExpression getCall = tryExtractMapGetCall(value, statement);
-      if(getCall == null || !isJavaUtilMapMethodWithName(getCall, "get")) return;
-      PsiElement nameElement = getCall.getMethodExpression().getReferenceNameElement();
-      if(nameElement == null) return;
-      PsiExpression[] args = getCall.getArgumentList().getExpressions();
-      if(args.length != 1) return;
-      PsiStatement thenBranch = ControlFlowUtils.stripBraces(ifStatement.getThenBranch());
-      Collection<PsiComment> comments = ContainerUtil.map(PsiTreeUtil.findChildrenOfType(ifStatement, PsiComment.class),
-                                                          comment -> (PsiComment)comment.copy());
-      PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
-      if(thenBranch instanceof PsiExpressionStatement) {
-        PsiExpression expression = ((PsiExpressionStatement)thenBranch).getExpression();
-        if (!(expression instanceof PsiAssignmentExpression)) return;
-        PsiExpression defaultValue = ((PsiAssignmentExpression)expression).getRExpression();
-        if (!ExpressionUtils.isSimpleExpression(defaultValue)) return;
-        if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
-        nameElement.replace(factory.createIdentifier("getOrDefault"));
-        getCall.getArgumentList().add(defaultValue);
-      } else if(thenBranch instanceof PsiBlockStatement) {
-        PsiStatement[] statements = ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements();
-        if(statements.length != 2) return;
-        PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(statements[0]);
-        if(assignment == null) return;
-        PsiExpression lambdaCandidate = assignment.getRExpression();
-        if(lambdaCandidate == null) return;
-        if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
-        nameElement.replace(factory.createIdentifier("computeIfAbsent"));
-        String varName = JavaCodeStyleManager.getInstance(project).suggestUniqueVariableName("k", lambdaCandidate, true);
-        PsiExpression lambda = factory.createExpressionFromText(varName + " -> " + lambdaCandidate.getText(), lambdaCandidate);
-        getCall.getArgumentList().add(lambda);
-      } else return;
-      ifStatement.delete();
-      CodeStyleManager.getInstance(project).reformat(statement);
-      comments.forEach(comment -> statement.getParent().addBefore(comment, statement));
-    }
-  }
-
-  private static class ReplaceWithRemoveIfQuickFix implements LocalQuickFix {
-    @Nls
-    @NotNull
-    @Override
-    public String getFamilyName() {
-      return QuickFixBundle.message("java.8.collections.api.inspection.remove.fix.name");
-    }
-
-    @Override
-    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
-      PsiElement element = descriptor.getStartElement();
-      if(!(element instanceof PsiLoopStatement)) return;
-      PsiLoopStatement loop = (PsiLoopStatement)element;
-      IteratorDeclaration declaration;
-      PsiElement previous = null;
-      if(loop instanceof PsiForStatement) {
-        declaration = IteratorDeclaration.extract(((PsiForStatement)loop).getInitialization());
-      } else if(loop instanceof PsiWhileStatement) {
-        previous = PsiTreeUtil.skipSiblingsBackward(loop, PsiComment.class, PsiWhiteSpace.class);
-        if(!(previous instanceof PsiDeclarationStatement)) return;
-        declaration = IteratorDeclaration.extract((PsiStatement)previous);
-      } else return;
-      if(declaration == null) return;
-      PsiStatement body = loop.getBody();
-      if(!(body instanceof PsiBlockStatement)) return;
-      PsiStatement[] statements = ((PsiBlockStatement)body).getCodeBlock().getStatements();
-      if(statements.length != 2 || !(statements[1] instanceof PsiIfStatement)) return;
-      PsiVariable variable = declaration.getNextElementVariable(statements[0]);
-      if(variable == null) return;
-      PsiExpression condition = ((PsiIfStatement)statements[1]).getCondition();
-      if(condition == null) return;
-      if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
-      String replacement = (declaration.myCollection == null ? "" : declaration.myCollection.getText() + ".") +
-                           "removeIf(" + LambdaUtil.createLambda(variable, condition) + ");";
-      Collection<PsiComment> comments = ContainerUtil.map(PsiTreeUtil.findChildrenOfType(loop, PsiComment.class),
-                                                          comment -> (PsiComment)comment.copy());
-      PsiElement result = loop.replace(JavaPsiFacade.getElementFactory(project).createStatementFromText(replacement, loop));
-      if(previous != null) previous.delete();
-      LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result);
-      CodeStyleManager.getInstance(project).reformat(result);
-      comments.forEach(comment -> result.getParent().addBefore(comment, result));
-    }
-  }
-
-  private static class IteratorDeclaration {
-    private final @NotNull PsiLocalVariable myIterator;
-    private final @Nullable PsiExpression myCollection;
-
-    private IteratorDeclaration(@NotNull PsiLocalVariable iterator, @Nullable PsiExpression collection) {
-      myIterator = iterator;
-      myCollection = collection;
-    }
-
-    public boolean isHasNextCall(PsiExpression condition) {
-      return isIteratorMethodCall(condition, "hasNext");
-    }
-
-    boolean isIteratorMethodCall(PsiExpression candidate, String method) {
-      if(!(candidate instanceof PsiMethodCallExpression)) return false;
-      PsiMethodCallExpression call = (PsiMethodCallExpression)candidate;
-      if(call.getArgumentList().getExpressions().length != 0) return false;
-      PsiReferenceExpression expression = call.getMethodExpression();
-      if(!method.equals(expression.getReferenceName())) return false;
-      PsiExpression qualifier = expression.getQualifierExpression();
-      if(!(qualifier instanceof PsiReferenceExpression)) return false;
-      return ((PsiReferenceExpression)qualifier).resolve() == myIterator;
-    }
-
-    public PsiVariable getNextElementVariable(PsiStatement statement) {
-      if(!(statement instanceof PsiDeclarationStatement)) return null;
-      PsiDeclarationStatement declaration = (PsiDeclarationStatement)statement;
-      if(declaration.getDeclaredElements().length != 1) return null;
-      PsiElement element = declaration.getDeclaredElements()[0];
-      if(!(element instanceof PsiLocalVariable)) return null;
-      PsiLocalVariable var = (PsiLocalVariable)element;
-      if(!isIteratorMethodCall(var.getInitializer(), "next")) return null;
-      return var;
-    }
-
-    @Contract("null -> null")
-    static IteratorDeclaration extract(PsiStatement statement) {
-      if(!(statement instanceof PsiDeclarationStatement)) return null;
-      PsiDeclarationStatement declaration = (PsiDeclarationStatement)statement;
-      if(declaration.getDeclaredElements().length != 1) return null;
-      PsiElement element = declaration.getDeclaredElements()[0];
-      if(!(element instanceof PsiLocalVariable)) return null;
-      PsiLocalVariable variable = (PsiLocalVariable)element;
-      PsiExpression initializer = variable.getInitializer();
-      if(!(initializer instanceof PsiMethodCallExpression)) return null;
-      PsiMethodCallExpression call = (PsiMethodCallExpression)initializer;
-      if(call.getArgumentList().getExpressions().length != 0) return null;
-      PsiReferenceExpression methodExpression = call.getMethodExpression();
-      if(!"iterator".equals(methodExpression.getReferenceName())) return null;
-      PsiMethod method = call.resolveMethod();
-      if(method == null || !InheritanceUtil.isInheritor(method.getContainingClass(), CommonClassNames.JAVA_UTIL_COLLECTION)) return null;
-      PsiType type = variable.getType();
-      if(!(type instanceof PsiClassType) || !((PsiClassType)type).rawType().equalsToText(CommonClassNames.JAVA_UTIL_ITERATOR)) return null;
-      return new IteratorDeclaration(variable, methodExpression.getQualifierExpression());
-    }
-  }
 }
\ No newline at end of file
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8ListSortInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8ListSortInspection.java
new file mode 100644 (file)
index 0000000..e393326
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.java18api;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.daemon.QuickFixBundle;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Tagir Valeev
+ */
+public class Java8ListSortInspection extends BaseJavaBatchLocalInspectionTool {
+
+  @NotNull
+  @Override
+  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+    if (!PsiUtil.isLanguageLevel8OrHigher(holder.getFile())) {
+      return PsiElementVisitor.EMPTY_VISITOR;
+    }
+    return new JavaElementVisitor() {
+      @Override
+      public void visitMethodCallExpression(PsiMethodCallExpression expression) {
+        super.visitMethodCallExpression(expression);
+        PsiElement nameElement = expression.getMethodExpression().getReferenceNameElement();
+        if(nameElement != null && expression.getArgumentList().getExpressions().length == 2 &&
+          "sort".equals(nameElement.getText())) {
+          PsiMethod method = expression.resolveMethod();
+          if(method != null) {
+            PsiClass containingClass = method.getContainingClass();
+            if(containingClass != null && CommonClassNames.JAVA_UTIL_COLLECTIONS.equals(containingClass.getQualifiedName())) {
+              //noinspection DialogTitleCapitalization
+              holder.registerProblem(nameElement, QuickFixBundle.message("java.8.list.sort.inspection.description"),
+                                     new ReplaceWithListSortFix());
+            }
+          }
+        }
+      }
+    };
+  }
+
+  private static class ReplaceWithListSortFix implements LocalQuickFix {
+    @Nls
+    @NotNull
+    @Override
+    public String getFamilyName() {
+      return QuickFixBundle.message("java.8.list.sort.inspection.fix.name");
+    }
+
+    @Override
+    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+      PsiElement element = descriptor.getStartElement();
+      PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
+      if(methodCallExpression != null) {
+        PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions();
+        if(args.length == 2) {
+          PsiExpression list = args[0];
+          PsiExpression comparator = args[1];
+          String replacement =
+            ParenthesesUtils.getText(list, ParenthesesUtils.METHOD_CALL_PRECEDENCE) + ".sort(" + comparator.getText() + ")";
+          if (!FileModificationService.getInstance().preparePsiElementForWrite(element.getContainingFile())) return;
+          methodCallExpression
+            .replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(replacement, methodCallExpression));
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8ReplaceMapGetInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java18api/Java8ReplaceMapGetInspection.java
new file mode 100644 (file)
index 0000000..030ce25
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.java18api;
+
+import com.intellij.codeInsight.ExceptionUtil;
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.daemon.QuickFixBundle;
+import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.siyeh.ig.psiutils.ControlFlowUtils;
+import com.siyeh.ig.psiutils.EquivalenceChecker;
+import com.siyeh.ig.psiutils.ExpressionUtils;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.Collection;
+
+/**
+ * @author Tagir Valeev
+ */
+public class Java8ReplaceMapGetInspection extends BaseJavaBatchLocalInspectionTool {
+
+  public boolean mySuggestMapGetOrDefault = true;
+  public boolean mySuggestMapComputeIfAbsent = true;
+
+  @Nullable
+  @Override
+  public JComponent createOptionsPanel() {
+    MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this);
+    panel.addCheckbox("Suggest conversion to Map.computeIfAbsent", "mySuggestMapComputeIfAbsent");
+    panel.addCheckbox("Suggest conversion to Map.getOrDefault", "mySuggestMapGetOrDefault");
+    return panel;
+  }
+
+  @NotNull
+  @Override
+  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+    if (!PsiUtil.isLanguageLevel8OrHigher(holder.getFile())) {
+      return PsiElementVisitor.EMPTY_VISITOR;
+    }
+    return new JavaElementVisitor() {
+      @Override
+      public void visitIfStatement(PsiIfStatement statement) {
+        if(statement.getElseBranch() != null) return;
+        PsiExpression condition = statement.getCondition();
+        PsiReferenceExpression value = getReferenceComparedWithNull(condition);
+        if (value == null) return;
+        PsiElement previous = PsiTreeUtil.skipSiblingsBackward(statement, PsiWhiteSpace.class, PsiComment.class);
+        PsiMethodCallExpression getCall = tryExtractMapGetCall(value, previous);
+        if(getCall == null) return;
+        PsiExpression[] getArguments = getCall.getArgumentList().getExpressions();
+        if(getArguments.length != 1) return;
+        PsiStatement thenBranch = ControlFlowUtils.stripBraces(statement.getThenBranch());
+        PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(thenBranch);
+        EquivalenceChecker equivalence = EquivalenceChecker.getCanonicalPsiEquivalence();
+        if(assignment != null) {
+          /*
+            value = map.get(key);
+            if(value == null) {
+              value = ...
+            }
+           */
+          if (!mySuggestMapGetOrDefault) return;
+          if (ExpressionUtils.isSimpleExpression(assignment.getRExpression()) &&
+              equivalence.expressionsAreEquivalent(assignment.getLExpression(), value)) {
+            holder.registerProblem(condition, QuickFixBundle.message("java.8.replace.map.get.inspection.description"),
+                                   new ReplaceGetNullCheck("getOrDefault"));
+          }
+        } else if(thenBranch instanceof PsiBlockStatement) {
+          /*
+            value = map.get(key);
+            if(value == null) {
+              value = ...
+              map.put(key, value);
+            }
+           */
+          if (!mySuggestMapComputeIfAbsent) return;
+          PsiExpression key = getArguments[0];
+          PsiStatement[] statements = ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements();
+          if(statements.length != 2) return;
+          assignment = ExpressionUtils.getAssignment(statements[0]);
+          if(assignment == null) return;
+          PsiExpression lambdaCandidate = assignment.getRExpression();
+          if (lambdaCandidate == null ||
+              !equivalence.expressionsAreEquivalent(assignment.getLExpression(), value) ||
+              !(statements[1] instanceof PsiExpressionStatement)) {
+            return;
+          }
+          PsiExpression expression = ((PsiExpressionStatement)statements[1]).getExpression();
+          if(!(expression instanceof PsiMethodCallExpression)) return;
+          PsiMethodCallExpression putCall = (PsiMethodCallExpression)expression;
+          if(!Java8CollectionsApiInspection.isJavaUtilMapMethodWithName(putCall, "put")) return;
+          PsiExpression[] putArguments = putCall.getArgumentList().getExpressions();
+          if (putArguments.length != 2 ||
+              !equivalence.expressionsAreEquivalent(putCall.getMethodExpression().getQualifierExpression(),
+                                                    getCall.getMethodExpression().getQualifierExpression()) ||
+              !equivalence.expressionsAreEquivalent(key, putArguments[0]) ||
+              !equivalence.expressionsAreEquivalent(value, putArguments[1])) {
+            return;
+          }
+          if(!ExceptionUtil.getThrownCheckedExceptions(lambdaCandidate).isEmpty()) return;
+          if(!PsiTreeUtil.processElements(lambdaCandidate, e -> {
+            if(!(e instanceof PsiReferenceExpression)) return true;
+            PsiElement element = ((PsiReferenceExpression)e).resolve();
+            if(!(element instanceof PsiVariable)) return true;
+            return HighlightControlFlowUtil.isEffectivelyFinal((PsiVariable)element, lambdaCandidate, null);
+          })) {
+            return;
+          }
+          holder.registerProblem(condition, QuickFixBundle.message("java.8.replace.map.get.inspection.description"),
+                                 new ReplaceGetNullCheck("computeIfAbsent"));
+        }
+      }
+    };
+  }
+
+  @Nullable
+  private static PsiReferenceExpression getReferenceComparedWithNull(PsiExpression condition) {
+    if(!(condition instanceof PsiBinaryExpression)) return null;
+    PsiBinaryExpression binOp = (PsiBinaryExpression)condition;
+    if(!binOp.getOperationTokenType().equals(JavaTokenType.EQEQ)) return null;
+    PsiExpression value = Java8CollectionsApiInspection.getValueComparedWithNull(binOp);
+    if(!(value instanceof PsiReferenceExpression)) return null;
+    return (PsiReferenceExpression)value;
+  }
+
+  @Nullable
+  @Contract("_, null -> null")
+  static PsiMethodCallExpression tryExtractMapGetCall(PsiReferenceExpression target, PsiElement element) {
+    if(element instanceof PsiDeclarationStatement) {
+      PsiDeclarationStatement declaration = (PsiDeclarationStatement)element;
+      PsiElement[] elements = declaration.getDeclaredElements();
+      if(elements.length > 0) {
+        PsiElement lastDeclaration = elements[elements.length - 1];
+        if(lastDeclaration instanceof PsiLocalVariable && lastDeclaration == target.resolve()) {
+          PsiLocalVariable var = (PsiLocalVariable)lastDeclaration;
+          PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(var.getInitializer());
+          if (initializer instanceof PsiMethodCallExpression &&
+              Java8CollectionsApiInspection.isJavaUtilMapMethodWithName((PsiMethodCallExpression)initializer, "get")) {
+            return (PsiMethodCallExpression)initializer;
+          }
+        }
+      }
+    }
+    PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(element);
+    if(assignment != null) {
+      PsiExpression lValue = assignment.getLExpression();
+      if (lValue instanceof PsiReferenceExpression &&
+          EquivalenceChecker.getCanonicalPsiEquivalence().expressionsAreEquivalent(target, lValue)) {
+        PsiExpression rValue = PsiUtil.skipParenthesizedExprDown(assignment.getRExpression());
+        if (rValue instanceof PsiMethodCallExpression &&
+            Java8CollectionsApiInspection.isJavaUtilMapMethodWithName((PsiMethodCallExpression)rValue, "get")) {
+          return (PsiMethodCallExpression)rValue;
+        }
+      }
+    }
+    return null;
+  }
+
+  private static class ReplaceGetNullCheck implements LocalQuickFix {
+    private final String myMethodName;
+
+    ReplaceGetNullCheck(String methodName) {
+      myMethodName = methodName;
+    }
+
+    @Nls
+    @NotNull
+    @Override
+    public String getName() {
+      return QuickFixBundle.message("java.8.collections.api.inspection.fix.text", myMethodName);
+    }
+
+    @Nls
+    @NotNull
+    @Override
+    public String getFamilyName() {
+      return QuickFixBundle.message("java.8.replace.map.get.inspection.fix.family.name");
+    }
+
+    @Override
+    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+      PsiElement element = descriptor.getStartElement();
+      PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class);
+      if(ifStatement == null) return;
+      PsiReferenceExpression value = getReferenceComparedWithNull(ifStatement.getCondition());
+      if(value == null) return;
+      PsiElement statement = PsiTreeUtil.skipSiblingsBackward(ifStatement, PsiWhiteSpace.class, PsiComment.class);
+      PsiMethodCallExpression getCall = tryExtractMapGetCall(value, statement);
+      if(getCall == null || !Java8CollectionsApiInspection.isJavaUtilMapMethodWithName(getCall, "get")) return;
+      PsiElement nameElement = getCall.getMethodExpression().getReferenceNameElement();
+      if(nameElement == null) return;
+      PsiExpression[] args = getCall.getArgumentList().getExpressions();
+      if(args.length != 1) return;
+      PsiStatement thenBranch = ControlFlowUtils.stripBraces(ifStatement.getThenBranch());
+      Collection<PsiComment> comments = ContainerUtil.map(PsiTreeUtil.findChildrenOfType(ifStatement, PsiComment.class),
+                                                          comment -> (PsiComment)comment.copy());
+      PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+      if(thenBranch instanceof PsiExpressionStatement) {
+        PsiExpression expression = ((PsiExpressionStatement)thenBranch).getExpression();
+        if (!(expression instanceof PsiAssignmentExpression)) return;
+        PsiExpression defaultValue = ((PsiAssignmentExpression)expression).getRExpression();
+        if (!ExpressionUtils.isSimpleExpression(defaultValue)) return;
+        if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
+        nameElement.replace(factory.createIdentifier("getOrDefault"));
+        getCall.getArgumentList().add(defaultValue);
+      } else if(thenBranch instanceof PsiBlockStatement) {
+        PsiStatement[] statements = ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements();
+        if(statements.length != 2) return;
+        PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(statements[0]);
+        if(assignment == null) return;
+        PsiExpression lambdaCandidate = assignment.getRExpression();
+        if(lambdaCandidate == null) return;
+        if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
+        nameElement.replace(factory.createIdentifier("computeIfAbsent"));
+        String varName = JavaCodeStyleManager.getInstance(project).suggestUniqueVariableName("k", lambdaCandidate, true);
+        PsiExpression lambda = factory.createExpressionFromText(varName + " -> " + lambdaCandidate.getText(), lambdaCandidate);
+        getCall.getArgumentList().add(lambda);
+      } else return;
+      ifStatement.delete();
+      CodeStyleManager.getInstance(project).reformat(statement);
+      comments.forEach(comment -> statement.getParent().addBefore(comment, statement));
+    }
+  }
+}
\ No newline at end of file
index 06d617b43670ea02f2dbaf2a66933e750a9b7da8..4dd8e7c06070ce5fc49e368d2227602ff45aa2b2 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.codeStyle.SuggestedNameInfo;
 import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.util.PsiTreeUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -120,6 +121,12 @@ class ReplaceWithCollectFix extends MigrateToStreamFix {
             }
           }
         }
+        PsiElement nextStatement = PsiTreeUtil.skipSiblingsForward(foreachStatement, PsiComment.class, PsiWhiteSpace.class);
+        String comparatorText = StreamApiMigrationInspection.tryExtractSortComparatorText(nextStatement, variable);
+        if(comparatorText != null) {
+          builder.append(".sorted(").append(comparatorText).append(")");
+          nextStatement.delete();
+        }
         String callText = builder.append(".collect(java.util.stream.Collectors.")
           .append(createInitializerReplacementText(qualifierExpression.getType(), initializer))
           .append(")").toString();
index cca64957fa3d13fe32aeba85d6e45a459a490aa6..d2a482e781905ffff3a72ae564949a1507e31e3a 100644 (file)
@@ -21,7 +21,9 @@ import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.siyeh.ig.psiutils.BoolUtils;
+import com.siyeh.ig.psiutils.ControlFlowUtils;
 import com.siyeh.ig.psiutils.ExpressionUtils;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
 import org.jetbrains.annotations.NotNull;
 
 /**
@@ -56,20 +58,28 @@ class ReplaceWithMatchFix extends MigrateToStreamFix {
       if (ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE)) {
         boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
         PsiReturnStatement nextReturnStatement = StreamApiMigrationInspection.getNextReturnStatement(foreachStatement);
-        if (nextReturnStatement != null && ExpressionUtils.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
+        if (nextReturnStatement != null) {
+          PsiExpression returnValue = nextReturnStatement.getReturnValue();
+          if(returnValue == null) return null;
           String methodName = foundResult ? "anyMatch" : "noneMatch";
           String streamText = generateStream(iteratedValue, tb.getLastOperation()).toString();
           streamText = addTerminalOperation(streamText, methodName, foreachStatement, tb);
           restoreComments(foreachStatement, body);
           if (nextReturnStatement.getParent() == foreachStatement.getParent()) {
-            nextReturnStatement.delete();
+            if(!ExpressionUtils.isLiteral(returnValue, !foundResult)) {
+              streamText+= (foundResult ? "||" : "&&") + ParenthesesUtils.getText(returnValue, ParenthesesUtils.AND_PRECEDENCE);
+            }
+            removeLoop(foreachStatement);
+            return returnValue.replace(elementFactory.createExpressionFromText(streamText, nextReturnStatement));
           }
           return foreachStatement.replace(elementFactory.createStatementFromText("return " + streamText + ";", foreachStatement));
         }
       }
     }
     PsiStatement[] statements = tb.getStatements();
-    if (!(statements.length == 1 || (statements.length == 2 && statements[1] instanceof PsiBreakStatement))) return null;
+    if (!(statements.length == 1 || (statements.length == 2 && ControlFlowUtils.statementBreaksLoop(statements[1], foreachStatement)))) {
+      return null;
+    }
     restoreComments(foreachStatement, body);
     String streamText = generateStream(iteratedValue, tb.getLastOperation()).toString();
     streamText = addTerminalOperation(streamText, "anyMatch", foreachStatement, tb);
index 5473f90dfeaf835d80cb3e60cb2aa8d8a6ec4539..41466665e68b0174146b90d1f8aec5e63bd8c2fa 100644 (file)
@@ -39,6 +39,7 @@ import com.intellij.util.ArrayUtil;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.IntArrayList;
 import com.siyeh.ig.psiutils.BoolUtils;
+import com.siyeh.ig.psiutils.ControlFlowUtils;
 import com.siyeh.ig.psiutils.EquivalenceChecker;
 import com.siyeh.ig.psiutils.ExpressionUtils;
 import one.util.streamex.EntryStream;
@@ -415,10 +416,6 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
   static InitializerUsageStatus getInitializerUsageStatus(PsiVariable var, PsiStatement nextStatement) {
     if(!(var instanceof PsiLocalVariable) || var.getInitializer() == null) return UNKNOWN;
     if(isDeclarationJustBefore(var, nextStatement)) return DECLARED_JUST_BEFORE;
-    PsiElement declaration = var.getParent();
-    // Check if variable is not referenced in the same declaration like "int a = 0, b = a;"
-    if(!PsiTreeUtil.processElements(declaration, e -> !(e instanceof PsiReferenceExpression) ||
-                                                  ((PsiReferenceExpression)e).resolve() != var)) return UNKNOWN;
     // Check that variable is declared in the same method or the same lambda expression
     if(PsiTreeUtil.getParentOfType(var, PsiLambdaExpression.class, PsiMethod.class) !=
        PsiTreeUtil.getParentOfType(nextStatement, PsiLambdaExpression.class, PsiMethod.class)) return UNKNOWN;
@@ -432,7 +429,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
     catch (AnalysisCanceledException ignored) {
       return UNKNOWN;
     }
-    int start = controlFlow.getEndOffset(declaration);
+    int start = controlFlow.getEndOffset(var.getInitializer())+1;
     int stop = controlFlow.getStartOffset(nextStatement);
     if(ControlFlowUtil.isVariableReferencedBetween(controlFlow, start, stop, var)) return UNKNOWN;
     if (!ControlFlowUtil.isValueUsedWithoutVisitingStop(controlFlow, start, stop, var)) return AT_WANTED_PLACE_ONLY;
@@ -559,8 +556,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
         PsiStatement[] statements = tb.getStatements();
         if (statements.length == 2) {
           PsiStatement breakStatement = statements[1];
-          if (!(breakStatement instanceof PsiBreakStatement) ||
-              ((PsiBreakStatement)breakStatement).findExitedStatement() != statement) {
+          if (!ControlFlowUtils.statementBreaksLoop(breakStatement, statement)) {
             return;
           }
           if (ReferencesSearch.search(tb.getVariable(), new LocalSearchScope(statements)).findFirst() == null
@@ -600,18 +596,19 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
       if (nextReturnStatement != null &&
           (ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE))) {
         boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
-        if(ExpressionUtils.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
-          String methodName;
-          if (foundResult) {
-            methodName = "anyMatch";
-          }
-          else {
-            methodName = "noneMatch";
-            Operation lastOp = tb.getLastOperation();
-            if(lastOp instanceof FilterOp && (((FilterOp)lastOp).isNegated() ^ BoolUtils.isNegation(lastOp.getExpression()))) {
-              methodName = "allMatch";
-            }
+        String methodName;
+        if (foundResult) {
+          methodName = "anyMatch";
+        }
+        else {
+          methodName = "noneMatch";
+          Operation lastOp = tb.getLastOperation();
+          if(lastOp instanceof FilterOp && (((FilterOp)lastOp).isNegated() ^ BoolUtils.isNegation(lastOp.getExpression()))) {
+            methodName = "allMatch";
           }
+        }
+        if(nextReturnStatement.getParent() == statement.getParent() ||
+           ExpressionUtils.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
           registerProblem(statement, methodName, new ReplaceWithMatchFix(methodName));
           return;
         }
@@ -662,6 +659,45 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
     }
   }
 
+  /**
+   *
+   * @param element sort statement candidate (must be PsiExpressionStatement)
+   * @param list list which should be sorted
+   * @return comparator string representation, empty string if natural order is used or null if given statement is not sort statement
+   */
+  @Contract(value = "null, _ -> null")
+  static String tryExtractSortComparatorText(PsiElement element, PsiVariable list) {
+    if(!(element instanceof PsiExpressionStatement)) return null;
+    PsiExpression expression = ((PsiExpressionStatement)element).getExpression();
+    if(!(expression instanceof PsiMethodCallExpression)) return null;
+    PsiMethodCallExpression methodCall = (PsiMethodCallExpression)expression;
+    PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
+    if(!"sort".equals(methodExpression.getReferenceName())) return null;
+    PsiMethod method = methodCall.resolveMethod();
+    if(method == null) return null;
+    PsiClass containingClass = method.getContainingClass();
+    if(containingClass == null) return null;
+    PsiExpression listExpression = null;
+    PsiExpression comparatorExpression = null;
+    if(CommonClassNames.JAVA_UTIL_COLLECTIONS.equals(containingClass.getQualifiedName())) {
+      PsiExpression[] args = methodCall.getArgumentList().getExpressions();
+      if(args.length == 1) {
+        listExpression = args[0];
+      } else if(args.length == 2) {
+        listExpression = args[0];
+        comparatorExpression = args[1];
+      } else return null;
+    } else if(InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_LIST)) {
+      listExpression = methodExpression.getQualifierExpression();
+      PsiExpression[] args = methodCall.getArgumentList().getExpressions();
+      if(args.length != 1) return null;
+      comparatorExpression = args[0];
+    }
+    if(!(listExpression instanceof PsiReferenceExpression) || ((PsiReferenceExpression)listExpression).resolve() != list) return null;
+    if(comparatorExpression == null || ExpressionUtils.isNullLiteral(comparatorExpression)) return "";
+    return comparatorExpression.getText();
+  }
+
   @Nullable
   static PsiMethodCallExpression extractToArrayExpression(PsiForeachStatement statement, PsiMethodCallExpression expression) {
     // return collection.toArray() or collection.toArray(new Type[0]) or collection.toArray(new Type[collection.size()]);
index 17c5c46b49433d7b46b7b198d91aa4cc688e3f42..1628d54c3f1a2afbf594eba493e080217a0ddbe6 100644 (file)
@@ -85,8 +85,6 @@ public class JavaHighlightingColors {
     = TextAttributesKey.createTextAttributesKey("ANONYMOUS_CLASS_NAME_ATTRIBUTES", CLASS_NAME_ATTRIBUTES);
   public static final TextAttributesKey IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES 
     = TextAttributesKey.createTextAttributesKey("IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES", CLASS_NAME_ATTRIBUTES);
-  public static final TextAttributesKey INLINE_PARAMETER_HINT
-    = TextAttributesKey.createTextAttributesKey("INLINE_PARAMETER_HINT");
   public static final TextAttributesKey TYPE_PARAMETER_NAME_ATTRIBUTES
     = TextAttributesKey.createTextAttributesKey("TYPE_PARAMETER_NAME_ATTRIBUTES", DefaultLanguageHighlighterColors.PARAMETER);
   public static final TextAttributesKey INTERFACE_NAME_ATTRIBUTES 
index a9abb809fa2a6ec9ae18ba54dc5c6e9ffb833e88..985481c1ac5df37c8f2decf318b105e4b6a0862f 100644 (file)
@@ -20,15 +20,17 @@ import com.intellij.codeHighlighting.TextEditorHighlightingPass;
 import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
 import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
 import com.intellij.openapi.components.AbstractProjectComponent;
+import com.intellij.openapi.editor.Caret;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.Inlay;
+import com.intellij.openapi.editor.VisualPosition;
 import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
 import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressIndicatorProvider;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Key;
 import com.intellij.psi.*;
 import com.intellij.util.containers.HashSet;
+import gnu.trove.TIntObjectHashMap;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -64,70 +66,20 @@ public class ParameterHintsPassFactory extends AbstractProjectComponent implemen
       myAnnotations.clear();
       if (!isEnabled() || !(myFile instanceof PsiJavaFile)) return;
       PsiJavaFile file = (PsiJavaFile) myFile;
-
-      PsiClass[] classes = file.getClasses();
-      for (PsiClass aClass : classes) {
-        ProgressIndicatorProvider.checkCanceled();
-        addElementsToFold(aClass);
-      }
+      
+      SyntaxTraverser.psiTraverser(file).forEach(element -> process(element));
     }
 
     private static boolean isEnabled() {
       return EditorSettingsExternalizable.getInstance().isShowParameterNameHints();
     }
 
-    private void addElementsToFold(PsiClass aClass) {
-      PsiElement[] children = aClass.getChildren();
-      for (PsiElement child : children) {
-        ProgressIndicatorProvider.checkCanceled();
-
-        if (child instanceof PsiMethod) {
-          PsiMethod method = (PsiMethod)child;
-          PsiCodeBlock body = method.getBody();
-          if (body != null) {
-            addCodeBlockFolds(body);
-          }
-        }
-        else if (child instanceof PsiField) {
-          PsiField field = (PsiField)child;
-          PsiExpression initializer = field.getInitializer();
-          if (initializer != null) {
-            addCodeBlockFolds(initializer);
-          } else if (field instanceof PsiEnumConstant) {
-            addCodeBlockFolds(field);
-          }
-        }
-        else if (child instanceof PsiClassInitializer) {
-          PsiClassInitializer initializer = (PsiClassInitializer)child;
-          addCodeBlockFolds(initializer);
-        }
-        else if (child instanceof PsiClass) {
-          addElementsToFold((PsiClass)child);
-        }
+    private void process(PsiElement child) {
+      if (child instanceof PsiCallExpression) {
+        inlineLiteralArgumentsNames((PsiCallExpression)child);
       }
     }
-
-    private void addCodeBlockFolds(PsiElement scope) {
-      scope.accept(new JavaRecursiveElementWalkingVisitor() {
-        @Override
-        public void visitClass(PsiClass aClass) {
-          addElementsToFold(aClass);
-        }
-
-        @Override
-        public void visitMethodCallExpression(PsiMethodCallExpression expression) {
-          inlineLiteralArgumentsNames(expression);
-          super.visitMethodCallExpression(expression);
-        }
-
-        @Override
-        public void visitNewExpression(PsiNewExpression expression) {
-          inlineLiteralArgumentsNames(expression);
-          super.visitNewExpression(expression);
-        }
-      });
-    }
-
+    
     private void inlineLiteralArgumentsNames(@NotNull PsiCallExpression expression) {
       ParameterNameHintsManager manager = new ParameterNameHintsManager(expression);
       for (InlayInfo info : manager.getDescriptors()) {
@@ -141,11 +93,16 @@ public class ParameterHintsPassFactory extends AbstractProjectComponent implemen
       boolean firstTime = myEditor.getUserData(REPEATED_PASS) == null;
       ParameterHintsPresentationManager presentationManager = ParameterHintsPresentationManager.getInstance();
       Set<String> removedHints = new HashSet<>();
+      TIntObjectHashMap<Caret> caretMap = new TIntObjectHashMap<>();
+      for (Caret caret : myEditor.getCaretModel().getAllCarets()) {
+        caretMap.put(caret.getOffset(), caret);
+      }
       for (Inlay inlay : myEditor.getInlayModel().getInlineElementsInRange(0, myDocument.getTextLength())) {
         if (!presentationManager.isParameterHint(inlay)) continue;
         int offset = inlay.getOffset();
-        String oldText = presentationManager.getHintText(inlay);
         String newText = myAnnotations.remove(offset);
+        if (delayRemoval(inlay, caretMap)) continue;
+        String oldText = presentationManager.getHintText(inlay);
         if (!Objects.equals(newText, oldText)) {
           if (newText == null) {
             removedHints.add(oldText);
@@ -163,5 +120,17 @@ public class ParameterHintsPassFactory extends AbstractProjectComponent implemen
       }
       myEditor.putUserData(REPEATED_PASS, Boolean.TRUE);
     }
+
+    private boolean delayRemoval(Inlay inlay, TIntObjectHashMap<Caret> caretMap) {
+      int offset = inlay.getOffset();
+      Caret caret = caretMap.get(offset);
+      if (caret == null) return false;
+      char afterCaret = myEditor.getDocument().getImmutableCharSequence().charAt(offset);
+      if (afterCaret != ',' && afterCaret != ')') return false;
+      VisualPosition afterInlayPosition = myEditor.offsetToVisualPosition(offset, true, false);
+      // check whether caret is to the right of inlay
+      if (!caret.getVisualPosition().equals(afterInlayPosition)) return false;
+      return true;
+    }
   }
 }
index 96f91aa2f9eea4acac868b7ec4674d083b49a557..ed494a786136c95b77de37cecef3b3162ed48a2c 100644 (file)
@@ -41,8 +41,6 @@ public class ParameterNameHintsManager {
     Couple.of("min", "max"),
     Couple.of("format", "arg")
   );
-
-  private static final Set<Character> ALLOWED_PARAMETER_NAME_CHARS = ContainerUtil.newHashSet('x', 'y', 'z', 'w', 'h');
   
   private static final Set<String> COMMON_METHOD_NAMES = ContainerUtil.newHashSet("set", "print", "println");
   
@@ -55,7 +53,7 @@ public class ParameterNameHintsManager {
     
     List<InlayInfo> descriptors = Collections.emptyList();
     if (resolveResult.getElement() instanceof PsiMethod
-        && isMethodToShowParams(resolveResult)
+        && isMethodToShowParams(callExpression, resolveResult)
         && hasUnclearExpressions(callArguments)) 
     {
       PsiMethod method = (PsiMethod)resolveResult.getElement();
@@ -66,19 +64,50 @@ public class ParameterNameHintsManager {
     myDescriptors = descriptors;
   }
 
-  private static boolean isMethodToShowParams(JavaResolveResult resolveResult) {
+  private static boolean isMethodToShowParams(@NotNull PsiCallExpression callExpression, @NotNull JavaResolveResult resolveResult) {
     PsiElement element = resolveResult.getElement();
     if (element instanceof PsiMethod) {
       PsiMethod method = (PsiMethod)element;
-      if (isSetter(method)) return false;
+      if (isSetter(method) || isBuilder(callExpression, method)) return false;
       if (hasSingleParameter(method)) {
-        return PsiType.VOID.equals(method.getReturnType());
+        PsiParameter parameter = method.getParameterList().getParameters()[0];
+        return PsiType.VOID.equals(method.getReturnType()) || isBoolean(parameter) || isNullOrThis(callExpression);
       }
       return !isCommonMethod(method);
     }
     return false;
   }
 
+  private static boolean isNullOrThis(@NotNull PsiCallExpression callExpression) {
+    PsiExpressionList list = callExpression.getArgumentList();
+    PsiExpression[] expressions = list != null ? list.getExpressions() : null;
+    if (expressions != null && expressions.length > 0) {
+      PsiExpression expression = expressions[0];
+      if (expression.textMatches("null") || expression.textMatches("this")) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private static boolean isBuilder(PsiCallExpression expression, PsiMethod method) {
+    if (expression instanceof PsiNewExpression) {
+      return false;
+    }
+    final PsiType returnType = method.getReturnType();
+    final PsiClass aClass = method.getContainingClass();
+    final String calledMethodFqn = aClass != null ? aClass.getQualifiedName() : null;
+    if (calledMethodFqn != null && returnType != null) {
+      return returnType.equalsToText(calledMethodFqn);
+    }
+    return false;
+  }
+
+  private static boolean isBoolean(PsiParameter parameter) {
+    PsiType type = parameter.getType();
+    return PsiType.BOOLEAN.equals(type) || PsiType.BOOLEAN.equals(PsiPrimitiveType.getUnboxedType(type));
+  }
+
   private static boolean hasSingleParameter(PsiMethod method) {
     return method.getParameterList().getParametersCount() == 1;
   }
@@ -144,30 +173,18 @@ public class ParameterNameHintsManager {
 
     final int totalDescriptors = descriptors.size();
     if (totalDescriptors == 1 && shouldIgnoreSingleHint(parameters, descriptors)
-        || totalDescriptors == 2 && parameters.length == 2 && isParamPairToIgnore(descriptors.get(0), descriptors.get(1))
-        || countOneCharLengthHints(descriptors) == totalDescriptors && !containsAnyMeaningfull(descriptors)) {
+        || totalDescriptors == 2 && parameters.length == 2 && isParamPairToIgnore(descriptors.get(0), descriptors.get(1))
+    {
       return ContainerUtil.emptyList();
     }
     
     return descriptors;
   }
-
-
-  private static long countOneCharLengthHints(List<InlayInfo> inlays) {
-    return inlays.stream().filter((e) -> e.getText().length() == 1).count();
-  }
-
+  
   private static boolean shouldIgnoreSingleHint(@NotNull PsiParameter[] parameters, List<InlayInfo> descriptors) {
     return isStringLiteral(descriptors.get(0)) && !hasMultipleStringParams(parameters);
   }
-
-  private static boolean containsAnyMeaningfull(List<InlayInfo> descriptors) {
-    return descriptors.stream().anyMatch((e) -> {
-      String text = e.getText();
-      return text.length() == 1 && ALLOWED_PARAMETER_NAME_CHARS.contains(text.charAt(0));
-    });
-  }
-
+  
   private static boolean hasMultipleStringParams(PsiParameter[] parameters) {
     int stringParams = 0;
     for (PsiParameter parameter : parameters) {
index c1603123d7159adc42c8bfa90a7d02e75fc685d4..13f49004a57112305c01c13223babe9d167509eb 100644 (file)
@@ -20,11 +20,11 @@ import com.intellij.psi.PsiElement;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorTopmost;
+import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset;
 
 public class StreamPostfixTemplate extends StringBasedPostfixTemplate {
   public StreamPostfixTemplate() {
-    super("stream", "Arrays.stream(expr)", JavaPostfixTemplatesUtils.atLeastJava8Selector(selectorTopmost(JavaPostfixTemplatesUtils.IS_ARRAY)));
+    super("stream", "Arrays.stream(expr)", JavaPostfixTemplatesUtils.atLeastJava8Selector(selectorAllExpressionsWithCurrentOffset(JavaPostfixTemplatesUtils.IS_ARRAY)));
   }
 
   @Nullable
index a6c706f4b8f70da5e01f94b9a19e5f91c2cf375e..4f7aade54c949b2e78bd0765f8bb6ea5e4cdda1a 100644 (file)
@@ -74,7 +74,6 @@ public class JavaColorSettingsPage implements RainbowColorSettingsPage, Inspecti
     new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.reassigned.local.variable"), JavaHighlightingColors.REASSIGNED_LOCAL_VARIABLE_ATTRIBUTES),
     new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.reassigned.parameter"), JavaHighlightingColors.REASSIGNED_PARAMETER_ATTRIBUTES),
     new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.implicit.anonymous.parameter"), JavaHighlightingColors.IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES),
-    new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.inline.parameter.hint"), JavaHighlightingColors.INLINE_PARAMETER_HINT),
     new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.instance.field"), JavaHighlightingColors.INSTANCE_FIELD_ATTRIBUTES),
     new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.instance.final.field"), JavaHighlightingColors.INSTANCE_FINAL_FIELD_ATTRIBUTES),
     new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.static.field"), JavaHighlightingColors.STATIC_FIELD_ATTRIBUTES),
index 5c372aa9e883f6a4e5a574748b42268ad208fba9..77d5e42a60230eae9a5f9b8bd8a01f1c8d365683 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.psi.*;
 import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.SLRUMap;
+import com.intellij.util.ui.JBUI;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -144,8 +145,8 @@ public class ProjectIconsAccessor {
   }
 
   private static boolean hasProperSize(Icon icon) {
-    return icon.getIconHeight() <= ICON_MAX_HEIGHT &&
-           icon.getIconWidth() <= ICON_MAX_WEIGHT;
+    return icon.getIconHeight() <= JBUI.scale(ICON_MAX_HEIGHT) &&
+           icon.getIconWidth() <= JBUI.scale(ICON_MAX_WEIGHT);
   }
 
   private static boolean isIdeaProject(Project project) {
index ef974e531b7036fa54ebd6a5584dbc86905c712e..710734674046f8559cc33e7d1c55c5dabf487d22 100644 (file)
@@ -285,8 +285,7 @@ public class IntroduceParameterDialog extends RefactoringDialog {
     if (myCbCollapseToLambda.isVisible() && myCbCollapseToLambda.isSelected() && parameterInitializer != null) {
       PsiExpression lambda = AnonymousCanBeLambdaInspection.replaceAnonymousWithLambda(parameterInitializer, selectedType);
       if (lambda != null) {
-        lambda = LambdaCanBeMethodReferenceInspection.replaceLambdaWithMethodReference(JavaPsiFacade.getElementFactory(getProject()),
-                                                                                       (PsiLambdaExpression)lambda);
+        lambda = LambdaCanBeMethodReferenceInspection.replaceLambdaWithMethodReference((PsiLambdaExpression)lambda);
         processor.setParameterInitializer(lambda);
       }
     }
index e98036cd4a6c9ad447150771f8345418c345804d..7c19448758942e876281162fea69a5f9546b3fa5 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.psi.search.LocalSearchScope;
 import com.intellij.psi.search.searches.ReferencesSearch;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiTypesUtil;
 import com.intellij.psi.util.RedundantCastUtil;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.util.IncorrectOperationException;
@@ -127,7 +128,7 @@ public class InlineUtil {
             if (substituted == null) break;
             copy.getTypeArgumentList().add(elementFactory.createTypeElement(substituted));
           }
-          if (varType.equals(copy.getType())) {
+          if (varType.equals(copy.getType()) && copy.resolveMethodGenerics().isValidResult()) {
             ((PsiCallExpression)expr).getTypeArgumentList().replace(copy.getTypeArgumentList());
             return (PsiMethod)resolved;
           }
index a60752e623601b83f825f38679a0c367d800a19f..8535e5756a0c3a2369ebe1b7c6e226ff9c04e676 100644 (file)
@@ -126,15 +126,26 @@ public class LambdaUtil {
 
   @Contract("null -> false")
   public static boolean isValidLambdaContext(@Nullable PsiElement context) {
-    return context instanceof PsiTypeCastExpression ||
+    context = PsiUtil.skipParenthesizedExprUp(context);
+    return isAssignmentOrInvocationContext(context) ||
+           context instanceof PsiTypeCastExpression ||
+           context instanceof PsiConditionalExpression && isAssignmentOrInvocationContext(PsiUtil.skipParenthesizedExprUp(context.getParent()));
+  }
+
+  private static boolean isAssignmentOrInvocationContext(PsiElement context) {
+    return isAssignmentContext(context) || isInvocationContext(context);
+  }
+
+  private static boolean isInvocationContext(@Nullable PsiElement context) {
+    return context instanceof PsiExpressionList;
+  }
+
+  private static boolean isAssignmentContext(PsiElement context) {
+    return context instanceof PsiLambdaExpression ||
+           context instanceof PsiReturnStatement ||
            context instanceof PsiAssignmentExpression ||
            context instanceof PsiVariable ||
-           context instanceof PsiLambdaExpression ||
-           context instanceof PsiReturnStatement ||
-           context instanceof PsiExpressionList ||
-           context instanceof PsiParenthesizedExpression ||
-           context instanceof PsiArrayInitializerExpression ||
-           context instanceof PsiConditionalExpression && PsiTreeUtil.getParentOfType(context, PsiTypeCastExpression.class) == null;
+           context instanceof PsiArrayInitializerExpression;
   }
 
   public static boolean isLambdaFullyInferred(PsiLambdaExpression expression, PsiType functionalInterfaceType) {
index 7216b5bb663cf4ee538a916d9d05081cd0065331..1c99e3e592e95cb4add51951ec625c37a7698e9a 100644 (file)
@@ -794,8 +794,6 @@ public class RedundantCastUtil {
     }
     else if (castType instanceof PsiClassType && ((PsiClassType)castType).hasParameters()) {
       if (opType instanceof PsiClassType && ((PsiClassType)opType).isRaw()) return true;
-    } else if (castType instanceof PsiClassType && ((PsiClassType)castType).isRaw()) {
-      if (opType instanceof PsiClassType && ((PsiClassType)opType).hasParameters()) return true;
     }
 
     final PsiExpression stripParenthesisOperand = PsiUtil.skipParenthesizedExprDown(operand);
@@ -807,6 +805,13 @@ public class RedundantCastUtil {
         }
       }
     }
+    else if (stripParenthesisOperand instanceof PsiConditionalExpression) {
+      final PsiExpression thenExpr = PsiUtil.skipParenthesizedExprDown(((PsiConditionalExpression)stripParenthesisOperand).getThenExpression());
+      final PsiExpression elseExpr = PsiUtil.skipParenthesizedExprDown(((PsiConditionalExpression)stripParenthesisOperand).getElseExpression());
+      if (thenExpr instanceof PsiFunctionalExpression || elseExpr instanceof PsiFunctionalExpression) {
+        return true;
+      }
+    }
 
     PsiElement parent = typeCast.getParent();
     while(parent instanceof PsiParenthesizedExpression) parent = parent.getParent();
diff --git a/java/java-runtime/src/com/intellij/rt/execution/testFrameworks/ChildVMStarter.java b/java/java-runtime/src/com/intellij/rt/execution/testFrameworks/ChildVMStarter.java
deleted file mode 100644 (file)
index 9e006d9..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2000-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.rt.execution.testFrameworks;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-
-public abstract class ChildVMStarter {
-
-  protected abstract void configureFrameworkAndRun(String[] args, PrintStream out, PrintStream err) throws Exception;
-  
-  //setup output wrappers
-  protected void startVM(String[] args) throws Exception {
-    final String testOutputPath = args[0];
-    final File file = new File(testOutputPath);
-    if (!file.exists()) {
-      if (!file.createNewFile()) return;
-    }
-    final FileOutputStream stream = new FileOutputStream(testOutputPath);
-    //noinspection UseOfSystemOutOrSystemErr
-    PrintStream oldOut = System.out;
-    //noinspection UseOfSystemOutOrSystemErr
-    PrintStream oldErr = System.err;
-    try {
-      final PrintStream out = new PrintStream(new ForkedVMWrapper(stream, false));
-      final PrintStream err = new PrintStream(new ForkedVMWrapper(stream, true));
-      System.setOut(out);
-      System.setErr(err);
-      configureFrameworkAndRun(args, out, err);
-    }
-    finally {
-      System.setOut(oldOut);
-      System.setErr(oldErr);
-      stream.close();
-    }
-  }
-}
index 0afce492692c693397727a5322e8284d0d1a6450..366665bb803239b6b4ec6cb95ed8010ff020a080 100644 (file)
@@ -27,17 +27,13 @@ public abstract class ForkedByModuleSplitter {
   protected final ForkedDebuggerHelper myForkedDebuggerHelper = new ForkedDebuggerHelper();
   protected final String myWorkingDirsPath;
   protected final String myForkMode;
-  protected final PrintStream myOut;
-  protected final PrintStream myErr;
   protected final List   myNewArgs;
   protected String myDynamicClasspath;
   protected List myVMParameters;
 
-  public ForkedByModuleSplitter(String workingDirsPath, String forkMode, PrintStream out, PrintStream err, List newArgs) {
+  public ForkedByModuleSplitter(String workingDirsPath, String forkMode, List newArgs) {
     myWorkingDirsPath = workingDirsPath;
     myForkMode = forkMode;
-    myOut = out;
-    myErr = err;
     myNewArgs = newArgs;
   }
 
@@ -66,15 +62,10 @@ public abstract class ForkedByModuleSplitter {
   }
 
   //read output from wrappers
-  protected int startChildFork(List args, File workingDir, String classpath, String repeatCount) throws IOException, InterruptedException {
+  protected int startChildFork(final List args, File workingDir, String classpath, String repeatCount) throws IOException, InterruptedException {
     List vmParameters = new ArrayList(myVMParameters);
 
     myForkedDebuggerHelper.setupDebugger(vmParameters);
-    //noinspection SSBasedInspection
-    final File tempFile = File.createTempFile("fork", "test");
-    tempFile.deleteOnExit();
-    final String testOutputPath = tempFile.getAbsolutePath();
-
     final ProcessBuilder builder = new ProcessBuilder();
     builder.add(vmParameters);
     builder.add("-classpath");
@@ -91,7 +82,6 @@ public abstract class ForkedByModuleSplitter {
     }
 
     builder.add(getStarterName());
-    builder.add(testOutputPath);
     builder.add(args);
     if (repeatCount != null) {
       builder.add(repeatCount);
@@ -99,9 +89,46 @@ public abstract class ForkedByModuleSplitter {
     builder.setWorkingDir(workingDir);
 
     final Process exec = builder.createProcess();
-    final int result = exec.waitFor();
-    ForkedVMWrapper.readWrapped(testOutputPath, myOut, myErr);
-    return result;
+    final boolean[] stopped = new boolean[1];
+
+    new Thread(createInputReader(exec.getErrorStream(), System.err, stopped), "Read forked error output").start();
+    new Thread(createInputReader(exec.getInputStream(), System.out, stopped), "Read forked output").start();
+    final int i = exec.waitFor();
+    stopped[0] = true;
+    return i;
+  }
+
+  private static Runnable createInputReader(final InputStream inputStream, final PrintStream outputStream, final boolean[] stopped) {
+    return new Runnable() {
+      char[] buf = new char[8192];
+
+      public void run() {
+        final InputStreamReader inputReader = new InputStreamReader(inputStream);
+        try {
+          while (true) {
+            if (stopped[0]) break;
+
+            int n;
+            try {
+              while (inputReader.ready() && (n = inputReader.read(buf)) > 0) {
+                outputStream.print(new String(buf, 0, n));
+              }
+            }
+            catch (IOException e) {
+              e.printStackTrace();
+            }
+          }
+        }
+        finally {
+          try {
+            inputReader.close();
+          }
+          catch (IOException e) {
+            e.printStackTrace();
+          }
+        }
+      }
+    };
   }
 
   //read file with classes grouped by module
index aadef8fabdf3b02727ce80b857bda01686bba450..7c82d99817f02b7b06abcff923f9b094cc6cbcc5 100644 (file)
@@ -28,8 +28,8 @@ public abstract class ForkedSplitter extends ForkedByModuleSplitter {
 
   private Object myRootDescription;
 
-  public ForkedSplitter(String workingDirsPath, String forkMode, PrintStream out, PrintStream err, List newArgs) {
-    super(workingDirsPath, forkMode, out, err, newArgs);
+  public ForkedSplitter(String workingDirsPath, String forkMode, List newArgs) {
+    super(workingDirsPath, forkMode, newArgs);
   }
 
   protected int startSplitting(String[] args,
diff --git a/java/java-runtime/src/com/intellij/rt/execution/testFrameworks/ForkedVMWrapper.java b/java/java-runtime/src/com/intellij/rt/execution/testFrameworks/ForkedVMWrapper.java
deleted file mode 100644 (file)
index 29f1892..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.rt.execution.testFrameworks;
-
-import java.io.*;
-
-/**
-* User: anna
-* Date: 4/6/11
-*/
-class ForkedVMWrapper extends DataOutputStream {
-
-  public static final char DELIMITER = '\u0002';
-  public static final byte[] ERROR = new byte[] {'\u0003'};
-  public static final byte[] OUTPUT = new byte[] {'\u0004'};
-  private FileOutputStream myOutputStream;
-  private boolean myError;
-
-  public ForkedVMWrapper(FileOutputStream outputStream, boolean error) throws FileNotFoundException {
-    super(outputStream);
-    myOutputStream = outputStream;
-    myError = error;
-  }
-
-  public synchronized void write(int b) throws IOException {
-    printPrefix();
-    myOutputStream.write(b);
-  }
-
-  private void printPrefix() throws IOException {
-    myOutputStream.write(("/" + DELIMITER).getBytes());
-    if (myError) {
-      myOutputStream.write(ERROR);
-    }
-    else {
-      myOutputStream.write(OUTPUT);
-    }
-  }
-
-  public void write(byte[] b) throws IOException {
-    printPrefix();
-    myOutputStream.write(b);
-  }
-
-  public synchronized void write(byte[] b, int off, int len) throws IOException {
-    printPrefix();
-    myOutputStream.write(b, off, len);
-  }
-
-  public void close() throws IOException {
-    myOutputStream.close();
-  }
-
-  public void flush() throws IOException {
-    myOutputStream.flush();
-  }
-
-  public static void readWrapped(String path, PrintStream out, PrintStream err) throws IOException {
-    FileInputStream stream = new FileInputStream(path);
-    try {
-      boolean error = false;
-      boolean afterSymbol = false;
-      boolean afterDelimiter = false;
-      while (stream.available() > 0) {
-        char read = (char)stream.read();
-        if (!afterSymbol && read == '/') {
-          afterSymbol = true;
-          continue;
-        }
-        if (afterSymbol) {
-          if (afterDelimiter) {
-            error = read == ERROR[0];
-            afterSymbol = false;
-            afterDelimiter = false;
-            continue;
-          }
-          if (read != DELIMITER) {
-            if (error) {
-              err.write("/".getBytes());
-              err.write(read);
-            }
-            else {
-              out.write("/".getBytes());
-              out.write(read);
-            }
-            afterSymbol = false;
-            afterDelimiter = false;
-            continue;
-          }
-          else {
-            afterDelimiter = true;
-            continue;
-          }
-        }
-        if (error) {
-          err.write(read);
-        }
-        else {
-          out.write(read);
-        }
-      }
-    }
-    finally {
-      if (stream != null) stream.close();
-    }
-  }
-}
index 4e46dfb14fce0e4ed77b1d16c4fbd851e7328b4d..702e0d80363581d15a49d3090f50440cbd783854 100644 (file)
@@ -49,7 +49,9 @@ public abstract class JavaClassTreeElementBase<Value extends PsiElement> extends
 
   @Override
   public int getAccessLevel() {
-    final PsiModifierList modifierList = ((PsiModifierListOwner)getElement()).getModifierList();
+    Value element = getElement();
+    if (!(element instanceof PsiModifierListOwner)) return PsiUtil.ACCESS_LEVEL_PUBLIC;
+    final PsiModifierList modifierList = ((PsiModifierListOwner)element).getModifierList();
     if (modifierList == null) {
       return PsiUtil.ACCESS_LEVEL_PUBLIC;
     }
index 60690b65a14f9a585316c5def675d3e39d101ca7..02a10c09fc47c829eaf8aa208e3a8fa07c565841 100644 (file)
@@ -10,6 +10,6 @@ class Test5_1 {
   static Node<String>.Details details;
   public static void main(String[] args) {
     Node<String> stringNode = new Node<String>();
-    details = <warning descr="Unchecked assignment: 'Node.Details' to 'Node<java.lang.String>.Details'">(Node.Details)stringNode.addNode(new Node<String>())</warning>;
+    details = <warning descr="Unchecked assignment: 'Node.Details' to 'Node<java.lang.String>.Details'">(<warning descr="Casting 'stringNode.addNode(new Node<String>())' to 'Node.Details' is redundant">Node.Details</warning>)stringNode.addNode(new Node<String>())</warning>;
   }
 }
\ No newline at end of file
index a5efd12bd7a08492d378d686bec220ddc982a9e8..cff20f66966615566744867eed19dbe7ed05a16c 100644 (file)
@@ -23,6 +23,8 @@ interface II {
 class Test1 {
   void bar(boolean b){
     II ik = b ? (s)-> true : (s)->false;
-    II ik1 = (II)(b ? <error descr="Lambda expression not expected here">(s)-> true</error> : <error descr="Lambda expression not expected here">(s)->false</error>);
+    II ik1 = (II)((b ? <error descr="Lambda expression not expected here">(s)-> true</error> : <error descr="Lambda expression not expected here">(s)->false</error>));
+    II ik2 = (II)(ik1 = (b ? (s)-> true : (s)->false));
+    (b ? <error descr="Lambda expression not expected here">(s) -> true</error> : ik)._("");
   }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/redundantCast/InvalidConditional.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/redundantCast/InvalidConditional.java
new file mode 100644 (file)
index 0000000..321ad2f
--- /dev/null
@@ -0,0 +1,18 @@
+import java.util.function.Function;
+
+class Main {
+  public static void main(String[] args) {
+    Test test = new Test();
+    ((Function<String, Long>)(args.length == 2 ? (<error descr="Method reference expression is not expected here">test::foo</error>) : <error descr="Method reference expression is not expected here">test::bar</error>)).apply("");
+  }
+
+  static class Test {
+    public long foo(String s) {
+      return 0;
+    }
+
+    public long bar(String s) {
+      return 0;
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAllMatchChain.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAllMatchChain.java
new file mode 100644 (file)
index 0000000..02032cf
--- /dev/null
@@ -0,0 +1,9 @@
+// "Replace with allMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  boolean find(List<String> data, boolean other, boolean third) {
+      return data.stream().map(String::trim).allMatch(trimmed -> trimmed.startsWith("xyz")) && (other || third);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchChain.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchChain.java
new file mode 100644 (file)
index 0000000..d5b9da7
--- /dev/null
@@ -0,0 +1,9 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  boolean find(List<String> data, boolean other, boolean third) {
+      return data.stream().map(String::trim).anyMatch(trimmed -> trimmed.startsWith("xyz")) || (other || third);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchCompoundAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchCompoundAssignment.java
new file mode 100644 (file)
index 0000000..d6bc498
--- /dev/null
@@ -0,0 +1,13 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  public boolean testAnyMatch(List<String> data) {
+    int x = 10;
+      if (data.stream().map(String::trim).anyMatch(String::isEmpty)) {
+          x *= 2;
+      }
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchExtends.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchExtends.java
new file mode 100644 (file)
index 0000000..dc7d98d
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.*;
+
+public class Main {
+  public List<? extends CharSequence> getList() {return Arrays.asList("a");}
+  public boolean test() {
+      return getList().stream().map(CharSequence::toString).anyMatch(s -> !s.isEmpty());
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchReturn.java
new file mode 100644 (file)
index 0000000..8942070
--- /dev/null
@@ -0,0 +1,17 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.Collection;
+import java.util.List;
+
+public class Main {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if (!data.isEmpty()) {
+        if (data.stream().flatMap(Collection::stream).anyMatch(str -> !str.isEmpty())) {
+            System.out.println("Found!");
+        }
+      return true;
+    }
+    return false;
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSorted.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSorted.java
new file mode 100644 (file)
index 0000000..aa7c38f
--- /dev/null
@@ -0,0 +1,15 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Collect {
+  class Person {
+    String getName() {
+      return "";
+    }
+  }
+
+  void collectNames(List<Person> persons){
+      List<String> names = persons.stream().map(Person::getName).sorted(Comparator.comparing(Person::getName)).collect(Collectors.toList());
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSortedNatural.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSortedNatural.java
new file mode 100644 (file)
index 0000000..6f6b72b
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace with collect" "true"
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class Collect {
+  void collectNames(List<String> persons){
+      List<String> names = persons.stream().map(String::toLowerCase).sorted().collect(Collectors.toList());
+      // sort
+  }
+}
index d513498dc463f5dcd6b7bcac7f0cd861c9866cca..9d2fedce705bc0607322c79649724fa4844a3779 100644 (file)
@@ -3,12 +3,11 @@
 import java.awt.*;
 import java.util.List;
 import java.util.Objects;
-import java.util.function.Predicate;
 
 public class Main {
   private Point field = new Point(0, 0);
 
   public Point find(List<Point> points) {
-      return points.stream().filter((Predicate<Point>) Objects::nonNull).findFirst().orElse(field);
+      return points.stream().filter(Objects::nonNull).findFirst().orElse(field);
   }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstIfPresentWithReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstIfPresentWithReturn.java
new file mode 100644 (file)
index 0000000..0ade6d4
--- /dev/null
@@ -0,0 +1,16 @@
+// "Replace with findFirst()" "true"
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class Main {
+  public List<Integer> testFindFirstIfPresent(List<List<String>> data) {
+    List<Integer> result = new ArrayList<>();
+    if (!data.isEmpty()) {
+        data.stream().flatMap(Collection::stream).filter(str -> !str.isEmpty()).findFirst().ifPresent(str -> result.add(str.length()));
+    }
+    return result;
+  }
+
+}
\ No newline at end of file
index 5023572711d0b12a96a083a72f1465df8742fd65..219566b708f055dc7d74ca528922701eb6634727 100644 (file)
@@ -3,12 +3,11 @@
 import java.awt.*;
 import java.util.List;
 import java.util.Objects;
-import java.util.function.Predicate;
 
 public class Main {
   private static Point ZERO = new Point(0, 0);
 
   public static Point find(List<Point> points) {
-      return points.stream().filter((Predicate<Point>) Objects::nonNull).findFirst().orElse(ZERO);
+      return points.stream().filter(Objects::nonNull).findFirst().orElse(ZERO);
   }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAllMatchChain.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAllMatchChain.java
new file mode 100644 (file)
index 0000000..e824a12
--- /dev/null
@@ -0,0 +1,15 @@
+// "Replace with allMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  boolean find(List<String> data, boolean other, boolean third) {
+    for(String e : da<caret>ta) {
+      String trimmed = e.trim();
+      if(!trimmed.startsWith("xyz")) {
+        return false;
+      }
+    }
+    return other || third;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchCompoundAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchCompoundAssignment.java
new file mode 100644 (file)
index 0000000..e408490
--- /dev/null
@@ -0,0 +1,17 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  public boolean testAnyMatch(List<String> data) {
+    int x = 10;
+    for(String str : da<caret>ta) {
+      String trimmed = str.trim();
+      if(trimmed.isEmpty()) {
+        x *= 2;
+        break;
+      }
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchExtends.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchExtends.java
new file mode 100644 (file)
index 0000000..79edd50
--- /dev/null
@@ -0,0 +1,16 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.*;
+
+public class Main {
+  public List<? extends CharSequence> getList() {return Arrays.asList("a");}
+  public boolean test() {
+    for(CharSequence cs : ge<caret>tList()) {
+      String s = cs.toString();
+      if(!s.isEmpty()) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchReturn.java
new file mode 100644 (file)
index 0000000..9a3e27d
--- /dev/null
@@ -0,0 +1,21 @@
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if (!data.isEmpty()) {
+      for (List<String> list : dat<caret>a) {
+        for (String str : list) {
+          if (!str.isEmpty()) {
+            System.out.println("Found!");
+            return true;
+          }
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchReturnDifferent.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchReturnDifferent.java
new file mode 100644 (file)
index 0000000..f0223d8
--- /dev/null
@@ -0,0 +1,21 @@
+// "Replace with anyMatch()" "false"
+
+import java.util.List;
+
+public class Main {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if (!data.isEmpty()) {
+      for (List<String> list : dat<caret>a) {
+        for (String str : list) {
+          if (!str.isEmpty()) {
+            System.out.println("Found!");
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchReturnInterrupted.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchReturnInterrupted.java
new file mode 100644 (file)
index 0000000..1f8261f
--- /dev/null
@@ -0,0 +1,22 @@
+// "Replace with anyMatch()" "false"
+
+import java.util.List;
+
+public class Main {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if (!data.isEmpty()) {
+      for (List<String> list : dat<caret>a) {
+        for (String str : list) {
+          if (!str.isEmpty()) {
+            System.out.println("Found!");
+            return true;
+          }
+        }
+      }
+      System.out.println("Oops");
+      return true;
+    }
+    return false;
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSorted.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSorted.java
new file mode 100644 (file)
index 0000000..1c616c5
--- /dev/null
@@ -0,0 +1,18 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public class Collect {
+  class Person {
+    String getName() {
+      return "";
+    }
+  }
+
+  void collectNames(List<Person> persons){
+    List<String> names = new ArrayList<>();
+    for (Person person : pers<caret>ons) {
+      names.add(person.getName());
+    }
+    Collections.sort(names, Comparator.comparing(Person::getName));
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSortedNatural.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSortedNatural.java
new file mode 100644 (file)
index 0000000..ce66211
--- /dev/null
@@ -0,0 +1,13 @@
+// "Replace with collect" "true"
+import java.util.*;
+
+public class Collect {
+  void collectNames(List<String> persons){
+    List<String> names = new ArrayList<>();
+    for (String person : pers<caret>ons) {
+      names.add(person.toLowerCase());
+    }
+    // sort
+    Collections.sort(names);
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstIfPresentWithReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstIfPresentWithReturn.java
new file mode 100644 (file)
index 0000000..9d13a52
--- /dev/null
@@ -0,0 +1,22 @@
+// "Replace with findFirst()" "true"
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Main {
+  public List<Integer> testFindFirstIfPresent(List<List<String>> data) {
+    List<Integer> result = new ArrayList<>();
+    if (!data.isEmpty()) {
+      for (List<String> list : da<caret>ta) {
+        for (String str : list) {
+          if (!str.isEmpty()) {
+            result.add(str.length());
+            return result;
+          }
+        }
+      }
+    }
+    return result;
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/afterForeachParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/afterForeachParameter.java
new file mode 100644 (file)
index 0000000..d360d00
--- /dev/null
@@ -0,0 +1,8 @@
+// "Suppress for statement" "true"
+public class Test {
+  {
+    for (@SuppressWarnings("unused") java.lang.Object o : ) {
+
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/afterTryWithResources.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/afterTryWithResources.java
new file mode 100644 (file)
index 0000000..085eddf
--- /dev/null
@@ -0,0 +1,8 @@
+// "Suppress for statement" "true"
+public class Test {
+  {
+    try(@SuppressWarnings("unused") java.lang.Object o) {
+
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/beforeForeachParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/beforeForeachParameter.java
new file mode 100644 (file)
index 0000000..524c90b
--- /dev/null
@@ -0,0 +1,8 @@
+// "Suppress for statement" "true"
+public class Test {
+  {
+    for (java.lang.Object <caret>o : ) {
+
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/beforeTryWithResources.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/suppress15Inspections/beforeTryWithResources.java
new file mode 100644 (file)
index 0000000..c44ff5e
--- /dev/null
@@ -0,0 +1,8 @@
+// "Suppress for statement" "true"
+public class Test {
+  {
+    try(java.lang.Object <caret>o) {
+
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/stream/expressionContext.java b/java/java-tests/testData/codeInsight/template/postfix/templates/stream/expressionContext.java
new file mode 100644 (file)
index 0000000..5ab071b
--- /dev/null
@@ -0,0 +1,9 @@
+package templates;
+
+public class Foo {
+  void m(int[] array) {
+    if (array.stream<caret>) {
+
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/stream/expressionContext_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/stream/expressionContext_after.java
new file mode 100644 (file)
index 0000000..f8db444
--- /dev/null
@@ -0,0 +1,11 @@
+package templates;
+
+import java.util.Arrays;
+
+public class Foo {
+  void m(int[] array) {
+    if (Arrays.stream(array)) {
+
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/java8CollectionRemoveIf/afterIteratorRemoveInline.java b/java/java-tests/testData/inspection/java8CollectionRemoveIf/afterIteratorRemoveInline.java
new file mode 100644 (file)
index 0000000..fe9b9e0
--- /dev/null
@@ -0,0 +1,9 @@
+// "Replace the loop with Collection.removeIf" "true"
+import java.util.Iterator;
+import java.util.List;
+
+public class Main {
+  public void testIterator(List<List<String>> data, boolean b) {
+      data.removeIf(strings -> strings.isEmpty() && b);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveInline.java b/java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveInline.java
new file mode 100644 (file)
index 0000000..ccf66bb
--- /dev/null
@@ -0,0 +1,13 @@
+// "Replace the loop with Collection.removeIf" "true"
+import java.util.Iterator;
+import java.util.List;
+
+public class Main {
+  public void testIterator(List<List<String>> data, boolean b) {
+    for(Ite<caret>rator<List<String>> iter = data.iterator(); iter.hasNext();) {
+      if(iter.next().isEmpty() && b) {
+        iter.remove();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveInlineShortCircuit.java b/java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveInlineShortCircuit.java
new file mode 100644 (file)
index 0000000..f907b8c
--- /dev/null
@@ -0,0 +1,13 @@
+// "Replace the loop with Collection.removeIf" "false"
+import java.util.Iterator;
+import java.util.List;
+
+public class Main {
+  public void testIterator(List<List<String>> data, boolean b) {
+    for(Ite<caret>rator<List<String>> iter = data.iterator(); iter.hasNext();) {
+      if(b && iter.next().isEmpty()) {
+        iter.remove();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveInlineTwice.java b/java/java-tests/testData/inspection/java8CollectionRemoveIf/beforeIteratorRemoveInlineTwice.java
new file mode 100644 (file)
index 0000000..eed1ec2
--- /dev/null
@@ -0,0 +1,13 @@
+// "Replace the loop with Collection.removeIf" "false"
+import java.util.Iterator;
+import java.util.List;
+
+public class Main {
+  public void testIterator(List<List<String>> data, boolean b) {
+    for(Ite<caret>rator<List<String>> iter = data.iterator(); iter.hasNext();) {
+      if(iter.next().isEmpty() && iter.next().isEmpty()) {
+        iter.remove();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/CastToRawType.java b/java/java-tests/testData/inspection/redundantCast/lambda/CastToRawType.java
new file mode 100644 (file)
index 0000000..dd3a848
--- /dev/null
@@ -0,0 +1,17 @@
+import java.util.Map;
+
+class Main {
+  private final Map<String, BreakpointState<?,?,?>> myBreakpointsDefaults = null;
+
+  @SuppressWarnings("unchecked")
+  public BreakpointState<String, String, String> foo1(String type, BreakpointState<?, ?, ?> defaults) {
+    return (BreakpointState) myBreakpointsDefaults.computeIfAbsent(type, k -> defaults);
+  }
+
+  public BreakpointState foo2(String type, BreakpointState<?, ?, ?> defaults) {
+    return (<warning descr="Casting 'myBreakpointsDefaults.computeIfAbsent(type, k -> defaults)' to 'BreakpointState' is redundant">BreakpointState</warning>) myBreakpointsDefaults.computeIfAbsent(type, k -> defaults);
+  }
+
+  private static class BreakpointState<A, B, C> {}
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/Conditional/expected.xml b/java/java-tests/testData/inspection/redundantCast/lambda/Conditional/expected.xml
deleted file mode 100644 (file)
index 4704d91..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems/>
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/ExpectedSupertype.java b/java/java-tests/testData/inspection/redundantCast/lambda/ExpectedSupertype.java
new file mode 100644 (file)
index 0000000..cea843d
--- /dev/null
@@ -0,0 +1,16 @@
+class Test {
+  interface I {
+  }
+
+  interface Bar extends I {
+    int compare(String o1, String o2);
+  }
+
+  {
+    I bar2 = (Bar) (o1, o2) -> 0;
+    g((Bar) (o1, o2) -> 0);
+    ((Bar) (o1, o2) -> 0).getClass();
+  }
+
+  void g(I i){}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/ExpectedSupertype/expected.xml b/java/java-tests/testData/inspection/redundantCast/lambda/ExpectedSupertype/expected.xml
deleted file mode 100644 (file)
index 5e93349..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
-</problems>
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/ExpectedSupertype/src/Test.java b/java/java-tests/testData/inspection/redundantCast/lambda/ExpectedSupertype/src/Test.java
deleted file mode 100644 (file)
index 97832e4..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2000-2012 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.
- */
-public class Test {
-  interface I {
-  }
-
-  interface Bar extends I {
-    int compare(String o1, String o2);
-  }
-
-  {
-    I bar2 = (Bar) (o1, o2) -> 0;
-    g((Bar) (o1, o2) -> 0);
-    ((Bar) (o1, o2) -> 0).getClass();
-  }
-
-  void g(I i){}
-}
\ No newline at end of file
similarity index 58%
rename from java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/src/Test.java
rename to java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue.java
index bd2236cfe9f1d8cc56f169940d718e245bf8bbee..a0b7f3730fa6757dd966711ae08bfdd2f9995482 100644 (file)
@@ -3,7 +3,7 @@ import java.util.Iterator;
 
 class IterableMain {
   public static void main(final String... args) {
-    for (final String s :  (Iterable<String>) XIterator::new) {}
+    for (final String s :  (Iterable<String>) <error descr="'XIterator' is abstract; cannot be instantiated">XIterator::new</error>) {}
   }
 
   public static interface XIterator extends Iterator<String> {}
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/expected.xml b/java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/expected.xml
deleted file mode 100644 (file)
index 4704d91..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems/>
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/InferApplicabilityError/expected.xml b/java/java-tests/testData/inspection/redundantCast/lambda/InferApplicabilityError/expected.xml
deleted file mode 100644 (file)
index 4704d91..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems/>
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/LambdaContext.java b/java/java-tests/testData/inspection/redundantCast/lambda/LambdaContext.java
new file mode 100644 (file)
index 0000000..feded77
--- /dev/null
@@ -0,0 +1,10 @@
+class Test {
+  interface I {
+    boolean foo(String s);
+  }
+  {
+    ((I)s -> s.endsWith(".java")).getClass();
+    I i = (<warning descr="Casting 's -> s.endsWith(\".java\")' to 'I' is redundant">I</warning>)s -> s.endsWith(".java");
+
+  }
+}
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/LambdaContext/expected.xml b/java/java-tests/testData/inspection/redundantCast/lambda/LambdaContext/expected.xml
deleted file mode 100644 (file)
index 5373cdc..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
-  <problem>
-    <file>Test.java</file>
-    <line>7</line>
-    <description>Casting &lt;code&gt;s -&gt; s.endsWith(&quot;.java&quot;)&lt;/code&gt; to &lt;code&gt;I&lt;/code&gt; is redundant</description>
-  </problem>
-</problems>
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/LambdaContext/src/Test.java b/java/java-tests/testData/inspection/redundantCast/lambda/LambdaContext/src/Test.java
deleted file mode 100644 (file)
index 510d184..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-class Test {
-  interface I {
-    boolean foo(String s);
-  }
-  {
-    ((I)s -> s.endsWith(".java")).getClass();
-    I i = (I)s -> s.endsWith(".java");
-    
-  }
-}
similarity index 80%
rename from java/java-tests/testData/inspection/redundantCast/lambda/MethodRefContext/src/Test.java
rename to java/java-tests/testData/inspection/redundantCast/lambda/MethodRefContext.java
index b82f2ca2538ae2a63b0152a9b05f957600fb5f09..d0a89cede5f2ecec894821ce8c10d6762f023508 100644 (file)
@@ -1,6 +1,6 @@
 class Test {
   {
-      ((Bar) Test::length)._("");
+    ((Bar) Test::length)._("");
   }
 
   public static Integer length(String s) {
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/MethodRefContext/expected.xml b/java/java-tests/testData/inspection/redundantCast/lambda/MethodRefContext/expected.xml
deleted file mode 100644 (file)
index 4704d91..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems/>
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedLambda.java b/java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedLambda.java
new file mode 100644 (file)
index 0000000..62a5fb1
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.allMatch(x -> !(...)) with Stream.noneMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(data.stream().flatMap(Collection::stream).noneMatch(str -> str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedLambdaTwice.java b/java/java-tests/testData/inspection/streamApiCallChains/afterAllMatchNegatedLambdaTwice.java
new file mode 100644 (file)
index 0000000..1b682b2
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !Stream.allMatch(x -> !(...)) with Stream.anyMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(data.stream().flatMap(Collection::stream).anyMatch(str -> str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegated.java b/java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegated.java
new file mode 100644 (file)
index 0000000..5d82172
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !Stream.anyMatch(...) with Stream.noneMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(data.stream().flatMap(Collection::stream).noneMatch(str -> str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegatedLambdaTwice.java b/java/java-tests/testData/inspection/streamApiCallChains/afterAnyMatchNegatedLambdaTwice.java
new file mode 100644 (file)
index 0000000..d51ced9
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !Stream.anyMatch(x -> !(...)) with Stream.allMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(data.stream().flatMap(Collection::stream).allMatch(str -> str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegated.java b/java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegated.java
new file mode 100644 (file)
index 0000000..51b4c0b
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !Stream.noneMatch(...) with Stream.anyMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(data.stream().flatMap(Collection::stream).anyMatch(str -> str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegatedLambda.java b/java/java-tests/testData/inspection/streamApiCallChains/afterNoneMatchNegatedLambda.java
new file mode 100644 (file)
index 0000000..e11a37f
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.noneMatch(x -> !(...)) with Stream.allMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(data.stream().flatMap(Collection::stream).allMatch(str -> str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegated.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegated.java
new file mode 100644 (file)
index 0000000..df19ee9
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.allMatch(x -> !(...)) with Stream.noneMatch(...)" "false"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(!data.stream().flatMap(Collection::stream).allM<caret>atch(str -> str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedLambda.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedLambda.java
new file mode 100644 (file)
index 0000000..d6c2fe5
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.allMatch(x -> !(...)) with Stream.noneMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(data.stream().flatMap(Collection::stream).allM<caret>atch(str -> !str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedLambdaTwice.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeAllMatchNegatedLambdaTwice.java
new file mode 100644 (file)
index 0000000..7a6514b
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !Stream.allMatch(x -> !(...)) with Stream.anyMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(!data.stream().flatMap(Collection::stream).allM<caret>atch(str -> !str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegated.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegated.java
new file mode 100644 (file)
index 0000000..204e69b
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !Stream.anyMatch(...) with Stream.noneMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(!data.stream().flatMap(Collection::stream).anyM<caret>atch(str -> str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedLambda.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedLambda.java
new file mode 100644 (file)
index 0000000..32ce1a0
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !Stream.anyMatch(x -> !(...)) with Stream.allMatch(...)" "false"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(data.stream().flatMap(Collection::stream).anyM<caret>atch(str -> !str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedLambdaTwice.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeAnyMatchNegatedLambdaTwice.java
new file mode 100644 (file)
index 0000000..b2dfcd9
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !Stream.anyMatch(x -> !(...)) with Stream.allMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(!data.stream().flatMap(Collection::stream).anyM<caret>atch(str -> !str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegated.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegated.java
new file mode 100644 (file)
index 0000000..2b01f91
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace !Stream.noneMatch(...) with Stream.anyMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(!data.stream().flatMap(Collection::stream).noneM<caret>atch(str -> str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegatedLambda.java b/java/java-tests/testData/inspection/streamApiCallChains/beforeNoneMatchNegatedLambda.java
new file mode 100644 (file)
index 0000000..a37b825
--- /dev/null
@@ -0,0 +1,10 @@
+// "Replace Stream.noneMatch(x -> !(...)) with Stream.allMatch(...)" "true"
+
+import java.util.*;
+
+class Test {
+  public boolean testAnyMatch(List<List<String>> data) {
+    if(data.stream().flatMap(Collection::stream).noneM<caret>atch(str -> !str.isEmpty()))
+      return true;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineLocal/AvoidTypeSpecificationWhenPossibleToAvoid.java b/java/java-tests/testData/refactoring/inlineLocal/AvoidTypeSpecificationWhenPossibleToAvoid.java
new file mode 100644 (file)
index 0000000..641243b
--- /dev/null
@@ -0,0 +1,12 @@
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+class Main {
+  public Collection<? extends Number> get() {
+    List<Number> lis<caret>t = IntStream.range(0, 100).boxed().collect(Collectors.toList());
+    return list;
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineLocal/AvoidTypeSpecificationWhenPossibleToAvoid.java.after b/java/java-tests/testData/refactoring/inlineLocal/AvoidTypeSpecificationWhenPossibleToAvoid.java.after
new file mode 100644 (file)
index 0000000..5eb5c27
--- /dev/null
@@ -0,0 +1,11 @@
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+class Main {
+  public Collection<? extends Number> get() {
+      return IntStream.range(0, 100).boxed().collect(Collectors.toList());
+  }
+
+}
\ No newline at end of file
index 6420e2377c05db08a5d9390b5ec5e0b9771a3e59..54c1636ea5353091a6218223e6b65a448a1172c3 100644 (file)
@@ -316,6 +316,17 @@ class Foo {
     assert lookup
   }
 
+  void "test no autopopup at the end of line comment"() {
+    LiveTemplateCompletionContributor.setShowTemplatesInTests(true, getTestRootDisposable())
+    myFixture.configureByText "a.java", """
+class Foo {
+  // foo bar <caret>
+}
+"""
+    type 't'
+    assert !lookup
+  }
+
   void testPrefixLengthDependentSorting() {
     myFixture.addClass("package foo; public class PsiJavaCodeReferenceElement {}")
     myFixture.configureByText("a.java", """
index deed6daef5c9f8cd26ba74736d67c09ff69ed628..e49fb2e6f8458c18362d268eddd13178a54cf7e5 100644 (file)
@@ -525,6 +525,50 @@ public class VarArgTest {
     onLineStartingWith("check(t")
         .assertInlays("test->this", "endIndex->1000")
   }
+  
+  fun `test inline strange methods`() {
+    setup("""
+public class Test {
+  
+  void main() {
+    createContent(null);
+    createNewContent(this);
+  }
+
+  Content createContent(DockManager manager) {}
+  Content createNewContent(Test test) {}
+
+}
+interface DockManager {}
+interface Content {}
+""")
+
+    onLineStartingWith("createContent").assertInlays("manager->null")
+    onLineStartingWith("createNewContent").assertInlays("test->this")
+  }
+  
+  fun `test do not inline builder pattern`() {
+    setup("""
+class Builder {
+  void await(boolean value) {}
+  Builder bwait(boolean xvalue) {}
+  Builder timeWait(int time) {}
+}
+
+class Test {
+  
+  public void test() {
+    Builder builder = new Builder();
+    builder.await(true);
+    builder.bwait(false).timeWait(100);
+  }
+  
+}
+""")
+
+    onLineStartingWith("builder.await").assertInlays("value->true")
+    onLineStartingWith("builder.bwait").assertNoInlays()
+  }
 
   fun `test do not show single parameter hint if it is string literal`() {
     setup("""
@@ -578,17 +622,34 @@ class Test {
     drawRect(x, y, 10, 12);
   }
 
+  void blah(int a, int b) {}
   void draw(int x, int y, int z) {}
   void drawRect(int x, int y, int w, int h) {}
 
 }
 """)
     
-    onLineStartingWith("blah").assertNoInlays()
+    onLineStartingWith("blah").assertInlays("a->1", "b->2")
     onLineStartingWith("draw").assertInlays("x->10", "y->20")
     onLineStartingWith("drawRect").assertInlays("w->10", "h->12")
   }
   
+  fun `test show for method with boolean param and return value`() {
+    setup("""
+class Test {
+  
+  void test() {
+    String name = getTestName(true);
+    System.out.println("");
+  }
+  
+  String getTestName(boolean lowerCase) {}
+}
+""")
+    
+    onLineStartingWith("String name").assertInlays("lowerCase->true")
+  }
+  
   private fun getInlays(): List<Inlay> {
     val editor = myFixture.editor
     return editor.inlayModel.getInlineElementsInRange(0, editor.document.textLength)
index e7b0bcdba6f3b085d12071049b40bafc9aefe37d..c2ed1efcd3303bb0fe0671366163a58f8b252e43 100644 (file)
@@ -84,6 +84,10 @@ public class LambdaRedundantCastTest extends LightDaemonAnalyzerTestCase {
     doTest();
   }
 
+  public void testInvalidConditional() throws Exception {
+    doTest();
+  }
+
   private void doTest() {
     doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false);
   }
index c3828b3cf1e03b7a093cacc55cf993ceaf8b93c2..f7d84be36c6cdfff4358dd6d721d7a8170175192 100644 (file)
@@ -51,7 +51,11 @@ public class StreamPostfixTemplateTest extends PostfixTemplateTestCase {
   public void testSimple() {
     doTest();
   }
-  
+
+  public void testExpressionContext() {
+    doTest();
+  }
+
   public void testDoNotExpandOnJavaLess8() {
     LanguageLevelProjectExtension.getInstance(myFixture.getProject()).setLanguageLevel(LanguageLevel.JDK_1_6);
     doTest();
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/Java8CollectionRemoveIfInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/Java8CollectionRemoveIfInspectionTest.java
new file mode 100644 (file)
index 0000000..e6fb012
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
+import com.intellij.codeInspection.java18api.Java8CollectionRemoveIfInspection;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Tagir Valeev
+ */
+public class Java8CollectionRemoveIfInspectionTest extends LightQuickFixParameterizedTestCase {
+  @NotNull
+  @Override
+  protected LocalInspectionTool[] configureLocalInspectionTools() {
+    return new LocalInspectionTool[]{new Java8CollectionRemoveIfInspection()};
+  }
+
+  public void test() throws Exception {
+    doAllTests();
+  }
+
+  @Override
+  protected String getBasePath() {
+    return "/inspection/java8CollectionRemoveIf";
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/Java8ListSortInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/Java8ListSortInspectionTest.java
new file mode 100644 (file)
index 0000000..de8709f
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
+import com.intellij.codeInspection.java18api.Java8ListSortInspection;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Tagir Valeev
+ */
+public class Java8ListSortInspectionTest extends LightQuickFixParameterizedTestCase {
+  @NotNull
+  @Override
+  protected LocalInspectionTool[] configureLocalInspectionTools() {
+    return new LocalInspectionTool[]{new Java8ListSortInspection()};
+  }
+
+  public void test() throws Exception {
+    doAllTests();
+  }
+
+  @Override
+  protected String getBasePath() {
+    return "/inspection/java8ListSort";
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/Java8ReplaceMapGetInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/Java8ReplaceMapGetInspectionTest.java
new file mode 100644 (file)
index 0000000..ac5aba7
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
+import com.intellij.codeInspection.java18api.Java8ReplaceMapGetInspection;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Tagir Valeev
+ */
+public class Java8ReplaceMapGetInspectionTest extends LightQuickFixParameterizedTestCase {
+  @NotNull
+  @Override
+  protected LocalInspectionTool[] configureLocalInspectionTools() {
+    return new LocalInspectionTool[]{new Java8ReplaceMapGetInspection()};
+  }
+
+  public void test() throws Exception {
+    doAllTests();
+  }
+
+  @Override
+  protected String getBasePath() {
+    return "/inspection/java8MapGet";
+  }
+}
index 7e9bcf8e18e4bccbedb01aecb8d5317cc43d8009..731c4634351c00790bf8e1535bf58542499678e9 100644 (file)
  */
 package com.intellij.codeInspection;
 
-import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
 import com.intellij.codeInspection.redundantCast.RedundantCastInspection;
-import com.intellij.testFramework.InspectionTestCase;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
 
-public class RedundantCast18Test extends InspectionTestCase {
-  private void doTest() throws Exception {
-    final LocalInspectionToolWrapper tool = new LocalInspectionToolWrapper(new RedundantCastInspection());
-    doTest("redundantCast/lambda/" + getTestName(false), tool, "java 1.5");
+public class RedundantCast18Test extends LightDaemonAnalyzerTestCase {
+  @NonNls static final String BASE_PATH = "/inspection/redundantCast/lambda";
+
+  @NotNull
+  @Override
+  protected LocalInspectionTool[] configureLocalInspectionTools() {
+    return new LocalInspectionTool[]{
+      new RedundantCastInspection()
+    };
+  }
+
+  private void doTest() {
+    doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false);
   }
 
   public void testLambdaContext() throws Exception { doTest(); }
@@ -31,4 +41,5 @@ public class RedundantCast18Test extends InspectionTestCase {
   public void testForeachValue() throws Exception { doTest(); }
   public void testConditional() throws Exception { doTest(); }
   public void testInferApplicabilityError() throws Exception { doTest(); }
+  public void testCastToRawType() throws Exception { doTest(); }
 }
\ No newline at end of file
index 57bb07abd225877c8e4a61ee55883b3d68dd5b42..6559b6bb64479e8492c59c75d9ea123575d18991 100644 (file)
@@ -292,6 +292,10 @@ public class InlineLocalTest extends LightCodeInsightTestCase {
                  "Variable 'hello' is accessed for writing");
   }
 
+  public void testAvoidTypeSpecificationWhenPossibleToAvoid() throws Exception {
+    doTest(false);
+  }
+
   private void doTest(final boolean inlineDef, String conflictMessage) throws Exception {
     try {
       doTest(inlineDef);
index fcc4def0298b052905ac78d4fbd32b9c95387459..93d2f7a58262599ea3fd5a60daa922269b244b74 100644 (file)
@@ -77,12 +77,21 @@ public class ExternalProcessUtil {
     return buildJavaCommandLine(javaExecutable, mainClass, bootClasspath, classpath, vmParams, programParams, true);
   }
 
+  public static List<String> buildJavaCommandLine(String javaExecutable,
+                                                String mainClass,
+                                                List<String> bootClasspath,
+                                                List<String> classpath,
+                                                List<String> vmParams,
+                                                List<String> programParams, final boolean useCommandLineWrapper) {
+    return buildJavaCommandLine(javaExecutable, mainClass, bootClasspath, classpath, vmParams, programParams, useCommandLineWrapper, true);
+  }
+
   public static List<String> buildJavaCommandLine(String javaExecutable,
                                                   String mainClass,
                                                   List<String> bootClasspath,
                                                   List<String> classpath,
                                                   List<String> vmParams,
-                                                  List<String> programParams, final boolean useCommandLineWrapper) {
+                                                  List<String> programParams, final boolean useCommandLineWrapper, boolean useClasspathJar) {
     final List<String> cmdLine = new ArrayList<String>();
 
     cmdLine.add(javaExecutable);
@@ -102,11 +111,31 @@ public class ExternalProcessUtil {
         final Class wrapperClass = getCommandLineWrapperClass();
         if (wrapperClass != null) {
           try {
-            final String classpathFile = CommandLineWrapperUtil.createClasspathJarFile(new Manifest(), classpath).getAbsolutePath();
-            commandLineWrapperArgs = Arrays.asList(
-              "-classpath",
-              classpathFile
-            );
+            if (useClasspathJar) {
+              final String classpathFile = CommandLineWrapperUtil.createClasspathJarFile(new Manifest(), classpath).getAbsolutePath();
+              commandLineWrapperArgs = Arrays.asList(
+                "-classpath",
+                classpathFile
+              );
+            }
+            else {
+              File classpathFile = FileUtil.createTempFile("classpath", null);
+              final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(classpathFile)));
+              try {
+                for (String path : classpath) {
+                  writer.println(path);
+                }
+              }
+              finally {
+                writer.close();
+              }
+              commandLineWrapperArgs = Arrays.asList(
+                "-classpath",
+                ClasspathBootstrap.getResourcePath(wrapperClass),
+                wrapperClass.getName(),
+                classpathFile.getAbsolutePath()
+    &nbs