From 6c15e386c0a2118af2949286de2600a12d7d9f9e Mon Sep 17 00:00:00 2001 From: xzl Date: Tue, 23 Apr 2024 14:12:10 +0800 Subject: [PATCH] feat: update eclipse-jdt-ui to 4.26 Eclipse Java Code Manipulation Functionality Issue: https://github.com/deepin-community/sig-deepin-sysdev-team/issues/547 Log: update repo --- .gitignore | 1 - Jenkinsfile | 34 + README.md | 12 +- debian/build.xml | 6 +- debian/changelog | 20 + debian/control | 16 +- debian/copyright | 2 +- debian/watch | 2 +- org.eclipse.jdt.astview.feature/feature.xml | 8 +- org.eclipse.jdt.astview.feature/pom.xml | 4 +- org.eclipse.jdt.astview/META-INF/MANIFEST.MF | 3 +- org.eclipse.jdt.astview/pom.xml | 4 +- .../eclipse/jdt/astview/views/ASTView.java | 11 +- .../.settings/.api_filters | 58 + .../META-INF/MANIFEST.MF | 15 +- .../manipulation/CodeStyleConfiguration.java | 1 - .../core/manipulation/CoreASTProvider.java | 24 + .../OrganizeImportsOperation.java | 24 +- .../manipulation/SharedASTProviderCore.java | 2 +- .../jdt/internal/common/ASTProcessor.java | 2469 +++++ .../jdt/internal/common/HelperVisitor.java | 8988 +++++++++++++++++ .../common/HelperVisitorProvider.java | 34 + .../jdt/internal/common/LambdaASTVisitor.java | 1826 ++++ .../jdt/internal/common/ReferenceHolder.java | 74 + .../jdt/internal/common/VisitorEnum.java | 593 ++ .../manipulation/JavaManipulationPlugin.java | 7 + ...nstantsForSystemPropertiesCleanUpCore.java | 54 +- .../jdt/internal/ui/fix/MultiFixMessages.java | 7 +- .../ui/fix/MultiFixMessages.properties | 10 +- .../StringConcatToTextBlockCleanUpCore.java | 86 + .../internal/ui/fix/SubstringCleanUpCore.java | 146 + .../ui/fix/UnnecessaryCodeCleanUpCore.java | 10 +- .../ui/fix/UnusedCodeCleanUpCore.java | 50 +- .../formatter/ProfileVersionerCore.java | 17 +- .../text/correction/CorrectionMessages.java | 24 +- .../correction/CorrectionMessages.properties | 24 +- .../correction/QuickAssistProcessorUtil.java | 492 + .../jdt/internal/ui/util/ASTHelper.java | 23 +- .../dom/NecessaryParenthesesChecker.java | 12 +- .../manipulation/dom/OperatorPrecedence.java | 5 +- .../search/BreakContinueTargetFinder.java | 8 +- .../search/ExceptionOccurrencesFinder.java | 5 +- .../search/ImplementOccurrencesFinder.java | 8 +- .../search/MethodExitsFinder.java | 5 +- .../manipulation/search/SearchMessages.java | 33 +- .../search/SearchMessages.properties | 38 +- .../callhierarchy/CallHierarchyCore.java | 7 +- .../CallSearchResultCollector.java | 12 +- .../callhierarchy/CalleeAnalyzerVisitor.java | 66 +- .../callhierarchy/CalleeMethodWrapper.java | 2 +- .../callhierarchy/CallerMethodWrapper.java | 4 +- .../corext/callhierarchy/Implementors.java | 9 +- .../corext/callhierarchy/MethodCall.java | 37 +- .../corext/callhierarchy/MethodWrapper.java | 16 + .../codemanipulation/StubUtility2Core.java | 201 +- .../jdt/internal/corext/dom/ASTFlattener.java | 150 +- .../internal/corext/dom/ASTNodeFactory.java | 111 +- .../jdt/internal/corext/dom/ASTNodes.java | 344 +- .../jdt/internal/corext/dom/Bindings.java | 48 +- .../corext/dom/HierarchicalASTVisitor.java | 109 +- .../internal/corext/dom/LinkedNodeFinder.java | 101 +- .../jdt/internal/corext/dom/TokenScanner.java | 2 - .../corext/dom/TypeAnnotationRewrite.java | 6 +- ...{AbstractFix.java => AbstractFixCore.java} | 4 +- ...tractPrimitiveRatherThanWrapperFinder.java | 8 + .../AbstractSerialVersionOperationCore.java | 2 +- .../fix/AddUnimplementedMethodsOperation.java | 18 +- .../corext/fix/ArrayWithCurlyFixCore.java | 18 +- .../internal/corext/fix/CleanUpConstants.java | 48 +- .../internal/corext/fix/CodeStyleFixCore.java | 17 +- ...mpilationUnitRewriteOperationsFixCore.java | 2 +- .../corext/fix/ConvertForLoopOperation.java | 2 +- .../fix/ConvertIterableLoopOperation.java | 11 +- .../fix/DoWhileRatherThanWhileFixCore.java | 10 + .../jdt/internal/corext/fix/FixMessages.java | 3 + .../corext/fix/FixMessages.properties | 3 + .../internal/corext/fix/Java50FixCore.java | 61 +- .../corext/fix/LambdaExpressionsFixCore.java | 28 +- .../internal/corext/fix/LibStandardNames.java | 5 + .../PrimitiveCharRatherThanWrapperFinder.java | 4 +- .../corext/fix/SealedClassFixCore.java | 306 + .../StringBufferToStringBuilderFixCore.java | 6 +- .../fix/StringConcatToTextBlockFixCore.java | 333 + .../corext/fix/SwitchExpressionsFixCore.java | 488 +- .../internal/corext/fix/SwitchFixCore.java | 55 +- .../corext/fix/TypeParametersFixCore.java | 2 +- .../corext/fix/UnimplementedCodeFixCore.java | 4 +- .../corext/fix/UnusedCodeFixCore.java | 342 +- .../internal/corext/fix/UpdateProperty.java | 187 +- .../fix/UseIteratorToForLoopFixCore.java | 82 + ...ValueOfRatherThanInstantiationFixCore.java | 42 +- .../corext/fix/helper/AbstractTool.java | 77 + .../fix/helper/WhileLoopToChangeHit.java | 44 + .../corext/fix/helper/WhileToForEach.java | 535 + .../refactoring/RefactoringCoreMessages.java | 9 +- .../refactoring/RefactoringScopeFactory.java | 22 + .../refactoring/RefactoringSearchEngine2.java | 7 +- .../changes/DynamicValidationStateChange.java | 6 + .../corext/refactoring/code/CallInliner.java | 65 +- .../ConvertAnonymousToNestedRefactoring.java | 84 +- .../code/InlineConstantRefactoring.java | 6 +- .../code/InlineTempRefactoring.java | 295 +- .../refactoring/code/SourceProvider.java | 64 +- .../refactoring/code/TargetProvider.java | 1 + .../generics/ElementStructureEnvironment.java | 0 .../InferTypeArgumentsConstraintCreator.java | 0 .../InferTypeArgumentsConstraintsSolver.java | 0 .../InferTypeArgumentsRefactoring.java | 24 +- .../generics/InferTypeArgumentsTCModel.java | 17 +- .../generics/InferTypeArgumentsUpdate.java | 0 .../generics/ParametricStructureComputer.java | 0 .../corext/refactoring/refactoring.properties | 5 +- .../refactoring/rename/MethodChecks.java | 13 +- .../structure/ConstructorReferenceFinder.java | 3 + .../refactoring/structure/ImportRemover.java | 29 +- .../structure/MemberVisibilityAdjustor.java | 6 +- .../structure/MoveInnerToTopRefactoring.java | 6 +- .../MoveInstanceMethodProcessor.java | 3 + .../structure/MoveStaticMembersProcessor.java | 6 +- .../surround/ExceptionAnalyzer.java | 10 +- .../SurroundWithTryWithResourcesAnalyzer.java | 39 +- ...ndWithTryWithResourcesRefactoringCore.java | 683 ++ .../typeconstraints/ASTCreator.java | 0 .../typeconstraints/CompilationUnitRange.java | 0 .../CompositeOrTypeConstraint.java | 0 .../typeconstraints/ConstraintCollector.java | 0 .../typeconstraints/ConstraintCreator.java | 0 .../typeconstraints/ConstraintOperator.java | 0 .../typeconstraints/ConstraintVariable.java | 0 .../ConstraintVariableFactory.java | 0 .../DeclaringTypeVariable.java | 0 .../typeconstraints/ExpressionVariable.java | 0 .../FullConstraintCreator.java | 0 .../IConstraintVariableFactory.java | 0 .../refactoring/typeconstraints/IContext.java | 0 .../typeconstraints/ITypeConstraint.java | 0 .../ITypeConstraintFactory.java | 0 .../typeconstraints/NullContext.java | 0 .../ParameterTypeVariable.java | 0 .../typeconstraints/RawBindingVariable.java | 0 .../typeconstraints/ReturnTypeVariable.java | 0 .../typeconstraints/SimpleTypeConstraint.java | 0 .../TypeConstraintFactory.java | 0 .../typeconstraints/TypeVariable.java | 0 .../typesets/ArraySuperTypeSet.java | 0 .../typesets/ArrayTypeSet.java | 0 .../typesets/EmptyTypeSet.java | 0 .../typesets/EnumeratedTypeSet.java | 0 .../typesets/SingletonTypeSet.java | 0 .../typesets/SubTypesOfSingleton.java | 0 .../typeconstraints/typesets/SubTypesSet.java | 0 .../typesets/SuperTypesOfSingleton.java | 0 .../typesets/SuperTypesSet.java | 0 .../typeconstraints/typesets/TypeSet.java | 0 .../typesets/TypeSetEnvironment.java | 0 .../typesets/TypeSetIntersection.java | 0 .../typesets/TypeSetUnion.java | 0 .../typesets/TypeUniverseSet.java | 0 .../ArrayElementVariable2.java | 0 .../typeconstraints2/ArrayTypeVariable2.java | 0 .../typeconstraints2/CastVariable2.java | 0 .../CollectionElementVariable2.java | 0 .../typeconstraints2/ConstraintVariable2.java | 0 .../ISourceConstraintVariable.java | 0 .../typeconstraints2/ITypeConstraint2.java | 0 .../ITypeConstraintVariable.java | 0 .../typeconstraints2/ITypeSet.java | 0 .../ImmutableTypeVariable2.java | 0 .../IndependentTypeVariable2.java | 0 .../ParameterTypeVariable2.java | 0 .../ParameterizedTypeVariable2.java | 0 .../typeconstraints2/ReturnTypeVariable2.java | 0 .../typeconstraints2/SubTypeConstraint2.java | 0 .../refactoring/typeconstraints2/TTypes.java | 0 .../typeconstraints2/TypeEquivalenceSet.java | 0 .../typeconstraints2/TypeVariable2.java | 0 .../typeconstraints2/VariableVariable2.java | 0 .../util/AbstractExceptionAnalyzer.java | 0 .../internal/corext/util/JavaModelUtil.java | 61 +- .../corext/util/MethodOverrideTester.java | 64 +- .../fix/UseIteratorToForLoopCleanUpCore.java | 106 + org.eclipse.jdt.core.manipulation/pom.xml | 6 +- org.eclipse.jdt.jeview.feature/feature.xml | 10 +- org.eclipse.jdt.jeview.feature/pom.xml | 4 +- org.eclipse.jdt.jeview/META-INF/MANIFEST.MF | 3 +- org.eclipse.jdt.jeview/pom.xml | 4 +- .../META-INF/MANIFEST.MF | 4 +- org.eclipse.jdt.junit.core/pom.xml | 4 +- .../jdt/internal/junit/JUnitCorePlugin.java | 3 +- .../junit/JUnitPreferencesConstants.java | 17 +- .../junit/JunitPreferenceInitializer.java | 9 +- .../junit/buildpath/BuildPathSupport.java | 62 +- .../buildpath/JUnitContainerInitializer.java | 28 +- .../junit/launcher/JUnit4TestFinder.java | 25 +- .../junit/launcher/JUnit5TestFinder.java | 61 +- .../junit/util/CoreTestSearchEngine.java | 7 +- .../JUnitLaunchConfigurationDelegate.java | 26 +- org.eclipse.jdt.junit.runtime/.classpath | 6 +- .../.settings/org.eclipse.jdt.core.prefs | 4 +- .../META-INF/MANIFEST.MF | 4 +- .../build.properties | 1 + org.eclipse.jdt.junit.runtime/pom.xml | 15 +- org.eclipse.jdt.junit/META-INF/MANIFEST.MF | 6 +- .../forceQualifierUpdate.txt | 3 +- .../icons/full/elcl16/alphab_sort_co.png | Bin 0 -> 317 bytes .../icons/full/elcl16/alphab_sort_co@2x.png | Bin 0 -> 490 bytes .../icons/full/elcl16/collapseall.png | Bin 0 -> 480 bytes .../icons/full/elcl16/collapseall@2x.png | Bin 0 -> 1049 bytes .../icons/full/elcl16/expandall.png | Bin 0 -> 479 bytes .../icons/full/elcl16/expandall@2x.png | Bin 0 -> 1078 bytes .../icons/full/elcl16/goto_input.png | Bin 0 -> 437 bytes .../icons/full/elcl16/goto_input@2x.png | Bin 0 -> 870 bytes .../icons/full/elcl16/rem_all_co.png | Bin 0 -> 727 bytes .../icons/full/elcl16/rem_all_co@2x.png | Bin 0 -> 1615 bytes .../icons/full/etool16/debug_exc.png | Bin 0 -> 563 bytes .../icons/full/etool16/debug_exc@2x.png | Bin 0 -> 1453 bytes .../icons/full/etool16/export_wiz.png | Bin 0 -> 346 bytes .../icons/full/etool16/export_wiz@2x.png | Bin 0 -> 772 bytes .../icons/full/etool16/import_wiz.png | Bin 0 -> 351 bytes .../icons/full/etool16/import_wiz@2x.png | Bin 0 -> 695 bytes .../icons/full/etool16/run_exc.png | Bin 0 -> 620 bytes .../icons/full/etool16/run_exc@2x.png | Bin 0 -> 1226 bytes .../full/obj16/stckframe_running_obj.png | Bin 0 -> 281 bytes .../full/obj16/stckframe_running_obj@2x.png | Bin 0 -> 614 bytes .../icons/full/obj16/time_obj.png | Bin 0 -> 441 bytes .../icons/full/obj16/time_obj@2x.png | Bin 0 -> 936 bytes org.eclipse.jdt.junit/pom.xml | 4 +- .../junit/ui/CopyFailureListAction.java | 6 +- .../internal/junit/ui/JUnitCopyAction.java | 6 +- .../jdt/internal/junit/ui/JUnitPlugin.java | 3 +- .../junit/ui/JUnitPreferencePage.java | 668 +- .../internal/junit/ui/OpenEditorAction.java | 1 + .../jdt/internal/junit/ui/OpenTestAction.java | 1 + .../jdt/internal/junit/ui/RerunAction.java | 7 + .../junit/ui/TestMethodSelectionDialog.java | 3 + .../internal/junit/ui/TestRunnerViewPart.java | 19 +- .../jdt/internal/junit/ui/TestViewer.java | 4 +- .../internal/junit/util/TestSearchEngine.java | 4 +- .../wizards/SuiteClassesContentProvider.java | 25 +- .../junit/wizards/UpdateTestSuite.java | 69 +- .../junit/wizards/WizardMessages.java | 6 +- .../junit/wizards/WizardMessages.properties | 9 +- .../launcher/JUnitLaunchConfigurationTab.java | 8 +- .../junit/launcher/JUnitLaunchShortcut.java | 85 +- .../wizards/NewTestCaseWizardPageOne.java | 4 +- .../junit/wizards/NewTestSuiteWizardPage.java | 153 +- org.eclipse.jdt.junit4.runtime/.classpath | 6 +- .../.settings/org.eclipse.jdt.core.prefs | 4 +- .../META-INF/MANIFEST.MF | 4 +- .../build.properties | 1 + org.eclipse.jdt.junit4.runtime/pom.xml | 15 +- org.eclipse.jdt.junit5.runtime/.classpath | 6 +- .../.settings/org.eclipse.jdt.core.prefs | 1 + .../META-INF/MANIFEST.MF | 28 +- .../build.properties | 1 + org.eclipse.jdt.junit5.runtime/pom.xml | 15 +- .../runner/FailuresFirstMethodOrderer.java | 83 + .../junit5/runner/JUnit5TestListener.java | 17 +- .../junit5/runner/JUnit5TestLoader.java | 24 +- .../META-INF/MANIFEST.MF | 6 +- org.eclipse.jdt.text.tests/pom.xml | 4 +- .../tests/BreakContinueTargetFinderTest.java | 5 +- .../EnumConstructorTargetFinderTest.java | 106 +- .../jdt/text/tests/IndentActionTest15.java | 184 + .../JavaStringDoubleClickStrategyTest.java | 263 + .../jdt/text/tests/JdtTextTestSuite.java | 1 + .../jdt/text/tests/MarkOccurrenceTest1d7.java | 6 +- .../jdt/text/tests/MarkOccurrenceTest1d8.java | 6 +- .../jdt/text/tests/PluginsNotLoadedTest.java | 10 +- .../ParameterNamesCodeMiningTest.java | 43 +- .../contentassist/CodeCompletionTest1d8.java | 214 + .../tests/performance/EditorTestHelper.java | 22 +- .../spelling/SpellCheckEngineTestCase.java | 3 +- .../templates/TemplateCompletionTests.java | 12 +- .../indentation15/issue30_1/Before.java | 10 + .../indentation15/issue30_1/Modified.java | 10 + .../indentation15/issue30_2/Before.java | 11 + .../indentation15/issue30_2/Modified.java | 11 + .../indentation15/issue30_3/Before.java | 10 + .../indentation15/issue30_3/Modified.java | 10 + .../indentation15/issue30_4/Before.java | 10 + .../indentation15/issue30_4/Modified.java | 10 + org.eclipse.jdt.ui.examples.projects/pom.xml | 2 +- .../pom.xml | 2 +- .../META-INF/MANIFEST.MF | 2 +- org.eclipse.jdt.ui.tests.refactoring/pom.xml | 4 +- .../canConvert/A_testTypeParameters1_in.java | 14 + .../canConvert/A_testTypeParameters1_out.java | 16 + .../error_out/A_test804.java | 4 +- .../lambdaExpression18_in/A_test328.java | 16 + .../lambdaExpression18_in/A_test329.java | 17 + .../lambdaExpression18_out/A_test328.java | 18 + .../lambdaExpression18_out/A_test329.java | 18 + .../semicolon_out/A_test402.java | 4 +- .../ExtractTemp/canExtract/A_test118_in.java | 12 + .../ExtractTemp/canExtract/A_test118_out.java | 13 + .../ExtractTemp/canExtract/A_test119_in.java | 10 + .../ExtractTemp/canExtract/A_test119_out.java | 10 + .../ExtractTemp/canExtract/A_test120_in.java | 14 + .../ExtractTemp/canExtract/A_test120_out.java | 17 + .../ExtractTemp/canExtract/A_test121_in.java | 11 + .../ExtractTemp/canExtract/A_test121_out.java | 13 + .../ExtractTemp/canExtract/A_test122_in.java | 7 + .../ExtractTemp/canExtract/A_test122_out.java | 7 + .../ExtractTemp/canExtract/A_test123_in.java | 12 + .../ExtractTemp/canExtract/A_test123_out.java | 13 + .../ExtractTemp/canExtract/A_test124_in.java | 14 + .../ExtractTemp/canExtract/A_test124_out.java | 16 + .../ExtractTemp/canExtract/A_test125_in.java | 16 + .../ExtractTemp/canExtract/A_test125_out.java | 18 + .../testCuWithLocalClass1/in/A.java | 12 + .../testCuWithLocalClass1/out/A.java | 12 + .../testCuWithLocalClass2/in/A.java | 12 + .../testCuWithLocalClass2/out/A.java | 12 + .../TestCases/bugs_in/Test_462038.java | 16 + .../TestCases/bugs_out/Test_462038.java | 16 + .../TestCases/enum_in/Test_138952.java | 22 + .../TestCases/enum_out/Test_138952.java | 27 + .../simple14_in/TestSwitchExpression1.java | 16 + .../simple14_in/TestSwitchExpression2.java | 16 + .../simple14_in/TestSwitchExpression3.java | 22 + .../simple14_in/TestSwitchExpression4.java | 22 + .../simple14_out/TestSwitchExpression1.java | 19 + .../simple14_out/TestSwitchExpression2.java | 19 + .../simple14_out/TestSwitchExpression3.java | 31 + .../simple14_out/TestSwitchExpression4.java | 31 + .../InlineTemp/canInline/A_test53_in.java | 16 + .../InlineTemp/canInline/A_test53_out.java | 15 + .../InlineTemp/canInline/A_test54_in.java | 11 + .../InlineTemp/canInline/A_test54_out.java | 10 + .../InlineTemp/canInline/A_test55_in.java | 19 + .../InlineTemp/canInline/A_test55_out.java | 18 + .../InlineTemp/canInline/A_test56_in.java | 17 + .../InlineTemp/canInline/A_test56_out.java | 16 + .../InlineTemp/canInline/A_test57_in.java | 20 + .../InlineTemp/canInline/A_test57_out.java | 18 + .../InlineTemp/canInline/A_test58_in.java | 19 + .../InlineTemp/canInline/A_test58_out.java | 17 + .../InlineTemp/canInline/A_test59_in.java | 21 + .../InlineTemp/canInline/A_test59_out.java | 20 + .../InlineTemp/canInline/A_test60_in.java | 15 + .../InlineTemp/canInline/A_test60_out.java | 14 + .../InlineTemp/canInline/A_test61_in.java | 14 + .../InlineTemp/canInline/A_test61_out.java | 13 + .../InlineTemp/canInline/A_test62_in.java | 18 + .../InlineTemp/canInline/A_test62_out.java | 17 + .../InlineTemp/canInline/A_test63_in.java | 19 + .../InlineTemp/canInline/A_test63_out.java | 18 + .../InlineTemp/canInline/A_test64_in.java | 11 + .../InlineTemp/canInline/A_test64_out.java | 10 + .../InlineTemp/cannotInline/A_testFail15.java | 18 + .../PullUp/testFieldMethod5/in/p/A.java | 10 + .../PullUp/testFieldMethod5/in/p/C.java | 4 + .../PullUp/testFieldMethod5/in/q/Asuper.java | 7 + .../PullUp/testFieldMethod5/in/q/C.java | 4 + .../PullUp/testFieldMethod5/out/p/A.java | 6 + .../PullUp/testFieldMethod5/out/p/C.java | 4 + .../PullUp/testFieldMethod5/out/q/Asuper.java | 11 + .../PullUp/testFieldMethod5/out/q/C.java | 4 + .../test41/in/A.java | 16 + .../test41/out/A.java | 16 + .../test42/in/A.java | 16 + .../test42/out/A.java | 16 + .../test43/in/A.java | 20 + .../test43/out/A.java | 20 + .../test44/in/A.java | 20 + .../test44/out/A.java | 20 + .../test45/in/A.java | 20 + .../test45/out/A.java | 20 + .../test46/in/A.java | 10 + .../test46/out/A.java | 10 + .../test47/in/A.java | 10 + .../test47/out/A.java | 10 + .../test48/in/A.java | 10 + .../test48/out/A.java | 10 + .../test49/in/A.java | 12 + .../test49/out/A.java | 12 + .../trycatch16_in/TestBug566949_1.java | 13 + .../trycatch16_in/TestBug566949_2.java | 15 + .../trycatch16_out/TestBug566949_1.java | 16 + .../trycatch16_out/TestBug566949_2.java | 18 + .../tryresources18_in/TestAnonymous1.java | 20 + .../tryresources18_in/TestSimple5.java | 16 + .../tryresources18_in/TestTry1.java | 16 + .../tryresources18_in/TestTry2.java | 17 + .../tryresources18_out/TestAnonymous1.java | 21 + .../tryresources18_out/TestSimple5.java | 17 + .../tryresources18_out/TestTry1.java | 17 + .../tryresources18_out/TestTry2.java | 22 + .../tryresources18_out/TestWithThrows3.java | 10 +- .../test0_/in/A.java | 22 + .../test0_/out/A.java | 22 + .../test1_/in/A.java | 22 + .../test1_/out/A.java | 22 + .../refactoring/AllRefactoringTests.java | 4 +- .../jdt/ui/tests/refactoring/AllTests.java | 4 +- .../ConvertAnonymousToNestedTests9.java | 49 + .../refactoring/ExtractMethodTests1d8.java | 10 + .../tests/refactoring/ExtractTempTests.java | 49 + .../refactoring/InferTypeArgumentsTests.java | 12 + .../tests/refactoring/InlineMethodTests.java | 12 +- .../refactoring/InlineMethodTests16.java | 20 + .../ui/tests/refactoring/InlineTempTests.java | 65 + .../refactoring/InlineTempTests.java.orig | 508 + .../jdt/ui/tests/refactoring/PullUpTests.java | 7 +- .../RenameVirtualMethodInClassTests.java | 48 +- .../SurroundWithResourcesTests1d8.java | 10 + .../refactoring/SurroundWithTestSetup16.java | 85 + .../refactoring/SurroundWithTests16.java | 71 + .../UseSupertypeWherePossibleTests16.java | 114 + org.eclipse.jdt.ui.tests/META-INF/MANIFEST.MF | 7 +- .../MyClasspathContainerInitializer.java | 19 +- .../leaktest/reftracker/ReferenceTracker.java | 2 +- .../performance/views/CleanUpPerfTest.java | 6 +- org.eclipse.jdt.ui.tests/pom.xml | 9 +- .../jdt/testplugin/JavaProjectHelper.java | 35 +- .../jdt/testplugin/util/DisplayHelper.java | 2 +- org.eclipse.jdt.ui.tests/test.xml | 309 +- .../internal/common/ExpectationTracer.java | 70 + .../jdt/internal/common/NodeFound.java | 18 + .../jdt/internal/common/VisitorTest.java | 625 ++ .../junit/tests/JUnit4TestFinderTest16.java | 122 + .../jdt/junit/tests/JUnitJUnitTests.java | 3 +- .../jdt/junit/tests/TestTestSearchEngine.java | 77 +- .../eclipse/jdt/ui/tests/AutomatedSuite.java | 2 + .../CallHierarchyContentProviderTest.java | 109 +- .../CallHierarchyTestHelper.java | 377 +- .../jdt/ui/tests/core/AddImportTest.java | 51 + .../ui/tests/core/BindingsHierarchyTest.java | 108 + .../jdt/ui/tests/core/CallHierarchyTest.java | 61 +- .../jdt/ui/tests/core/CoreTestSuite.java | 1 + .../core/HierarchicalASTVisitorTest.java | 58 +- .../jdt/ui/tests/core/ImportOrganizeTest.java | 41 + .../jdt/ui/tests/core/TypeInfoTest.java | 84 +- .../core/rules/Java17ProjectTestSetup.java | 79 + .../core/rules/Java1d8ProjectTestSetup.java | 5 +- .../AddUnimplementedMethodsTest1d8.java | 26 +- .../jdt/ui/tests/hover/JavadocHoverTests.java | 93 +- .../ui/tests/hover/PackageJavadocTests.java | 2 +- .../packageview/ContentProviderTests1.java | 10 +- .../packageview/ContentProviderTests2.java | 10 +- .../packageview/ContentProviderTests3.java | 10 +- .../packageview/ContentProviderTests4.java | 10 +- .../packageview/ContentProviderTests5.java | 13 +- .../tests/quickfix/AnnotateAssistTest1d8.java | 179 + .../ui/tests/quickfix/AssistQuickFixTest.java | 353 +- .../tests/quickfix/AssistQuickFixTest15.java | 398 + .../tests/quickfix/AssistQuickFixTest1d8.java | 270 +- .../ui/tests/quickfix/CleanUpStressTest.java | 23 +- .../jdt/ui/tests/quickfix/CleanUpTest.java | 1510 ++- .../jdt/ui/tests/quickfix/CleanUpTest10.java | 26 +- .../jdt/ui/tests/quickfix/CleanUpTest12.java | 94 +- .../jdt/ui/tests/quickfix/CleanUpTest14.java | 419 +- .../jdt/ui/tests/quickfix/CleanUpTest15.java | 156 + .../jdt/ui/tests/quickfix/CleanUpTest16.java | 28 + .../jdt/ui/tests/quickfix/CleanUpTest1d5.java | 249 +- .../jdt/ui/tests/quickfix/CleanUpTest1d6.java | 7 +- .../jdt/ui/tests/quickfix/CleanUpTest1d7.java | 35 + .../jdt/ui/tests/quickfix/CleanUpTest1d8.java | 1413 ++- .../tests/quickfix/CleanUpTestCaseSuite.java | 3 +- .../LocalCorrectionsQuickFixTest.java | 120 +- .../LocalCorrectionsQuickFixTest1d8.java | 200 +- .../ModifierCorrectionsQuickFixTest.java | 52 +- .../NullAnnotationsCleanUpTest1d8.java | 2 +- .../quickfix/NullAnnotationsQuickFixTest.java | 2 +- .../NullAnnotationsQuickFixTest1d8.java | 38 +- .../NullAnnotationsQuickFixTest1d8Mix.java | 2 +- .../jdt/ui/tests/quickfix/QuickFixTest.java | 14 + .../jdt/ui/tests/quickfix/QuickFixTest17.java | 675 ++ .../ui/tests/quickfix/QuickFixTest1d8.java | 148 +- .../tests/quickfix/QuickFixTestPreview.java | 564 +- .../ui/tests/quickfix/QuickFixTestSuite.java | 6 +- .../quickfix/TypeMismatchQuickFixTests.java | 6 +- .../UnresolvedMethodsQuickFixTest16.java | 121 + .../UnresolvedMethodsQuickFixTest1d8.java | 208 +- .../quickfix/UnresolvedTypesQuickFixTest.java | 31 + .../ui/tests/wizardapi/NewTypeWizardTest.java | 55 + .../tests/wizardapi/NewTypeWizardTest17.java | 1424 +++ .../feature.xml | 4 +- .../pom.xml | 4 +- .../META-INF/MANIFEST.MF | 6 +- org.eclipse.jdt.ui.unittest.junit/pom.xml | 4 +- .../JUnitLaunchConfigurationDelegate.java | 30 +- .../launcher/JUnitLaunchConfigurationTab.java | 8 +- .../junit/launcher/JUnitLaunchShortcut.java | 75 +- org.eclipse.jdt.ui/.settings/.api_filters | 37 +- org.eclipse.jdt.ui/META-INF/MANIFEST.MF | 25 +- .../corext/callhierarchy/CallHierarchy.java | 2 +- .../codemanipulation/AddImportsOperation.java | 92 +- .../AddUnimplementedMethodsOperation.java | 2 +- .../corext/codemanipulation/StubUtility2.java | 4 +- .../corext/fix/CleanUpConstantsOptions.java | 12 +- .../jdt/internal/corext/fix/CodeStyleFix.java | 89 +- .../corext/fix/ControlStatementsFix.java | 76 +- .../internal/corext/fix/ConvertLoopFix.java | 83 - .../corext/fix/DoWhileRatherThanWhileFix.java | 51 - ...ExternalNullAnnotationChangeProposals.java | 18 +- .../corext/fix/LambdaExpressionsFix.java | 95 - .../fix/PotentialProgrammingProblemsFix.java | 104 +- .../corext/fix/SwitchExpressionsFix.java | 60 - .../corext/fix/TypeParametersFix.java | 144 - .../corext/fix/UnimplementedCodeFix.java | 203 - .../fix/UnnecessaryArrayCreationFix.java | 232 +- .../internal/corext/fix/UnusedCodeFix.java | 169 +- .../corext/fix/VariableDeclarationFix.java | 82 - .../corext/javadoc/JavaDocLocations.java | 88 +- .../internal/corext/util/TypeInfoFilter.java | 116 +- .../RefactoringAvailabilityTester.java | 3 +- .../code/ExtractMethodAnalyzer.java | 2 +- .../code/ExtractMethodRefactoring.java | 23 +- .../code/ExtractTempRefactoring.java | 323 +- .../code/IntroduceFactoryRefactoring.java | 11 +- .../code/IntroduceIndirectionRefactoring.java | 21 +- .../corext/refactoring/nls/NLSHintHelper.java | 9 +- .../rename/RefactoringScanner.java | 11 +- .../rename/RenameFieldProcessor.java | 21 +- .../rename/RenameMethodProcessor.java | 5 +- .../rename/RenameModuleProcessor.java | 9 +- .../rename/RenamePackageProcessor.java | 7 +- .../rename/RenameTypeProcessor.java | 4 + .../rename/RenameVirtualMethodProcessor.java | 11 +- .../rename/RippleMethodFinder2.java | 112 +- .../CreateCopyOfCompilationUnitChange.java | 8 +- .../reorg/MoveCuUpdateCreator.java | 16 +- .../sef/SelfEncapsulateFieldRefactoring.java | 84 +- .../structure/ChangeSignatureProcessor.java | 6 + .../structure/ChangeTypeRefactoring.java | 4 + .../structure/ExtractSupertypeProcessor.java | 4 +- .../structure/HierarchyProcessor.java | 6 +- .../structure/ParameterObjectFactory.java | 17 +- .../structure/PullUpRefactoringProcessor.java | 55 + .../PushDownRefactoringProcessor.java | 10 +- .../SuperTypeConstraintsCreator.java | 6 +- .../SuperTypeRefactoringProcessor.java | 6 +- .../SurroundWithTryCatchAnalyzer.java | 47 +- .../SurroundWithTryCatchRefactoring.java | 115 +- ...rroundWithTryWithResourcesRefactoring.java | 650 +- .../corext/refactoring/util/NullChecker.java | 230 + .../dictionaries/en_GB.dictionary | 246 +- .../dictionaries/en_US.dictionary | 243 + org.eclipse.jdt.ui/forceQualifierUpdate.txt | 6 +- org.eclipse.jdt.ui/plugin.xml | 24 +- org.eclipse.jdt.ui/pom.xml | 6 +- org.eclipse.jdt.ui/preview/formatter.java | 64 +- .../templates/default-postfixtemplates.xml | 8 +- .../JavaPrecomputedNamesAssistProcessor.java | 4 + .../nls/search/NLSSearchQuery.java | 5 +- .../ui/refactoring/reorg/PasteAction.java | 9 +- .../refactoring/reorg/RenameLinkedMode.java | 74 +- .../RenameMethodUserInterfaceStarter.java | 1 - .../reorg/RenameUserInterfaceManager.java | 3 +- .../ui/JavaElementAdapterFactory.java | 19 +- .../eclipse/jdt/internal/ui/JavaPlugin.java | 361 +- .../actions/AddGetterSetterTypeProposal.java | 79 + .../internal/ui/actions/CleanUpAction.java | 11 +- .../actions/HashCodeEqualsTypeProposal.java | 79 + .../jdt/internal/ui/actions/IndentAction.java | 86 +- .../ui/actions/SelectionConverter.java | 16 +- .../ui/actions/ToStringTypeProposal.java | 79 + .../CallHierarchyContentProvider.java | 10 +- .../CallHierarchyLabelProvider.java | 51 +- .../callhierarchy/CallHierarchyMessages.java | 2 + .../CallHierarchyMessages.properties | 2 + .../ui/dialogs/OpenTypeSelectionDialog.java | 52 + .../jdt/internal/ui/filtertable/Filter.java | 64 + .../ui/filtertable/FilterLabelProvider.java | 69 + .../ui/filtertable/FilterManager.java | 126 + .../filtertable/FilterViewerComparator.java | 54 + .../ui/filtertable/JavaFilterTable.java | 629 ++ .../internal/ui/filtertable/SWTFactory.java | 126 + .../TypeFilterInputDialog.java | 18 +- .../ui/fix/AbstractCleanUpCoreWrapper.java | 81 + .../ui/fix/AbstractMultiFixCoreWrapper.java | 46 + .../ui/fix/ArrayWithCurlyCleanUp.java | 45 +- .../internal/ui/fix/AutoboxingCleanUp.java | 90 +- ...oleanValueRatherThanComparisonCleanUp.java | 44 +- .../internal/ui/fix/CleanUpFixWrapper.java | 23 + .../ui/fix/CleanUpSelectionDialog.java | 23 + .../jdt/internal/ui/fix/CodeStyleCleanUp.java | 86 +- .../ConstantsForSystemPropertyCleanUp.java | 45 +- .../internal/ui/fix/ConvertLoopCleanUp.java | 7 +- .../ui/fix/DoWhileRatherThanWhileCleanUp.java | 44 +- .../internal/ui/fix/InvertEqualsCleanUp.java | 43 +- .../jdt/internal/ui/fix/Java50CleanUp.java | 35 +- .../jdt/internal/ui/fix/JoinCleanUp.java | 48 +- .../LambdaExpressionAndMethodRefCleanUp.java | 13 +- .../ui/fix/LambdaExpressionsCleanUp.java | 48 +- ...DuplicateBlocksThatFallThroughCleanUp.java | 45 +- .../ui/fix/OperandFactorizationCleanUp.java | 154 +- .../ui/fix/OverriddenAssignmentCleanUp.java | 284 +- .../PatternMatchingForInstanceofCleanUp.java | 44 +- .../ui/fix/PlainReplacementCleanUp.java | 43 +- .../PotentialProgrammingProblemsCleanUp.java | 93 +- .../ui/fix/PrimitiveComparisonCleanUp.java | 44 +- .../PrimitiveRatherThanWrapperCleanUp.java | 46 +- .../ui/fix/PullOutIfFromIfElseCleanUp.java | 46 +- .../ui/fix/ReduceIndentationCleanUp.java | 11 +- .../ui/fix/RedundantComparatorCleanUp.java | 46 +- .../ui/fix/ReturnExpressionCleanUp.java | 46 +- .../ui/fix/SingleUsedFieldCleanUp.java | 4 +- .../ui/fix/StandardComparisonCleanUp.java | 46 +- .../ui/fix/StaticInnerClassCleanUp.java | 90 +- .../fix/StrictlyEqualOrDifferentCleanUp.java | 19 +- .../StringBufferToStringBuilderCleanUp.java | 46 +- .../fix/StringConcatToTextBlockCleanUp.java | 31 + .../jdt/internal/ui/fix/SubstringCleanUp.java | 121 +- .../jdt/internal/ui/fix/SwitchCleanUp.java | 44 +- .../ui/fix/SwitchExpressionsCleanUp.java | 50 +- .../ui/fix/TypeParametersCleanUp.java | 10 +- .../jdt/internal/ui/fix/UnboxingCleanUp.java | 94 +- .../ui/fix/UnimplementedCodeCleanUp.java | 11 +- .../ui/fix/UnnecessaryCodeCleanUp.java | 82 +- .../internal/ui/fix/UnusedCodeCleanUp.java | 196 +- .../ui/fix/UseIteratorToForLoopCleanUp.java | 56 + ...ValueOfRatherThanInstantiationCleanUp.java | 46 +- .../jdt/internal/ui/fix/VarCleanUp.java | 4 +- .../ui/fix/VariableDeclarationCleanUp.java | 50 +- .../internal/ui/infoviews/JavadocView.java | 5 +- .../FatJarPackageWizardPage.java | 18 +- .../ui/javadocexport/JavadocWizard.java | 2 +- .../ui/javaeditor/ClassFileEditor.java | 5 + .../javaeditor/ClipboardOperationAction.java | 11 +- .../ui/javaeditor/CompilationUnitEditor.java | 11 +- .../internal/ui/javaeditor/EditorUtility.java | 14 + .../EnumConstructorTargetFinder.java | 55 +- .../internal/ui/javaeditor/IndentUtil.java | 6 +- .../internal/ui/javaeditor/JavaEditor.java | 25 +- .../JavaElementHyperlinkDetector.java | 16 +- .../SemanticHighlightingReconciler.java | 27 +- .../CalleeJavaMethodParameterVisitor.java | 94 +- .../JavaMethodParameterCodeMining.java | 20 +- .../codemining/JavaReferenceCodeMining.java | 6 + .../GoToNextPreviousMemberAction.java | 12 +- .../ui/packageview/ClassPathContainer.java | 2 +- .../CodeAssistConfigurationBlock.java | 10 +- .../ComplianceConfigurationBlock.java | 60 +- .../preferences/JavaBasePreferencePage.java | 9 + .../ui/preferences/PreferencesMessages.java | 8 +- .../PreferencesMessages.properties | 8 +- .../PropertyAndPreferencePage.java | 3 +- .../preferences/TypeFilterPreferencePage.java | 211 +- .../preferences/cleanup/CleanUpMessages.java | 9 +- .../cleanup/CleanUpMessages.properties | 12 +- .../preferences/cleanup/CleanUpTabPage.java | 61 +- .../cleanup/JavaFeatureTabPage.java | 12 +- .../cleanup/UnnecessaryCodeTabPage.java | 9 +- .../formatter/FormatterMessages.java | 14 +- .../formatter/FormatterMessages.properties | 14 +- .../formatter/FormatterModifyDialog.java | 27 +- .../formatter/ModifyDialogTabPage.java | 65 +- .../search/OccurrencesSearchResultPage.java | 4 +- .../internal/ui/search/SearchMessages.java | 28 +- .../ui/search/SearchMessages.properties | 38 +- .../ui/text/DocumentCharacterIterator.java | 6 + .../JavaCompositeReconcilingStrategy.java | 4 + .../jdt/internal/ui/text/JavaReconciler.java | 10 +- .../jdt/internal/ui/text/JavaWordFinder.java | 6 +- .../AdvancedQuickAssistProcessor.java | 253 +- .../DefaultModulepathFixProcessor.java | 3 + .../text/correction/IProposalRelevance.java | 8 +- .../LocalCorrectionsSubProcessor.java | 181 +- .../ModifierCorrectionSubProcessor.java | 9 +- .../ModuleCorrectionsSubProcessor.java | 3 + .../text/correction/QuickAssistProcessor.java | 753 +- .../ui/text/correction/QuickFixProcessor.java | 14 +- .../SuppressWarningsSubProcessor.java | 5 +- .../UnresolvedElementsSubProcessor.java | 52 +- .../proposals/AddStaticFavoriteProposal.java | 69 + .../AssignToVariableAssistProposal.java | 4 +- .../ChangeMethodSignatureProposal.java | 11 +- .../InitializeFinalFieldProposal.java | 6 +- .../ModifierChangeCorrectionProposal.java | 14 +- .../proposals/NewCUUsingWizardProposal.java | 95 +- .../proposals/NewDefiningMethodProposal.java | 21 +- .../NewInterfaceImplementationProposal.java | 55 + .../NewMethodCorrectionProposal.java | 76 +- .../proposals/QualifyTypeProposal.java | 59 + .../proposals/TaskMarkerProposal.java | 12 +- .../TypeChangeCorrectionProposal.java | 4 +- .../java/ChainCompletionProposalComputer.java | 5 +- .../FilledArgumentNamesMethodProposal.java | 19 +- .../text/java/IJavaReconcilingListener.java | 12 + .../JavaAllCompletionProposalComputer.java | 1 + .../java/JavaLambdaCompletionProposal.java | 155 + ...JavaMultiLineStringAutoIndentStrategy.java | 6 +- .../JavaNoTypeCompletionProposalComputer.java | 1 + .../ui/text/java/JavaReconcilingStrategy.java | 8 +- .../java/JavaStringDoubleClickStrategy.java | 181 + .../JavaTypeCompletionProposalComputer.java | 16 +- .../java/PartitionDoubleClickSelector.java | 2 +- .../ui/text/java/hover/JavaSourceHover.java | 83 +- .../ui/text/java/hover/JavadocHover.java | 4 +- .../ui/text/java/hover/NLSStringHover.java | 22 +- .../ui/text/java/hover/ProblemHover.java | 10 + .../JavaDocSnippetStringEvaluator.java | 665 ++ .../text/javadoc/JavadocContentAccess2.java | 82 +- .../ui/text/spelling/JavaSpellingEngine.java | 2 +- .../PropertiesFileSpellCheckIterator.java | 6 +- .../PropertiesFileSpellingEngine.java | 4 +- .../ui/text/spelling/SpellCheckIterator.java | 16 +- .../ui/text/spelling/TextSpellingEngine.java | 2 +- .../ui/util/TypeNameMatchLabelProvider.java | 6 + .../ImagesOnFileSystemRegistry.java | 13 +- .../ui/viewsupport/JavaElementLinks.java | 10 +- .../ui/viewsupport/ProblemMarkerManager.java | 87 +- .../ui/wizards/NewWizardMessages.java | 29 +- .../ui/wizards/NewWizardMessages.properties | 32 +- .../SuperInterfaceSelectionDialog.java | 7 +- .../wizards/buildpaths/BuildPathBasePage.java | 21 +- .../wizards/buildpaths/BuildPathsBlock.java | 31 +- .../ui/wizards/buildpaths/CPListElement.java | 6 +- .../ExternalAnnotationsAttachmentBlock.java | 190 +- .../ExternalAnnotationsAttachmentDialog.java | 33 +- ...rnalAnnotationsAttributeConfiguration.java | 5 +- .../buildpaths/LibrariesWorkbookPage.java | 2 +- .../buildpaths/ModuleDependenciesAdapter.java | 30 +- .../buildpaths/ModuleDependenciesPage.java | 20 +- .../StringButtonStatusDialogField.java | 2 +- .../jdt/ui/CodeStyleConfiguration.java | 1 - .../ui/org/eclipse/jdt/ui/JavaUI.java | 47 +- .../eclipse/jdt/ui/PreferenceConstants.java | 3 +- .../jdt/ui/ProblemsLabelDecorator.java | 369 +- .../org/eclipse/jdt/ui/SharedASTProvider.java | 2 +- .../jdt/ui/actions/AddGetterSetterAction.java | 3 +- .../jdt/ui/actions/CCPActionGroup.java | 2 +- ...dBreakContinueTargetOccurrencesAction.java | 5 +- .../FindExceptionOccurrencesAction.java | 5 +- .../FindImplementOccurrencesAction.java | 5 +- .../FindMethodExitOccurrencesAction.java | 5 +- .../ui/actions/GenerateToStringAction.java | 7 +- .../ui/actions/OpenNewRecordWizardAction.java | 178 +- .../text/JavaSourceViewerConfiguration.java | 28 +- .../java/CompletionProposalCollector.java | 18 +- .../java/CompletionProposalLabelProvider.java | 27 + .../jdt/ui/wizards/BuildPathDialogAccess.java | 8 +- .../ui/wizards/NewAnnotationWizardPage.java | 27 +- .../jdt/ui/wizards/NewClassWizardPage.java | 42 +- .../jdt/ui/wizards/NewEnumWizardPage.java | 27 +- .../ui/wizards/NewInterfaceWizardPage.java | 7 +- .../wizards/NewJavaProjectWizardPageOne.java | 185 +- .../wizards/NewJavaProjectWizardPageTwo.java | 50 +- .../jdt/ui/wizards/NewRecordWizardPage.java | 74 +- .../jdt/ui/wizards/NewTypeWizardPage.java | 759 +- .../pom.xml | 2 +- .../META-INF/MANIFEST.MF | 6 +- org.eclipse.ltk.core.refactoring/pom.xml | 4 +- .../ltk/core/refactoring/CompositeChange.java | 22 +- .../refactoring/RefactoringStatusContext.java | 2 +- .../UndoableOperation2ChangeAdapter.java | 12 +- .../resource/DeleteResourcesProcessor.java | 6 +- org.eclipse.ltk.ui.refactoring.tests/pom.xml | 2 +- .../META-INF/MANIFEST.MF | 2 +- org.eclipse.ltk.ui.refactoring/pom.xml | 4 +- .../ui/refactoring/PreviewWizardPage.java | 14 +- .../ui/refactoring/RefactoringUIMessages.java | 6 +- .../RefactoringUIMessages.properties | 5 +- .../ltk/ui/refactoring/RefactoringWizard.java | 4 +- pom.xml | 25 +- tests-pom/pom.xml | 2 +- 759 files changed, 45137 insertions(+), 7831 deletions(-) delete mode 100644 .gitignore create mode 100644 Jenkinsfile create mode 100644 org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/ASTProcessor.java create mode 100644 org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/HelperVisitor.java create mode 100644 org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/HelperVisitorProvider.java create mode 100644 org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/LambdaASTVisitor.java create mode 100644 org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/ReferenceHolder.java create mode 100644 org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/VisitorEnum.java create mode 100644 org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/StringConcatToTextBlockCleanUpCore.java create mode 100644 org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/SubstringCleanUpCore.java create mode 100644 org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessorUtil.java rename {org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui => org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation}/search/BreakContinueTargetFinder.java (97%) rename {org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui => org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation}/search/ExceptionOccurrencesFinder.java (98%) rename {org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui => org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation}/search/ImplementOccurrencesFinder.java (96%) rename {org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui => org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation}/search/MethodExitsFinder.java (98%) rename {org.eclipse.jdt.ui => org.eclipse.jdt.core.manipulation}/core extension/org/eclipse/jdt/internal/corext/dom/TypeAnnotationRewrite.java (97%) rename org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/{AbstractFix.java => AbstractFixCore.java} (89%) rename org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/Java50Fix.java => org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/Java50FixCore.java (87%) create mode 100644 org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SealedClassFixCore.java create mode 100644 org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringConcatToTextBlockFixCore.java create mode 100644 org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UseIteratorToForLoopFixCore.java create mode 100644 org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/AbstractTool.java create mode 100644 org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/WhileLoopToChangeHit.java create mode 100644 org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/WhileToForEach.java rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/generics/ElementStructureEnvironment.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintCreator.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintsSolver.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsRefactoring.java (96%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java (98%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsUpdate.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/generics/ParametricStructureComputer.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/rename/MethodChecks.java (91%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java (96%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java (89%) create mode 100644 org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoringCore.java rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ASTCreator.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompilationUnitRange.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompositeOrTypeConstraint.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCollector.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCreator.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintOperator.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariable.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariableFactory.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/DeclaringTypeVariable.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ExpressionVariable.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/FullConstraintCreator.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IConstraintVariableFactory.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IContext.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraint.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraintFactory.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/NullContext.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ParameterTypeVariable.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/RawBindingVariable.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ReturnTypeVariable.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/SimpleTypeConstraint.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeConstraintFactory.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeVariable.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArraySuperTypeSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArrayTypeSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EmptyTypeSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EnumeratedTypeSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SingletonTypeSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesOfSingleton.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesOfSingleton.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetEnvironment.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetIntersection.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetUnion.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeUniverseSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayElementVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayTypeVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CastVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CollectionElementVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ConstraintVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ISourceConstraintVariable.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraint2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraintVariable.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ImmutableTypeVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/IndependentTypeVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterTypeVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterizedTypeVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ReturnTypeVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/SubTypeConstraint2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TTypes.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeEquivalenceSet.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/VariableVariable2.java (100%) rename {org.eclipse.jdt.ui/core refactoring => org.eclipse.jdt.core.manipulation/core extension}/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java (100%) create mode 100644 org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/ui/fix/UseIteratorToForLoopCleanUpCore.java create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/alphab_sort_co.png create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/alphab_sort_co@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/collapseall.png create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/collapseall@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/expandall.png create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/expandall@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/goto_input.png create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/goto_input@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/rem_all_co.png create mode 100644 org.eclipse.jdt.junit/icons/full/elcl16/rem_all_co@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/etool16/debug_exc.png create mode 100644 org.eclipse.jdt.junit/icons/full/etool16/debug_exc@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/etool16/export_wiz.png create mode 100644 org.eclipse.jdt.junit/icons/full/etool16/export_wiz@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/etool16/import_wiz.png create mode 100644 org.eclipse.jdt.junit/icons/full/etool16/import_wiz@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/etool16/run_exc.png create mode 100644 org.eclipse.jdt.junit/icons/full/etool16/run_exc@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/obj16/stckframe_running_obj.png create mode 100644 org.eclipse.jdt.junit/icons/full/obj16/stckframe_running_obj@2x.png create mode 100644 org.eclipse.jdt.junit/icons/full/obj16/time_obj.png create mode 100644 org.eclipse.jdt.junit/icons/full/obj16/time_obj@2x.png create mode 100644 org.eclipse.jdt.junit5.runtime/src/org/eclipse/jdt/internal/junit5/runner/FailuresFirstMethodOrderer.java create mode 100644 org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/IndentActionTest15.java create mode 100644 org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JavaStringDoubleClickStrategyTest.java create mode 100644 org.eclipse.jdt.text.tests/testResources/indentation15/issue30_1/Before.java create mode 100644 org.eclipse.jdt.text.tests/testResources/indentation15/issue30_1/Modified.java create mode 100644 org.eclipse.jdt.text.tests/testResources/indentation15/issue30_2/Before.java create mode 100644 org.eclipse.jdt.text.tests/testResources/indentation15/issue30_2/Modified.java create mode 100644 org.eclipse.jdt.text.tests/testResources/indentation15/issue30_3/Before.java create mode 100644 org.eclipse.jdt.text.tests/testResources/indentation15/issue30_3/Modified.java create mode 100644 org.eclipse.jdt.text.tests/testResources/indentation15/issue30_4/Before.java create mode 100644 org.eclipse.jdt.text.tests/testResources/indentation15/issue30_4/Modified.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ConvertAnonymousToNested9/canConvert/A_testTypeParameters1_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ConvertAnonymousToNested9/canConvert/A_testTypeParameters1_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/lambdaExpression18_in/A_test328.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/lambdaExpression18_in/A_test329.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/lambdaExpression18_out/A_test328.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/lambdaExpression18_out/A_test329.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test118_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test118_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test119_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test119_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test120_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test120_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test121_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test121_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test122_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test122_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test123_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test123_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test124_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test124_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test125_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract/A_test125_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InferTypeArguments/testCuWithLocalClass1/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InferTypeArguments/testCuWithLocalClass1/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InferTypeArguments/testCuWithLocalClass2/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InferTypeArguments/testCuWithLocalClass2/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/bugs_in/Test_462038.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/bugs_out/Test_462038.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/enum_in/Test_138952.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/enum_out/Test_138952.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/simple14_in/TestSwitchExpression1.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/simple14_in/TestSwitchExpression2.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/simple14_in/TestSwitchExpression3.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/simple14_in/TestSwitchExpression4.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/simple14_out/TestSwitchExpression1.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/simple14_out/TestSwitchExpression2.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/simple14_out/TestSwitchExpression3.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineMethodWorkspace/TestCases/simple14_out/TestSwitchExpression4.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test53_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test53_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test54_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test54_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test55_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test55_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test56_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test56_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test57_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test57_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test58_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test58_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test59_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test59_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test60_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test60_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test61_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test61_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test62_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test62_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test63_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test63_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test64_in.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline/A_test64_out.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/cannotInline/A_testFail15.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/PullUp/testFieldMethod5/in/p/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/PullUp/testFieldMethod5/in/p/C.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/PullUp/testFieldMethod5/in/q/Asuper.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/PullUp/testFieldMethod5/in/q/C.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/PullUp/testFieldMethod5/out/p/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/PullUp/testFieldMethod5/out/p/C.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/PullUp/testFieldMethod5/out/q/Asuper.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/PullUp/testFieldMethod5/out/q/C.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test41/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test41/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test42/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test42/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test43/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test43/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test44/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test44/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test45/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test45/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test46/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test46/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test47/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test47/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test48/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test48/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test49/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/RenameVirtualMethodInClass/test49/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch16_in/TestBug566949_1.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch16_in/TestBug566949_2.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch16_out/TestBug566949_1.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch16_out/TestBug566949_2.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestAnonymous1.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestSimple5.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestTry1.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestTry2.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestAnonymous1.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestSimple5.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestTry1.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestTry2.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/UseSupertypeWherePossible16/test0_/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/UseSupertypeWherePossible16/test0_/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/UseSupertypeWherePossible16/test1_/in/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/resources/UseSupertypeWherePossible16/test1_/out/A.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ConvertAnonymousToNestedTests9.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineTempTests.java.orig create mode 100644 org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTestSetup16.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTests16.java create mode 100644 org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/UseSupertypeWherePossibleTests16.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/ExpectationTracer.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/NodeFound.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/VisitorTest.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/JUnit4TestFinderTest16.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/BindingsHierarchyTest.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/rules/Java17ProjectTestSetup.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest15.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest15.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest17.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedMethodsQuickFixTest16.java create mode 100644 org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest17.java delete mode 100644 org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ConvertLoopFix.java delete mode 100644 org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/DoWhileRatherThanWhileFix.java delete mode 100644 org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFix.java delete mode 100644 org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFix.java delete mode 100644 org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFix.java delete mode 100644 org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnimplementedCodeFix.java delete mode 100644 org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/VariableDeclarationFix.java create mode 100644 org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/NullChecker.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/AddGetterSetterTypeProposal.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/HashCodeEqualsTypeProposal.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ToStringTypeProposal.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/filtertable/Filter.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/filtertable/FilterLabelProvider.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/filtertable/FilterManager.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/filtertable/FilterViewerComparator.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/filtertable/JavaFilterTable.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/filtertable/SWTFactory.java rename org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/{preferences => filtertable}/TypeFilterInputDialog.java (90%) create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/AbstractCleanUpCoreWrapper.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/AbstractMultiFixCoreWrapper.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/StringConcatToTextBlockCleanUp.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/UseIteratorToForLoopCleanUp.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/AddStaticFavoriteProposal.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/NewInterfaceImplementationProposal.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/QualifyTypeProposal.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaLambdaCompletionProposal.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaStringDoubleClickStrategy.java create mode 100644 org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavaDocSnippetStringEvaluator.java diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 224e7f05..00000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.pc/ diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..6c3078ac --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,34 @@ +pipeline { + options { + timeout(time: 40, unit: 'MINUTES') + buildDiscarder(logRotator(numToKeepStr:'5')) + timestamps() + } + agent { + label "centos-latest" + } + tools { + maven 'apache-maven-latest' + jdk 'openjdk-jdk17-latest' + } + stages { + stage('Build') { + steps { + wrap([$class: 'Xvnc', useXauthority: true]) { + sh """ + mvn -f pom.xml -Dmaven.compiler.failOnWarning=true -DskipTests=false -Dmaven.repo.local=$WORKSPACE/.m2/repository \ + clean verify --batch-mode -Pbuild-individual-bundles -Pbree-libs -Papi-check + """ + } + } + post { + always { + archiveArtifacts artifacts: '*.log,*/target/work/data/.metadata/*.log,*/tests/target/work/data/.metadata/*.log,apiAnalyzer-workspace/.metadata/*.log', allowEmptyArchive: true + recordIssues aggregatingResults: true, enabledForFailure: true, qualityGates: [[threshold: 1, type: 'DELTA', unstable: false]], tools: [acuCobol()] + publishIssues issues:[scanForIssues(tool: java()), scanForIssues(tool: mavenConsole())] + junit '**/target/surefire-reports/*.xml' + } + } + } + } +} diff --git a/README.md b/README.md index 2d0ab9f3..c6e53f60 100644 --- a/README.md +++ b/README.md @@ -38,19 +38,19 @@ Public forum for Eclipse JDT users. - -Search for bugs: +Search for bugs/issues: ---------------- -This project uses Bugzilla to track ongoing development and issues. +This project uses Github issues to track ongoing development and issues. -- +- [https://github.com/eclipse-jdt/eclipse.jdt.ui/issues](https://github.com/eclipse-jdt/eclipse.jdt.ui/issues) -Create a new bug: +Create a new bug/issue: ----------------- -Be sure to search for existing bugs before you create another one. Remember that contributions are always welcome! +Be sure to search for existing issue before you create another one. Remember that contributions are always welcome! -- +- [https://github.com/eclipse-jdt/eclipse.jdt.ui/issues](https://github.com/eclipse-jdt/eclipse.jdt.ui/issues) Contact: -------- diff --git a/debian/build.xml b/debian/build.xml index 48730536..73f5100c 100644 --- a/debian/build.xml +++ b/debian/build.xml @@ -25,7 +25,7 @@ - + @@ -68,7 +68,7 @@ - + @@ -100,7 +100,7 @@ - + diff --git a/debian/changelog b/debian/changelog index d1834379..ca25ed5f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,23 @@ +eclipse-jdt-ui (4.26-1) unstable; urgency=medium + + * New upstream release + - Depend on libeclipse-jdt-core-java (>= 3.32) + - Build more bundles with Java 11 + * Standards-Version updated to 4.6.2 + + -- Emmanuel Bourg Thu, 05 Jan 2023 12:19:29 +0100 + +eclipse-jdt-ui (4.23-1) unstable; urgency=medium + + * New upstream release + - Depend on libeclipse-core-resources-java (>= 3.16) + - Depend on libeclipse-jface-text-java (>= 3.20) + - Build org.eclipse.jdt.ui with Java 11 + * Standards-Version updated to 4.6.1 + * Track and download the new releases from GitHub + + -- Emmanuel Bourg Fri, 09 Dec 2022 09:32:38 +0100 + eclipse-jdt-ui (4.21-1) unstable; urgency=medium * New upstream release diff --git a/debian/control b/debian/control index 73ac6a46..f9c6dd80 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,7 @@ Maintainer: Debian Java Maintainers Build-Depends: debhelper-compat (= 13), - default-jdk, + default-jdk (>= 2:1.11), ant, junit, junit4, @@ -17,16 +17,16 @@ Build-Depends: libeclipse-core-filebuffers-java, libeclipse-core-filesystem-java, libeclipse-core-jobs-java, - libeclipse-core-resources-java, + libeclipse-core-resources-java (>= 3.16), libeclipse-core-runtime-java, libeclipse-core-variables-java, libeclipse-debug-core-java, libeclipse-debug-ui-java, libeclipse-help-java, - libeclipse-jdt-core-java (>= 3.20), + libeclipse-jdt-core-java (>= 3.32), libeclipse-jdt-launching-java (>= 3.11), libeclipse-jface-java (>= 3.14), - libeclipse-jface-text-java (>= 3.16), + libeclipse-jface-text-java (>= 3.20), libeclipse-search-java, libeclipse-team-core-java, libeclipse-team-ui-java, @@ -48,7 +48,7 @@ Build-Depends: libicu4j-java, libswt-gtk-4-java, eclipse-debian-helper -Standards-Version: 4.6.0.1 +Standards-Version: 4.6.2 Vcs-Git: https://salsa.debian.org/java-team/eclipse-jdt-ui.git Vcs-Browser: https://salsa.debian.org/java-team/eclipse-jdt-ui Homepage: https://www.eclipse.org/jdt/ui/ @@ -112,7 +112,7 @@ Depends: libeclipse-core-jobs-java, libeclipse-core-resources-java, libeclipse-core-runtime-java, - libeclipse-jdt-core-java (>= 3.20), + libeclipse-jdt-core-java (>= 3.32), libeclipse-jdt-launching-java, libeclipse-text-java (>= 3.8), libequinox-common-java, @@ -275,7 +275,7 @@ Depends: libeclipse-jdt-core-java (>= 3.16), libeclipse-jdt-launching-java (>= 3.11), libeclipse-jface-java (>= 3.14), - libeclipse-jface-text-java (>= 3.16), + libeclipse-jface-text-java (>= 3.20), libeclipse-search-java, libeclipse-team-core-java, libeclipse-team-ui-java, @@ -332,7 +332,7 @@ Depends: libeclipse-core-filebuffers-java, libeclipse-core-filesystem-java, libeclipse-core-jobs-java, - libeclipse-core-resources-java, + libeclipse-core-resources-java (>= 3.16), libeclipse-core-runtime-java, libeclipse-text-java, libequinox-common-java, diff --git a/debian/copyright b/debian/copyright index 440cc7ef..c04cbac2 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,6 +1,6 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Eclipse JDT UI -Source: https://github.com/eclipse/eclipse.jdt.ui +Source: https://github.com/eclipse-jdt/eclipse.jdt.ui Files-Excluded: *.jar *.class */testresources/*.zip diff --git a/debian/watch b/debian/watch index 4963e34a..24ea45f9 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ version=4 opts="mode=git,repack,compression=xz,uversionmangle=s/_/./g" \ -https://git.eclipse.org/r/jdt/eclipse.jdt.ui refs/tags/R([\d_]+[az]?) +https://github.com/eclipse-jdt/eclipse.jdt.ui refs/tags/R([\d_]+[az]?) diff --git a/org.eclipse.jdt.astview.feature/feature.xml b/org.eclipse.jdt.astview.feature/feature.xml index 7ecc462b..5f23fb4e 100644 --- a/org.eclipse.jdt.astview.feature/feature.xml +++ b/org.eclipse.jdt.astview.feature/feature.xml @@ -2,13 +2,13 @@ - AST View for Eclipse 2020-12 and later (jdt.core 3.24) + AST View for Eclipse 2021-12 and later (jdt.core 3.28) @@ -20,8 +20,8 @@ - - + + diff --git a/org.eclipse.jdt.astview.feature/pom.xml b/org.eclipse.jdt.astview.feature/pom.xml index b377d681..85b70203 100644 --- a/org.eclipse.jdt.astview.feature/pom.xml +++ b/org.eclipse.jdt.astview.feature/pom.xml @@ -14,10 +14,10 @@ eclipse.jdt.ui eclipse.jdt.ui - 4.21.0-SNAPSHOT + 4.26.0-SNAPSHOT org.eclipse.jdt.feature org.eclipse.jdt.astview.feature - 1.1.13-SNAPSHOT + 1.1.15-SNAPSHOT eclipse-feature diff --git a/org.eclipse.jdt.astview/META-INF/MANIFEST.MF b/org.eclipse.jdt.astview/META-INF/MANIFEST.MF index d025cd1e..bb57db17 100644 --- a/org.eclipse.jdt.astview/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.astview/META-INF/MANIFEST.MF @@ -3,8 +3,7 @@ Automatic-Module-Name: org.eclipse.jdt.astview Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.astview; singleton:=true -Bundle-Version: 1.5.0.qualifier -Eclipse-SourceReferences: scm:git:https://git.eclipse.org/r/jdt/eclipse.jdt.ui.git;path="org.eclipse.jdt.astview";tag=R4_4 +Bundle-Version: 1.5.200.qualifier Bundle-Activator: org.eclipse.jdt.astview.ASTViewPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/org.eclipse.jdt.astview/pom.xml b/org.eclipse.jdt.astview/pom.xml index 9b4c3152..bd2ee4bc 100644 --- a/org.eclipse.jdt.astview/pom.xml +++ b/org.eclipse.jdt.astview/pom.xml @@ -14,10 +14,10 @@ eclipse.jdt.ui eclipse.jdt.ui - 4.21.0-SNAPSHOT + 4.26.0-SNAPSHOT org.eclipse.jdt org.eclipse.jdt.astview - 1.5.0-SNAPSHOT + 1.5.200-SNAPSHOT eclipse-plugin diff --git a/org.eclipse.jdt.astview/src/org/eclipse/jdt/astview/views/ASTView.java b/org.eclipse.jdt.astview/src/org/eclipse/jdt/astview/views/ASTView.java index 9428e986..cc6ea29e 100644 --- a/org.eclipse.jdt.astview/src/org/eclipse/jdt/astview/views/ASTView.java +++ b/org.eclipse.jdt.astview/src/org/eclipse/jdt/astview/views/ASTView.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -138,6 +138,9 @@ public class ASTView extends ViewPart implements IShowInSource, IShowInTargetList { static final int JLS_LATEST= AST.getJLSLatest(); + private static final int JLS19= ASTHelper.JLS19; + private static final int JLS18= ASTHelper.JLS18; + private static final int JLS17= ASTHelper.JLS17; private static final int JLS16= ASTHelper.JLS16; private static final int JLS15= ASTHelper.JLS15; private static final int JLS14= ASTHelper.JLS14; @@ -509,6 +512,9 @@ public ASTView() { case JLS14: case JLS15: case JLS16: + case JLS17: + case JLS18: + case JLS19: fCurrentASTLevel= level; } } catch (NumberFormatException e) { @@ -1131,6 +1137,9 @@ public void run() { new ASTLevelToggle("AST Level 1&4 (14)", JLS14), //$NON-NLS-1$ new ASTLevelToggle("AST Level 1&5 (15)", JLS15), //$NON-NLS-1$ new ASTLevelToggle("AST Level 1&6 (16)", JLS16), //$NON-NLS-1$ + new ASTLevelToggle("AST Level 1&7 (17)", JLS17), //$NON-NLS-1$ + new ASTLevelToggle("AST Level 1&8 (18)", JLS18), //$NON-NLS-1$ + new ASTLevelToggle("AST Level 1&9 (19)", JLS19), //$NON-NLS-1$ }; fAddToTrayAction= new Action() { diff --git a/org.eclipse.jdt.core.manipulation/.settings/.api_filters b/org.eclipse.jdt.core.manipulation/.settings/.api_filters index bae7ae86..54a2bc3b 100644 --- a/org.eclipse.jdt.core.manipulation/.settings/.api_filters +++ b/org.eclipse.jdt.core.manipulation/.settings/.api_filters @@ -8,4 +8,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF index 6040a568..6a1e2966 100644 --- a/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF @@ -3,17 +3,17 @@ Automatic-Module-Name: org.eclipse.jdt.core.manipulation Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.core.manipulation; singleton:=true -Bundle-Version: 1.15.0.qualifier +Bundle-Version: 1.17.0.qualifier Bundle-Vendor: %providerName Bundle-Activator: org.eclipse.jdt.internal.core.manipulation.JavaManipulationPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)", org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)", org.eclipse.ltk.core.refactoring;bundle-version="[3.6.0,4.0.0)", - org.eclipse.jdt.core;bundle-version="[3.22.0,4.0.0)", + org.eclipse.jdt.core;bundle-version="[3.28.0,4.0.0)", org.eclipse.core.expressions;bundle-version="[3.4.100,4.0.0)", - org.eclipse.text;bundle-version="[3.5.0,4.0.0)", - org.eclipse.jdt.launching;bundle-version="3.9.0", + org.eclipse.text;bundle-version="[3.12.0,4.0.0)", + org.eclipse.jdt.launching;bundle-version="3.19.400", org.eclipse.core.filesystem;bundle-version="1.7.200", org.eclipse.core.filebuffers;bundle-version="3.6.300" Bundle-ActivationPolicy: lazy @@ -21,6 +21,7 @@ Export-Package: org.eclipse.jdt.core.manipulation, org.eclipse.jdt.core.refactoring, org.eclipse.jdt.core.refactoring.descriptors, org.eclipse.jdt.core.refactoring.participants, + org.eclipse.jdt.internal.common;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.core.manipulation;x-friends:="org.eclipse.jdt.ui,org.eclipse.jdt.junit", org.eclipse.jdt.internal.core.manipulation.dom;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.core.manipulation.search;x-friends:="org.eclipse.jdt.ui,org.eclipse.jdt.text.tests", @@ -33,20 +34,26 @@ Export-Package: org.eclipse.jdt.core.manipulation, org.eclipse.jdt.internal.corext.dom;manipulation=split;mandatory:=manipulation;x-friends:="org.eclipse.jdt.ui,org.eclipse.jdt.junit", org.eclipse.jdt.internal.corext.dom.fragments;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.fix;x-friends:="org.eclipse.jdt.ui", + org.eclipse.jdt.internal.corext.fix.helper;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.base;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.changes;manipulation=split;mandatory:=manipulation;x-friends:="org.eclipse.jdt.ui.examples.javafamily,org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.code;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.code.flow;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.delegates;x-friends:="org.eclipse.jdt.ui", + org.eclipse.jdt.internal.corext.refactoring.generics;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.nls;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.nls.changes;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.participants;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.rename;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.reorg;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.structure;x-friends:="org.eclipse.jdt.ui", + org.eclipse.jdt.internal.corext.refactoring.surround;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.tagging;x-friends:="org.eclipse.jdt.ui", + org.eclipse.jdt.internal.corext.refactoring.typeconstraints;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types;manipulation=split;mandatory:=manipulation;x-friends:="org.eclipse.jdt.ui", + org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets;x-friends:="org.eclipse.jdt.ui", + org.eclipse.jdt.internal.corext.refactoring.typeconstraints2;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.refactoring.util;manipulation=split;mandatory:=manipulation;x-friends:="org.eclipse.jdt.ui", org.eclipse.jdt.internal.corext.template.java;manipulation=split;mandatory:=manipulation;x-friends:="org.eclipse.jdt.ui,org.eclipse.jdt.debug.ui", org.eclipse.jdt.internal.corext.util;manipulation=split;mandatory:=manipulation;x-friends:="org.eclipse.jdt.ui,org.eclipse.jdt.junit,org.eclipse.jdt.ui.unittest.junit", diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CodeStyleConfiguration.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CodeStyleConfiguration.java index fe0c05bf..2f072003 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CodeStyleConfiguration.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CodeStyleConfiguration.java @@ -72,7 +72,6 @@ private CodeStyleConfiguration() { /** * Returns a {@link ImportRewrite} using {@link ImportRewrite#create(ICompilationUnit, boolean)} and * configures the rewriter with the settings as specified in the JDT UI preferences. - *

* * @param cu the compilation unit to create the rewriter on * @param restoreExistingImports specifies if the existing imports should be kept or removed. diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CoreASTProvider.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CoreASTProvider.java index bb444b68..fc77b797 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CoreASTProvider.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/CoreASTProvider.java @@ -62,6 +62,7 @@ public final class CoreASTProvider { private Object fReconcileLock= new Object(); private Object fWaitLock= new Object(); private volatile boolean fIsReconciling; + private volatile Runnable fFinishReconciling; /** * Wait flag class. @@ -166,6 +167,7 @@ public CompilationUnit getAST(final ITypeRoot input, WAIT_FLAG waitFlag, IProgre if (isReconciling) { try { + notifyReconciler(); // Wait for AST synchronized (fWaitLock) { if (isReconciling(input)) { @@ -215,6 +217,13 @@ public CompilationUnit getAST(final ITypeRoot input, WAIT_FLAG waitFlag, IProgre return ast; } + private void notifyReconciler() { + Runnable finishReconciling= fFinishReconciling; + if (finishReconciling!=null) { + finishReconciling.run(); + } + } + /** * Informs that reconciling for the given element is about to be started. * @@ -222,6 +231,18 @@ public CompilationUnit getAST(final ITypeRoot input, WAIT_FLAG waitFlag, IProgre * See org.eclipse.jdt.internal.ui.text.java.IJavaReconcilingListener#aboutToBeReconciled() */ public void aboutToBeReconciled(ITypeRoot javaElement) { + aboutToBeReconciled(javaElement, null); + } + + /** + * Informs that reconciling for the given element is about to be started. + * + * @param javaElement the Java element + * @param finishReconciling Runnable to be run. + * see org.eclipse.jdt.internal.ui.text.java.IJavaReconcilingListener#aboutToBeReconciled(JavaReconciler) + * @since 1.16 + */ + public void aboutToBeReconciled(ITypeRoot javaElement, Runnable finishReconciling) { if (javaElement == null) return; @@ -232,6 +253,7 @@ public void aboutToBeReconciled(ITypeRoot javaElement) { synchronized (fReconcileLock) { fReconcilingJavaElement= javaElement; fIsReconciling= true; + this.fFinishReconciling = finishReconciling; } cache(null, javaElement); } @@ -302,6 +324,7 @@ public void reconciled(CompilationUnit ast, ITypeRoot javaElement, IProgressMoni synchronized (fReconcileLock) { fIsReconciling= false; + fFinishReconciling= null; if (javaElement == null || !javaElement.equals(fReconcilingJavaElement)) { if (JavaManipulationPlugin.DEBUG_AST_PROVIDER) @@ -498,6 +521,7 @@ public void clearReconciliation () { synchronized (fReconcileLock) { fIsReconciling = false; fReconcilingJavaElement = null; + fFinishReconciling = null; } } diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/OrganizeImportsOperation.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/OrganizeImportsOperation.java index 41343cc7..d613563f 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/OrganizeImportsOperation.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/OrganizeImportsOperation.java @@ -499,6 +499,7 @@ public int findInContext(String qualifier, String name, int kind) { private boolean fDoSave; private boolean fIgnoreLowerCaseNames; + private boolean fRestoreExistingImports; private IChooseImportQuery fChooseImportQuery; @@ -528,6 +529,7 @@ public OrganizeImportsOperation(ICompilationUnit cu, CompilationUnit astRoot, bo fDoSave= save; fIgnoreLowerCaseNames= ignoreLowerCaseNames; + fRestoreExistingImports= false; fAllowSyntaxErrors= allowSyntaxErrors; fChooseImportQuery= chooseImportQuery; @@ -537,6 +539,23 @@ public OrganizeImportsOperation(ICompilationUnit cu, CompilationUnit astRoot, bo fParsingError= null; } + /** + * Creates a new OrganizeImportsOperation operation. + * + * @param cu The compilation unit + * @param astRoot the compilation unit AST node + * @param ignoreLowerCaseNames when true, type names starting with a lower case are ignored + * @param save If set, the result will be saved + * @param allowSyntaxErrors If set, the operation will only proceed when the compilation unit has no syntax errors + * @param chooseImportQuery Query element to be used for UI interaction or null to not select anything + * @param restoreExistingImports when true, the operation will restore existing imports + * @since 1.17 + */ + public OrganizeImportsOperation(ICompilationUnit cu, CompilationUnit astRoot, boolean ignoreLowerCaseNames, boolean save, boolean allowSyntaxErrors, IChooseImportQuery chooseImportQuery, boolean restoreExistingImports) { + this(cu, astRoot, ignoreLowerCaseNames, save, allowSyntaxErrors, chooseImportQuery); + fRestoreExistingImports= restoreExistingImports; + } + /** * Runs the operation. * @param monitor the progress monitor @@ -564,7 +583,7 @@ public TextEdit createTextEdit(IProgressMonitor m) throws CoreException, Operati } subMonitor.setWorkRemaining(7); - ImportRewrite importsRewrite= CodeStyleConfiguration.createImportRewrite(astRoot, false); + ImportRewrite importsRewrite= CodeStyleConfiguration.createImportRewrite(astRoot, fRestoreExistingImports); if (astRoot.getAST().hasResolvedBindings()) { importsRewrite.setUseContextToFilterImplicitImports(true); } @@ -675,6 +694,9 @@ private void addStaticImports( } if (unresolvableImports.isEmpty()) { String pref= JavaManipulation.getPreference(JavaManipulationPlugin.CODEASSIST_FAVORITE_STATIC_MEMBERS, importRewrite.getCompilationUnit().getJavaProject()); + if (pref == null || pref.isBlank()) { + return; + } String[] favourites= pref.split(";"); //$NON-NLS-1$ if (favourites.length == 0) { return; diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/SharedASTProviderCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/SharedASTProviderCore.java index 7a3c05d3..8930b0d7 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/SharedASTProviderCore.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/core/manipulation/SharedASTProviderCore.java @@ -32,7 +32,7 @@ *

Clients can make the following assumptions about the AST:

*
    *
  • the AST has a {@link ITypeRoot} as source: {@link CompilationUnit#getTypeRoot()} is not null.
  • - *
  • the {@link AST#apiLevel() AST API level} is {@link AST#JLS16 API level 16} or higher
  • + *
  • the {@link AST#apiLevel() AST API level} is {@link AST#JLS17 API level 17} or higher
  • *
  • the AST has bindings resolved ({@link AST#hasResolvedBindings()})
  • *
  • {@link AST#hasStatementsRecovery() statement} and {@link AST#hasBindingsRecovery() bindings} * recovery are enabled diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/ASTProcessor.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/ASTProcessor.java new file mode 100644 index 00000000..67c34774 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/ASTProcessor.java @@ -0,0 +1,2469 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.common; + +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Set; +import java.util.function.BiPredicate; +import java.util.function.Function; + +import org.eclipse.jdt.core.dom.ASTNode; + +/** + * + * @author chammer + * @param - type extending HelperVisitorProvider mapping V -> E entries + * @param - key type for HelperVisitorProvider + * @param - value type for HelperVisitorProvider + */ +public class ASTProcessor, V, T> { + + class NodeHolder { + public NodeHolder(BiPredicate callee, Function navigate) { + this.callee= callee; + this.navigate= navigate; + } + + public NodeHolder(BiPredicate callee, Function navigate, Object object) { + this.callee= callee; + this.navigate= navigate; + this.object= object; + } + + public BiPredicate callee; + + public Function navigate; + + public Object object; + } + + private final LinkedHashMap nodetypelist; + + E dataholder; + + Set nodesprocessed; + + LinkedList nodetypekeylist; + + /** + * + * @param dataholder - HelperVisitorProvider mapping V -> E entries + * @param nodesprocessed - set to store processed nodes + */ + public ASTProcessor(E dataholder, Set nodesprocessed) { + this.dataholder= dataholder; + this.nodesprocessed= nodesprocessed; + this.nodetypelist= new LinkedHashMap<>(); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAnnotationTypeDeclarationVisitor( + BiPredicate bs) { + return callAnnotationTypeDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAnnotationTypeDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.AnnotationTypeDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAnnotationTypeMemberDeclarationVisitor( + BiPredicate bs) { + return callAnnotationTypeMemberDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAnnotationTypeMemberDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.AnnotationTypeMemberDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAnonymousClassDeclarationVisitor( + BiPredicate bs) { + return callAnonymousClassDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAnonymousClassDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.AnonymousClassDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callArrayAccessVisitor( + BiPredicate bs) { + return callArrayAccessVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callArrayAccessVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ArrayAccess, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callArrayCreationVisitor( + BiPredicate bs) { + return callArrayCreationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callArrayCreationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ArrayCreation, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callArrayInitializerVisitor( + BiPredicate bs) { + return callArrayInitializerVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callArrayInitializerVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ArrayInitializer, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callArrayTypeVisitor( + BiPredicate bs) { + return callArrayTypeVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callArrayTypeVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ArrayType, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAssertStatementVisitor( + BiPredicate bs) { + return callAssertStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAssertStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.AssertStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAssignmentVisitor( + BiPredicate bs) { + return callAssignmentVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callAssignmentVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.Assignment, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callBlockVisitor( + BiPredicate bs) { + return callBlockVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callBlockVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.Block, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callBlockCommentVisitor( + BiPredicate bs) { + return callBlockCommentVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callBlockCommentVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.BlockComment, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callBooleanLiteralVisitor( + BiPredicate bs) { + return callBooleanLiteralVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callBooleanLiteralVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.BooleanLiteral, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callBreakStatementVisitor( + BiPredicate bs) { + return callBreakStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callBreakStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.BreakStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCastExpressionVisitor( + BiPredicate bs) { + return callCastExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCastExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.CastExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCatchClauseVisitor( + BiPredicate bs) { + return callCatchClauseVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCatchClauseVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.CatchClause, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCharacterLiteralVisitor( + BiPredicate bs) { + return callCharacterLiteralVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCharacterLiteralVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.CharacterLiteral, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callClassInstanceCreationVisitor( + BiPredicate bs) { + return callClassInstanceCreationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callClassInstanceCreationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ClassInstanceCreation, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCompilationUnitVisitor( + BiPredicate bs) { + return callCompilationUnitVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCompilationUnitVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.CompilationUnit, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callConditionalExpressionVisitor( + BiPredicate bs) { + return callConditionalExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callConditionalExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ConditionalExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callConstructorInvocationVisitor( + BiPredicate bs) { + return callConstructorInvocationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callConstructorInvocationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ConstructorInvocation, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callContinueStatementVisitor( + BiPredicate bs) { + return callContinueStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callContinueStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ContinueStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCreationReferenceVisitor( + BiPredicate bs) { + return callCreationReferenceVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callCreationReferenceVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.CreationReference, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callDimensionVisitor( + BiPredicate bs) { + return callDimensionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callDimensionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.Dimension, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callDoStatementVisitor( + BiPredicate bs) { + return callDoStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callDoStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.DoStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callEmptyStatementVisitor( + BiPredicate bs) { + return callEmptyStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callEmptyStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.EmptyStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callEnhancedForStatementVisitor( + BiPredicate bs) { + return callEnhancedForStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callEnhancedForStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.EnhancedForStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callEnumConstantDeclarationVisitor( + BiPredicate bs) { + return callEnumConstantDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callEnumConstantDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.EnumConstantDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callEnumDeclarationVisitor( + BiPredicate bs) { + return callEnumDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callEnumDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.EnumDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callExportsDirectiveVisitor( + BiPredicate bs) { + return callExportsDirectiveVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callExportsDirectiveVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ExportsDirective, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callExpressionMethodReferenceVisitor( + BiPredicate bs) { + return callExpressionMethodReferenceVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callExpressionMethodReferenceVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ExpressionMethodReference, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callExpressionStatementVisitor( + BiPredicate bs) { + return callExpressionStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callExpressionStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ExpressionStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callFieldAccessVisitor( + BiPredicate bs) { + return callFieldAccessVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callFieldAccessVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.FieldAccess, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callFieldDeclarationVisitor( + BiPredicate bs) { + return callFieldDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callFieldDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.FieldDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callForStatementVisitor( + BiPredicate bs) { + return callForStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callForStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ForStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callIfStatementVisitor( + BiPredicate bs) { + return callIfStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callIfStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.IfStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callImportDeclarationVisitor( + BiPredicate bs) { + return callImportDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callImportDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ImportDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callInfixExpressionVisitor( + BiPredicate bs) { + return callInfixExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callInfixExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.InfixExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callInitializerVisitor( + BiPredicate bs) { + return callInitializerVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callInitializerVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.Initializer, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callInstanceofExpressionVisitor( + BiPredicate bs) { + return callInstanceofExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callInstanceofExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.InstanceofExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callIntersectionTypeVisitor( + BiPredicate bs) { + return callIntersectionTypeVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callIntersectionTypeVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.IntersectionType, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callJavadocVisitor( + BiPredicate bs) { + return callJavadocVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callJavadocVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.Javadoc, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callLabeledStatementVisitor( + BiPredicate bs) { + return callLabeledStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callLabeledStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.LabeledStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callLambdaExpressionVisitor( + BiPredicate bs) { + return callLambdaExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callLambdaExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.LambdaExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callLineCommentVisitor( + BiPredicate bs) { + return callLineCommentVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callLineCommentVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.LineComment, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMarkerAnnotationVisitor( + BiPredicate bs) { + return callMarkerAnnotationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMarkerAnnotationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.MarkerAnnotation, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMemberRefVisitor( + BiPredicate bs) { + return callMemberRefVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMemberRefVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.MemberRef, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMemberValuePairVisitor( + BiPredicate bs) { + return callMemberValuePairVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMemberValuePairVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.MemberValuePair, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodRefVisitor( + BiPredicate bs) { + return callMethodRefVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodRefVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.MethodRef, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodRefParameterVisitor( + BiPredicate bs) { + return callMethodRefParameterVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodRefParameterVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.MethodRefParameter, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodDeclarationVisitor( + BiPredicate bs) { + return callMethodDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.MethodDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodInvocationVisitor( + BiPredicate bs) { + return callMethodInvocationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodInvocationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.MethodInvocation, new NodeHolder(bs, navigate)); + return this; + } + + /** + * @param methodname - name of method to search for calls to + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodInvocationVisitor(String methodname, + BiPredicate bs) { + nodetypelist.put(VisitorEnum.MethodInvocation, new NodeHolder(bs, null, methodname)); + return this; + } + + /** + * @param methodname - name of method to search for calls to + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callMethodInvocationVisitor(String methodname, + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.MethodInvocation, new NodeHolder(bs, navigate, methodname)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callModifierVisitor( + BiPredicate bs) { + return callModifierVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callModifierVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.Modifier, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callModuleDeclarationVisitor( + BiPredicate bs) { + return callModuleDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callModuleDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ModuleDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callModuleModifierVisitor( + BiPredicate bs) { + return callModuleModifierVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callModuleModifierVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ModuleModifier, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callNameQualifiedTypeVisitor( + BiPredicate bs) { + return callNameQualifiedTypeVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callNameQualifiedTypeVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.NameQualifiedType, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callNormalAnnotationVisitor( + BiPredicate bs) { + return callNormalAnnotationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callNormalAnnotationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.NormalAnnotation, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callNullLiteralVisitor( + BiPredicate bs) { + return callNullLiteralVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callNullLiteralVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.NullLiteral, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callNumberLiteralVisitor( + BiPredicate bs) { + return callNumberLiteralVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callNumberLiteralVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.NumberLiteral, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callOpensDirectiveVisitor( + BiPredicate bs) { + return callOpensDirectiveVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callOpensDirectiveVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.OpensDirective, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPackageDeclarationVisitor( + BiPredicate bs) { + return callPackageDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPackageDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.PackageDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callParameterizedTypeVisitor( + BiPredicate bs) { + return callParameterizedTypeVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callParameterizedTypeVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ParameterizedType, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callParenthesizedExpressionVisitor( + BiPredicate bs) { + return callParenthesizedExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callParenthesizedExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ParenthesizedExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPatternInstanceofExpressionVisitor( + BiPredicate bs) { + return callPatternInstanceofExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPatternInstanceofExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.PatternInstanceofExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPostfixExpressionVisitor( + BiPredicate bs) { + return callPostfixExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPostfixExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.PostfixExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPrefixExpressionVisitor( + BiPredicate bs) { + return callPrefixExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPrefixExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.PrefixExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callProvidesDirectiveVisitor( + BiPredicate bs) { + return callProvidesDirectiveVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callProvidesDirectiveVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ProvidesDirective, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPrimitiveTypeVisitor( + BiPredicate bs) { + return callPrimitiveTypeVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callPrimitiveTypeVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.PrimitiveType, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callQualifiedNameVisitor( + BiPredicate bs) { + return callQualifiedNameVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callQualifiedNameVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.QualifiedName, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callQualifiedTypeVisitor( + BiPredicate bs) { + return callQualifiedTypeVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callQualifiedTypeVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.QualifiedType, new NodeHolder(bs, navigate)); + return this; + } + +// /** +// * +// * @param bs - BiPredicate functional interface that can be assigned a lambda expression +// * @return - ASTProcessor +// */ +// public ASTProcessor callModuleQualifiedNameVisitor( +// BiPredicate bs) { +// return callModuleQualifiedNameVisitor(bs,null); +// } +// +// /** +// * +// * @param bs - BiPredicate functional interface that can be assigned a lambda expression +// * @param navigate - single argument function interface that can be assigned a lambda expression +// * @return - ASTProcessor +// */ +// public ASTProcessor callModuleQualifiedNameVisitor( +// BiPredicate bs, Function navigate) { +// nodetypelist.put(VisitorEnum.ModuleQualifiedName, new NodeHolder(bs,navigate)); +// return this; +// } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callRequiresDirectiveVisitor( + BiPredicate bs) { + return callRequiresDirectiveVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callRequiresDirectiveVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.RequiresDirective, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callRecordDeclarationVisitor( + BiPredicate bs) { + return callRecordDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callRecordDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.RecordDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callReturnStatementVisitor( + BiPredicate bs) { + return callReturnStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callReturnStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ReturnStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSimpleNameVisitor( + BiPredicate bs) { + return callSimpleNameVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSimpleNameVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SimpleName, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSimpleTypeVisitor( + BiPredicate bs) { + return callSimpleTypeVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSimpleTypeVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SimpleType, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSingleMemberAnnotationVisitor( + BiPredicate bs) { + return callSingleMemberAnnotationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSingleMemberAnnotationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SingleMemberAnnotation, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSingleVariableDeclarationVisitor( + BiPredicate bs) { + return callSingleVariableDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSingleVariableDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SingleVariableDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callStringLiteralVisitor( + BiPredicate bs) { + return callStringLiteralVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callStringLiteralVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.StringLiteral, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSuperConstructorInvocationVisitor( + BiPredicate bs) { + return callSuperConstructorInvocationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSuperConstructorInvocationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SuperConstructorInvocation, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSuperFieldAccessVisitor( + BiPredicate bs) { + return callSuperFieldAccessVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSuperFieldAccessVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SuperFieldAccess, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSuperMethodInvocationVisitor( + BiPredicate bs) { + return callSuperMethodInvocationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSuperMethodInvocationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SuperMethodInvocation, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSuperMethodReferenceVisitor( + BiPredicate bs) { + return callSuperMethodReferenceVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSuperMethodReferenceVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SuperMethodReference, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSwitchCaseVisitor( + BiPredicate bs) { + return callSwitchCaseVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSwitchCaseVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SwitchCase, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSwitchExpressionVisitor( + BiPredicate bs) { + return callSwitchExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSwitchExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SwitchExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSwitchStatementVisitor( + BiPredicate bs) { + return callSwitchStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSwitchStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SwitchStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSynchronizedStatementVisitor( + BiPredicate bs) { + return callSynchronizedStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callSynchronizedStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.SynchronizedStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTagElementVisitor( + BiPredicate bs) { + return callTagElementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTagElementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.TagElement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTextBlockVisitor( + BiPredicate bs) { + return callTextBlockVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTextBlockVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.TextBlock, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTextElementVisitor( + BiPredicate bs) { + return callTextElementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTextElementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.TextElement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callThisExpressionVisitor( + BiPredicate bs) { + return callThisExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callThisExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ThisExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callThrowStatementVisitor( + BiPredicate bs) { + return callThrowStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callThrowStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.ThrowStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTryStatementVisitor( + BiPredicate bs) { + return callTryStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTryStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.TryStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeDeclarationVisitor( + BiPredicate bs) { + return callTypeDeclarationVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeDeclarationVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.TypeDeclaration, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeDeclarationStatementVisitor( + BiPredicate bs) { + return callTypeDeclarationStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeDeclarationStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.TypeDeclarationStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeLiteralVisitor( + BiPredicate bs) { + return callTypeLiteralVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeLiteralVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.TypeLiteral, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeMethodReferenceVisitor( + BiPredicate bs) { + return callTypeMethodReferenceVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeMethodReferenceVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.TypeMethodReference, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeParameterVisitor( + BiPredicate bs) { + return callTypeParameterVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callTypeParameterVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.TypeParameter, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callUnionTypeVisitor( + BiPredicate bs) { + return callUnionTypeVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callUnionTypeVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.UnionType, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callUsesDirectiveVisitor( + BiPredicate bs) { + return callUsesDirectiveVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callUsesDirectiveVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.UsesDirective, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callVariableDeclarationExpressionVisitor( + BiPredicate bs) { + return callVariableDeclarationExpressionVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callVariableDeclarationExpressionVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.VariableDeclarationExpression, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callVariableDeclarationStatementVisitor( + BiPredicate bs) { + return callVariableDeclarationStatementVisitor(bs, null); + } + + /** + * @param class1 - type of variable declaration to look for + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callVariableDeclarationStatementVisitor(Class class1, BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.VariableDeclarationStatement, new NodeHolder(bs, navigate, class1)); + return this; + } + + /** + * @param class1 - type of variable declaration to look for + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callVariableDeclarationStatementVisitor(Class class1, BiPredicate bs) { + nodetypelist.put(VisitorEnum.VariableDeclarationStatement, new NodeHolder(bs, null, class1)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callVariableDeclarationStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.VariableDeclarationStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callVariableDeclarationFragmentVisitor( + BiPredicate bs) { + return callVariableDeclarationFragmentVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callVariableDeclarationFragmentVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.VariableDeclarationFragment, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callWhileStatementVisitor( + BiPredicate bs) { + return callWhileStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callWhileStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.WhileStatement, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callWildcardTypeVisitor( + BiPredicate bs) { + return callWildcardTypeVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callWildcardTypeVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.WildcardType, new NodeHolder(bs, navigate)); + return this; + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callYieldStatementVisitor( + BiPredicate bs) { + return callYieldStatementVisitor(bs, null); + } + + /** + * + * @param bs - BiPredicate functional interface that can be assigned a lambda expression + * @param navigate - single argument function interface that can be assigned a lambda expression + * @return - ASTProcessor + */ + public ASTProcessor callYieldStatementVisitor( + BiPredicate bs, Function navigate) { + nodetypelist.put(VisitorEnum.YieldStatement, new NodeHolder(bs, navigate)); + return this; + } + + + /** + * + * @param node - ASTNode + */ + public void build(ASTNode node) { + nodetypekeylist= new LinkedList<>(nodetypelist.keySet()); + process(node, 0); + } + + void process(ASTNode localnode, final int i) { + if (i == nodetypekeylist.size()) { + return; + } + final VisitorEnum next= nodetypekeylist.get(i); + ASTProcessor.NodeHolder nodeHolder= nodetypelist.get(next); + BiPredicate biPredicate= nodeHolder.callee; + HelperVisitor hv= new HelperVisitor<>(nodesprocessed, dataholder); + if (nodeHolder.object != null) { + hv.add(nodeHolder.object, next, (node, holder) -> { + boolean test= biPredicate.test(node, holder); + if (nodeHolder.navigate != null) { + process(nodeHolder.navigate.apply(node), i + 1); + } else { + process(node, i + 1); + } + return test; + }); + } else { + hv.add(next, (node, holder) -> { + boolean test= biPredicate.test(node, holder); + if (nodeHolder.navigate != null) { + process(nodeHolder.navigate.apply(node), i + 1); + } else { + process(node, i + 1); + } + return test; + }); + } + hv.build(localnode); + } + + + +} diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/HelperVisitor.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/HelperVisitor.java new file mode 100644 index 00000000..3ea19f4b --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/HelperVisitor.java @@ -0,0 +1,8988 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer + *******************************************************************************/ +package org.eclipse.jdt.internal.common; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BiPredicate; + +import org.eclipse.jdt.core.dom.*; + +/** + * This class allows to use Lambda expressions for building up your visitor processing + * + * @author chammer + * + * @param - type extending HelperVisitorProvider mapping V -> E entries + * @param - key type for HelperVisitorProvider + * @param - value type for HelperVisitorProvider + */ +public class HelperVisitor,V,T> { + + ASTVisitor astvisitor; + + /** + * + */ + public E dataholder; + + /** + * This map contains one VisitorSupplier per kind if supplied Each BiPredicate is called with + * two parameters 1) ASTNode 2) your data object Call is processed when build(ASTNode) is + * called. + */ + Map> predicatemap; + + /** + * This map contains one VisitorConsumer per kind if supplied Each BiConsumer is called with two + * parameters 1) ASTNode 2) your data object Call is processed when build(ASTNode) is called. + * Because the "visitend" does not return a boolean we need a consumer instead of a supplier + * here. + */ + Map> consumermap; + + /** + * Here we store data to implement convenience methods like method visitor where the method name + * can be given as parameter + */ + Map predicatedata; + + Map consumerdata; + + /** + * + * @return - Map of visitor kinds -> BiPredicates + */ + public Map> getSuppliermap() { + return predicatemap; + } + + /** + * + * @return - Map of visitor kinds -> BiConsumers + */ + public Map> getConsumermap() { + return consumermap; + } + + /** + * + */ + public Set nodesprocessed; + + /** + * + * @return - set of nodes processed + */ + public Set getNodesprocessed() { + return nodesprocessed; + } + + /** + * + * @param nodesprocessed - set of nodes processed + * @param dataholder - HelperVisitorProvider providing this HelperVisitor + */ + public HelperVisitor(Set nodesprocessed, E dataholder) { + this.predicatemap= new LinkedHashMap<>(); + this.consumermap= new LinkedHashMap<>(); + this.predicatedata= new HashMap<>(); + this.consumerdata= new HashMap<>(); + + this.dataholder= dataholder; + dataholder.setHelperVisitor(this); + this.nodesprocessed= nodesprocessed; + } + + /** + * + * @param node - ASTNode + * @return - HelperVisitor + */ + public HelperVisitor build(ASTNode node) { + return build(node, false); + } + + /** + * + * @param node - ASTNode + * @param visitjavadoc - true if Javadoc comments should be visited + * @return - HelperVisitor + */ + public HelperVisitor build(ASTNode node, boolean visitjavadoc) { + astvisitor= new LambdaASTVisitor<>(this, visitjavadoc); + node.accept(astvisitor); + return this; + } + + /** + * Add BiPredicate for visitor kind + * + * @param key - visitor kind + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate added or null + */ + public BiPredicate add(VisitorEnum key, BiPredicate bs) { + return predicatemap.put(key, bs); + } + + /** + * Add BiPrediate for visitor kind with additional Object + * + * @param object - additional Object to put in predicate map + * @param key - visitor kind + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate added or null + */ + public BiPredicate add(Object object, VisitorEnum key, BiPredicate bs) { + this.predicatedata.put(key, object); + return predicatemap.put(key, bs); + } + + /** + * Add BiConsumer for visitor kind to consumer map + * + * @param key - visitor kind + * @param bc - BiConsumer + * @return - previous BiConsumer for visitor kind or null + */ + public BiConsumer addEnd(VisitorEnum key, BiConsumer bc) { + return consumermap.put(key, bc); + } + + /** + * Add BiPredidate and BiConsumer to predicate and consumer maps + * + * @param key - visitor kind + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc - BiConsumer + */ + public void add(VisitorEnum key, BiPredicate bs, BiConsumer bc) { + predicatemap.put(key, bs); + consumermap.put(key, bc); + } + + /** + * Remove visitor kind entries from predicate and consumer maps + * + * @param ve - visitor kind + */ + public void removeVisitor(VisitorEnum ve) { + this.predicatemap.remove(ve); + this.consumermap.remove(ve); + } + + /** + * Get consumer map + * + * @return - Map of visitor kind to consumer + */ + protected Map getConsumerData() { + return this.consumerdata; + } + + /** + * Get predicate map + * + * @return - Map of visitor kind to predicate + */ + protected Map getSupplierData() { + return this.predicatedata; + } + + /** + * Add BiPredicate to use for AnnotationTypeDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate for annotation type declaration + */ + public BiPredicate addAnnotationTypeDeclaration( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.AnnotationTypeDeclaration, bs); + } + + /** + * Add BiPredicate to use for AnnotationTypeMemberDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addAnnotationTypeMemberDeclaration( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.AnnotationTypeMemberDeclaration, bs); + } + + /** + * Add BiPredicate to use for AnonymousClassDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addAnonymousClassDeclaration( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.AnonymousClassDeclaration, bs); + } + + /** + * Add BiPredicate to use for ArrayAccess visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addArrayAccess(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ArrayAccess, bs); + } + + /** + * Add BiPredicate to use for ArrayCreation visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addArrayCreation(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ArrayCreation, bs); + } + + /** + * Add BiPredicate to use for ArrayInitializer visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addArrayInitializer(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ArrayInitializer, bs); + } + + /** + * Add BiPredicat to use for ArrayType visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addArrayType(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ArrayType, bs); + } + + /** + * Add BiPredicate to use for AssertStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addAssertStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.AssertStatement, bs); + } + + /** + * Add BiPredicate to use for Assignment visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addAssignment(BiPredicate bs) { + return predicatemap.put(VisitorEnum.Assignment, bs); + } + + /** + * Add BiPredicate to use for Block visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addBlock(BiPredicate bs) { + return predicatemap.put(VisitorEnum.Block, bs); + } + + /** + * Add BiPredicate to use for BlockComment visit + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addBlockComment(BiPredicate bs) { + return predicatemap.put(VisitorEnum.BlockComment, bs); + } + + /** + * Add BiPredicate to use for BooleanLiteral visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addBooleanLiteral(BiPredicate bs) { + return predicatemap.put(VisitorEnum.BooleanLiteral, bs); + } + + /** + * Add BiPredicate to use for BreakStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addBreakStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.BreakStatement, bs); + } + + /** + * Add BiPredicate to use for CastExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addCastExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.CastExpression, bs); + } + + /** + * Add BiPredicate to use for CatchClause visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addCatchClause(BiPredicate bs) { + return predicatemap.put(VisitorEnum.CatchClause, bs); + } + + /** + * Add BiPredicate to use for CharacterLiteral visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addCharacterLiteral(BiPredicate bs) { + return predicatemap.put(VisitorEnum.CharacterLiteral, bs); + } + + /** + * Add BiPredicate to use for ClassInstanceCreation visit + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addClassInstanceCreation(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ClassInstanceCreation, bs); + } + + /** + * Add BiPredicate to use for CompilationUnit visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addCompilationUnit(BiPredicate bs) { + return predicatemap.put(VisitorEnum.CompilationUnit, bs); + } + + /** + * Add BiPredicate to use for ConditionalExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addConditionalExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ConditionalExpression, bs); + } + + /** + * Add BiPredicate to use for ConstructorInvocation visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addConstructorInvocation(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ConstructorInvocation, bs); + } + + /** + * Add BiPredicate to use for ContinueStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addContinueStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ContinueStatement, bs); + } + + /** + * Add BiPredicate to use for CreationReference visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addCreationReference(BiPredicate bs) { + return predicatemap.put(VisitorEnum.CreationReference, bs); + } + + /** + * Add BiPredicate to use for Dimension visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addDimension(BiPredicate bs) { + return predicatemap.put(VisitorEnum.Dimension, bs); + } + + /** + * Add BiPredicate to use for DoStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addDoStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.DoStatement, bs); + } + + /** + * Add BiPredicate to use for EmptyStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addEmptyStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.EmptyStatement, bs); + } + + /** + * Add BiPredicate to use for EnhancedForStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addEnhancedForStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.EnhancedForStatement, bs); + } + + /** + * Add BiPredicate to use for EnumConstantDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addEnumConstantDeclaration(BiPredicate bs) { + return predicatemap.put(VisitorEnum.EnumConstantDeclaration, bs); + } + + /** + * Add BiPredicate to use for EnumDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addEnumDeclaration(BiPredicate bs) { + return predicatemap.put(VisitorEnum.EnumDeclaration, bs); + } + + /** + * Add BiPredicate to use for ExportsDirective visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addExportsDirective(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ExportsDirective, bs); + } + + /** + * Add BiPredicate to use for ExpressionMethodReference visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addExpressionMethodReference( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.ExpressionMethodReference, bs); + } + + /** + * Add BiPredicate to use for ExpressionStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addExpressionStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ExpressionStatement, bs); + } + + /** + * Add BiPredicate to use for FieldAccess visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addFieldAccess(BiPredicate bs) { + return predicatemap.put(VisitorEnum.FieldAccess, bs); + } + + /** + * Add BiPredicate to use for FieldDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addFieldDeclaration(BiPredicate bs) { + return predicatemap.put(VisitorEnum.FieldDeclaration, bs); + } + + /** + * Add BiPredicate to use for a ForStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addForStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ForStatement, bs); + } + + /** + * Add BiPredicate to use for IfStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addIfStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.IfStatement, bs); + } + + /** + * Add BiPredicate to use for ImportDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addImportDeclaration(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ImportDeclaration, bs); + } + + /** + * Add BiPredicate to use for InfixExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addInfixExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.InfixExpression, bs); + } + + /** + * Add BiPredicate to use for Initializer visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addInitializer(BiPredicate bs) { + return predicatemap.put(VisitorEnum.Initializer, bs); + } + + /** + * Add BiPredicate to use for InstanceofExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addInstanceofExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.InstanceofExpression, bs); + } + + /** + * Add BiPredicate to use for IntersectionType visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addIntersectionType(BiPredicate bs) { + return predicatemap.put(VisitorEnum.IntersectionType, bs); + } + + /** + * Add BiPredicate to use for Javadoc visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addJavadoc(BiPredicate bs) { + return predicatemap.put(VisitorEnum.Javadoc, bs); + } + + /** + * Add BiPredicate to use for LabeledStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addLabeledStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.LabeledStatement, bs); + } + + /** + * Add BiPredicate to use for LambdaExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addLambdaExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.LambdaExpression, bs); + } + + /** + * Add BiPredicate to use for LineComment visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addLineComment(BiPredicate bs) { + return predicatemap.put(VisitorEnum.LineComment, bs); + } + + /** + * Add BiPredicate to use for MarkerAnnotation visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addMarkerAnnotation(BiPredicate bs) { + return predicatemap.put(VisitorEnum.MarkerAnnotation, bs); + } + + /** + * Add BiPredicate to use for MemberRef visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addMemberRef(BiPredicate bs) { + return predicatemap.put(VisitorEnum.MemberRef, bs); + } + + /** + * Add BiPredicate to use for MemberValuePair visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addMemberValuePair(BiPredicate bs) { + return predicatemap.put(VisitorEnum.MemberValuePair, bs); + } + + /** + * Add BiPredicate to use for MethodRef visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addMethodRef(BiPredicate bs) { + return predicatemap.put(VisitorEnum.MethodRef, bs); + } + + /** + * Add BiPredicate to use for MethodRefParameter visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addMethodRefParameter(BiPredicate bs) { + return predicatemap.put(VisitorEnum.MethodRefParameter, bs); + } + + /** + * Add BiPredicate to use for MethodDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addMethodDeclaration(BiPredicate bs) { + return predicatemap.put(VisitorEnum.MethodDeclaration, bs); + } + + /** + * Add BiPredicate to use for MethodInvocation visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addMethodInvocation(BiPredicate bs) { + return predicatemap.put(VisitorEnum.MethodInvocation, bs); + } + + /** + * Add BiPredicate to use for MethodInvocation visit where method name is specified + * + * @param methodname + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addMethodInvocation(String methodname, + BiPredicate bs) { + this.predicatedata.put(VisitorEnum.MethodInvocation, methodname); + return predicatemap.put(VisitorEnum.MethodInvocation, bs); + } + + /** + * Add BiPredicate to use for Modifier visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addModifier(BiPredicate bs) { + return predicatemap.put(VisitorEnum.Modifier, bs); + } + + /** + * Add BiPredicate to sue for ModuleDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addModuleDeclaration(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ModuleDeclaration, bs); + } + + /** + * Add BiPredicate to use for ModuleModifier visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addModuleModifier(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ModuleModifier, bs); + } + + /** + * Add BiPredicate to use for NameQualifiedType visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addNameQualifiedType(BiPredicate bs) { + return predicatemap.put(VisitorEnum.NameQualifiedType, bs); + } + + /** + * Add BiPredicate to use for NormalAnnotation visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addNormalAnnotation(BiPredicate bs) { + return predicatemap.put(VisitorEnum.NormalAnnotation, bs); + } + + /** + * Add BiPredicate to use for NullLiteral visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addNullLiteral(BiPredicate bs) { + return predicatemap.put(VisitorEnum.NullLiteral, bs); + } + + /** + * Add BiPredicate to use for NumberLiteral visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addNumberLiteral(BiPredicate bs) { + return predicatemap.put(VisitorEnum.NumberLiteral, bs); + } + + /** + * Add BiPredicate to use for OpensDirective visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addOpensDirective(BiPredicate bs) { + return predicatemap.put(VisitorEnum.OpensDirective, bs); + } + + /** + * Add BiPredicate to use for PackageDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addPackageDeclaration(BiPredicate bs) { + return predicatemap.put(VisitorEnum.PackageDeclaration, bs); + } + + /** + * Add BiPredicate to use for ParameterizedType visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addParameterizedType(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ParameterizedType, bs); + } + + /** + * Add BiPredicate to use for ParenthesizedExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addParenthesizedExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ParenthesizedExpression, bs); + } + + /** + * Add BiPredicate to use for InstanceofExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addPatternInstanceofExpression( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.PatternInstanceofExpression, bs); + } + + /** + * Add BiPredicate to use for PostfixExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addPostfixExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.PostfixExpression, bs); + } + + /** + * Add BiPredicate to use for PrefixExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addPrefixExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.PrefixExpression, bs); + } + + /** + * Add BiPredicate to use for ProvidesDirective visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addProvidesDirective(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ProvidesDirective, bs); + } + + /** + * Add BiPredicate to use for PrimitiveType visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addPrimitiveType(BiPredicate bs) { + return predicatemap.put(VisitorEnum.PrimitiveType, bs); + } + + /** + * Add BiPredicate to use for QualifiedName visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addQualifiedName(BiPredicate bs) { + return predicatemap.put(VisitorEnum.QualifiedName, bs); + } + + /** + * Add BiPredicate to use for QualifiedType visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addQualifiedType(BiPredicate bs) { + return predicatemap.put(VisitorEnum.QualifiedType, bs); + } + +// public BiPredicate addModuleQualifiedName( +// BiPredicate bs) { +// return predicatemap.put(VisitorEnum.ModuleQualifiedName, bs); +// } + + /** + * Add BiPredicate to use for RequiresdDirective visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + + public BiPredicate addRequiresDirective(BiPredicate bs) { + return predicatemap.put(VisitorEnum.RequiresDirective, bs); + } + + /** + * Add BiPredicate to use for RecordDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addRecordDeclaration(BiPredicate bs) { + return predicatemap.put(VisitorEnum.RecordDeclaration, bs); + } + + /** + * Add BiPredicate to use for ReturnStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addReturnStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ReturnStatement, bs); + } + + /** + * Add BiPredicate to use for SimpleName visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSimpleName(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SimpleName, bs); + } + + /** + * Add BiPredicate to use for SimpleType visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSimpleType(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SimpleType, bs); + } + + /** + * Add BiPredicate to use for SingleMemberAnnotation visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSingleMemberAnnotation(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SingleMemberAnnotation, bs); + } + + /** + * Add BiPredicate to use for SingleVariableDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSingleVariableDeclaration( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.SingleVariableDeclaration, bs); + } + + /** + * Add BiPredicate to use for StringLiteral visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addStringLiteral(BiPredicate bs) { + return predicatemap.put(VisitorEnum.StringLiteral, bs); + } + + /** + * Add BiPredicate to use for SuperConstructorInvocation visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSuperConstructorInvocation( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.SuperConstructorInvocation, bs); + } + + /** + * Add BiPredicate to use for SuperFieldAccess visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSuperFieldAccess(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SuperFieldAccess, bs); + } + + /** + * Add BiPredicate to use for SuperMethodInvocation visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSuperMethodInvocation(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SuperMethodInvocation, bs); + } + + /** + * Add BiPredicate to use for SuperMethodReference visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSuperMethodReference(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SuperMethodReference, bs); + } + + /** + * Add BiPredicate to use for SwitchCase visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSwitchCase(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SwitchCase, bs); + } + + /** + * Add BiPredicate to use for SwitchExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSwitchExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SwitchExpression, bs); + } + + /** + * Add BiPredicate to use for SwitchStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSwitchStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SwitchStatement, bs); + } + + /** + * Add BiPredicate to use for SynchronizedStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addSynchronizedStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.SynchronizedStatement, bs); + } + + /** + * Add BiPredicate to use for TagElement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addTagElement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.TagElement, bs); + } + + /** + * Add BiPredicate to use for TextBlock visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addTextBlock(BiPredicate bs) { + return predicatemap.put(VisitorEnum.TextBlock, bs); + } + + /** + * Add BiPredicate to use for TextElement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addTextElement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.TextElement, bs); + } + + /** + * Add BiPredicate to use for ThisExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addThisExpression(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ThisExpression, bs); + } + + /** + * Add BiPredicate to use for ThrowStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addThrowStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.ThrowStatement, bs); + } + + /** + * Add BiPredicate to use for TryStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addTryStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.TryStatement, bs); + } + + /** + * Add BiPredicate to use for TypeDeclaration visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addTypeDeclaration(BiPredicate bs) { + return predicatemap.put(VisitorEnum.TypeDeclaration, bs); + } + + /** + * Add BiPredicate to use for TypeDeclarationStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addTypeDeclarationStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.TypeDeclarationStatement, bs); + } + + /** + * Add BiPredicate to use for TypeLiteral visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addTypeLiteral(BiPredicate bs) { + return predicatemap.put(VisitorEnum.TypeLiteral, bs); + } + + /** + * Add BiPredicate to use for TypeMethodReference visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addTypeMethodReference(BiPredicate bs) { + return predicatemap.put(VisitorEnum.TypeMethodReference, bs); + } + + /** + * Add BiPredicate to use for TypeParameter visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addTypeParameter(BiPredicate bs) { + return predicatemap.put(VisitorEnum.TypeParameter, bs); + } + + /** + * Add BiPredicate to use for UnionType visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addUnionType(BiPredicate bs) { + return predicatemap.put(VisitorEnum.UnionType, bs); + } + + /** + * Add BiPredicate to use for UsesDirective visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addUsesDirective(BiPredicate bs) { + return predicatemap.put(VisitorEnum.UsesDirective, bs); + } + + /** + * Add BiPredicate to use for VariableDeclarationExpression visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addVariableDeclarationExpression( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.VariableDeclarationExpression, bs); + } + + /** + * Add BiPredicate to use for VariableDeclarationStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addVariableDeclarationStatement( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.VariableDeclarationStatement, bs); + } + + /** + * Add BiPredicate to use for VariableDeclarationStatement visit when type specified matches + * + * @param class1 - specified type to match for VariableDeclarationStatement + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addVariableDeclarationStatement(Class class1, + BiPredicate bs) { + this.predicatedata.put(VisitorEnum.VariableDeclarationStatement, class1); + return predicatemap.put(VisitorEnum.VariableDeclarationStatement, bs); + } + + /** + * Add BiPredicate to use for VariableDeclarationFragment visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addVariableDeclarationFragment( + BiPredicate bs) { + return predicatemap.put(VisitorEnum.VariableDeclarationFragment, bs); + } + + /** + * Add BiPredicate to use for WhileStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addWhileStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.WhileStatement, bs); + } + + /** + * Add BiPredicate to use for WildcardType visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addWildcardType(BiPredicate bs) { + return predicatemap.put(VisitorEnum.WildcardType, bs); + } + + /** + * Add BiPredicate to use for YieldStatement visit + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @return - previous BiPredicate registered + */ + public BiPredicate addYieldStatement(BiPredicate bs) { + return predicatemap.put(VisitorEnum.YieldStatement, bs); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addAnnotationTypeDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.AnnotationTypeDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addAnnotationTypeMemberDeclaration( + BiConsumer bc) { + return consumermap.put(VisitorEnum.AnnotationTypeMemberDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addAnonymousClassDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.AnonymousClassDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addArrayAccess(BiConsumer bc) { + return consumermap.put(VisitorEnum.ArrayAccess, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addArrayCreation(BiConsumer bc) { + return consumermap.put(VisitorEnum.ArrayCreation, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addArrayInitializer(BiConsumer bc) { + return consumermap.put(VisitorEnum.ArrayInitializer, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addArrayType(BiConsumer bc) { + return consumermap.put(VisitorEnum.ArrayType, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addAssertStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.AssertStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addAssignment(BiConsumer bc) { + return consumermap.put(VisitorEnum.Assignment, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addBlock(BiConsumer bc) { + return consumermap.put(VisitorEnum.Block, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addBlockComment(BiConsumer bc) { + return consumermap.put(VisitorEnum.BlockComment, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addBooleanLiteral(BiConsumer bc) { + return consumermap.put(VisitorEnum.BooleanLiteral, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addBreakStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.BreakStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addCastExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.CastExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addCatchClause(BiConsumer bc) { + return consumermap.put(VisitorEnum.CatchClause, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addCharacterLiteral(BiConsumer bc) { + return consumermap.put(VisitorEnum.CharacterLiteral, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addClassInstanceCreation(BiConsumer bc) { + return consumermap.put(VisitorEnum.ClassInstanceCreation, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addCompilationUnit(BiConsumer bc) { + return consumermap.put(VisitorEnum.CompilationUnit, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addConditionalExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.ConditionalExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addConstructorInvocation(BiConsumer bc) { + return consumermap.put(VisitorEnum.ConstructorInvocation, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addContinueStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.ContinueStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addCreationReference(BiConsumer bc) { + return consumermap.put(VisitorEnum.CreationReference, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addDimension(BiConsumer bc) { + return consumermap.put(VisitorEnum.Dimension, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addDoStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.DoStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addEmptyStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.EmptyStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addEnhancedForStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.EnhancedForStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addEnumConstantDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.EnumConstantDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addEnumDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.EnumDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addExportsDirective(BiConsumer bc) { + return consumermap.put(VisitorEnum.ExportsDirective, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addExpressionMethodReference(BiConsumer bc) { + return consumermap.put(VisitorEnum.ExpressionMethodReference, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addExpressionStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.ExpressionStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addFieldAccess(BiConsumer bc) { + return consumermap.put(VisitorEnum.FieldAccess, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addFieldDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.FieldDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addForStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.ForStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addIfStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.IfStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addImportDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.ImportDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addInfixExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.InfixExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addInitializer(BiConsumer bc) { + return consumermap.put(VisitorEnum.Initializer, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addInstanceofExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.InstanceofExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addIntersectionType(BiConsumer bc) { + return consumermap.put(VisitorEnum.IntersectionType, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addJavadoc(BiConsumer bc) { + return consumermap.put(VisitorEnum.Javadoc, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addLabeledStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.LabeledStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addLambdaExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.LambdaExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addLineComment(BiConsumer bc) { + return consumermap.put(VisitorEnum.LineComment, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addMarkerAnnotation(BiConsumer bc) { + return consumermap.put(VisitorEnum.MarkerAnnotation, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addMemberRef(BiConsumer bc) { + return consumermap.put(VisitorEnum.MemberRef, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addMemberValuePair(BiConsumer bc) { + return consumermap.put(VisitorEnum.MemberValuePair, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addMethodRef(BiConsumer bc) { + return consumermap.put(VisitorEnum.MethodRef, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addMethodRefParameter(BiConsumer bc) { + return consumermap.put(VisitorEnum.MethodRefParameter, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addMethodDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.MethodDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addMethodInvocation(BiConsumer bc) { + return consumermap.put(VisitorEnum.MethodInvocation, bc); + } + + /** + * + * @param methodname + * @param bc + * @return + */ + public BiConsumer addMethodInvocation(String methodname, BiConsumer bc) { + this.consumerdata.put(VisitorEnum.MethodInvocation, methodname); + return consumermap.put(VisitorEnum.MethodInvocation, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addModifier(BiConsumer bc) { + return consumermap.put(VisitorEnum.Modifier, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addModuleDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.ModuleDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addModuleModifier(BiConsumer bc) { + return consumermap.put(VisitorEnum.ModuleModifier, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addNameQualifiedType(BiConsumer bc) { + return consumermap.put(VisitorEnum.NameQualifiedType, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addNormalAnnotation(BiConsumer bc) { + return consumermap.put(VisitorEnum.NormalAnnotation, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addNullLiteral(BiConsumer bc) { + return consumermap.put(VisitorEnum.NullLiteral, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addNumberLiteral(BiConsumer bc) { + return consumermap.put(VisitorEnum.NumberLiteral, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addOpensDirective(BiConsumer bc) { + return consumermap.put(VisitorEnum.OpensDirective, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addPackageDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.PackageDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addParameterizedType(BiConsumer bc) { + return consumermap.put(VisitorEnum.ParameterizedType, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addParenthesizedExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.ParenthesizedExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addPatternInstanceofExpression( + BiConsumer bc) { + return consumermap.put(VisitorEnum.PatternInstanceofExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addPostfixExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.PostfixExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addPrefixExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.PrefixExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addProvidesDirective(BiConsumer bc) { + return consumermap.put(VisitorEnum.ProvidesDirective, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addPrimitiveType(BiConsumer bc) { + return consumermap.put(VisitorEnum.PrimitiveType, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addQualifiedName(BiConsumer bc) { + return consumermap.put(VisitorEnum.QualifiedName, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addQualifiedType(BiConsumer bc) { + return consumermap.put(VisitorEnum.QualifiedType, bc); + } + +// public BiConsumer addModuleQualifiedName(BiConsumer bc) { +// return consumermap.put(VisitorEnum.ModuleQualifiedName, bc); +// } + + /** + * + * @param bc + * @return + */ + + public BiConsumer addRequiresDirective(BiConsumer bc) { + return consumermap.put(VisitorEnum.RequiresDirective, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addRecordDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.RecordDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addReturnStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.ReturnStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSimpleName(BiConsumer bc) { + return consumermap.put(VisitorEnum.SimpleName, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSimpleType(BiConsumer bc) { + return consumermap.put(VisitorEnum.SimpleType, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSingleMemberAnnotation(BiConsumer bc) { + return consumermap.put(VisitorEnum.SingleMemberAnnotation, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSingleVariableDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.SingleVariableDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addStringLiteral(BiConsumer bc) { + return consumermap.put(VisitorEnum.StringLiteral, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSuperConstructorInvocation( + BiConsumer bc) { + return consumermap.put(VisitorEnum.SuperConstructorInvocation, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSuperFieldAccess(BiConsumer bc) { + return consumermap.put(VisitorEnum.SuperFieldAccess, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSuperMethodInvocation(BiConsumer bc) { + return consumermap.put(VisitorEnum.SuperMethodInvocation, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSuperMethodReference(BiConsumer bc) { + return consumermap.put(VisitorEnum.SuperMethodReference, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSwitchCase(BiConsumer bc) { + return consumermap.put(VisitorEnum.SwitchCase, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSwitchExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.SwitchExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSwitchStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.SwitchStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addSynchronizedStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.SynchronizedStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addTagElement(BiConsumer bc) { + return consumermap.put(VisitorEnum.TagElement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addTextBlock(BiConsumer bc) { + return consumermap.put(VisitorEnum.TextBlock, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addTextElement(BiConsumer bc) { + return consumermap.put(VisitorEnum.TextElement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addThisExpression(BiConsumer bc) { + return consumermap.put(VisitorEnum.ThisExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addThrowStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.ThrowStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addTryStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.TryStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addTypeDeclaration(BiConsumer bc) { + return consumermap.put(VisitorEnum.TypeDeclaration, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addTypeDeclarationStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.TypeDeclarationStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addTypeLiteral(BiConsumer bc) { + return consumermap.put(VisitorEnum.TypeLiteral, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addTypeMethodReference(BiConsumer bc) { + return consumermap.put(VisitorEnum.TypeMethodReference, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addTypeParameter(BiConsumer bc) { + return consumermap.put(VisitorEnum.TypeParameter, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addUnionType(BiConsumer bc) { + return consumermap.put(VisitorEnum.UnionType, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addUsesDirective(BiConsumer bc) { + return consumermap.put(VisitorEnum.UsesDirective, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addVariableDeclarationExpression( + BiConsumer bc) { + return consumermap.put(VisitorEnum.VariableDeclarationExpression, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addVariableDeclarationStatement( + BiConsumer bc) { + return consumermap.put(VisitorEnum.VariableDeclarationStatement, bc); + } + + /** + * + * @param class1 + * @param bc + * @return + */ + public BiConsumer addVariableDeclarationStatement(Class class1, + BiConsumer bc) { + this.consumerdata.put(VisitorEnum.VariableDeclarationStatement, class1); + return consumermap.put(VisitorEnum.VariableDeclarationStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addVariableDeclarationFragment( + BiConsumer bc) { + return consumermap.put(VisitorEnum.VariableDeclarationFragment, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addWhileStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.WhileStatement, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addWildcardType(BiConsumer bc) { + return consumermap.put(VisitorEnum.WildcardType, bc); + } + + /** + * + * @param bc + * @return + */ + public BiConsumer addYieldStatement(BiConsumer bc) { + return consumermap.put(VisitorEnum.YieldStatement, bc); + } + + + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addAnnotationTypeDeclaration(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.AnnotationTypeDeclaration, bs); + consumermap.put(VisitorEnum.AnnotationTypeDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addAnnotationTypeMemberDeclaration(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.AnnotationTypeMemberDeclaration, bs); + consumermap.put(VisitorEnum.AnnotationTypeMemberDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addAnonymousClassDeclaration(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.AnonymousClassDeclaration, bs); + consumermap.put(VisitorEnum.AnonymousClassDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addArrayAccess(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ArrayAccess, bs); + consumermap.put(VisitorEnum.ArrayAccess, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addArrayCreation(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ArrayCreation, bs); + consumermap.put(VisitorEnum.ArrayCreation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addArrayInitializer(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ArrayInitializer, bs); + consumermap.put(VisitorEnum.ArrayInitializer, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addArrayType(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ArrayType, bs); + consumermap.put(VisitorEnum.ArrayType, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addAssertStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.AssertStatement, bs); + consumermap.put(VisitorEnum.AssertStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addAssignment(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.Assignment, bs); + consumermap.put(VisitorEnum.Assignment, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addBlock(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.Block, bs); + consumermap.put(VisitorEnum.Block, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addBlockComment(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.BlockComment, bs); + consumermap.put(VisitorEnum.BlockComment, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addBooleanLiteral(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.BooleanLiteral, bs); + consumermap.put(VisitorEnum.BooleanLiteral, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addBreakStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.BreakStatement, bs); + consumermap.put(VisitorEnum.BreakStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addCastExpression(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.CastExpression, bs); + consumermap.put(VisitorEnum.CastExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addCatchClause(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.CatchClause, bs); + consumermap.put(VisitorEnum.CatchClause, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addCharacterLiteral(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.CharacterLiteral, bs); + consumermap.put(VisitorEnum.CharacterLiteral, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addClassInstanceCreation(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.ClassInstanceCreation, bs); + consumermap.put(VisitorEnum.ClassInstanceCreation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addCompilationUnit(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.CompilationUnit, bs); + consumermap.put(VisitorEnum.CompilationUnit, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addConditionalExpression(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.ConditionalExpression, bs); + consumermap.put(VisitorEnum.ConditionalExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addConstructorInvocation(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.ConstructorInvocation, bs); + consumermap.put(VisitorEnum.ConstructorInvocation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addContinueStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ContinueStatement, bs); + consumermap.put(VisitorEnum.ContinueStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addCreationReference(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.CreationReference, bs); + consumermap.put(VisitorEnum.CreationReference, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addDimension(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.Dimension, bs); + consumermap.put(VisitorEnum.Dimension, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addDoStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.DoStatement, bs); + consumermap.put(VisitorEnum.DoStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addEmptyStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.EmptyStatement, bs); + consumermap.put(VisitorEnum.EmptyStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addEnhancedForStatement(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.EnhancedForStatement, bs); + consumermap.put(VisitorEnum.EnhancedForStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addEnumConstantDeclaration(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.EnumConstantDeclaration, bs); + consumermap.put(VisitorEnum.EnumConstantDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addEnumDeclaration(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.EnumDeclaration, bs); + consumermap.put(VisitorEnum.EnumDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addExportsDirective(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ExportsDirective, bs); + consumermap.put(VisitorEnum.ExportsDirective, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addExpressionMethodReference(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.ExpressionMethodReference, bs); + consumermap.put(VisitorEnum.ExpressionMethodReference, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addExpressionStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ExpressionStatement, bs); + consumermap.put(VisitorEnum.ExpressionStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addFieldAccess(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.FieldAccess, bs); + consumermap.put(VisitorEnum.FieldAccess, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addFieldDeclaration(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.FieldDeclaration, bs); + consumermap.put(VisitorEnum.FieldDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addForStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ForStatement, bs); + consumermap.put(VisitorEnum.ForStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addIfStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.IfStatement, bs); + consumermap.put(VisitorEnum.IfStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addImportDeclaration(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ImportDeclaration, bs); + consumermap.put(VisitorEnum.ImportDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addInfixExpression(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.InfixExpression, bs); + consumermap.put(VisitorEnum.InfixExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addInitializer(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.Initializer, bs); + consumermap.put(VisitorEnum.Initializer, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addInstanceofExpression(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.InstanceofExpression, bs); + consumermap.put(VisitorEnum.InstanceofExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addIntersectionType(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.IntersectionType, bs); + consumermap.put(VisitorEnum.IntersectionType, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addJavadoc(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.Javadoc, bs); + consumermap.put(VisitorEnum.Javadoc, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addLabeledStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.LabeledStatement, bs); + consumermap.put(VisitorEnum.LabeledStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addLambdaExpression(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.LambdaExpression, bs); + consumermap.put(VisitorEnum.LambdaExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addLineComment(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.LineComment, bs); + consumermap.put(VisitorEnum.LineComment, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addMarkerAnnotation(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.MarkerAnnotation, bs); + consumermap.put(VisitorEnum.MarkerAnnotation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addMemberRef(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.MemberRef, bs); + consumermap.put(VisitorEnum.MemberRef, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addMemberValuePair(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.MemberValuePair, bs); + consumermap.put(VisitorEnum.MemberValuePair, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addMethodRef(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.MethodRef, bs); + consumermap.put(VisitorEnum.MethodRef, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addMethodRefParameter(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.MethodRefParameter, bs); + consumermap.put(VisitorEnum.MethodRefParameter, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addMethodDeclaration(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.MethodDeclaration, bs); + consumermap.put(VisitorEnum.MethodDeclaration, bc); + } + + /** + * + * @param methodname + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addMethodInvocation(String methodname, BiPredicate bs, + BiConsumer bc) { + this.predicatedata.put(VisitorEnum.MethodInvocation, methodname); + predicatemap.put(VisitorEnum.MethodInvocation, bs); + consumermap.put(VisitorEnum.MethodInvocation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addMethodInvocation(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.MethodInvocation, bs); + consumermap.put(VisitorEnum.MethodInvocation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addModifier(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.Modifier, bs); + consumermap.put(VisitorEnum.Modifier, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addModuleDeclaration(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ModuleDeclaration, bs); + consumermap.put(VisitorEnum.ModuleDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addModuleModifier(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ModuleModifier, bs); + consumermap.put(VisitorEnum.ModuleModifier, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addNameQualifiedType(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.NameQualifiedType, bs); + consumermap.put(VisitorEnum.NameQualifiedType, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addNormalAnnotation(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.NormalAnnotation, bs); + consumermap.put(VisitorEnum.NormalAnnotation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addNullLiteral(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.NullLiteral, bs); + consumermap.put(VisitorEnum.NullLiteral, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addNumberLiteral(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.NumberLiteral, bs); + consumermap.put(VisitorEnum.NumberLiteral, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addOpensDirective(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.OpensDirective, bs); + consumermap.put(VisitorEnum.OpensDirective, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addPackageDeclaration(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.PackageDeclaration, bs); + consumermap.put(VisitorEnum.PackageDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addParameterizedType(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ParameterizedType, bs); + consumermap.put(VisitorEnum.ParameterizedType, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addParenthesizedExpression(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.ParenthesizedExpression, bs); + consumermap.put(VisitorEnum.ParenthesizedExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addPatternInstanceofExpression(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.PatternInstanceofExpression, bs); + consumermap.put(VisitorEnum.PatternInstanceofExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addPostfixExpression(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.PostfixExpression, bs); + consumermap.put(VisitorEnum.PostfixExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addPrefixExpression(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.PrefixExpression, bs); + consumermap.put(VisitorEnum.PrefixExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addProvidesDirective(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ProvidesDirective, bs); + consumermap.put(VisitorEnum.ProvidesDirective, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addPrimitiveType(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.PrimitiveType, bs); + consumermap.put(VisitorEnum.PrimitiveType, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addQualifiedName(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.QualifiedName, bs); + consumermap.put(VisitorEnum.QualifiedName, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addQualifiedType(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.QualifiedType, bs); + consumermap.put(VisitorEnum.QualifiedType, bc); + } + +// public void addModuleQualifiedName(BiPredicate bs, +// BiConsumer bc) { +// predicatemap.put(VisitorEnum.ModuleQualifiedName, bs); +// consumermap.put(VisitorEnum.ModuleQualifiedName, bc); +// } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + + public void addRequiresDirective(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.RequiresDirective, bs); + consumermap.put(VisitorEnum.RequiresDirective, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addRecordDeclaration(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.RecordDeclaration, bs); + consumermap.put(VisitorEnum.RecordDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addReturnStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ReturnStatement, bs); + consumermap.put(VisitorEnum.ReturnStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSimpleName(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.SimpleName, bs); + consumermap.put(VisitorEnum.SimpleName, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSimpleType(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.SimpleType, bs); + consumermap.put(VisitorEnum.SimpleType, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSingleMemberAnnotation(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.SingleMemberAnnotation, bs); + consumermap.put(VisitorEnum.SingleMemberAnnotation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSingleVariableDeclaration(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.SingleVariableDeclaration, bs); + consumermap.put(VisitorEnum.SingleVariableDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addStringLiteral(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.StringLiteral, bs); + consumermap.put(VisitorEnum.StringLiteral, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSuperConstructorInvocation(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.SuperConstructorInvocation, bs); + consumermap.put(VisitorEnum.SuperConstructorInvocation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSuperFieldAccess(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.SuperFieldAccess, bs); + consumermap.put(VisitorEnum.SuperFieldAccess, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSuperMethodInvocation(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.SuperMethodInvocation, bs); + consumermap.put(VisitorEnum.SuperMethodInvocation, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSuperMethodReference(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.SuperMethodReference, bs); + consumermap.put(VisitorEnum.SuperMethodReference, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSwitchCase(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.SwitchCase, bs); + consumermap.put(VisitorEnum.SwitchCase, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSwitchExpression(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.SwitchExpression, bs); + consumermap.put(VisitorEnum.SwitchExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSwitchStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.SwitchStatement, bs); + consumermap.put(VisitorEnum.SwitchStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addSynchronizedStatement(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.SynchronizedStatement, bs); + consumermap.put(VisitorEnum.SynchronizedStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addTagElement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.TagElement, bs); + consumermap.put(VisitorEnum.TagElement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addTextBlock(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.TextBlock, bs); + consumermap.put(VisitorEnum.TextBlock, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addTextElement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.TextElement, bs); + consumermap.put(VisitorEnum.TextElement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addThisExpression(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ThisExpression, bs); + consumermap.put(VisitorEnum.ThisExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addThrowStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.ThrowStatement, bs); + consumermap.put(VisitorEnum.ThrowStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addTryStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.TryStatement, bs); + consumermap.put(VisitorEnum.TryStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addTypeDeclaration(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.TypeDeclaration, bs); + consumermap.put(VisitorEnum.TypeDeclaration, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addTypeDeclarationStatement(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.TypeDeclarationStatement, bs); + consumermap.put(VisitorEnum.TypeDeclarationStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addTypeLiteral(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.TypeLiteral, bs); + consumermap.put(VisitorEnum.TypeLiteral, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addTypeMethodReference(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.TypeMethodReference, bs); + consumermap.put(VisitorEnum.TypeMethodReference, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addTypeParameter(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.TypeParameter, bs); + consumermap.put(VisitorEnum.TypeParameter, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addUnionType(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.UnionType, bs); + consumermap.put(VisitorEnum.UnionType, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addUsesDirective(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.UsesDirective, bs); + consumermap.put(VisitorEnum.UsesDirective, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addVariableDeclarationExpression(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.VariableDeclarationExpression, bs); + consumermap.put(VisitorEnum.VariableDeclarationExpression, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addVariableDeclarationStatement(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.VariableDeclarationStatement, bs); + consumermap.put(VisitorEnum.VariableDeclarationStatement, bc); + } + + /** + * + * @param class1 + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addVariableDeclarationStatement(Class class1, BiPredicate bs, + BiConsumer bc) { + predicatedata.put(VisitorEnum.VariableDeclarationStatement, class1); + consumerdata.put(VisitorEnum.VariableDeclarationStatement, class1); + predicatemap.put(VisitorEnum.VariableDeclarationStatement, bs); + consumermap.put(VisitorEnum.VariableDeclarationStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addVariableDeclarationFragment(BiPredicate bs, + BiConsumer bc) { + predicatemap.put(VisitorEnum.VariableDeclarationFragment, bs); + consumermap.put(VisitorEnum.VariableDeclarationFragment, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addWhileStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.WhileStatement, bs); + consumermap.put(VisitorEnum.WhileStatement, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addWildcardType(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.WildcardType, bs); + consumermap.put(VisitorEnum.WildcardType, bc); + } + + /** + * + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public void addYieldStatement(BiPredicate bs, BiConsumer bc) { + predicatemap.put(VisitorEnum.YieldStatement, bs); + consumermap.put(VisitorEnum.YieldStatement, bc); + } + + + + /** + * + * @param + * @param + * @param cu + * @param myset + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callVisitor(ASTNode cu, EnumSet myset, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor, V, T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + myset.forEach(ve -> { + hv.add(ve, bs, bc); + }); + hv.build(cu); + } + + /** + * + * @param + * @param + * @param cu + * @param myset + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callVisitor(ASTNode cu, EnumSet myset, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + myset.forEach(ve -> { + hv.add(ve, bs); + }); + hv.build(cu); + } + + /** + * + * @param + * @param + * @param cu + * @param myset + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callVisitor(ASTNode cu, EnumSet myset, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + myset.forEach(ve -> { + hv.addEnd(ve, bc); + }); + hv.build(cu); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callAnnotationTypeDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAnnotationTypeDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callAnnotationTypeMemberDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAnnotationTypeMemberDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callAnonymousClassDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAnonymousClassDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callArrayAccessVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayAccess(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callArrayCreationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayCreation(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callArrayInitializerVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayInitializer(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callArrayTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayType(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callAssertStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAssertStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callAssignmentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAssignment(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callBlockVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBlock(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callBlockCommentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBlockComment(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callBooleanLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBooleanLiteral(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callBreakStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBreakStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callCastExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCastExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callCatchClauseVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCatchClause(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callCharacterLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCharacterLiteral(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callClassInstanceCreationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addClassInstanceCreation(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callCompilationUnitVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCompilationUnit(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callConditionalExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addConditionalExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callConstructorInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addConstructorInvocation(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callContinueStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addContinueStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callCreationReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCreationReference(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callDimensionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addDimension(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callDoStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addDoStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callEmptyStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEmptyStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callEnhancedForStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEnhancedForStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callEnumConstantDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEnumConstantDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callEnumDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEnumDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callExportsDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addExportsDirective(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callExpressionMethodReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addExpressionMethodReference(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callExpressionStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addExpressionStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callFieldAccessVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addFieldAccess(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callFieldDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addFieldDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callForStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addForStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callIfStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addIfStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callImportDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addImportDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callInfixExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addInfixExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callInitializerVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addInitializer(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callInstanceofExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addInstanceofExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callIntersectionTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addIntersectionType(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callJavadocVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addJavadoc(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callLabeledStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addLabeledStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callLambdaExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addLambdaExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callLineCommentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addLineComment(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callMarkerAnnotationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMarkerAnnotation(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callMemberRefVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMemberRef(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callMemberValuePairVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMemberValuePair(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callMethodRefVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodRef(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callMethodRefParameterVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodRefParameter(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callMethodDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callMethodInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodInvocation(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param methodname + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callMethodInvocationVisitor(String methodname, ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodInvocation(methodname, bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callModifierVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addModifier(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callModuleDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addModuleDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callModuleModifierVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addModuleModifier(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callNameQualifiedTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNameQualifiedType(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callNormalAnnotationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNormalAnnotation(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callNullLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNullLiteral(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callNumberLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNumberLiteral(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callOpensDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addOpensDirective(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callPackageDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPackageDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callParameterizedTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addParameterizedType(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callParenthesizedExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addParenthesizedExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callPatternInstanceofExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPatternInstanceofExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callPostfixExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPostfixExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callPrefixExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPrefixExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callProvidesDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addProvidesDirective(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callPrimitiveTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPrimitiveType(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callQualifiedNameVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addQualifiedName(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callQualifiedTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addQualifiedType(bs); + hv.build(node); + } + +// public static void callModuleQualifiedNameVisitor(ASTNode node, ReferenceHolder dataholder, BiPredicate> bs) { HelperVisitor> hv = new HelperVisitor<>(nodesprocessed, dataholder); hv.addModuleQualifiedName(bs); hv.build(node);} + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + + public static void callRequiresDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addRequiresDirective(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callRecordDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addRecordDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callReturnStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addReturnStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSimpleNameVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSimpleName(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSimpleTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSimpleType(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSingleMemberAnnotationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSingleMemberAnnotation(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSingleVariableDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSingleVariableDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callStringLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addStringLiteral(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSuperConstructorInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperConstructorInvocation(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSuperFieldAccessVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperFieldAccess(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSuperMethodInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperMethodInvocation(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSuperMethodReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperMethodReference(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSwitchCaseVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSwitchCase(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSwitchExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSwitchExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSwitchStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSwitchStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callSynchronizedStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSynchronizedStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callTagElementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTagElement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callTextBlockVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTextBlock(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callTextElementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTextElement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callThisExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addThisExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callThrowStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addThrowStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callTryStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTryStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callTypeDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeDeclaration(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callTypeDeclarationStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeDeclarationStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callTypeLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeLiteral(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callTypeMethodReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeMethodReference(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callTypeParameterVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeParameter(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callUnionTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addUnionType(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callUsesDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addUsesDirective(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callVariableDeclarationExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationExpression(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callVariableDeclarationStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param class1 + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callVariableDeclarationStatementVisitor(Class class1, ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationStatement(class1, bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callVariableDeclarationFragmentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationFragment(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callWhileStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addWhileStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callWildcardTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addWildcardType(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + */ + public static void callYieldStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addYieldStatement(bs); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callAnnotationTypeDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAnnotationTypeDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callAnnotationTypeMemberDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAnnotationTypeMemberDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callAnonymousClassDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAnonymousClassDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callArrayAccessVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayAccess(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callArrayCreationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayCreation(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callArrayInitializerVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayInitializer(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callArrayTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayType(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callAssertStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAssertStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callAssignmentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAssignment(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callBlockVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBlock(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callBlockCommentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBlockComment(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callBooleanLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBooleanLiteral(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callBreakStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBreakStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callCastExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCastExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callCatchClauseVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCatchClause(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callCharacterLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCharacterLiteral(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callClassInstanceCreationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addClassInstanceCreation(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callCompilationUnitVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCompilationUnit(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callConditionalExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addConditionalExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callConstructorInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addConstructorInvocation(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callContinueStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addContinueStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callCreationReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCreationReference(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callDimensionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addDimension(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callDoStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addDoStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callEmptyStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEmptyStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callEnhancedForStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEnhancedForStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callEnumConstantDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEnumConstantDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callEnumDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEnumDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callExportsDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addExportsDirective(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callExpressionMethodReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addExpressionMethodReference(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callExpressionStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addExpressionStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callFieldAccessVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addFieldAccess(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callFieldDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addFieldDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callForStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addForStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callIfStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addIfStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callImportDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addImportDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callInfixExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addInfixExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callInitializerVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addInitializer(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callInstanceofExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addInstanceofExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callIntersectionTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addIntersectionType(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callJavadocVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addJavadoc(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callLabeledStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addLabeledStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callLambdaExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addLambdaExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callLineCommentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addLineComment(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callMarkerAnnotationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMarkerAnnotation(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callMemberRefVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMemberRef(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callMemberValuePairVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMemberValuePair(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callMethodRefVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodRef(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callMethodRefParameterVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodRefParameter(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callMethodDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callMethodInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodInvocation(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callModifierVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addModifier(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callModuleDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addModuleDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callModuleModifierVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addModuleModifier(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callNameQualifiedTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNameQualifiedType(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callNormalAnnotationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNormalAnnotation(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callNullLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNullLiteral(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callNumberLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNumberLiteral(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callOpensDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addOpensDirective(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callPackageDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPackageDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callParameterizedTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addParameterizedType(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callParenthesizedExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addParenthesizedExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callPatternInstanceofExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPatternInstanceofExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callPostfixExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPostfixExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callPrefixExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPrefixExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callProvidesDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addProvidesDirective(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callPrimitiveTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPrimitiveType(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callQualifiedNameVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addQualifiedName(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callQualifiedTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addQualifiedType(bc); + hv.build(node); + } + +// public static void callModuleQualifiedNameVisitor(ASTNode node, ReferenceHolder dataholder, BiConsumer> bc) { HelperVisitor> hv = new HelperVisitor<>(nodesprocessed, dataholder); hv.addModuleQualifiedName(bc); hv.build(node);} + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + + public static void callRequiresDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addRequiresDirective(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callRecordDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addRecordDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callReturnStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addReturnStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSimpleNameVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSimpleName(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSimpleTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSimpleType(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSingleMemberAnnotationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSingleMemberAnnotation(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSingleVariableDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSingleVariableDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callStringLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addStringLiteral(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSuperConstructorInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperConstructorInvocation(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSuperFieldAccessVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperFieldAccess(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSuperMethodInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperMethodInvocation(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSuperMethodReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperMethodReference(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSwitchCaseVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSwitchCase(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSwitchExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSwitchExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSwitchStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSwitchStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callSynchronizedStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSynchronizedStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callTagElementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTagElement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callTextBlockVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTextBlock(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callTextElementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTextElement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callThisExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addThisExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callThrowStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addThrowStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callTryStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTryStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callTypeDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeDeclaration(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callTypeDeclarationStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeDeclarationStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callTypeLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeLiteral(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callTypeMethodReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeMethodReference(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callTypeParameterVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeParameter(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callUnionTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addUnionType(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callUsesDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addUsesDirective(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callVariableDeclarationExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationExpression(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callVariableDeclarationStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param class1 + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callVariableDeclarationStatementVisitor(Class class1, ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationStatement(class1, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callVariableDeclarationFragmentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationFragment(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callWhileStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addWhileStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callWildcardTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addWildcardType(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bc + */ + public static void callYieldStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addYieldStatement(bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callAnnotationTypeDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAnnotationTypeDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callAnnotationTypeMemberDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAnnotationTypeMemberDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callAnonymousClassDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAnonymousClassDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callArrayAccessVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayAccess(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callArrayCreationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayCreation(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callArrayInitializerVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayInitializer(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callArrayTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addArrayType(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callAssertStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAssertStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callAssignmentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addAssignment(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callBlockVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBlock(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callBlockCommentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBlockComment(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callBooleanLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBooleanLiteral(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callBreakStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addBreakStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callCastExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCastExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callCatchClauseVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCatchClause(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callCharacterLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCharacterLiteral(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callClassInstanceCreationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addClassInstanceCreation(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callCompilationUnitVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCompilationUnit(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callConditionalExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addConditionalExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callConstructorInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addConstructorInvocation(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callContinueStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addContinueStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callCreationReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addCreationReference(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callDimensionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addDimension(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callDoStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addDoStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callEmptyStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEmptyStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callEnhancedForStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEnhancedForStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callEnumConstantDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEnumConstantDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callEnumDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addEnumDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callExportsDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addExportsDirective(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callExpressionMethodReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addExpressionMethodReference(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callExpressionStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addExpressionStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callFieldAccessVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addFieldAccess(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callFieldDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addFieldDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callForStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addForStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callIfStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addIfStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callImportDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addImportDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callInfixExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addInfixExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callInitializerVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addInitializer(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callInstanceofExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addInstanceofExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callIntersectionTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addIntersectionType(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callJavadocVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addJavadoc(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callLabeledStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addLabeledStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callLambdaExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addLambdaExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callLineCommentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addLineComment(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callMarkerAnnotationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMarkerAnnotation(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callMemberRefVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMemberRef(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callMemberValuePairVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMemberValuePair(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callMethodRefVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodRef(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callMethodRefParameterVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodRefParameter(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callMethodDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callMethodInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addMethodInvocation(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callModifierVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addModifier(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callModuleDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addModuleDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callModuleModifierVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addModuleModifier(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callNameQualifiedTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNameQualifiedType(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callNormalAnnotationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNormalAnnotation(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callNullLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNullLiteral(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callNumberLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addNumberLiteral(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callOpensDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addOpensDirective(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callPackageDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPackageDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callParameterizedTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addParameterizedType(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callParenthesizedExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addParenthesizedExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callPatternInstanceofExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPatternInstanceofExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callPostfixExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPostfixExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callPrefixExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPrefixExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callProvidesDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addProvidesDirective(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callPrimitiveTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addPrimitiveType(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callQualifiedNameVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addQualifiedName(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callQualifiedTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addQualifiedType(bs, bc); + hv.build(node); + } + +// public static void callModuleQualifiedNameVisitor(ASTNode node, ReferenceHolder dataholder, BiPredicate> bs, BiConsumer> bc) { HelperVisitor> hv = new HelperVisitor<>(nodesprocessed, dataholder); hv.addModuleQualifiedName(bs,bc); hv.build(node);} + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + + public static void callRequiresDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addRequiresDirective(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callRecordDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addRecordDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callReturnStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addReturnStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSimpleNameVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSimpleName(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSimpleTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSimpleType(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSingleMemberAnnotationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSingleMemberAnnotation(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSingleVariableDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSingleVariableDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callStringLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addStringLiteral(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSuperConstructorInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperConstructorInvocation(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSuperFieldAccessVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperFieldAccess(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSuperMethodInvocationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperMethodInvocation(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSuperMethodReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSuperMethodReference(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSwitchCaseVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSwitchCase(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSwitchExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSwitchExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSwitchStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSwitchStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callSynchronizedStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addSynchronizedStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callTagElementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTagElement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callTextBlockVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTextBlock(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callTextElementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTextElement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callThisExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addThisExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callThrowStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addThrowStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callTryStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTryStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callTypeDeclarationVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeDeclaration(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callTypeDeclarationStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeDeclarationStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callTypeLiteralVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeLiteral(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callTypeMethodReferenceVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeMethodReference(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callTypeParameterVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addTypeParameter(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callUnionTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addUnionType(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callUsesDirectiveVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addUsesDirective(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callVariableDeclarationExpressionVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationExpression(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callVariableDeclarationStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param class1 + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callVariableDeclarationStatementVisitor(Class class1, ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationStatement(class1, bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callVariableDeclarationFragmentVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addVariableDeclarationFragment(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callWhileStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addWhileStatement(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callWildcardTypeVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addWildcardType(bs, bc); + hv.build(node); + } + + /** + * + * @param + * @param + * @param node + * @param dataholder + * @param nodesprocessed - set of nodes processed + * @param bs - BiPredicate that can be assigned a lambda expression + * @param bc + */ + public static void callYieldStatementVisitor(ASTNode node, ReferenceHolder dataholder, Set nodesprocessed, + BiPredicate> bs, + BiConsumer> bc) { + + HelperVisitor,V,T> hv= new HelperVisitor<>(nodesprocessed, dataholder); + hv.addYieldStatement(bs, bc); + hv.build(node); + } + + /** + * + */ + public void clear() { + this.consumermap.clear(); + this.consumerdata.clear(); + this.predicatemap.clear(); + this.predicatedata.clear(); + } + +} diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/HelperVisitorProvider.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/HelperVisitorProvider.java new file mode 100644 index 00000000..e1553a66 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/HelperVisitorProvider.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.common; + +/** + * + * @author chammer + * @param - type of key in HelperVisitor mapping + * @param - type of value in HelperVisitor mapping + * @param - type that extends HelperVisitorProvider providing HelperVisitor mapping V -> T + * + */ +public interface HelperVisitorProvider> { + /** + * @return - HelperVisitor + */ + HelperVisitor getHelperVisitor(); + + /** + * @param hv - HelperVisitor + */ + void setHelperVisitor(HelperVisitor hv); +} diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/LambdaASTVisitor.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/LambdaASTVisitor.java new file mode 100644 index 00000000..517d60fd --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/LambdaASTVisitor.java @@ -0,0 +1,1826 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.common; + +import java.util.function.BiConsumer; +import java.util.function.BiPredicate; + +import org.eclipse.jdt.core.dom.*; + +/** + * + * @author chammer + * + * @param - type that extends HelpVisitorProvider that provides HelperVisitor + * @param - type that HelperVisitor uses as map key type + * @param - type that HelperVisitor uses as map value type + */ +@SuppressWarnings("unchecked") +public class LambdaASTVisitor, V, T> extends ASTVisitor { + /** + * + */ + private final HelperVisitor helperVisitor; + + /** + * @param helperVisitor - HelperVisitor + */ + LambdaASTVisitor(HelperVisitor helperVisitor) { + super(false); + this.helperVisitor = helperVisitor; + } + + LambdaASTVisitor(HelperVisitor helperVisitor, boolean visitjavadoc) { + super(visitjavadoc); + this.helperVisitor = helperVisitor; + } + + @Override + public boolean visit(AnnotationTypeDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.AnnotationTypeDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.AnnotationTypeDeclaration))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(AnnotationTypeMemberDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.AnnotationTypeMemberDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.AnnotationTypeMemberDeclaration))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(AnonymousClassDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.AnonymousClassDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.AnonymousClassDeclaration))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ArrayAccess node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ArrayAccess)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ArrayAccess))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ArrayCreation node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ArrayCreation)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ArrayCreation))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ArrayInitializer node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ArrayInitializer)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ArrayInitializer))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ArrayType node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ArrayType)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ArrayType))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(AssertStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.AssertStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.AssertStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(Assignment node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.Assignment)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.Assignment))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(Block node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.Block)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.Block))).test(node, this.helperVisitor.dataholder) + ; + } + return true; + } + + @Override + public boolean visit(BlockComment node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.BlockComment)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.BlockComment))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(BooleanLiteral node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.BooleanLiteral)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.BooleanLiteral))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(BreakStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.BreakStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.BreakStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(CastExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.CastExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.CastExpression))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(CatchClause node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.CatchClause)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.CatchClause))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(CharacterLiteral node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.CharacterLiteral)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.CharacterLiteral))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ClassInstanceCreation node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ClassInstanceCreation)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.ClassInstanceCreation))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(CompilationUnit node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.CompilationUnit)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.CompilationUnit))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ConditionalExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ConditionalExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.ConditionalExpression))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ConstructorInvocation node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ConstructorInvocation)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.ConstructorInvocation))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ContinueStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ContinueStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ContinueStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(CreationReference node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.CreationReference)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.CreationReference))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(Dimension node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.Dimension)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.Dimension))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(DoStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.DoStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.DoStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(EmptyStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.EmptyStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.EmptyStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(EnhancedForStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.EnhancedForStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.EnhancedForStatement))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(EnumConstantDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.EnumConstantDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.EnumConstantDeclaration))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(EnumDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.EnumDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.EnumDeclaration))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ExportsDirective node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ExportsDirective)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ExportsDirective))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ExpressionMethodReference node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.BreakStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.ExpressionMethodReference))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ExpressionStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ExpressionStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.ExpressionStatement))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(FieldAccess node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.FieldAccess)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.FieldAccess))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(FieldDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.FieldDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.FieldDeclaration))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ForStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ForStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ForStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(IfStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.IfStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.IfStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ImportDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ImportDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ImportDeclaration))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(InfixExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.InfixExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.InfixExpression))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(Initializer node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.Initializer)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.Initializer))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(InstanceofExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.InstanceofExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.InstanceofExpression))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(IntersectionType node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.IntersectionType)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.IntersectionType))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(Javadoc node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.Javadoc)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.Javadoc))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(LabeledStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.LabeledStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.LabeledStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(LambdaExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.LambdaExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.LambdaExpression))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(LineComment node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.LineComment)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.LineComment))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(MarkerAnnotation node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.MarkerAnnotation)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.MarkerAnnotation))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(MemberRef node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.MemberRef)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.MemberRef))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(MemberValuePair node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.MemberValuePair)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.MemberValuePair))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(MethodRef node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.MethodRef)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.MethodRef))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(MethodRefParameter node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.MethodRefParameter)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.MethodRefParameter))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(MethodDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.MethodDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.MethodDeclaration))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(MethodInvocation node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.MethodInvocation)) { + String data=(String) this.helperVisitor.getSupplierData().get(VisitorEnum.MethodInvocation); + if (data!= null && !node.getName().getIdentifier().equals(data)) { + return true; + } + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.MethodInvocation))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(Modifier node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.Modifier)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.Modifier))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ModuleDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ModuleDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ModuleDeclaration))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ModuleModifier node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ModuleModifier)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ModuleModifier))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(NameQualifiedType node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.NameQualifiedType)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.NameQualifiedType))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(NormalAnnotation node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.NormalAnnotation)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.NormalAnnotation))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(NullLiteral node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.NullLiteral)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.NullLiteral))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(NumberLiteral node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.NumberLiteral)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.NumberLiteral))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(OpensDirective node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.OpensDirective)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.OpensDirective))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(PackageDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.PackageDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.PackageDeclaration))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ParameterizedType node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ParameterizedType)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ParameterizedType))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ParenthesizedExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ParenthesizedExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.ParenthesizedExpression))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(PatternInstanceofExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.PatternInstanceofExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.PatternInstanceofExpression))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(PostfixExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.PostfixExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.PostfixExpression))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(PrefixExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.PrefixExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.PrefixExpression))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ProvidesDirective node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ProvidesDirective)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ProvidesDirective))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(PrimitiveType node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.PrimitiveType)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.PrimitiveType))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(QualifiedName node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.QualifiedName)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.QualifiedName))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(QualifiedType node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.QualifiedType)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.QualifiedType))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + +// @Override +// public boolean visit(ModuleQualifiedName node) { +// if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ModuleQualifiedName)) { +// return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ModuleQualifiedName))) +// .test(node, this.helperVisitor.dataholder); +// } +// return true; +// } + + @Override + public boolean visit(RequiresDirective node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.RequiresDirective)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.RequiresDirective))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(RecordDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.RecordDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.RecordDeclaration))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ReturnStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ReturnStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ReturnStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SimpleName node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SimpleName)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.SimpleName))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SimpleType node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SimpleType)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.SimpleType))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SingleMemberAnnotation node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SingleMemberAnnotation)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.SingleMemberAnnotation))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SingleVariableDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SingleVariableDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.SingleVariableDeclaration))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(StringLiteral node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.StringLiteral)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.StringLiteral))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SuperConstructorInvocation node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SuperConstructorInvocation)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.SuperConstructorInvocation))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SuperFieldAccess node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SuperFieldAccess)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.SuperFieldAccess))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SuperMethodInvocation node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SuperMethodInvocation)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.SuperMethodInvocation))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SuperMethodReference node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SuperMethodReference)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.SuperMethodReference))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SwitchCase node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SwitchCase)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.SwitchCase))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SwitchExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SwitchExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.SwitchExpression))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SwitchStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SwitchStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.SwitchStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(SynchronizedStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.SynchronizedStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.SynchronizedStatement))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(TagElement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.TagElement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.TagElement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(TextBlock node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.TextBlock)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.TextBlock))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(TextElement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.TextElement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.TextElement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ThisExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ThisExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ThisExpression))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(ThrowStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.ThrowStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.ThrowStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(TryStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.TryStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.TryStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(TypeDeclaration node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.TypeDeclaration)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.TypeDeclaration))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(TypeDeclarationStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.TypeDeclarationStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.TypeDeclarationStatement))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(TypeLiteral node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.TypeLiteral)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.TypeLiteral))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(TypeMethodReference node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.TypeMethodReference)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.TypeMethodReference))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(TypeParameter node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.TypeParameter)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.TypeParameter))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(UnionType node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.UnionType)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.UnionType))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(UsesDirective node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.UsesDirective)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.UsesDirective))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(VariableDeclarationExpression node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.VariableDeclarationExpression)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.VariableDeclarationExpression))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(VariableDeclarationStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.VariableDeclarationStatement)) { + Class data=(Class) this.helperVisitor.getSupplierData().get(VisitorEnum.VariableDeclarationStatement); + if (data!= null) { + VariableDeclarationFragment bli = (VariableDeclarationFragment) node.fragments().get(0); + IVariableBinding resolveBinding = bli.resolveBinding(); + if(resolveBinding!=null) { + String qualifiedName = resolveBinding.getType().getErasure().getQualifiedName(); + if (!data.getCanonicalName().equals(qualifiedName)) { + return true; + } + } + } + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.VariableDeclarationStatement))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(VariableDeclarationFragment node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.VariableDeclarationFragment)) { + return ((BiPredicate) (this.helperVisitor.predicatemap + .get(VisitorEnum.VariableDeclarationFragment))).test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(WhileStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.WhileStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.WhileStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(WildcardType node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.WildcardType)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.WildcardType))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public boolean visit(YieldStatement node) { + if (this.helperVisitor.predicatemap.containsKey(VisitorEnum.YieldStatement)) { + return ((BiPredicate) (this.helperVisitor.predicatemap.get(VisitorEnum.YieldStatement))) + .test(node, this.helperVisitor.dataholder); + } + return true; + } + + @Override + public void endVisit(AnnotationTypeDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.AnnotationTypeDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.AnnotationTypeDeclaration))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(AnnotationTypeMemberDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.AnnotationTypeMemberDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap + .get(VisitorEnum.AnnotationTypeMemberDeclaration))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(AnonymousClassDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.AnonymousClassDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.AnonymousClassDeclaration))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ArrayAccess node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ArrayAccess)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ArrayAccess))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ArrayCreation node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ArrayCreation)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ArrayCreation))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ArrayInitializer node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ArrayInitializer)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ArrayInitializer))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ArrayType node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ArrayType)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ArrayType))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(AssertStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.AssertStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.AssertStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(Assignment node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.Assignment)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.Assignment))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(Block node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.Block)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.Block))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(BlockComment node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.BlockComment)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.BlockComment))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(BooleanLiteral node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.BooleanLiteral)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.BooleanLiteral))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(BreakStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.BreakStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.BreakStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(CastExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.CastExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.CastExpression))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(CatchClause node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.CatchClause)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.CatchClause))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(CharacterLiteral node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.CharacterLiteral)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.CharacterLiteral))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ClassInstanceCreation node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ClassInstanceCreation)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ClassInstanceCreation))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(CompilationUnit node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.CompilationUnit)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.CompilationUnit))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ConditionalExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ConditionalExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ConditionalExpression))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ConstructorInvocation node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ConstructorInvocation)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ConstructorInvocation))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ContinueStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ContinueStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ContinueStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(CreationReference node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.CreationReference)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.CreationReference))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(Dimension node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.Dimension)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.Dimension))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(DoStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.DoStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.DoStatement))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(EmptyStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.EmptyStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.EmptyStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(EnhancedForStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.EnhancedForStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.EnhancedForStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(EnumConstantDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.EnumConstantDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.EnumConstantDeclaration))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(EnumDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.EnumDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.EnumDeclaration))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ExportsDirective node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ExportsDirective)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ExportsDirective))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ExpressionMethodReference node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ExpressionMethodReference)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ExpressionMethodReference))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ExpressionStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ExpressionStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ExpressionStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(FieldAccess node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.FieldAccess)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.FieldAccess))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(FieldDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.FieldDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.FieldDeclaration))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ForStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ForStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ForStatement))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(IfStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.IfStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.IfStatement))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ImportDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ImportDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ImportDeclaration))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(InfixExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.InfixExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.InfixExpression))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(Initializer node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.Initializer)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.Initializer))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(InstanceofExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.InstanceofExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.InstanceofExpression))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(IntersectionType node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.IntersectionType)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.IntersectionType))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(Javadoc node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.Javadoc)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.Javadoc))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(LabeledStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.LabeledStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.LabeledStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(LambdaExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.LambdaExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.LambdaExpression))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(LineComment node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.LineComment)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.LineComment))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(MarkerAnnotation node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.MarkerAnnotation)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.MarkerAnnotation))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(MemberRef node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.MemberRef)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.MemberRef))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(MemberValuePair node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.MemberValuePair)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.MemberValuePair))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(MethodRef node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.MethodRef)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.MethodRef))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(MethodRefParameter node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.MethodRefParameter)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.MethodRefParameter))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(MethodDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.MethodDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.MethodDeclaration))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(MethodInvocation node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.MethodInvocation)) { + String data=(String) this.helperVisitor.getConsumerData().get(VisitorEnum.MethodInvocation); + if (data!= null && !node.getName().getIdentifier().equals(data)) { + return; + } + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.MethodInvocation))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(Modifier node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.Modifier)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.Modifier))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ModuleDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ModuleDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ModuleDeclaration))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ModuleModifier node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ModuleModifier)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ModuleModifier))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(NameQualifiedType node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.NameQualifiedType)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.NameQualifiedType))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(NormalAnnotation node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.NormalAnnotation)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.NormalAnnotation))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(NullLiteral node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.NullLiteral)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.NullLiteral))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(NumberLiteral node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.NumberLiteral)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.NumberLiteral))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(OpensDirective node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.OpensDirective)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.OpensDirective))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(PackageDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.PackageDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.PackageDeclaration))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ParameterizedType node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ParameterizedType)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ParameterizedType))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ParenthesizedExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ParenthesizedExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ParenthesizedExpression))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(PatternInstanceofExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.PatternInstanceofExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap + .get(VisitorEnum.PatternInstanceofExpression))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(PostfixExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.PostfixExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.PostfixExpression))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(PrefixExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.PrefixExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.PrefixExpression))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ProvidesDirective node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ProvidesDirective)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ProvidesDirective))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(PrimitiveType node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.PrimitiveType)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.PrimitiveType))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(QualifiedName node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.QualifiedName)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.QualifiedName))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(QualifiedType node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.QualifiedType)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.QualifiedType))).accept(node, this.helperVisitor.dataholder); + } + } + +// @Override +// public void endVisit(ModuleQualifiedName node) { +// if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ModuleQualifiedName)) { +// ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ModuleQualifiedName))).accept(node, +// this.helperVisitor.dataholder); +// } +// } + + @Override + public void endVisit(RequiresDirective node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.RequiresDirective)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.RequiresDirective))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(RecordDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.RecordDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.RecordDeclaration))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ReturnStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ReturnStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ReturnStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SimpleName node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SimpleName)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SimpleName))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SimpleType node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SimpleType)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SimpleType))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SingleMemberAnnotation node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SingleMemberAnnotation)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SingleMemberAnnotation))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SingleVariableDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SingleVariableDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SingleVariableDeclaration))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(StringLiteral node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.StringLiteral)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.StringLiteral))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SuperConstructorInvocation node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SuperConstructorInvocation)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SuperConstructorInvocation))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SuperFieldAccess node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SuperFieldAccess)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SuperFieldAccess))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SuperMethodInvocation node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SuperMethodInvocation)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SuperMethodInvocation))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SuperMethodReference node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SuperMethodReference)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SuperMethodReference))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SwitchCase node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SwitchCase)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SwitchCase))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SwitchExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SwitchExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SwitchExpression))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SwitchStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SwitchStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SwitchStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(SynchronizedStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.SynchronizedStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.SynchronizedStatement))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(TagElement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.TagElement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.TagElement))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(TextBlock node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.TextBlock)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.TextBlock))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(TextElement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.TextElement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.TextElement))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ThisExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ThisExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ThisExpression))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(ThrowStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.ThrowStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.ThrowStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(TryStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.TryStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.TryStatement))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(TypeDeclaration node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.TypeDeclaration)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.TypeDeclaration))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(TypeDeclarationStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.TypeDeclarationStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.TypeDeclarationStatement))) + .accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(TypeLiteral node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.TypeLiteral)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.TypeLiteral))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(TypeMethodReference node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.TypeMethodReference)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.TypeMethodReference))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(TypeParameter node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.TypeParameter)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.TypeParameter))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(UnionType node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.UnionType)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.UnionType))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(UsesDirective node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.UsesDirective)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.UsesDirective))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(VariableDeclarationExpression node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.VariableDeclarationExpression)) { + ((BiConsumer) (this.helperVisitor.consumermap + .get(VisitorEnum.VariableDeclarationExpression))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(VariableDeclarationStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.VariableDeclarationStatement)) { + Class data=(Class) this.helperVisitor.getConsumerData().get(VisitorEnum.VariableDeclarationStatement); + if (data!= null) { + VariableDeclarationFragment bli = (VariableDeclarationFragment) node.fragments().get(0); + IVariableBinding resolveBinding = bli.resolveBinding(); + if(resolveBinding!=null) { + String qualifiedName = resolveBinding.getType().getErasure().getQualifiedName(); + if (!data.getCanonicalName().equals(qualifiedName)) { + return; + } + } + } + ((BiConsumer) (this.helperVisitor.consumermap + .get(VisitorEnum.VariableDeclarationStatement))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(VariableDeclarationFragment node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.VariableDeclarationFragment)) { + ((BiConsumer) (this.helperVisitor.consumermap + .get(VisitorEnum.VariableDeclarationFragment))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(WhileStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.WhileStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.WhileStatement))).accept(node, + this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(WildcardType node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.WildcardType)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.WildcardType))).accept(node, this.helperVisitor.dataholder); + } + } + + @Override + public void endVisit(YieldStatement node) { + if (this.helperVisitor.consumermap.containsKey(VisitorEnum.YieldStatement)) { + ((BiConsumer) (this.helperVisitor.consumermap.get(VisitorEnum.YieldStatement))).accept(node, + this.helperVisitor.dataholder); + } + } +} \ No newline at end of file diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/ReferenceHolder.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/ReferenceHolder.java new file mode 100644 index 00000000..f629801c --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/ReferenceHolder.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.common; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.concurrent.ConcurrentHashMap; + +/** + * This class does not allow null to be used as a key or value because it is derived from + * ConcurrentHashMap. + * + * @author chammer + * + * @param - type of key in HelperVisitor map + * @param - type of value in HelpVisitor map + */ +public class ReferenceHolder extends ConcurrentHashMap implements HelperVisitorProvider> { + + /** + * + */ + private static final long serialVersionUID= 1L; + + HelperVisitor, V, T> hv; + + /** + * + */ + public ReferenceHolder() { + } + + @Override + public HelperVisitor, V, T> getHelperVisitor() { + return hv; + } + + @Override + public void setHelperVisitor(HelperVisitor, V, T> hv) { + this.hv= hv; + } + + private void writeObject(ObjectOutputStream stream) + throws IOException { + stream.defaultWriteObject(); + } + + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object o) { + return super.equals(o); + } +} diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/VisitorEnum.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/VisitorEnum.java new file mode 100644 index 00000000..efa0a866 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/common/VisitorEnum.java @@ -0,0 +1,593 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.common; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.jdt.core.dom.ASTNode; + +/** + * + * @author chammer + */ +public enum VisitorEnum { + + /** + * + */ + AnnotationTypeDeclaration(ASTNode.ANNOTATION_TYPE_DECLARATION), + + /** + * + */ + AnnotationTypeMemberDeclaration(ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION), + + /** + * + */ + AnonymousClassDeclaration(ASTNode.ANONYMOUS_CLASS_DECLARATION), + + /** + * + */ + ArrayAccess(ASTNode.ARRAY_ACCESS), + + /** + * + */ + ArrayCreation(ASTNode.ARRAY_CREATION), + + /** + * + */ + ArrayInitializer(ASTNode.ARRAY_INITIALIZER), + + /** + * + */ + ArrayType(ASTNode.ARRAY_TYPE), + + /** + * + */ + AssertStatement(ASTNode.ASSERT_STATEMENT), + + /** + * + */ + Assignment(ASTNode.ASSIGNMENT), + + /** + * + */ + Block(ASTNode.BLOCK), + + /** + * + */ + BlockComment(ASTNode.BLOCK_COMMENT), + + /** + * + */ + BooleanLiteral(ASTNode.BOOLEAN_LITERAL), + + /** + * + */ + BreakStatement(ASTNode.BREAK_STATEMENT), + + /** + * + */ + CastExpression(ASTNode.CAST_EXPRESSION), + + /** + * + */ + CatchClause(ASTNode.CATCH_CLAUSE), + + /** + * + */ + CharacterLiteral(ASTNode.CHARACTER_LITERAL), + + /** + * + */ + ClassInstanceCreation(ASTNode.CLASS_INSTANCE_CREATION), + + /** + * + */ + CompilationUnit(ASTNode.COMPILATION_UNIT), + + /** + * + */ + ConditionalExpression(ASTNode.CONDITIONAL_EXPRESSION), + + /** + * + */ + ConstructorInvocation(ASTNode.CONSTRUCTOR_INVOCATION), + + /** + * + */ + ContinueStatement(ASTNode.CONTINUE_STATEMENT), + + /** + * + */ + CreationReference(ASTNode.CREATION_REFERENCE), + + /** + * + */ + Dimension(ASTNode.DIMENSION), + + /** + * + */ + DoStatement(ASTNode.DO_STATEMENT), + + /** + * + */ + EmptyStatement(ASTNode.EMPTY_STATEMENT), + + /** + * + */ + EnhancedForStatement(ASTNode.ENHANCED_FOR_STATEMENT), + + /** + * + */ + EnumConstantDeclaration(ASTNode.ENUM_CONSTANT_DECLARATION), + + /** + * + */ + EnumDeclaration(ASTNode.ENUM_DECLARATION), + + /** + * + */ + ExportsDirective(ASTNode.EXPORTS_DIRECTIVE), + + /** + * + */ + ExpressionMethodReference(ASTNode.EXPRESSION_METHOD_REFERENCE), + + /** + * + */ + ExpressionStatement(ASTNode.EXPRESSION_STATEMENT), + + /** + * + */ + FieldAccess(ASTNode.FIELD_ACCESS), + + /** + * + */ + FieldDeclaration(ASTNode.FIELD_DECLARATION), + + /** + * + */ + ForStatement(ASTNode.FOR_STATEMENT), + + /** + * + */ + IfStatement(ASTNode.IF_STATEMENT), + + /** + * + */ + ImportDeclaration(ASTNode.IMPORT_DECLARATION), + + /** + * + */ + InfixExpression(ASTNode.INFIX_EXPRESSION), + + /** + * + */ + Initializer(ASTNode.INITIALIZER), + + /** + * + */ + InstanceofExpression(ASTNode.INSTANCEOF_EXPRESSION), + + /** + * + */ + IntersectionType(ASTNode.INTERSECTION_TYPE), + + /** + * + */ + Javadoc(ASTNode.JAVADOC), + + /** + * + */ + LabeledStatement(ASTNode.LABELED_STATEMENT), + + /** + * + */ + LambdaExpression(ASTNode.LAMBDA_EXPRESSION), + + /** + * + */ + LineComment(ASTNode.LINE_COMMENT), + + /** + * + */ + MarkerAnnotation(ASTNode.MARKER_ANNOTATION), + + /** + * + */ + MemberRef(ASTNode.MEMBER_REF), + + /** + * + */ + MemberValuePair(ASTNode.MEMBER_VALUE_PAIR), + + /** + * + */ + MethodRef(ASTNode.METHOD_REF), + + /** + * + */ + MethodRefParameter(ASTNode.METHOD_REF_PARAMETER), + + /** + * + */ + MethodDeclaration(ASTNode.METHOD_DECLARATION), + + /** + * + */ + MethodInvocation(ASTNode.METHOD_INVOCATION), + + /** + * + */ + Modifier(ASTNode.MODIFIER), + + /** + * + */ + ModuleDeclaration(ASTNode.MODULE_DECLARATION), + + /** + * + */ + ModuleModifier(ASTNode.MODULE_MODIFIER), + + /** + * + */ + NameQualifiedType(ASTNode.NAME_QUALIFIED_TYPE), + + /** + * + */ + NormalAnnotation(ASTNode.NORMAL_ANNOTATION), + + /** + * + */ + NullLiteral(ASTNode.NULL_LITERAL), + + /** + * + */ + NumberLiteral(ASTNode.NUMBER_LITERAL), + + /** + * + */ + OpensDirective(ASTNode.OPENS_DIRECTIVE), + + /** + * + */ + PackageDeclaration(ASTNode.PACKAGE_DECLARATION), + + /** + * + */ + ParameterizedType(ASTNode.PARAMETERIZED_TYPE), + + /** + * + */ + ParenthesizedExpression(ASTNode.PARENTHESIZED_EXPRESSION), + + /** + * + */ + PatternInstanceofExpression(ASTNode.PATTERN_INSTANCEOF_EXPRESSION), + + /** + * + */ + PostfixExpression(ASTNode.POSTFIX_EXPRESSION), + + /** + * + */ + PrefixExpression(ASTNode.PREFIX_EXPRESSION), + + /** + * + */ + ProvidesDirective(ASTNode.PROVIDES_DIRECTIVE), + + /** + * + */ + PrimitiveType(ASTNode.PRIMITIVE_TYPE), + + /** + * + */ + QualifiedName(ASTNode.QUALIFIED_NAME), + + /** + * + */ + QualifiedType(ASTNode.QUALIFIED_TYPE), +// ModuleQualifiedName(ASTNode.MODULE_QUALIFIED_NAME), + + /** + * + */ + RequiresDirective(ASTNode.REQUIRES_DIRECTIVE), + + /** + * + */ + RecordDeclaration(ASTNode.RECORD_DECLARATION), + + /** + * + */ + ReturnStatement(ASTNode.RETURN_STATEMENT), + + /** + * + */ + SimpleName(ASTNode.SIMPLE_NAME), + + /** + * + */ + SimpleType(ASTNode.SIMPLE_TYPE), + + /** + * + */ + SingleMemberAnnotation(ASTNode.SINGLE_MEMBER_ANNOTATION), + + /** + * + */ + SingleVariableDeclaration(ASTNode.SINGLE_VARIABLE_DECLARATION), + + /** + * + */ + StringLiteral(ASTNode.STRING_LITERAL), + + /** + * + */ + SuperConstructorInvocation(ASTNode.SUPER_CONSTRUCTOR_INVOCATION), + + /** + * + */ + SuperFieldAccess(ASTNode.SUPER_FIELD_ACCESS), + + /** + * + */ + SuperMethodInvocation(ASTNode.SUPER_METHOD_INVOCATION), + + /** + * + */ + SuperMethodReference(ASTNode.SUPER_METHOD_REFERENCE), + + /** + * + */ + SwitchCase(ASTNode.SWITCH_CASE), + + /** + * + */ + SwitchExpression(ASTNode.SWITCH_EXPRESSION), + + /** + * + */ + SwitchStatement(ASTNode.SWITCH_STATEMENT), + + /** + * + */ + SynchronizedStatement(ASTNode.SYNCHRONIZED_STATEMENT), + + /** + * + */ + TagElement(ASTNode.TAG_ELEMENT), + + /** + * + */ + TextBlock(ASTNode.TEXT_BLOCK), + + /** + * + */ + TextElement(ASTNode.TEXT_ELEMENT), + + /** + * + */ + ThisExpression(ASTNode.THIS_EXPRESSION), + + /** + * + */ + ThrowStatement(ASTNode.THROW_STATEMENT), + + /** + * + */ + TryStatement(ASTNode.TRY_STATEMENT), + + /** + * + */ + TypeDeclaration(ASTNode.TYPE_DECLARATION), + + /** + * + */ + TypeDeclarationStatement(ASTNode.TYPE_DECLARATION_STATEMENT), + + /** + * + */ + TypeLiteral(ASTNode.TYPE_LITERAL), + + /** + * + */ + TypeMethodReference(ASTNode.TYPE_METHOD_REFERENCE), + + /** + * + */ + TypeParameter(ASTNode.TYPE_PARAMETER), + + /** + * + */ + UnionType(ASTNode.UNION_TYPE), + + /** + * + */ + UsesDirective(ASTNode.USES_DIRECTIVE), + + /** + * + */ + VariableDeclarationExpression(ASTNode.VARIABLE_DECLARATION_EXPRESSION), + + /** + * + */ + VariableDeclarationStatement(ASTNode.VARIABLE_DECLARATION_STATEMENT), + + /** + * + */ + VariableDeclarationFragment(ASTNode.VARIABLE_DECLARATION_FRAGMENT), + + /** + * + */ + WhileStatement(ASTNode.WHILE_STATEMENT), + + /** + * + */ + WildcardType(ASTNode.WILDCARD_TYPE), + + /** + * + */ + YieldStatement(ASTNode.YIELD_STATEMENT); + + int nodetype; + + VisitorEnum(int nodetype) { + this.nodetype= nodetype; + } + + /** + * + * @return - node type + */ + public int getValue() { + return nodetype; + } + + /** + * + * @return - Stream if VisitorEnum values + */ + public static Stream stream() { + return Stream.of(VisitorEnum.values()); + } + + static final Map values= Arrays.stream(VisitorEnum.values()) + .collect(Collectors.toMap(VisitorEnum::getValue, Function.identity())); + + /** + * + * @param nodetype - node type + * @return - corresponding VistorEnum + */ + public static VisitorEnum fromNodetype(final int nodetype) { + return values.get(nodetype); + } + + /** + * + * @param node - ASTNode + * @return - corresponding VistorEnum + */ + public static VisitorEnum fromNode(ASTNode node) { + return fromNodetype(node.getNodeType()); + } +} diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/core/manipulation/JavaManipulationPlugin.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/core/manipulation/JavaManipulationPlugin.java index 07961a12..56d70c1f 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/core/manipulation/JavaManipulationPlugin.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/core/manipulation/JavaManipulationPlugin.java @@ -43,6 +43,8 @@ public class JavaManipulationPlugin extends Plugin implements DebugOptionsListen public static boolean DEBUG_AST_PROVIDER; + public static boolean DEBUG_TYPE_CONSTRAINTS; + //The shared instance. private static JavaManipulationPlugin fgDefault; @@ -100,8 +102,13 @@ public static void log(Throwable e) { Platform.getLog(JavaManipulationPlugin.class).log(new Status(IStatus.ERROR, JavaManipulation.ID_PLUGIN, IStatusConstants.INTERNAL_ERROR, JavaManipulationMessages.JavaManipulationMessages_internalError, e)); } + public static void log(IStatus status) { + Platform.getLog(JavaManipulationPlugin.class).log(status); + } + @Override public void optionsChanged(DebugOptions options) { DEBUG_AST_PROVIDER= options.getBooleanOption("org.eclipse.jdt.core.manipulation/debug/ASTProvider", false); //$NON-NLS-1$ + DEBUG_TYPE_CONSTRAINTS= options.getBooleanOption("org.eclipse.jdt.core.manipulation/debug/TypeConstraints", false); //$NON-NLS-1$ } } diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/ConstantsForSystemPropertiesCleanUpCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/ConstantsForSystemPropertiesCleanUpCore.java index bf5d83bc..aabb57ad 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/ConstantsForSystemPropertiesCleanUpCore.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/ConstantsForSystemPropertiesCleanUpCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021 IBM Corporation and others. + * Copyright (c) 2021, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -14,7 +14,7 @@ package org.eclipse.jdt.internal.ui.fix; import static org.eclipse.jdt.internal.corext.fix.CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY; -import static org.eclipse.jdt.internal.corext.fix.CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOOLEAN; +import static org.eclipse.jdt.internal.corext.fix.CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOXED; import static org.eclipse.jdt.internal.corext.fix.CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_FILE_ENCODING; import static org.eclipse.jdt.internal.corext.fix.CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_FILE_SEPARATOR; import static org.eclipse.jdt.internal.corext.fix.CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_LINE_SEPARATOR; @@ -23,7 +23,9 @@ import static org.eclipse.jdt.internal.corext.fix.UpdateProperty.BOOLEAN_PROPERTY; import static org.eclipse.jdt.internal.corext.fix.UpdateProperty.FILE_ENCODING; import static org.eclipse.jdt.internal.corext.fix.UpdateProperty.FILE_SEPARATOR; +import static org.eclipse.jdt.internal.corext.fix.UpdateProperty.INTEGER_PROPERTY; import static org.eclipse.jdt.internal.corext.fix.UpdateProperty.LINE_SEPARATOR; +import static org.eclipse.jdt.internal.corext.fix.UpdateProperty.LONG_PROPERTY; import static org.eclipse.jdt.internal.corext.fix.UpdateProperty.PATH_SEPARATOR; import static org.eclipse.jdt.internal.ui.fix.MultiFixMessages.ConstantsCleanUp_description; @@ -105,8 +107,10 @@ private EnumSet computeFixSet() { if(isEnabled(CONSTANTS_FOR_SYSTEM_PROPERTY_LINE_SEPARATOR)) { fixSet.add(LINE_SEPARATOR); } - if(isEnabled(CONSTANTS_FOR_SYSTEM_PROPERTY_BOOLEAN)) { + if(isEnabled(CONSTANTS_FOR_SYSTEM_PROPERTY_BOXED)) { fixSet.add(BOOLEAN_PROPERTY); + fixSet.add(INTEGER_PROPERTY); + fixSet.add(LONG_PROPERTY); } return fixSet; } @@ -155,10 +159,52 @@ public String getPreview() { } if (isEnabled && computeFixSet.contains(UpdateProperty.BOOLEAN_PROPERTY)) { - sb.append("Boolean b = Boolean.getBoolean(\"arbitrarykey\")\n"); //$NON-NLS-1$ + sb.append("Boolean b = Boolean.getBoolean(\"arbitrarykey\");\n"); //$NON-NLS-1$ } else { sb.append("Boolean b = Boolean.parseBoolean(System.getProperty(\"arbitrarykey\"));\n"); //$NON-NLS-1$ } + + if (isEnabled && computeFixSet.contains(UpdateProperty.BOOLEAN_PROPERTY)) { + sb.append("Boolean b2 = Boolean.getBoolean(\"arbitrarykey\");\n"); //$NON-NLS-1$ + } else { + sb.append("Boolean b2 = Boolean.parseBoolean(System.getProperty(\"arbitrarykey\", \"false\"));\n"); //$NON-NLS-1$ + } + + if (isEnabled && computeFixSet.contains(UpdateProperty.INTEGER_PROPERTY)) { + sb.append("Integer i = Integer.getInteger(\"arbitrarykey\");\n"); //$NON-NLS-1$ + } else { + sb.append("Integer i = Integer.parseInt(System.getProperty(\"arbitrarykey\"));\n"); //$NON-NLS-1$ + } + + if (isEnabled && computeFixSet.contains(UpdateProperty.INTEGER_PROPERTY)) { + sb.append("Integer i2 = Integer.getInteger(\"arbitrarykey\");\n"); //$NON-NLS-1$ + } else { + sb.append("Integer i2 = Integer.parseInt(System.getProperty(\"arbitrarykey\",\"0\"));\n"); //$NON-NLS-1$ + } + + if (isEnabled && computeFixSet.contains(UpdateProperty.INTEGER_PROPERTY)) { + sb.append("Integer i3 = Integer.getInteger(\"arbitrarykey\", 15);\n"); //$NON-NLS-1$ + } else { + sb.append("Integer i3 = Integer.parseInt(System.getProperty(\"arbitrarykey\",\"15\"));\n"); //$NON-NLS-1$ + } + + if (isEnabled && computeFixSet.contains(UpdateProperty.LONG_PROPERTY)) { + sb.append("Long l = Long.getLong(\"arbitrarykey\");\n"); //$NON-NLS-1$ + } else { + sb.append("Long l = Long.parseLong(System.getProperty(\"arbitrarykey\"));\n"); //$NON-NLS-1$ + } + + if (isEnabled && computeFixSet.contains(UpdateProperty.LONG_PROPERTY)) { + sb.append("Long l2 = Long.getLong(\"arbitrarykey\");\n"); //$NON-NLS-1$ + } else { + sb.append("Long l2 = Long.parseLong(System.getProperty(\"arbitrarykey\" ,\"0\"));\n"); //$NON-NLS-1$ + } + + if (isEnabled && computeFixSet.contains(UpdateProperty.LONG_PROPERTY)) { + sb.append("Long l3 = Long.getLong(\"arbitrarykey\", 15);\n"); //$NON-NLS-1$ + } else { + sb.append("Long l3 = Long.parseLong(System.getProperty(\"arbitrarykey\" ,\"15\"));\n"); //$NON-NLS-1$ + } return sb.toString(); } } diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java index aa7d64b6..0e64a3b5 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -58,6 +58,7 @@ private MultiFixMessages() { public static String UnusedCodeMultiFix_RemoveUnusedType_description; public static String UnusedCodeMultiFix_RemoveUnusedConstructor_description; public static String UnusedCodeMultiFix_RemoveUnusedMethod_description; + public static String UnusedCodeMultiFix_RemoveUnusedParameter_description; public static String UnusedCodeMultiFix_RemoveUnusedImport_description; public static String UnusedCodeCleanUp_RemoveUnusedCasts_description; @@ -93,6 +94,9 @@ private MultiFixMessages() { public static String CleanUpRefactoringWizard_PageTitle; public static String CleanUpRefactoringWizard_formatterException_errorMessage; + public static String CleanUpSelectionDialog_restoreDefaults_label; + public static String CleanUpSelectionDialog_resetProfile_label; + public static String ControlStatementsCleanUp_RemoveUnnecessaryBlocks_description; public static String ControlStatementsCleanUp_RemoveUnnecessaryBlocksWithReturnOrThrow_description; @@ -199,6 +203,7 @@ private MultiFixMessages() { public static String MultiCatchCleanUp_description; public static String ConstantsCleanUp_description; public static String StringBufferToStringBuilderCleanUp_description; + public static String StringConcatToTextBlockCleanUp_description; public static String StringBuilderForLocalVarsOnlyCleanUp_description; static { diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties index a84926ca..0e86faae 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2005, 2021 IBM Corporation and others. +# Copyright (c) 2005, 2022 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -21,6 +21,7 @@ UnusedCodeMultiFix_RemoveUnusedType_description=Remove unused private types UnusedCodeCleanUp_RemoveUnusedCasts_description=Remove unnecessary casts UnusedCodeMultiFix_RemoveUnusedConstructor_description=Remove unused private constructors UnusedCodeMultiFix_RemoveUnusedMethod_description=Remove unused private methods +UnusedCodeMultiFix_RemoveUnusedParameter_description=Remove unused private method parameters UnusedCodeMultiFix_RemoveUnusedImport_description=Remove unused imports CodeStyleMultiFix_ChangeNonStaticAccess_description=Change non static accesses to static members using declaring type @@ -53,7 +54,7 @@ CodeStyleMultiFix_ConvertSingleStatementInControlBodyToBlock_description=Convert CodeStyleCleanUp_Switch_description=Convert if/else if/else chain to switch Java50MultiFix_AddMissingDeprecated_description=Add missing '@Deprecated' annotations -Java50CleanUp_ConvertToEnhancedForLoop_description=Convert 'for' loops to enhanced 'for' loops +Java50CleanUp_ConvertToEnhancedForLoop_description=Convert to enhanced 'for' loops Java50CleanUp_ConvertLoopOnlyIfLoopVarUsed_description=Convert to enhanced 'for' loops only if the loop variable is used Java50CleanUp_AddTypeParameters_description=Add type arguments to raw type references Java50MultiFix_AddMissingOverride_description=Add missing '@Override' annotations @@ -74,6 +75,8 @@ CleanUpRefactoringWizard_CleaningUpNN_Title=Cleaning up {0} files in {1} project CleanUpRefactoringWizard_formatterException_errorMessage=The formatter threw an unhandled exception while formatting the preview. CleanUpRefactoringWizard_WindowTitle=Clean Up CleanUpRefactoringWizard_PageTitle=Clean Up +CleanUpSelectionDialog_restoreDefaults_label=Restore Defaults +CleanUpSelectionDialog_resetProfile_label=Reset Profile ExpressionsCleanUp_addParanoiac_description=Put expressions in parentheses ExpressionsCleanUp_removeUnnecessary_description=Remove unnecessary parentheses VariableDeclarationCleanUp_AddFinalField_description=Add final modifier to private fields @@ -168,7 +171,7 @@ UnloopedWhileCleanUp_description=Convert loop into if AddAllCleanup_description=Add elements in collections without loop ObjectsEqualsCleanup_description=Use Objects.equals() in the equals method implementation -OperandFactorizationCleanUp_description=Replace (X && Y) || (X && Z) by (X && (Y || Z)) +OperandFactorizationCleanUp_description=Factorize operands OneIfRatherThanDuplicateBlocksThatFallThroughCleanUp_description=Single 'if' statement rather than duplicate blocks that fall through PullOutIfFromIfElseCleanUp_description=Pull out a duplicate 'if' from an if/else @@ -182,4 +185,5 @@ TryWithResourceCleanup_description=Use try-with-resource MultiCatchCleanUp_description=Multi-catch ConstantsCleanUp_description=Use Java method instead of system property ''{0}'' StringBufferToStringBuilderCleanUp_description=Convert StringBuffer to StringBuilder +StringConcatToTextBlockCleanUp_description=Convert String concatenation to Text Block StringBuilderForLocalVarsOnlyCleanUp_description=Convert StringBuffer to StringBuilder for local variables diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/StringConcatToTextBlockCleanUpCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/StringConcatToTextBlockCleanUpCore.java new file mode 100644 index 00000000..8fa3e705 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/StringConcatToTextBlockCleanUpCore.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2021 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.fix; + +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.manipulation.CleanUpContextCore; +import org.eclipse.jdt.core.manipulation.CleanUpRequirementsCore; +import org.eclipse.jdt.core.manipulation.ICleanUpFixCore; + +import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; +import org.eclipse.jdt.internal.corext.fix.StringConcatToTextBlockFixCore; + +public class StringConcatToTextBlockCleanUpCore extends AbstractCleanUpCore { + + public StringConcatToTextBlockCleanUpCore(final Map options) { + super(options); + } + + public StringConcatToTextBlockCleanUpCore() { + } + + @Override + public CleanUpRequirementsCore getRequirementsCore() { + return new CleanUpRequirementsCore(requireAST(), false, false, null); + } + + public boolean requireAST() { + return isEnabled(CleanUpConstants.STRINGCONCAT_TO_TEXTBLOCK); + } + + @Override + public ICleanUpFixCore createFixCore(final CleanUpContextCore context) throws CoreException { + CompilationUnit compilationUnit= context.getAST(); + + if (compilationUnit == null || !isEnabled(CleanUpConstants.STRINGCONCAT_TO_TEXTBLOCK)) { + return null; + } + + return StringConcatToTextBlockFixCore.createCleanUp(compilationUnit); + } + + @Override + public String[] getStepDescriptions() { + if (isEnabled(CleanUpConstants.STRINGCONCAT_TO_TEXTBLOCK)) { + return new String[] {MultiFixMessages.StringConcatToTextBlockCleanUp_description}; + } + return new String[0]; + } + + @Override + public String getPreview() { + StringBuilder bld= new StringBuilder(); + + if (isEnabled(CleanUpConstants.STRINGCONCAT_TO_TEXTBLOCK)) { + bld.append("String buf = \"\"\"\n"); //$NON-NLS-1$ + bld.append(" public class A {\n"); //$NON-NLS-1$ + bld.append(" public void foo() {\n"); //$NON-NLS-1$ + bld.append(" }\n"); //$NON-NLS-1$ + bld.append(" }\n"); //$NON-NLS-1$ + bld.append(" \"\"\";\n"); //$NON-NLS-1$ + } else { + bld.append("String buf = \"\" +\n"); //$NON-NLS-1$ + bld.append(" \"public class A {\" +\n"); //$NON-NLS-1$ + bld.append(" \" public void foo() {\" +\n"); //$NON-NLS-1$ + bld.append(" \" }\" + \n"); //$NON-NLS-1$ + bld.append(" \"}\";\n"); //$NON-NLS-1$ + } + + return bld.toString(); + } +} diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/SubstringCleanUpCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/SubstringCleanUpCore.java new file mode 100644 index 00000000..b7fe61a0 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/SubstringCleanUpCore.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2022 Fabrice TIERCELIN and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Fabrice TIERCELIN - initial API and implementation + * Red Hat - moved here from jdt.ui project + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.fix; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.manipulation.CleanUpRequirementsCore; +import org.eclipse.jdt.core.manipulation.ICleanUpFixCore; + +import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation; +import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; + +import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; + +/** + * A fix that removes the second substring() parameter if this parameter is the length of the string: + *
      + *
    • It must reference the same expression,
    • + *
    • The expression must be passive.
    • + *
    + */ +public class SubstringCleanUpCore extends AbstractMultiFixCore { + public SubstringCleanUpCore() { + this(Collections.emptyMap()); + } + + public SubstringCleanUpCore(final Map options) { + super(options); + } + + @Override + public CleanUpRequirementsCore getRequirementsCore() { + boolean requireAST= isEnabled(CleanUpConstants.SUBSTRING); + return new CleanUpRequirementsCore(requireAST, false, false, null); + } + + @Override + public String[] getStepDescriptions() { + if (isEnabled(CleanUpConstants.SUBSTRING)) { + return new String[] { MultiFixMessages.SubstringCleanUp_description }; + } + + return new String[0]; + } + + @Override + public String getPreview() { + if (isEnabled(CleanUpConstants.SUBSTRING)) { + return "String shortenedText = text.substring(2);\n"; //$NON-NLS-1$ + } + + return "String shortenedText = text.substring(2, text.length());\n"; //$NON-NLS-1$ + } + + @Override + public ICleanUpFixCore createFix(final CompilationUnit unit) throws CoreException { + if (!isEnabled(CleanUpConstants.SUBSTRING)) { + return null; + } + + final List rewriteOperations= new ArrayList<>(); + + unit.accept(new ASTVisitor() { + @Override + public boolean visit(final MethodInvocation visited) { + if (ASTNodes.usesGivenSignature(visited, String.class.getCanonicalName(), "substring", int.class.getCanonicalName(), int.class.getCanonicalName())) { //$NON-NLS-1$ + MethodInvocation endIndex= ASTNodes.as((Expression) visited.arguments().get(1), MethodInvocation.class); + + if (endIndex != null + && endIndex.getExpression() != null + && ASTNodes.usesGivenSignature(endIndex, String.class.getCanonicalName(), "length") //$NON-NLS-1$ + && ASTNodes.match(visited.getExpression(), endIndex.getExpression()) + && ASTNodes.isPassive(visited.getExpression())) { + rewriteOperations.add(new SubstringOperation(visited)); + return false; + } + } + + return true; + } + }); + + if (rewriteOperations.isEmpty()) { + return null; + } + + return new CompilationUnitRewriteOperationsFixCore(MultiFixMessages.SubstringCleanUp_description, unit, + rewriteOperations.toArray(new CompilationUnitRewriteOperation[0])); + } + @Override + public ICleanUpFixCore createFix(CompilationUnit unit, IProblemLocationCore[] problems) throws CoreException { + return createFix(unit); + } + + + @Override + public boolean canFix(final ICompilationUnit compilationUnit, final IProblemLocationCore problem) { + return false; + } + + private static class SubstringOperation extends CompilationUnitRewriteOperation { + private final MethodInvocation visited; + + public SubstringOperation(final MethodInvocation visited) { + this.visited= visited; + } + + @Override + public void rewriteAST(final CompilationUnitRewrite cuRewrite, final LinkedProposalModelCore linkedModel) throws CoreException { + ASTRewrite rewrite= cuRewrite.getASTRewrite(); + TextEditGroup group= createTextEditGroup(MultiFixMessages.SubstringCleanUp_description, cuRewrite); + + rewrite.remove((ASTNode) visited.arguments().get(1), group); + } + } +} diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/UnnecessaryCodeCleanUpCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/UnnecessaryCodeCleanUpCore.java index 32b0a21a..a0733aee 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/UnnecessaryCodeCleanUpCore.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/UnnecessaryCodeCleanUpCore.java @@ -59,7 +59,8 @@ public ICleanUpFixCore createFix(CompilationUnit compilationUnit) throws CoreExc false, false, false, - isEnabled(CleanUpConstants.REMOVE_UNNECESSARY_CASTS)); + isEnabled(CleanUpConstants.REMOVE_UNNECESSARY_CASTS), + false); } @Override @@ -71,7 +72,8 @@ public ICleanUpFixCore createFix(CompilationUnit compilationUnit, IProblemLocati false, false, false, - isEnabled(CleanUpConstants.REMOVE_UNNECESSARY_CASTS)); + isEnabled(CleanUpConstants.REMOVE_UNNECESSARY_CASTS), + false); } private Map getRequiredOptions() { @@ -80,6 +82,10 @@ private Map getRequiredOptions() { if (isEnabled(CleanUpConstants.REMOVE_UNNECESSARY_CASTS)) result.put(JavaCore.COMPILER_PB_UNNECESSARY_TYPE_CHECK, JavaCore.WARNING); + if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS)) { + result.put(JavaCore.COMPILER_PB_UNUSED_PARAMETER, JavaCore.WARNING); + } + return result; } diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/UnusedCodeCleanUpCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/UnusedCodeCleanUpCore.java index 77cda55a..86a8f8d7 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/UnusedCodeCleanUpCore.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/UnusedCodeCleanUpCore.java @@ -64,11 +64,12 @@ removeUnuseMembers && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_CONS removeUnuseMembers && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_FELDS) || removeUnuseMembers && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_TYPES) || isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES) || - isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_IMPORTS) && !isEnabled(CleanUpConstants.ORGANIZE_IMPORTS); + isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_IMPORTS) && !isEnabled(CleanUpConstants.ORGANIZE_IMPORTS) || + isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS); } @Override - protected ICleanUpFixCore createFix(CompilationUnit compilationUnit) throws CoreException { + public ICleanUpFixCore createFix(CompilationUnit compilationUnit) throws CoreException { boolean removeUnuseMembers= isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_MEMBERS); return UnusedCodeFixCore.createCleanUp(compilationUnit, @@ -78,11 +79,12 @@ removeUnuseMembers && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_FELD removeUnuseMembers && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_TYPES), isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES), isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_IMPORTS) && !isEnabled(CleanUpConstants.ORGANIZE_IMPORTS), - false); + false, + true); } @Override - protected ICleanUpFixCore createFix(CompilationUnit compilationUnit, IProblemLocationCore[] problems) throws CoreException { + public ICleanUpFixCore createFix(CompilationUnit compilationUnit, IProblemLocationCore[] problems) throws CoreException { boolean removeMembers= isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_MEMBERS); return UnusedCodeFixCore.createCleanUp(compilationUnit, problems, @@ -92,7 +94,8 @@ removeMembers && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_FELDS), removeMembers && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_TYPES), isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES), isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_IMPORTS) && !isEnabled(CleanUpConstants.ORGANIZE_IMPORTS), - false); + false, + true); } public Map getRequiredOptions() { @@ -112,6 +115,10 @@ public Map getRequiredOptions() { if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES)) result.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.WARNING); + if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS)) { + result.put(JavaCore.COMPILER_PB_UNUSED_PARAMETER, JavaCore.WARNING); + } + return result; } @@ -130,7 +137,9 @@ public String[] getStepDescriptions() { result.add(MultiFixMessages.UnusedCodeMultiFix_RemoveUnusedField_description); if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES)) result.add(MultiFixMessages.UnusedCodeMultiFix_RemoveUnusedVariable_description); - return result.toArray(new String[0]); + if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS)) + result.add(MultiFixMessages.UnusedCodeMultiFix_RemoveUnusedParameter_description); + return result.toArray(new String[0]); } @Override @@ -159,6 +168,29 @@ public String getPreview() { buf.append(" int i= 10;\n"); //$NON-NLS-1$ } buf.append(" }\n"); //$NON-NLS-1$ + + + if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS)) { + String code= " public void zoz() {\n" //$NON-NLS-1$ + + " zozo();\n" //$NON-NLS-1$ + + " }\n" //$NON-NLS-1$ + + "\n" //$NON-NLS-1$ + + " private void zozo() {\n" //$NON-NLS-1$ + + " System.out.println(\"\");\n" //$NON-NLS-1$ + + " };\n"; //$NON-NLS-1$ + + buf.append(code); + } else { + String code= " public void zoz() {\n" //$NON-NLS-1$ + + " zozo(34);\n" //$NON-NLS-1$ + + " }\n" //$NON-NLS-1$ + + "\n" //$NON-NLS-1$ + + " private void zozo(int k) {\n" //$NON-NLS-1$ + + " System.out.println(\"\");\n" //$NON-NLS-1$ + + " };\n"; //$NON-NLS-1$ + buf.append(code); + } + buf.append("}\n"); //$NON-NLS-1$ if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_IMPORTS)) { @@ -202,6 +234,10 @@ public boolean canFix(ICompilationUnit compilationUnit, IProblemLocationCore pro isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_MEMBERS) && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_FELDS) || isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES); + if (UnusedCodeFixCore.isUnusedParameter(problem)) { + return isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS); + } + return false; } @@ -227,6 +263,8 @@ public int computeNumberOfFixes(CompilationUnit compilationUnit) { result+= getNumberOfProblems(problems, IProblem.UnusedPrivateField); if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES)) result+= getNumberOfProblems(problems, IProblem.LocalVariableIsNeverUsed); + if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS)) + result+= getNumberOfProblems(problems, IProblem.ArgumentIsNeverUsed); return result; } } diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileVersionerCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileVersionerCore.java index d17bd716..a017fdab 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileVersionerCore.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileVersionerCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 IBM Corporation and others. + * Copyright (c) 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -23,7 +23,7 @@ public class ProfileVersionerCore { - private static final int CURRENT_VERSION= 21; + private static final int CURRENT_VERSION= 22; public static int getFirstVersion() { return 1; @@ -94,6 +94,9 @@ public static Map updateAndComplete(Map oldSetti case 20: version20to21(oldSettings); //$FALL-THROUGH$ + case 21: + version21to22(oldSettings); + //$FALL-THROUGH$ default: for (Map.Entry entry : oldSettings.entrySet()) { final String key= entry.getKey(); @@ -733,6 +736,16 @@ private static void version20to21(Map oldSettings) { } } + private static void version21to22(Map oldSettings) { + oldSettings.put(DefaultCodeFormatterConstants.FORMATTER_ALIGN_SELECTOR_IN_METHOD_INVOCATION_ON_EXPRESSION_FIRST_LINE, DefaultCodeFormatterConstants.FALSE); + oldSettings.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SWITCH_CASE_WITH_ARROW, + DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_NO_SPLIT, DefaultCodeFormatterConstants.INDENT_DEFAULT)); + oldSettings.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_SWITCH_CASE_WITH_ARROW, + DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_NO_SPLIT, DefaultCodeFormatterConstants.INDENT_DEFAULT)); + oldSettings.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_SWITCH_CASE_WITH_COLON, + DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_NO_SPLIT, DefaultCodeFormatterConstants.INDENT_DEFAULT)); + } + /* old format constant values */ private static final String FORMATTER_METHOD_DECLARATION_ARGUMENTS_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.method_declaration_arguments_alignment"; //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java index 92b93372..8ca07ee5 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -70,6 +70,8 @@ private CorrectionMessages() { public static String QuickAssistProcessor_convert_to_static_import; public static String QuickAssistProcessor_convert_to_static_import_replace_all; public static String QuickAssistProcessor_inline_local_description; + public static String QuickAssistProcessor_modify_favorites; + public static String QuickAssistProcessor_modify_favorites_desc; public static String QuickAssistProcessor_name_extension_from_class; public static String QuickAssistProcessor_name_extension_from_interface; public static String SerialVersionHashOperation_computing_id; @@ -196,8 +198,6 @@ private CorrectionMessages() { public static String UnimplementedMethodsCorrectionProposal_info_singular; public static String UnimplementedMethodsCorrectionProposal_info_plural; - public static String UnimplementedCodeFix_DependenciesErrorMessage; - public static String UnimplementedCodeFix_DependenciesStatusMessage; public static String UnimplementedCodeFix_MakeAbstractFix_label; public static String UnimplementedCodeFix_TextEditGroup_label; @@ -216,6 +216,7 @@ private CorrectionMessages() { public static String UnresolvedElementsSubProcessor_changetype_description; public static String UnresolvedElementsSubProcessor_changetype_nopack_description; public static String UnresolvedElementsSubProcessor_importtype_description; + public static String UnresolvedElementsSubProcessor_change_to_qualified_description; public static String UnresolvedElementsSubProcessor_changevariable_description; public static String UnresolvedElementsSubProcessor_createfield_description; public static String UnresolvedElementsSubProcessor_createfield_other_description; @@ -270,16 +271,23 @@ private CorrectionMessages() { public static String NoCorrectionProposal_description; public static String MarkerResolutionProposal_additionaldesc; public static String NewCUCompletionUsingWizardProposal_createclass_description; + public static String NewCUCompletionUsingWizardProposal_createrecord_description; public static String NewCUCompletionUsingWizardProposal_createenum_description; public static String NewCUCompletionUsingWizardProposal_createclass_inpackage_description; + public static String NewCUCompletionUsingWizardProposal_createrecord_inpackage_description; public static String NewCUCompletionUsingWizardProposal_createinnerclass_description; + public static String NewCUCompletionUsingWizardProposal_createnewinnerclass_description; + public static String NewCUCompletionUsingWizardProposal_createinnerrecord_description; + public static String NewCUCompletionUsingWizardProposal_createnewinnerrecord_description; public static String NewCUCompletionUsingWizardProposal_createinnerenum_description; public static String NewCUCompletionUsingWizardProposal_createannotation_description; public static String NewCUCompletionUsingWizardProposal_createinnerclass_intype_description; + public static String NewCUCompletionUsingWizardProposal_createinnerrecord_intype_description; public static String NewCUCompletionUsingWizardProposal_createinnerenum_intype_description; public static String NewCUCompletionUsingWizardProposal_createinterface_description; public static String NewCUCompletionUsingWizardProposal_createinterface_inpackage_description; public static String NewCUCompletionUsingWizardProposal_createinnerinterface_description; + public static String NewCUCompletionUsingWizardProposal_createnewinnerinterface_description; public static String NewCUCompletionUsingWizardProposal_createenum_inpackage_description; public static String NewCUCompletionUsingWizardProposal_createinnerannotation_description; public static String NewCUCompletionUsingWizardProposal_createinnerinterface_intype_description; @@ -293,6 +301,7 @@ private CorrectionMessages() { public static String NewCUCompletionUsingWizardProposal_createnewinterface_inpackage_description; public static String NewCUCompletionUsingWizardProposal_createnewannotation_inpackage_description; public static String NewCUCompletionUsingWizardProposal_createnewenum_inpackage_description; + public static String NewCUCompletionUsingWizardProposal_createnewrecord_inpackage_description; public static String ConfigureProblemSeveritySubProcessor_compiler_info; public static String ConfigureProblemSeveritySubProcessor_info; public static String ConfigureProblemSeveritySubProcessor_name; @@ -389,6 +398,12 @@ private CorrectionMessages() { public static String AdvancedQuickAssistProcessor_joinWithOr_description; public static String AdvancedQuickAssistProcessor_splitOrCondition_description; public static String AdvancedQuickAssistProcessor_exchangeOperands_description; + public static String AddGetterSetter_creategetterssettersfortype_description; + public static String AddGettersSetters_additional_info; + public static String AddHashCodeEquals_createhashcodeequalsfortype_description; + public static String AddHashCodeEquals_additional_info; + public static String AddToString_createtostringfortype_description; + public static String AddToString_additional_info; public static String AddTypeParameterProposal_method_label; public static String AddTypeParameterProposal_type_label; @@ -422,12 +437,15 @@ private CorrectionMessages() { public static String QuickAssistProcessor_extract_to_local_all_description; public static String QuickAssistProcessor_extract_to_local_description; public static String QuickAssistProcessor_extractmethod_description; + public static String QuickAssistProcessor_extractmethod_from_lambda_description; public static String QuickAssistProcessor_move_exception_to_separate_catch_block; public static String QuickAssistProcessor_move_exceptions_to_separate_catch_block; public static String QuickAssistProcessor_create_new_junit_test_case; public static String QuickAssistProcessor_create_new_junit_test_case_desc; public static String QuickAssistProcessor_create_new_impl; public static String QuickAssistProcessor_create_new_impl_desc; + public static String QuickAssistProcessor_create_new_interface_impl; + public static String QuickAssistProcessor_create_new_interface_impl_desc; public static String SuppressWarningsSubProcessor_suppress_warnings_label; public static String ReorgCorrectionsSubProcessor_accessrules_description; public static String ReorgCorrectionsSubProcessor_project_seup_fix_description; diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties index 725322b5..b71038f8 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2021 IBM Corporation and others. +# Copyright (c) 2000, 2022 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -189,6 +189,9 @@ ModifierCorrectionSubProcessor_removenative_description=Remove 'native' modifier ModifierCorrectionSubProcessor_removefinal_description=Remove 'final' modifier ModifierCorrectionSubProcessor_default_visibility_label=(package) ModifierCorrectionSubProcessor_addmissingbody_description=Add body +AddGettersSetters_additional_info=Starts the 'Generate Getters and Setters' action to create getters and setters +AddHashCodeEquals_additional_info=Starts the 'Generate Hashcode and Equals' action to create hashCode() and equals() methods +AddToString_additional_info=Starts the 'Generate toString()' action to create toString() method GetterSetterCorrectionSubProcessor_additional_info=Starts the 'Encapsulate field' refactoring to create getter and setters GetterSetterCorrectionSubProcessor_replacewithgetter_description=Replace {0} with getter GetterSetterCorrectionSubProcessor_replacewithsetter_description=Replace {0} with setter @@ -230,6 +233,7 @@ UnresolvedElementsSubProcessor_changetype_nopack_description=Change to ''{0}'' UnresolvedElementsSubProcessor_change_full_type_description=Change type to ''{0}'' UnresolvedElementsSubProcessor_change_to_static_import_description=Change to ''{0}'' UnresolvedElementsSubProcessor_importtype_description=Import ''{0}'' ({1}) +UnresolvedElementsSubProcessor_change_to_qualified_description=Change to ''{0}'' UnresolvedElementsSubProcessor_changevariable_description=Change to ''{0}'' UnresolvedElementsSubProcessor_createfield_description=Create field ''{0}'' @@ -306,16 +310,23 @@ MarkerResolutionProposal_additionaldesc=Problem description: {0} NewCUCompletionUsingWizardProposal_createclass_description=Create class ''{0}'' NewCUCompletionUsingWizardProposal_createenum_description=Create enum ''{0}'' +NewCUCompletionUsingWizardProposal_createrecord_description=Create record ''{0}'' NewCUCompletionUsingWizardProposal_createclass_inpackage_description=Create class ''{0}'' in package ''{1}'' +NewCUCompletionUsingWizardProposal_createrecord_inpackage_description=Create record ''{0}'' in package ''{1}'' NewCUCompletionUsingWizardProposal_createinnerclass_description=Create member class ''{0}'' +NewCUCompletionUsingWizardProposal_createnewinnerclass_description=Create new member class +NewCUCompletionUsingWizardProposal_createinnerrecord_description=Create member record ''{0}'' +NewCUCompletionUsingWizardProposal_createnewinnerrecord_description=Create new member record NewCUCompletionUsingWizardProposal_createinnerenum_description=Create member enum ''{0}'' NewCUCompletionUsingWizardProposal_createannotation_description=Create annotation ''{0}'' NewCUCompletionUsingWizardProposal_createinnerclass_intype_description=Create class ''{0}'' in type ''{1}'' NewCUCompletionUsingWizardProposal_createinnerenum_intype_description=Create enum ''{0}'' in type ''{1}'' +NewCUCompletionUsingWizardProposal_createinnerrecord_intype_description=Create record ''{0}'' in type ''{1}'' NewCUCompletionUsingWizardProposal_createinterface_description=Create interface ''{0}'' NewCUCompletionUsingWizardProposal_createinterface_inpackage_description=Create interface ''{0}'' in package ''{1}'' NewCUCompletionUsingWizardProposal_createinnerinterface_description=Create member interface ''{0}'' +NewCUCompletionUsingWizardProposal_createnewinnerinterface_description=Create new member interface NewCUCompletionUsingWizardProposal_createenum_inpackage_description=Create enum ''{0}'' in package ''{1}'' NewCUCompletionUsingWizardProposal_createinnerannotation_description=Create member annotation ''{0}'' NewCUCompletionUsingWizardProposal_createinnerinterface_intype_description=Create interface ''{0}'' in type ''{1}'' @@ -325,6 +336,7 @@ NewCUCompletionUsingWizardProposal_createnewclass_inpackage_description=Create n NewCUCompletionUsingWizardProposal_createnewinterface_inpackage_description=Create new interface in package ''{0}'' NewCUCompletionUsingWizardProposal_createnewannotation_inpackage_description=Create new annotation in package ''{0}'' NewCUCompletionUsingWizardProposal_createnewenum_inpackage_description=Create new enum in package ''{0}'' +NewCUCompletionUsingWizardProposal_createnewrecord_inpackage_description=Create new record in package ''{0}'' NewCUCompletionUsingWizardProposal_createclass_info=Opens the new class wizard to create the type. NewCUCompletionUsingWizardProposal_createenum_info=Opens the new enum wizard to create the type. @@ -340,8 +352,6 @@ UnimplementedMethodsCorrectionProposal_enum_info=Adding all method required in e UnimplementedMethodsCorrectionProposal_info_singular=1 method to implement: UnimplementedMethodsCorrectionProposal_info_plural={0} methods to implement: -UnimplementedCodeFix_DependenciesErrorMessage=The quick fix could not resolve the error. -UnimplementedCodeFix_DependenciesStatusMessage=Can not implement the missing methods, either due to compile errors or the projects build path does not resolve all dependencies. UnimplementedCodeFix_MakeAbstractFix_label=Make classes abstract UnimplementedCodeFix_TextEditGroup_label=Add abstract modifier @@ -384,6 +394,7 @@ QuickAssistProcessor_exceptiontothrows_description=Replace exception with throws QuickAssistProcessor_extract_to_local_all_description=Extract to local variable (replace all occurrences) QuickAssistProcessor_extract_to_local_description=Extract to local variable QuickAssistProcessor_extractmethod_description=Extract to method +QuickAssistProcessor_extractmethod_from_lambda_description=Extract lambda body to method QuickAssistProcessor_extract_to_constant_description=Extract to constant QuickAssistProcessor_joindeclaration_description=Join variable declaration QuickAssistProcessor_add_inferred_lambda_parameter_types=Add inferred lambda parameter types @@ -406,6 +417,8 @@ QuickAssistProcessor_convert_to_static_import=Convert to static import QuickAssistProcessor_convert_to_static_import_replace_all=Convert to static import (replace all occurrences) QuickAssistProcessor_convert_anonym_to_nested=Convert anonymous to nested class QuickAssistProcessor_name_extension_from_class={0}Implementation +QuickAssistProcessor_modify_favorites=Add {0} to static member favorites list +QuickAssistProcessor_modify_favorites_desc=Add new entry to static member favorites preferences QuickAssistProcessor_typetoarrayInitializer_description=Add type to initializer QuickAssistProcessor_convert_local_to_field_description=Convert local variable to field QuickAssistProcessor_convert_to_indexed_for_loop=Convert to 'for' loop using index @@ -429,6 +442,8 @@ QuickAssistProcessor_create_new_junit_test_case=Create new JUnit test case for ' QuickAssistProcessor_create_new_junit_test_case_desc=Open the New > JUnit Test Case wizard. QuickAssistProcessor_create_new_impl=Create new implementation of ''{0}'' QuickAssistProcessor_create_new_impl_desc=Open the New > Class wizard. +QuickAssistProcessor_create_new_interface_impl=Create new interface, extending ''{0}'' +QuickAssistProcessor_create_new_interface_impl_desc=Open the New > Interface wizard. LinkedNamesAssistProposal_proposalinfo=Link all references for a local rename (does not change references in other files) LinkedNamesAssistProposal_description=Rename in file @@ -500,6 +515,9 @@ SuppressWarningsSubProcessor_fix_suppress_token_label=Change to ''{0}'' SuppressWarningsSubProcessor_remove_annotation_label=Remove ''{0}'' token ModifierCorrectionSubProcessor_changefieldmodifiertononstatic_description=Remove ''static'' modifier of ''{0}'' GetterSetterCorrectionSubProcessor_creategetterunsingencapsulatefield_description=Create getter and setter for ''{0}''... +AddGetterSetter_creategetterssettersfortype_description=Create getters and setters for ''{0}'' +AddHashCodeEquals_createhashcodeequalsfortype_description=Create hashCode() and equals() methods for ''{0}'' +AddToString_createtostringfortype_description=Create toString() method for ''{0}'' VarargsWarningsSubProcessor_add_safevarargs_label=Add @SafeVarargs VarargsWarningsSubProcessor_add_safevarargs_to_method_label=Add @SafeVarargs to ''{0}(..)'' VarargsWarningsSubProcessor_remove_safevarargs_label=Remove @SafeVarargs diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessorUtil.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessorUtil.java new file mode 100644 index 00000000..47148d97 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessorUtil.java @@ -0,0 +1,492 @@ +/******************************************************************************* + * Copyright (c) 2021 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + * Red Hat Inc. - moved static methods from QuickAssistProcessor to here + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.text.correction; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.jface.text.link.LinkedPositionGroup; + +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.ArrayCreation; +import org.eclipse.jdt.core.dom.ArrayType; +import org.eclipse.jdt.core.dom.Block; +import org.eclipse.jdt.core.dom.ClassInstanceCreation; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.CreationReference; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ExpressionMethodReference; +import org.eclipse.jdt.core.dom.ExpressionStatement; +import org.eclipse.jdt.core.dom.IBinding; +import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.IVariableBinding; +import org.eclipse.jdt.core.dom.LambdaExpression; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.MethodReference; +import org.eclipse.jdt.core.dom.Modifier; +import org.eclipse.jdt.core.dom.Name; +import org.eclipse.jdt.core.dom.ParameterizedType; +import org.eclipse.jdt.core.dom.ReturnStatement; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.SuperMethodInvocation; +import org.eclipse.jdt.core.dom.SuperMethodReference; +import org.eclipse.jdt.core.dom.ThisExpression; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.TypeMethodReference; +import org.eclipse.jdt.core.dom.VariableDeclaration; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; + +import org.eclipse.jdt.internal.core.manipulation.StubUtility; +import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.dom.Bindings; +import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder; +import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; +import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore; + +public class QuickAssistProcessorUtil { + + /** + * Returns the functional interface method being implemented by the given method reference. + * + * @param methodReference the method reference to get the functional method + * @return the functional interface method being implemented by methodReference or + * null if it could not be derived + */ + public static IMethodBinding getFunctionalMethodForMethodReference(MethodReference methodReference) { + ITypeBinding targetTypeBinding= ASTNodes.getTargetType(methodReference); + if (targetTypeBinding == null) + return null; + + IMethodBinding functionalMethod= targetTypeBinding.getFunctionalInterfaceMethod(); + if (functionalMethod != null && functionalMethod.isSynthetic()) { + functionalMethod= Bindings.findOverriddenMethodInType(functionalMethod.getDeclaringClass(), functionalMethod); + } + return functionalMethod; + } + + /** + * Converts and replaces the given method reference with corresponding lambda expression in the + * given ASTRewrite. + * + * @param methodReference the method reference to convert + * @param functionalMethod the non-generic functional interface method to be implemented by the + * lambda expression + * @param astRoot the AST root + * @param rewrite the ASTRewrite + * @param linkedProposalModel to create linked proposals for lambda's parameters or + * null if linked proposals are not required + * @param createBlockBody true if lambda expression's body should be a block + * + * @return lambda expression used to replace the method reference in the given ASTRewrite + * @throws JavaModelException if an exception occurs while accessing the Java element + * corresponding to the functionalMethod + */ + public static LambdaExpression convertMethodRefernceToLambda(MethodReference methodReference, IMethodBinding functionalMethod, CompilationUnit astRoot, + ASTRewrite rewrite, LinkedProposalModelCore linkedProposalModel, boolean createBlockBody) throws JavaModelException { + + AST ast= astRoot.getAST(); + LambdaExpression lambda= ast.newLambdaExpression(); + + String[] lambdaParamNames= QuickAssistProcessorUtil.getUniqueParameterNames(methodReference, functionalMethod); + List lambdaParameters= lambda.parameters(); + for (int i= 0; i < lambdaParamNames.length; i++) { + String paramName= lambdaParamNames[i]; + VariableDeclarationFragment lambdaParameter= ast.newVariableDeclarationFragment(); + SimpleName name= ast.newSimpleName(paramName); + lambdaParameter.setName(name); + lambdaParameters.add(lambdaParameter); + if (linkedProposalModel != null) { + linkedProposalModel.getPositionGroup(name.getIdentifier(), true).addPosition(rewrite.track(name), i == 0); + } + } + + int noOfLambdaParameters= lambdaParamNames.length; + lambda.setParentheses(noOfLambdaParameters != 1); + + ITypeBinding returnTypeBinding= functionalMethod.getReturnType(); + IMethodBinding referredMethodBinding= methodReference.resolveMethodBinding(); // too often null, see bug 440000, bug 440344, bug 333665 + + if (methodReference instanceof CreationReference) { + CreationReference creationRef= (CreationReference) methodReference; + Type type= creationRef.getType(); + if (type instanceof ArrayType) { + ArrayCreation arrayCreation= ast.newArrayCreation(); + if (createBlockBody) { + Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(arrayCreation, returnTypeBinding, ast); + lambda.setBody(blockBody); + } else { + lambda.setBody(arrayCreation); + } + + ArrayType arrayType= (ArrayType) type; + Type copiedElementType= (Type) rewrite.createCopyTarget(arrayType.getElementType()); + arrayCreation.setType(ast.newArrayType(copiedElementType, arrayType.getDimensions())); + SimpleName name= ast.newSimpleName(lambdaParamNames[0]); + arrayCreation.dimensions().add(name); + if (linkedProposalModel != null) { + linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP); + } + } else { + ClassInstanceCreation cic= ast.newClassInstanceCreation(); + if (createBlockBody) { + Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(cic, returnTypeBinding, ast); + lambda.setBody(blockBody); + } else { + lambda.setBody(cic); + } + + ITypeBinding typeBinding= type.resolveBinding(); + if (!(type instanceof ParameterizedType) && typeBinding != null && typeBinding.getTypeDeclaration().isGenericType()) { + cic.setType(ast.newParameterizedType((Type) rewrite.createCopyTarget(type))); + } else { + cic.setType((Type) rewrite.createCopyTarget(type)); + } + List invocationArgs= QuickAssistProcessorUtil.getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames); + cic.arguments().addAll(invocationArgs); + if (linkedProposalModel != null) { + for (SimpleName name : invocationArgs) { + linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP); + } + } + cic.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodReference.typeArguments())); + } + + } else if (referredMethodBinding != null && Modifier.isStatic(referredMethodBinding.getModifiers())) { + MethodInvocation methodInvocation= ast.newMethodInvocation(); + if (createBlockBody) { + Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(methodInvocation, returnTypeBinding, ast); + lambda.setBody(blockBody); + } else { + lambda.setBody(methodInvocation); + } + + Expression expr= null; + boolean hasConflict= QuickAssistProcessorUtil.hasConflict(methodReference.getStartPosition(), referredMethodBinding, ScopeAnalyzer.METHODS | ScopeAnalyzer.CHECK_VISIBILITY, astRoot); + if (hasConflict || !Bindings.isSuperType(referredMethodBinding.getDeclaringClass(), ASTNodes.getEnclosingType(methodReference)) || methodReference.typeArguments().size() != 0) { + if (methodReference instanceof ExpressionMethodReference) { + ExpressionMethodReference expressionMethodReference= (ExpressionMethodReference) methodReference; + expr= (Expression) rewrite.createCopyTarget(expressionMethodReference.getExpression()); + } else if (methodReference instanceof TypeMethodReference) { + Type type= ((TypeMethodReference) methodReference).getType(); + ITypeBinding typeBinding= type.resolveBinding(); + if (typeBinding != null) { + ImportRewrite importRewrite= StubUtility.createImportRewrite(astRoot, true); + expr= ast.newName(importRewrite.addImport(typeBinding)); + } + } + } + methodInvocation.setExpression(expr); + SimpleName methodName= QuickAssistProcessorUtil.getMethodInvocationName(methodReference); + methodInvocation.setName((SimpleName) rewrite.createCopyTarget(methodName)); + List invocationArgs= QuickAssistProcessorUtil.getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames); + methodInvocation.arguments().addAll(invocationArgs); + if (linkedProposalModel != null) { + for (SimpleName name : invocationArgs) { + linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP); + } + } + methodInvocation.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodReference.typeArguments())); + + } else if (methodReference instanceof SuperMethodReference) { + SuperMethodInvocation superMethodInvocation= ast.newSuperMethodInvocation(); + if (createBlockBody) { + Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(superMethodInvocation, returnTypeBinding, ast); + lambda.setBody(blockBody); + } else { + lambda.setBody(superMethodInvocation); + } + + Name superQualifier= ((SuperMethodReference) methodReference).getQualifier(); + if (superQualifier != null) { + superMethodInvocation.setQualifier((Name) rewrite.createCopyTarget(superQualifier)); + } + SimpleName methodName= QuickAssistProcessorUtil.getMethodInvocationName(methodReference); + superMethodInvocation.setName((SimpleName) rewrite.createCopyTarget(methodName)); + List invocationArgs= QuickAssistProcessorUtil.getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames); + superMethodInvocation.arguments().addAll(invocationArgs); + if (linkedProposalModel != null) { + for (SimpleName name : invocationArgs) { + linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP); + } + } + superMethodInvocation.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodReference.typeArguments())); + + } else { + MethodInvocation methodInvocation= ast.newMethodInvocation(); + if (createBlockBody) { + Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(methodInvocation, returnTypeBinding, ast); + lambda.setBody(blockBody); + } else { + lambda.setBody(methodInvocation); + } + + boolean isTypeReference= QuickAssistProcessorUtil.isTypeReferenceToInstanceMethod(methodReference); + if (isTypeReference) { + SimpleName name= ast.newSimpleName(lambdaParamNames[0]); + methodInvocation.setExpression(name); + if (linkedProposalModel != null) { + linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP); + } + } else { + Expression expr= ((ExpressionMethodReference) methodReference).getExpression(); + if (!(expr instanceof ThisExpression) || (methodReference.typeArguments().size() != 0)) { + methodInvocation.setExpression((Expression) rewrite.createCopyTarget(expr)); + } + } + SimpleName methodName= QuickAssistProcessorUtil.getMethodInvocationName(methodReference); + methodInvocation.setName((SimpleName) rewrite.createCopyTarget(methodName)); + List invocationArgs= QuickAssistProcessorUtil.getInvocationArguments(ast, isTypeReference ? 1 : 0, noOfLambdaParameters, lambdaParamNames); + methodInvocation.arguments().addAll(invocationArgs); + if (linkedProposalModel != null) { + for (SimpleName name : invocationArgs) { + linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP); + } + } + methodInvocation.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodReference.typeArguments())); + } + + rewrite.replace(methodReference, lambda, null); + return lambda; + } + + public static Block getBlockBodyForLambda(Expression bodyExpr, ITypeBinding returnTypeBinding, AST ast) { + Statement statementInBlockBody; + if (ast.resolveWellKnownType("void").isEqualTo(returnTypeBinding)) { //$NON-NLS-1$ + ExpressionStatement expressionStatement= ast.newExpressionStatement(bodyExpr); + statementInBlockBody= expressionStatement; + } else { + ReturnStatement returnStatement= ast.newReturnStatement(); + returnStatement.setExpression(bodyExpr); + statementInBlockBody= returnStatement; + } + Block blockBody= ast.newBlock(); + blockBody.statements().add(statementInBlockBody); + return blockBody; + } + + public static List getCopiedTypeArguments(ASTRewrite rewrite, List typeArguments) { + List copiedTypeArgs= new ArrayList<>(); + for (Type typeArg : typeArguments) { + copiedTypeArgs.add((Type) rewrite.createCopyTarget(typeArg)); + } + return copiedTypeArgs; + } + + private static SimpleName getMethodInvocationName(MethodReference methodReference) { + SimpleName name= null; + if (methodReference instanceof ExpressionMethodReference) { + name= ((ExpressionMethodReference) methodReference).getName(); + } else if (methodReference instanceof TypeMethodReference) { + name= ((TypeMethodReference) methodReference).getName(); + } else if (methodReference instanceof SuperMethodReference) { + name= ((SuperMethodReference) methodReference).getName(); + } + return name; + } + + public static String[] getUniqueParameterNames(MethodReference methodReference, IMethodBinding functionalMethod) throws JavaModelException { + String[] originalParameterNames= ((IMethod) functionalMethod.getJavaElement()).getParameterNames(); + String[] newNames= new String[originalParameterNames.length]; + Set excludedNames= new HashSet<>(ASTNodes.getVisibleLocalVariablesInScope(methodReference)); + + for (int i= 0; i < originalParameterNames.length; i++) { + String paramName= originalParameterNames[i]; + + if (excludedNames.contains(paramName)) { + Set allNamesToExclude= new HashSet<>(excludedNames); + Collections.addAll(allNamesToExclude, originalParameterNames); + + String newParamName= QuickAssistProcessorUtil.createName(paramName, allNamesToExclude); + + excludedNames.add(newParamName); + newNames[i]= newParamName; + } else { + newNames[i]= paramName; + } + } + + return newNames; + } + + private static String createName(final String nameRoot, final Set excludedNames) { + int i= 1; + String candidate; + + do { + candidate= nameRoot + i++; + } while (excludedNames.remove(candidate)); + + return candidate; + } + + private static List getInvocationArguments(AST ast, int begIndex, int noOfLambdaParameters, String[] lambdaParamNames) { + List args= new ArrayList<>(); + for (int i= begIndex; i < noOfLambdaParameters; i++) { + args.add(ast.newSimpleName(lambdaParamNames[i])); + } + return args; + } + + private static boolean hasConflict(int startPosition, IMethodBinding referredMethodBinding, int flags, CompilationUnit cu) { + ScopeAnalyzer analyzer= new ScopeAnalyzer(cu); + for (IBinding decl : analyzer.getDeclarationsInScope(startPosition, flags)) { + if (decl.getName().equals(referredMethodBinding.getName()) && !referredMethodBinding.getMethodDeclaration().isEqualTo(decl)) + return true; + } + return false; + } + + public static boolean isTypeReferenceToInstanceMethod(MethodReference methodReference) { + if (methodReference instanceof TypeMethodReference) + return true; + if (methodReference instanceof ExpressionMethodReference) { + Expression expression= ((ExpressionMethodReference) methodReference).getExpression(); + if (expression instanceof Name) { + IBinding nameBinding= ((Name) expression).resolveBinding(); + if (nameBinding instanceof ITypeBinding) { + return true; + } + } + } + return false; + } + + /** + * Changes the expression body of the given lambda expression to block form. + * {@link LambdaExpression#resolveMethodBinding()} should not be null for the given + * lambda expression. + * + * @param lambda the lambda expression to convert the body form + * @param ast the AST to create new nodes + * @param rewrite the ASTRewrite + */ + public static void changeLambdaBodyToBlock(LambdaExpression lambda, AST ast, ASTRewrite rewrite) { + Expression bodyExpr= (Expression) rewrite.createMoveTarget(lambda.getBody()); + Block blockBody= getBlockBodyForLambda(bodyExpr, lambda.resolveMethodBinding().getReturnType(), ast); + rewrite.set(lambda, LambdaExpression.BODY_PROPERTY, blockBody, null); + } + + /** + * Return the first auto closable nodes. When a node that isn't Autoclosable is found the method + * returns. + * + * @param astNodes The nodes covered. + * @return List of the first AutoClosable nodes found + */ + public static List getCoveredAutoClosableNodes(List astNodes) { + List autoClosableNodes= new ArrayList<>(); + for (ASTNode astNode : astNodes) { + if (isAutoClosable(astNode)) { + autoClosableNodes.add(astNode); + } else { + return autoClosableNodes; + } + } + return autoClosableNodes; + } + + public static int findEndPostion(ASTNode node) { + int end= node.getStartPosition() + node.getLength(); + Map nodeSimpleNameBindings= getVariableStatementBinding(node); + List nodeNames= new ArrayList<>(nodeSimpleNameBindings.keySet()); + if (nodeNames.isEmpty()) { + return -1; + } + SimpleName nodeSimpleName= nodeNames.get(0); + SimpleName[] coveredNodeBindings= LinkedNodeFinder.findByNode(node.getRoot(), nodeSimpleName); + if (coveredNodeBindings.length == 0) { + return -1; + } + for (ASTNode astNode : coveredNodeBindings) { + end= Math.max(end, (astNode.getStartPosition() + astNode.getLength())); + } + return end; + } + + public static Map getVariableStatementBinding(ASTNode astNode) { + Map variableBindings= new HashMap<>(); + astNode.accept(new ASTVisitor() { + @Override + public boolean visit(VariableDeclarationStatement node) { + for (Object o : node.fragments()) { + if (o instanceof VariableDeclarationFragment) { + VariableDeclarationFragment vdf= (VariableDeclarationFragment) o; + SimpleName name= vdf.getName(); + IBinding binding= name.resolveBinding(); + if (binding instanceof IVariableBinding) { + variableBindings.put(name, (IVariableBinding) binding); + break; + } + } + } + return false; + } + }); + return variableBindings; + } + + public static boolean isAutoClosable(ITypeBinding typeBinding) { + return Bindings.findTypeInHierarchy(typeBinding, "java.lang.AutoCloseable") != null; //$NON-NLS-1$ + } + + public static boolean isAutoClosable(ASTNode astNode) { + Map simpleNames= getVariableStatementBinding(astNode); + for (Entry entry : simpleNames.entrySet()) { + ITypeBinding typeBinding= null; + switch (entry.getKey().getParent().getNodeType()) { + case ASTNode.VARIABLE_DECLARATION_FRAGMENT: + case ASTNode.VARIABLE_DECLARATION_STATEMENT: + case ASTNode.ASSIGNMENT: + typeBinding= entry.getValue().getType(); + break; + default: + continue; + } + if (typeBinding != null && isAutoClosable(typeBinding)) { + return true; + } + } + return false; + } + + public static int getIndex(int offset, List statements) { + for (int i= 0; i < statements.size(); i++) { + Statement s= statements.get(i); + if (offset <= s.getStartPosition()) { + return i; + } + if (offset < s.getStartPosition() + s.getLength()) { + return -1; + } + } + return statements.size(); + } + +} diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/util/ASTHelper.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/util/ASTHelper.java index cc206dfd..7cc8f85b 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/util/ASTHelper.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/util/ASTHelper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2021 IBM Corporation and others. + * Copyright (c) 2019, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -32,6 +32,9 @@ public class ASTHelper { public static final int JLS14 = AST.JLS14; public static final int JLS15 = AST.JLS15; public static final int JLS16 = AST.JLS16; + public static final int JLS17 = AST.JLS17; + public static final int JLS18 = AST.JLS18; + public static final int JLS19 = AST.JLS19; private static boolean isNodeTypeSupportedInAST(AST ast, int nodeType) { switch (nodeType) { @@ -44,6 +47,11 @@ private static boolean isNodeTypeSupportedInAST(AST ast, int nodeType) { case ASTNode.RECORD_DECLARATION: case ASTNode.INSTANCEOF_EXPRESSION: return ast.apiLevel() >= JLS16; + case ASTNode.TAG_PROPERTY: + return ast.apiLevel() >= AST.JLS18; + case ASTNode.TYPE_PATTERN: + case ASTNode.RECORD_PATTERN: + return ast.isPreviewEnabled(); default: break; } @@ -54,7 +62,7 @@ private static boolean isModifierSupportedInAST(AST ast, int modifier) { switch (modifier) { case Modifier.SEALED: case Modifier.NON_SEALED: - return ast.isPreviewEnabled(); + return ast.apiLevel() >= JLS17; default: break; } @@ -89,4 +97,15 @@ public static boolean isInstanceofExpressionPatternSupported(AST ast) { return isNodeTypeSupportedInAST(ast, ASTNode.INSTANCEOF_EXPRESSION); } + public static boolean isPatternSupported(AST ast) { + return isNodeTypeSupportedInAST(ast, ASTNode.TYPE_PATTERN); + } + + public static boolean isRecordPatternSupported(AST ast) { + return isNodeTypeSupportedInAST(ast, ASTNode.RECORD_PATTERN); + } + + public static boolean isJavaDocCodeSnippetSupported(AST ast) { + return isNodeTypeSupportedInAST(ast, ASTNode.TAG_PROPERTY); + } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/NecessaryParenthesesChecker.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/NecessaryParenthesesChecker.java index 889ad828..3a3ba4e1 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/NecessaryParenthesesChecker.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/NecessaryParenthesesChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2019 IBM Corporation and others. + * Copyright (c) 2011, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -21,6 +21,7 @@ import org.eclipse.jdt.core.dom.ArrayAccess; import org.eclipse.jdt.core.dom.ArrayCreation; import org.eclipse.jdt.core.dom.AssertStatement; +import org.eclipse.jdt.core.dom.CastExpression; import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; import org.eclipse.jdt.core.dom.ConditionalExpression; import org.eclipse.jdt.core.dom.DoStatement; @@ -40,6 +41,7 @@ import org.eclipse.jdt.core.dom.SwitchStatement; import org.eclipse.jdt.core.dom.SynchronizedStatement; import org.eclipse.jdt.core.dom.ThrowStatement; +import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.dom.WhileStatement; @@ -60,6 +62,7 @@ private static boolean expressionTypeNeedsParentheses(Expression expression) { || type == ASTNode.POSTFIX_EXPRESSION || type == ASTNode.CAST_EXPRESSION || type == ASTNode.INSTANCEOF_EXPRESSION + || type == ASTNode.PATTERN_INSTANCEOF_EXPRESSION || type == ASTNode.ARRAY_CREATION || type == ASTNode.ASSIGNMENT; } @@ -404,6 +407,13 @@ private static boolean needsParenthesesForPrefixExpression(Expression parentExpr (expressionOperator == PrefixExpression.Operator.MINUS || expressionOperator == PrefixExpression.Operator.DECREMENT)) { return true; } + } else if (parentExpression instanceof CastExpression) { + CastExpression castExp= (CastExpression) parentExpression; + Type type= castExp.getType(); + if (type != null && type.isPrimitiveType()) { + return false; + } + return true; } return false; } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/OperatorPrecedence.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/OperatorPrecedence.java index 065da72b..d245dd84 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/OperatorPrecedence.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/OperatorPrecedence.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -24,6 +24,7 @@ import org.eclipse.jdt.core.dom.InfixExpression.Operator; import org.eclipse.jdt.core.dom.InstanceofExpression; import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.PatternInstanceofExpression; import org.eclipse.jdt.core.dom.PostfixExpression; import org.eclipse.jdt.core.dom.PrefixExpression; @@ -73,7 +74,7 @@ public static int getExpressionPrecedence(Expression expression) { return ASSIGNMENT; } else if (expression instanceof ConditionalExpression) { return CONDITIONAL; - } else if (expression instanceof InstanceofExpression) { + } else if (expression instanceof InstanceofExpression || expression instanceof PatternInstanceofExpression) { return RELATIONAL; } else if (expression instanceof CastExpression) { return TYPEGENERATION; diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/BreakContinueTargetFinder.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/BreakContinueTargetFinder.java similarity index 97% rename from org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/BreakContinueTargetFinder.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/BreakContinueTargetFinder.java index d01cb810..44f34dc8 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/BreakContinueTargetFinder.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/BreakContinueTargetFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -11,7 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.jdt.internal.ui.search; +package org.eclipse.jdt.internal.core.manipulation.search; import java.util.ArrayList; import java.util.List; @@ -36,13 +36,11 @@ import org.eclipse.jdt.core.dom.SwitchStatement; import org.eclipse.jdt.core.dom.WhileStatement; -import org.eclipse.jdt.internal.core.manipulation.search.IOccurrencesFinder; +import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.TokenScanner; import org.eclipse.jdt.internal.corext.util.Messages; -import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; - /** * Class used to find the target for a break or continue statement according diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ExceptionOccurrencesFinder.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/ExceptionOccurrencesFinder.java similarity index 98% rename from org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ExceptionOccurrencesFinder.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/ExceptionOccurrencesFinder.java index 46c0b9f6..c190689c 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ExceptionOccurrencesFinder.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/ExceptionOccurrencesFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -11,7 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.jdt.internal.ui.search; +package org.eclipse.jdt.internal.core.manipulation.search; import java.util.ArrayList; import java.util.List; @@ -48,7 +48,6 @@ import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving; -import org.eclipse.jdt.internal.core.manipulation.search.IOccurrencesFinder; import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.Bindings; diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ImplementOccurrencesFinder.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/ImplementOccurrencesFinder.java similarity index 96% rename from org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ImplementOccurrencesFinder.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/ImplementOccurrencesFinder.java index 3a45e1d3..01c999ff 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ImplementOccurrencesFinder.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/ImplementOccurrencesFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -11,7 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.jdt.internal.ui.search; +package org.eclipse.jdt.internal.core.manipulation.search; import java.util.ArrayList; import java.util.List; @@ -33,13 +33,11 @@ import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.TypeDeclarationStatement; -import org.eclipse.jdt.internal.core.manipulation.search.IOccurrencesFinder; +import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.Bindings; import org.eclipse.jdt.internal.corext.util.Messages; -import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; - /** * Finds all implement occurrences of an extended class or an implemented interface. diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/MethodExitsFinder.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/MethodExitsFinder.java similarity index 98% rename from org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/MethodExitsFinder.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/MethodExitsFinder.java index ea2c9a78..f1f24735 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/MethodExitsFinder.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/MethodExitsFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -11,7 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.jdt.internal.ui.search; +package org.eclipse.jdt.internal.core.manipulation.search; import java.util.ArrayList; import java.util.List; @@ -48,7 +48,6 @@ import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving; -import org.eclipse.jdt.internal.core.manipulation.search.IOccurrencesFinder; import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.Bindings; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/SearchMessages.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/SearchMessages.java index c7bb826d..5236acc8 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/SearchMessages.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/SearchMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -35,4 +35,35 @@ private SearchMessages() { public static String OccurrencesFinder_occurrence_description; public static String OccurrencesFinder_occurrence_write_description; public static String OccurrencesSearchLabelProvider_line_number; + + public static String ExceptionOccurrencesFinder_no_exception; + public static String ExceptionOccurrencesFinder_searchfor; + public static String ExceptionOccurrencesFinder_label_singular; + public static String ExceptionOccurrencesFinder_label_plural; + public static String ExceptionOccurrencesFinder_occurrence_description; + public static String ExceptionOccurrencesFinder_occurrence_implicit_close_description; + + public static String ImplementOccurrencesFinder_invalidTarget; + public static String ImplementOccurrencesFinder_searchfor; + public static String ImplementOccurrencesFinder_label_singular; + public static String ImplementOccurrencesFinder_label_plural; + public static String ImplementOccurrencesFinder_occurrence_description; + + public static String MethodExitsFinder_job_label; + public static String MethodExitsFinder_label_plural; + public static String MethodExitsFinder_label_singular; + public static String MethodExitsFinder_no_return_type_selected; + public static String MethodExitsFinder_occurrence_exit_description; + public static String MethodExitsFinder_occurrence_exit_impclict_close_description; + public static String MethodExitsFinder_occurrence_return_description; + + public static String BreakContinueTargetFinder_break_label_plural; + public static String BreakContinueTargetFinder_break_label_singular; + public static String BreakContinueTargetFinder_cannot_highlight; + public static String BreakContinueTargetFinder_continue_label_plural; + public static String BreakContinueTargetFinder_continue_label_singular; + public static String BreakContinueTargetFinder_job_label; + public static String BreakContinueTargetFinder_no_break_or_continue_selected; + public static String BreakContinueTargetFinder_occurrence_description; + } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/SearchMessages.properties b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/SearchMessages.properties index 7a76fa7d..2a5452d2 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/SearchMessages.properties +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/search/SearchMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2016 IBM Corporation and others. +# Copyright (c) 2000, 2022 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -21,3 +21,39 @@ OccurrencesFinder_label_plural=''{0}'' - {1} occurrences in ''{2}'' OccurrencesFinder_occurrence_description=Occurrence of ''{0}'' OccurrencesFinder_occurrence_write_description=Write occurrence of ''{0}'' OccurrencesSearchLabelProvider_line_number={0}: + +ExceptionOccurrencesFinder_no_exception= Cannot search for current selection. Please select an exception. +ExceptionOccurrencesFinder_searchfor= Search for Exception Occurrences + +# The first argument will be replaced by the element name and the second one by the file name +ExceptionOccurrencesFinder_label_singular=''{0}'' - 1 exception occurrence in ''{1}'' +# The first argument will be replaced by the element name, the second by the count and the last by the file name +ExceptionOccurrencesFinder_label_plural=''{0}'' - {1} exception occurrences in ''{2}'' +ExceptionOccurrencesFinder_occurrence_description=Occurrences throwing ''{0}'' +ExceptionOccurrencesFinder_occurrence_implicit_close_description=''{0}'' is thrown from implicit close() methods of highlighted resources. + +ImplementOccurrencesFinder_invalidTarget= Cannot search for current selection. Please select a type behind 'implements' or 'extends'. +ImplementOccurrencesFinder_searchfor= Search for Implement Occurrences + +# The first argument will be replaced by the element name and the second one by the file name +ImplementOccurrencesFinder_label_singular=''{0}'' - 1 implement occurrence in ''{1}'' +# The first argument will be replaced by the element name, the second by the count and the last by the file name +ImplementOccurrencesFinder_label_plural=''{0}'' - {1} implement occurrences in ''{2}'' +ImplementOccurrencesFinder_occurrence_description=Implementors of methods in ''{0}'' + +MethodExitsFinder_job_label=Search for Method Exit Occurrences +MethodExitsFinder_label_plural=''{0}(...)'' - {1} method exit occurrence in ''{2}'' +MethodExitsFinder_label_singular=''{0}(...)'' - 1 method exit occurrence in ''{1}'' +MethodExitsFinder_no_return_type_selected=No return type selected +MethodExitsFinder_occurrence_exit_description=Exit point of ''{0}()'' +MethodExitsFinder_occurrence_exit_impclict_close_description=Exit point of ''{0}()'': Exception is thrown from implicit close() methods of highlighted resources. +MethodExitsFinder_occurrence_return_description=Return type of ''{0}()'' + +BreakContinueTargetFinder_break_label_plural=''{0}'' - {1} break target occurrences in ''{2}'' +BreakContinueTargetFinder_break_label_singular=''{0}'' - 1 break target occurrence in ''{1}'' +BreakContinueTargetFinder_cannot_highlight=Occurrences in this element cannot be highlighted +BreakContinueTargetFinder_continue_label_plural=''{0}'' - {1} continue target occurrences in ''{2}'' +BreakContinueTargetFinder_continue_label_singular=''{0}'' - 1 continue target occurrence in ''{1}'' +BreakContinueTargetFinder_job_label=Search for Break/Continue Target Occurrences +BreakContinueTargetFinder_no_break_or_continue_selected=No break or continue selected +BreakContinueTargetFinder_occurrence_description=Target of ''{0}'' diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchyCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchyCore.java index 145abb8e..1c24a09a 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchyCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchyCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 IBM Corporation and others. + * Copyright (c) 2019, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -120,6 +120,9 @@ private MethodWrapper[] getRoots(IMember[] members, boolean callers) { if (constructors.length == 0) { addRoot(member, roots, callers); // IType is a stand-in for the non-existing default constructor } else { + if (type.isRecord()) { + addRoot(member, roots, callers); + } for (IMethod constructor : constructors) { addRoot(constructor, roots, callers); } @@ -309,7 +312,7 @@ public static boolean isPossibleInputElement(Object element){ if (element instanceof IType) { IType type= (IType) element; try { - return type.isClass() || type.isEnum(); + return type.isClass() || type.isEnum() || type.isRecord(); } catch (JavaModelException e) { return false; } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallSearchResultCollector.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallSearchResultCollector.java index c792b197..2ab3af77 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallSearchResultCollector.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallSearchResultCollector.java @@ -43,21 +43,23 @@ public Map getCallers() { } protected void addMember(IMember member, IMember calledMember, int start, int end) { - addMember(member, calledMember, start, end, CallLocation.UNKNOWN_LINE_NUMBER); + addMember(member, calledMember, start, end, CallLocation.UNKNOWN_LINE_NUMBER, false); } - protected void addMember(IMember member, IMember calledMember, int start, int end, int lineNumber) { + protected void addMember(IMember member, IMember calledMember, int start, int end, int lineNumber, boolean potential) { if ((member != null) && (calledMember != null)) { if (!isIgnored(calledMember)) { MethodCall methodCall = fCalledMembers.get(calledMember.getHandleIdentifier()); if (methodCall == null) { - methodCall = new MethodCall(calledMember); + methodCall = new MethodCall(calledMember, potential); fCalledMembers.put(calledMember.getHandleIdentifier(), methodCall); } - methodCall.addCallLocation(new CallLocation(member, calledMember, start, - end, lineNumber)); + if(start > -1 && end > -1) { + methodCall.addCallLocation(new CallLocation(member, calledMember, start, + end, lineNumber)); + } } } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeAnalyzerVisitor.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeAnalyzerVisitor.java index 61493d91..ec46c451 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeAnalyzerVisitor.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeAnalyzerVisitor.java @@ -15,13 +15,16 @@ *******************************************************************************/ package org.eclipse.jdt.internal.corext.callhierarchy; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Optional; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; @@ -39,8 +42,10 @@ import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.SuperConstructorInvocation; import org.eclipse.jdt.core.dom.SuperMethodInvocation; +import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.internal.core.manipulation.JavaManipulationPlugin; @@ -55,9 +60,11 @@ class CalleeAnalyzerVisitor extends HierarchicalASTVisitor { private final IProgressMonitor fProgressMonitor; private int fMethodEndPosition; private int fMethodStartPosition; + private CallLocation fCalledAt; - CalleeAnalyzerVisitor(IMember member, CompilationUnit compilationUnit, IProgressMonitor progressMonitor) { - fSearchResults = new CallSearchResultCollector(); + CalleeAnalyzerVisitor(CallLocation calledAt, IMember member, CompilationUnit compilationUnit, IProgressMonitor progressMonitor) { + fSearchResults = new CallSearchResultCollector(); + this.fCalledAt= calledAt; this.fMember = member; this.fCompilationUnit= compilationUnit; this.fProgressMonitor = progressMonitor; @@ -145,6 +152,10 @@ public boolean visit(AbstractTypeDeclaration node) { @Override public boolean visit(MethodDeclaration node) { progressMonitorWorked(1); + if(Modifier.isAbstract(node.getModifiers()) || + ((node.getParent() instanceof TypeDeclaration) && ((TypeDeclaration)node.getParent()).isInterface())) { + addMethodCall(node.resolveBinding(), node); + } return isFurtherTraversalNecessary(node); } @@ -253,23 +264,41 @@ protected void addMethodCall(IMethodBinding calledMethodBinding, ASTNode node) { IMethod calledMethod = findIncludingSupertypes(calledMethodBinding, calledType, fProgressMonitor); - IMember referencedMember= null; + List referencedMembers= new ArrayList<>(); + boolean implementationResults = false; if (calledMethod == null) { if (calledMethodBinding.isConstructor() && calledMethodBinding.getParameterTypes().length == 0) { - referencedMember= calledType; + referencedMembers.add(calledType); } } else { - if (calledType.isInterface()) { - calledMethod = findImplementingMethods(calledMethod); - } - - if (!isIgnoredBySearchScope(calledMethod)) { - referencedMember= calledMethod; + // only find implementations if we are handling a method declaration. + if (node instanceof MethodDeclaration && (calledType.isInterface() || Flags.isAbstract(calledType.getFlags()))) { + Collection implementingMethods= CallHierarchyCore.getDefault().getImplementingMethods(calledMethod); + implementationResults = true; + for (IJavaElement element : implementingMethods) { + if(element instanceof IMethod) { + if(!isIgnoredBySearchScope((IMethod) element)) { + referencedMembers.add((IMethod) element); + } + } else if(element instanceof IMember) { + referencedMembers.add((IMember) element); + } + } + } else { + referencedMembers.add(calledMethod); } } - final int position= node.getStartPosition(); - final int number= fCompilationUnit.getLineNumber(position); - fSearchResults.addMember(fMember, referencedMember, position, position + node.getLength(), number < 1 ? 1 : number); + + Optional calledAt= Optional.ofNullable(fCalledAt); + Integer ignore = Integer.valueOf(-1); + final int position= implementationResults ? calledAt.map(CallLocation::getStart).orElse(ignore).intValue() : node.getStartPosition(); + final int number= implementationResults ? calledAt.map(CallLocation::getLineNumber).orElse(ignore).intValue() : fCompilationUnit.getLineNumber(position); + final int length = implementationResults ? calledAt.map(c -> Integer.valueOf(c.getEnd() - position)).orElse(ignore).intValue() : node.getLength(); + final IMember member = implementationResults ? calledAt.map(CallLocation::getMember).orElse(fMember) : fMember; + final boolean potential = implementationResults; + referencedMembers.forEach(m -> { + fSearchResults.addMember(member, m, position, position + length, number < 1 ? 1 : number, potential); + }); } } catch (JavaModelException jme) { JavaManipulationPlugin.log(jme); @@ -330,17 +359,6 @@ private boolean isFurtherTraversalNecessary(ASTNode node) { return isNodeWithinMethod(node) || isNodeEnclosingMethod(node); } - private IMethod findImplementingMethods(IMethod calledMethod) { - Collection implementingMethods = CallHierarchyCore.getDefault() - .getImplementingMethods(calledMethod); - - if ((implementingMethods.isEmpty()) || (implementingMethods.size() > 1)) { - return calledMethod; - } else { - return (IMethod) implementingMethods.iterator().next(); - } - } - private void progressMonitorWorked(int work) { if (fProgressMonitor != null) { fProgressMonitor.worked(work); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeMethodWrapper.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeMethodWrapper.java index b6c75853..4f895549 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeMethodWrapper.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeMethodWrapper.java @@ -96,7 +96,7 @@ protected Map findChildren(IProgressMonitor progressMonitor) } if (cu != null) { - CalleeAnalyzerVisitor visitor = new CalleeAnalyzerVisitor(member, cu, progressMonitor); + CalleeAnalyzerVisitor visitor = new CalleeAnalyzerVisitor(this.getMethodCall().getFirstCallLocation(), member, cu, progressMonitor); cu.accept(visitor); return visitor.getCallees(); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallerMethodWrapper.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallerMethodWrapper.java index d2fcd005..3c25907d 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallerMethodWrapper.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallerMethodWrapper.java @@ -22,7 +22,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IField; @@ -100,7 +100,7 @@ public boolean canHaveChildren() { protected Map findChildren(IProgressMonitor progressMonitor) { try { - IProgressMonitor monitor= new SubProgressMonitor(progressMonitor, 95, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL); + SubMonitor monitor = SubMonitor.convert(progressMonitor,"" , 95); //$NON-NLS-1$ checkCanceled(progressMonitor); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/Implementors.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/Implementors.java index b59e1f16..a0b358b1 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/Implementors.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/Implementors.java @@ -22,6 +22,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; @@ -68,7 +69,7 @@ public IJavaElement[] searchForImplementors(IJavaElement[] elements, IMember member = (IMember) element; IType type = member.getDeclaringType(); - if (type.isInterface()) { + if (type.isInterface() || Flags.isAbstract(type.getFlags())) { IType[] implementingTypes = findImplementingTypes(type, progressMonitor); @@ -181,6 +182,12 @@ private IJavaElement[] findMethods(IMethod method, IType[] types, try { for (IType type : types) { + // we don't want the type we start the searched on be searched again. This happens when + // searching for abstract method implementations on abstract classes. + if(method.getDeclaringType().equals(type)) { + continue; + } + IMethod[] methods = type.findMethods(method); if (methods != null) { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodCall.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodCall.java index 21882dbb..a04e7977 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodCall.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodCall.java @@ -23,14 +23,27 @@ public class MethodCall { private IMember fMember; private List fCallLocations; + private boolean potential; /** * @param enclosingElement */ public MethodCall(IMember enclosingElement) { - this.fMember = enclosingElement; + this(enclosingElement, false); } + /** + * @param enclosingElement enclosing member of this call object + * @param potential indicate whether this call object is a potential item in the hierarchy. A + * item is considered as potential when there is no direct reference, like methods on + * a implementation class which are referred through the interface in actual code. + */ + public MethodCall(IMember enclosingElement, boolean potential) { + this.fMember= enclosingElement; + this.potential = potential; + } + + /** * */ @@ -74,4 +87,26 @@ public void addCallLocation(CallLocation location) { fCallLocations.add(location); } + + /** + * Returns if this is a potential call object. + * + * @return true if its potential. + * @see #MethodCall(IMember, boolean) + */ + public boolean isPotential() { + return potential; + } + + @Override + public String toString() { + StringBuilder builder= new StringBuilder(); + builder.append("MethodCall ["); //$NON-NLS-1$ + if (fMember != null) { + builder.append(fMember); + } + builder.append(',').append(potential); + builder.append("]"); //$NON-NLS-1$ + return builder.toString(); + } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodWrapper.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodWrapper.java index ee938c52..0bbc2dde 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodWrapper.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodWrapper.java @@ -332,4 +332,20 @@ public void removeFromCache() { fElements= null; fMethodCache.remove(getMethodCall().getKey()); } + + @Override + public String toString() { + StringBuilder builder= new StringBuilder(); + builder.append("MethodWrapper ["); //$NON-NLS-1$ + if (fMethodCall != null) { + builder.append(fMethodCall); + } + if (fParent != null) { + builder.append(", "); //$NON-NLS-1$ + builder.append("parent="); //$NON-NLS-1$ + builder.append(fParent); + } + builder.append("]"); //$NON-NLS-1$ + return builder.toString(); + } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2Core.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2Core.java index 8ae4f6f2..688aeb2f 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2Core.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2Core.java @@ -18,11 +18,13 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.EnumSet; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.function.Predicate; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; @@ -95,7 +97,8 @@ public final class StubUtility2Core { /* This method should work with all AST levels. */ - public static MethodDeclaration createConstructorStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, ImportRewriteContext context, IMethodBinding binding, String type, int modifiers, boolean omitSuperForDefConst, boolean todo, CodeGenerationSettings settings, Map formatSettings) throws CoreException { + public static MethodDeclaration createConstructorStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, ImportRewriteContext context, IMethodBinding binding, String type, + int modifiers, boolean omitSuperForDefConst, boolean todo, CodeGenerationSettings settings, Map formatSettings) throws CoreException { AST ast= rewrite.getAST(); MethodDeclaration decl= ast.newMethodDeclaration(); decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, modifiers & ~Modifier.ABSTRACT & ~Modifier.NATIVE)); @@ -361,7 +364,7 @@ public static MethodDeclaration createImplementationStubCore(ICompilationUnit un String bodyStatement= ""; //$NON-NLS-1$ if (Modifier.isAbstract(modifiers)) { - Expression expression= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions()); + Expression expression= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), bindingReturnType, decl.getExtraDimensions()); if (expression != null) { ReturnStatement returnStatement= ast.newReturnStatement(); returnStatement.setExpression(expression); @@ -552,14 +555,6 @@ private static List getThrownExceptions(MethodDeclaration decl) { return decl.thrownExceptions(); } - private static IMethodBinding findMethodBinding(IMethodBinding method, List allMethods) { - for (IMethodBinding curr : allMethods) { - if (Bindings.isSubsignature(method, curr)) { - return curr; - } - } - return null; - } private static IMethodBinding findOverridingMethod(IMethodBinding method, List allMethods) { for (IMethodBinding curr : allMethods) { @@ -569,49 +564,6 @@ private static IMethodBinding findOverridingMethod(IMethodBinding method, List visited, - ArrayList allMethods, IPackageBinding currPack, ArrayList toImplement) { - - if (visited.add(typeBinding)) { - nextMethod: for (IMethodBinding curr : typeBinding.getDeclaredMethods()) { - for (Iterator allIter= allMethods.iterator(); allIter.hasNext();) { - IMethodBinding oneMethod= allIter.next(); - if (Bindings.isSubsignature(oneMethod, curr)) { - // We've already seen a method that is a subsignature of curr. - if (!Bindings.isSubsignature(curr, oneMethod)) { - // oneMethod is a true subsignature of curr; let's go with oneMethod - continue nextMethod; - } - // Subsignatures are equivalent. - // Check visibility and return types ('getErasure()' tries to achieve effect of "rename type variables") - if (Bindings.isVisibleInHierarchy(oneMethod, currPack) - && oneMethod.getReturnType().getErasure().isSubTypeCompatible(curr.getReturnType().getErasure())) { - // oneMethod is visible and curr doesn't have a stricter return type; let's go with oneMethod - continue nextMethod; - } - // curr is stricter than oneMethod, so let's remove oneMethod - allIter.remove(); - toImplement.remove(oneMethod); - } else if (Bindings.isSubsignature(curr, oneMethod)) { - // curr is a true subsignature of oneMethod. Let's remove oneMethod. - allIter.remove(); - toImplement.remove(oneMethod); - } - } - int modifiers= curr.getModifiers(); - if (!Modifier.isStatic(modifiers)) { - allMethods.add(curr); - if (Modifier.isAbstract(modifiers)) { - toImplement.add(curr); - } - } - } - for (ITypeBinding superInterface : typeBinding.getInterfaces()) { - findUnimplementedInterfaceMethods(superInterface, visited, allMethods, currPack, toImplement); - } - } - } - public static List getImplementationModifiers(AST ast, IMethodBinding method, boolean inInterface, ImportRewrite importRewrite, ImportRewriteContext context, EnumSet nullnessDefault) throws JavaModelException { IJavaProject javaProject= importRewrite.getCompilationUnit().getJavaProject(); int modifiers= method.getModifiers(); @@ -816,52 +768,133 @@ private static String suggestParameterName(ICompilationUnit unit, IVariableBindi return StubUtility.suggestArgumentName(unit.getJavaProject(), name, excluded); } - public static IMethodBinding[] getUnimplementedMethods(ITypeBinding typeBinding) { - return getUnimplementedMethods(typeBinding, false); - } + @SuppressWarnings("unchecked") + public static Collection getMethodsIn(ITypeBinding type, Predicate ignoreTheseMethods) { + if (type == null) { + return Collections.EMPTY_LIST; + } - public static IMethodBinding[] getUnimplementedMethods(ITypeBinding typeBinding, boolean implementAbstractsOfInput) { - ArrayList allMethods= new ArrayList<>(); - ArrayList toImplement= new ArrayList<>(); + if (ignoreTheseMethods == null) { + ignoreTheseMethods= m->false; + } + List allMethods= new ArrayList<>(); + IMethodBinding[] declaredMethods= type.getDeclaredMethods(); + for (IMethodBinding method : declaredMethods) { + if (!isStatic(method) && !method.isConstructor() && !isPrivate(method) && !ignoreTheseMethods.test(method)) { + allMethods.add(method); + } + } + + ITypeBinding[] interfaces= type.getInterfaces(); + Collection[] interfaceMethods; - for (IMethodBinding curr : typeBinding.getDeclaredMethods()) { - int modifiers= curr.getModifiers(); - if (!curr.isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) { - allMethods.add(curr); + if (!type.isInterface()) { + Collection superMethods= getMethodsIn(type.getSuperclass(), ignoreTheseMethods); + interfaceMethods= new Collection[interfaces.length + 1]; + interfaceMethods[interfaceMethods.length - 1]= superMethods; + for (IMethodBinding method : superMethods) { + if (isConcrete(method) && Bindings.isVisibleInHierarchy(method, type.getPackage()) && findSubSignatureMethod(method, allMethods) == null) { + allMethods.add(method); + } } + } else { + interfaceMethods= new Collection[interfaces.length]; + } + + for (int i= 0; i < interfaces.length; i++) { + interfaceMethods[i]= getMethodsIn(interfaces[i], ignoreTheseMethods); } - ITypeBinding superClass= typeBinding.getSuperclass(); - while (superClass != null) { - for (IMethodBinding curr : superClass.getDeclaredMethods()) { - int modifiers= curr.getModifiers(); - if (!curr.isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) { - if (findMethodBinding(curr, allMethods) == null) { - allMethods.add(curr); + List allInterfaceMethods= new ArrayList<>(); + + for (int i= 0; i < interfaceMethods.length; i++) { + for (IMethodBinding method : interfaceMethods[i]) { + if (isDefault(method) || isAbstract(method)) { + IMethodBinding previouslyFound= findSubSignatureMethod(method, allMethods); + if (previouslyFound == null) { + IMethodBinding subSigMethod= findSubSignatureMethod(method, allInterfaceMethods); + IMethodBinding superSigMethod= findSuperSignatureMethod(method, allInterfaceMethods); + + if (superSigMethod != null && method.overrides(superSigMethod)) { + allInterfaceMethods.remove(subSigMethod); + allInterfaceMethods.add(method); + } else { + if (subSigMethod != null && superSigMethod != null) { + if (!subSigMethod.getReturnType().getErasure().isSubTypeCompatible(method.getReturnType().getErasure())) { + // keep the most specific one + allInterfaceMethods.remove(subSigMethod); + allInterfaceMethods.add(method); + } + } else if (superSigMethod != null) { + allInterfaceMethods.remove(superSigMethod); + allInterfaceMethods.add(method); + } else if (subSigMethod == null) { + allInterfaceMethods.add(method); + } + } } } } - superClass= superClass.getSuperclass(); } - for (IMethodBinding curr : allMethods) { - int modifiers= curr.getModifiers(); - if ((Modifier.isAbstract(modifiers) || curr.getDeclaringClass().isInterface()) && (implementAbstractsOfInput || typeBinding != curr.getDeclaringClass())) { - // implement all abstract methods - toImplement.add(curr); + allMethods.addAll(allInterfaceMethods); + + return allMethods; + } + + private static IMethodBinding findSubSignatureMethod(IMethodBinding method, Collection methods) { + for (IMethodBinding candidate : methods) { + if (candidate.getName().equals(method.getName()) && candidate.isSubsignature(method)) { + return candidate; } } + return null; + } - HashSet visited= new HashSet<>(); - ITypeBinding curr= typeBinding; - while (curr != null) { - for (ITypeBinding superInterface : curr.getInterfaces()) { - findUnimplementedInterfaceMethods(superInterface, visited, allMethods, typeBinding.getPackage(), toImplement); + private static IMethodBinding findSuperSignatureMethod(IMethodBinding method, Collection methods) { + for (IMethodBinding candidate : methods) { + if (candidate.getName().equals(method.getName()) && method.isSubsignature(candidate)) { + return candidate; } - curr= curr.getSuperclass(); } + return null; + } + + private static boolean isStatic(IMethodBinding method) { + return Modifier.isStatic(method.getModifiers()); + } + + private static boolean isPrivate(IMethodBinding method) { + return Modifier.isPrivate(method.getModifiers()); + } + + private static boolean isAbstract(IMethodBinding method) { + return Modifier.isAbstract(method.getModifiers()); + } + + private static boolean isDefault(IMethodBinding method) { + return Modifier.isDefault(method.getModifiers()); + } - return toImplement.toArray(new IMethodBinding[toImplement.size()]); + private static boolean isConcrete(IMethodBinding method) { + return !isAbstract(method) && !isDefault(method); + } + + + public static Predicate ignoreAbstractsOfInput(final ITypeBinding type) { + return m->isAbstract(m) && type == m.getDeclaringClass(); + } + + public static Predicate IMPLEMENT_RECORD_SYNTHETICS= (IMethodBinding m) -> m.isSyntheticRecordMethod(); + + public static IMethodBinding[] getUnimplementedMethods(ITypeBinding typeBinding, Predicate ignoreTheseMethods) { + List abstractMethods= new ArrayList<>(); + for (IMethodBinding method : getMethodsIn(typeBinding, ignoreTheseMethods)) { + if (isAbstract(method)) { + abstractMethods.add(method); + } + } + return abstractMethods.toArray(new IMethodBinding[abstractMethods.size()]); } public static IMethodBinding[] getVisibleConstructors(ITypeBinding binding, boolean accountExisting, boolean proposeDefault) { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTFlattener.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTFlattener.java index 65a5af75..d0dbdead 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTFlattener.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTFlattener.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -356,6 +356,14 @@ public boolean visit(BreakStatement node) { return false; } + @Override + public boolean visit(CaseDefaultExpression node) { + if (ASTHelper.isPatternSupported(node.getAST())) { + this.fBuffer.append("default");//$NON-NLS-1$ + } + return false; + } + /* * @see ASTVisitor#visit(CastExpression) */ @@ -727,6 +735,16 @@ public boolean visit(ForStatement node) { return false; } + @Override + public boolean visit(GuardedPattern node) { + if (ASTHelper.isPatternSupported(node.getAST())) { + node.getPattern().accept(this); + this.fBuffer.append(" when ");//$NON-NLS-1$ + node.getExpression().accept(this); + } + return false; + } + /* * @see ASTVisitor#visit(IfStatement) */ @@ -846,6 +864,17 @@ public boolean visit(Javadoc node) { return false; } + @Override + public boolean visit(JavaDocRegion node) { + return false; + } + + @Override + public boolean visit(JavaDocTextElement node) { + this.fBuffer.append(node.getText()); + return false; + } + /* * @see ASTVisitor#visit(LabeledStatement) */ @@ -1179,6 +1208,14 @@ public boolean visit(NullLiteral node) { return false; } + @Override + public boolean visit(NullPattern node) { + if (ASTHelper.isPatternSupported(node.getAST())) { + this.fBuffer.append("null");//$NON-NLS-1$ + } + return false; + } + /* * @see ASTVisitor#visit(NumberLiteral) */ @@ -1284,6 +1321,17 @@ public boolean visit(ProvidesDirective node) { return false; } + @Override + public boolean visit(ModuleQualifiedName node) { + node.getModuleQualifier().accept(this); + this.fBuffer.append("/");//$NON-NLS-1$ + ASTNode cNode = node.getName(); + if (cNode != null) { + cNode.accept(this); + } + return false; + } + /* * @see ASTVisitor#visit(QualifiedName) */ @@ -1363,6 +1411,52 @@ public boolean visit(RecordDeclaration node) { return false; } + @Override + public boolean visit(RecordPattern node) { + if (ASTHelper.isRecordPatternSupported(node.getAST())) { + + if (node.getPatternType() != null) { + node.getPatternType().accept(this); + } + boolean addBraces = node.patterns().size() >= 1; + if (addBraces) { + this.fBuffer.append("(");//$NON-NLS-1$ + } + int size = 1; + for (Pattern pattern : node.patterns()) { + visitPattern(pattern); + if (addBraces && size < node.patterns().size()) { + this.fBuffer.append(", ");//$NON-NLS-1$ + } + size++; + } + if (addBraces) { + this.fBuffer.append(")");//$NON-NLS-1$ + } + if (node.getPatternName() != null) { + this.fBuffer.append(" ");//$NON-NLS-1$ + node.getPatternName().accept(this); + } + } + return false; + } + + private boolean visitPattern(Pattern node) { + if (!ASTHelper.isPatternSupported(node.getAST())) { + return false; + } + if (node instanceof RecordPattern) { + return visit((RecordPattern) node); + } + if (node instanceof GuardedPattern) { + return visit((GuardedPattern) node); + } + if (node instanceof TypePattern) { + return visit((TypePattern) node); + } + return false; + } + @Override public boolean visit(RequiresDirective node) { this.fBuffer.append("requires");//$NON-NLS-1$ @@ -1467,15 +1561,6 @@ public boolean visit(StringLiteral node) { return false; } - /* - * @see ASTVisitor#visit(StringLiteral) - */ - @Override - public boolean visit(TextBlock node) { - this.fBuffer.append(node.getEscapedValue()); - return false; - } - /* * @see ASTVisitor#visit(SuperConstructorInvocation) */ @@ -1578,7 +1663,7 @@ public boolean visit(SuperMethodReference node) { @Override public boolean visit(SwitchCase node) { if (ASTHelper.isSwitchCaseExpressionsSupportedInAST(node.getAST())) { - if (node.isDefault()) { + if (node.isDefault() && !isCaseDefaultExpression(node)) { this.fBuffer.append("default");//$NON-NLS-1$ this.fBuffer.append(node.isSwitchLabeledRule() ? " ->" : ":");//$NON-NLS-1$ //$NON-NLS-2$ } else { @@ -1591,7 +1676,7 @@ public boolean visit(SwitchCase node) { } } } else { - if (node.isDefault()) { + if (node.isDefault() && !isCaseDefaultExpression(node)) { this.fBuffer.append("default :\n");//$NON-NLS-1$ } else { this.fBuffer.append("case ");//$NON-NLS-1$ @@ -1602,6 +1687,13 @@ public boolean visit(SwitchCase node) { return false; } + private boolean isCaseDefaultExpression(SwitchCase node) { + if (node.expressions() != null && node.expressions().size() == 1 && node.expressions().get(0) instanceof CaseDefaultExpression) { + return true; + } + return false; + } + @Override public boolean visit(YieldStatement node) { if (ASTHelper.isYieldNodeSupportedInAST(node.getAST()) && node.isImplicit() && node.getExpression() == null) { @@ -1698,12 +1790,38 @@ public boolean visit(TagElement node) { e.accept(this); previousRequiresWhiteSpace= !currentIncludesWhiteSpace && !(e instanceof TagElement); } + if (ASTHelper.isJavaDocCodeSnippetSupported(node.getAST())) { + for (Iterator it = node.tagProperties().iterator(); it.hasNext(); ) { + TagProperty tagProperty = it.next(); + tagProperty.accept(this); + } + + } if (node.isNested()) { this.fBuffer.append("}");//$NON-NLS-1$ } return false; } + @Override + public boolean visit(TagProperty node) { + this.fBuffer.append("\n{"); //$NON-NLS-1$ + this.fBuffer.append(node.getName()); + this.fBuffer.append(" = "); //$NON-NLS-1$ + this.fBuffer.append(node.getStringValue()); + node.getNodeValue().accept(this); + this.fBuffer.append("}"); //$NON-NLS-1$ + return false; + } + + + + @Override + public boolean visit(TextBlock node) { + this.fBuffer.append(node.getEscapedValue()); + return false; + } + /* * @see ASTVisitor#visit(TextElement) * @since 3.0 @@ -1901,6 +2019,14 @@ public boolean visit(TypeParameter node) { return false; } + @Override + public boolean visit(TypePattern node) { + if (ASTHelper.isPatternSupported(node.getAST())) { + node.getPatternVariable().accept(this); + } + return false; + } + /* * @see ASTVisitor#visit(UnionType) */ diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodeFactory.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodeFactory.java index fada460a..ab8d279e 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodeFactory.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodeFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -36,6 +36,7 @@ import org.eclipse.jdt.core.dom.InfixExpression.Operator; import org.eclipse.jdt.core.dom.LambdaExpression; import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.NodeFinder; @@ -43,6 +44,7 @@ import org.eclipse.jdt.core.dom.ParenthesizedExpression; import org.eclipse.jdt.core.dom.PrefixExpression; import org.eclipse.jdt.core.dom.PrimitiveType; +import org.eclipse.jdt.core.dom.SimpleType; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; @@ -187,6 +189,31 @@ public static Expression not(final AST ast, final Expression expression) { * @return the negated expression, as move or copy */ public static Expression negate(final AST ast, final ASTRewrite rewrite, final Expression booleanExpression, final boolean isMove) { + return negateAndUnwrap(ast, rewrite, booleanExpression, isMove, false); + } + + /** + * Negates the provided expression and applies the provided copy operation on + * the returned expression and unwraps parentheses of result (e.g. !(x > 2) => x > 2: + * + * isValid => !isValid + * !isValid => isValid + * true => false + * false => true + * i > 0 => i <= 0 + * isValid || isEnabled => !isValid && !isEnabled + * !isValid || !isEnabled => isValid && isEnabled + * isValid ? (i > 0) : !isEnabled => isValid ? (i <= 0) : isEnabled + * + * @param ast The AST to create the resulting node with. + * @param rewrite the rewrite + * @param booleanExpression the expression to negate + * @param isMove False if the returned nodes need to be new nodes + * @param unWrap True if the expression being negated should remove parentheses of result + * @return the negated expression, as move or copy + */ + public static Expression negateAndUnwrap(final AST ast, final ASTRewrite rewrite, final Expression booleanExpression, + final boolean isMove, final boolean unWrap) { Expression unparenthesedExpression= ASTNodes.getUnparenthesedExpression(booleanExpression); if (unparenthesedExpression instanceof PrefixExpression) { @@ -200,6 +227,10 @@ public static Expression negate(final AST ast, final ASTRewrite rewrite, final E return negate(ast, rewrite, otherPrefixExpression.getOperand(), isMove); } + if (unWrap) { + otherExpression= ASTNodes.getUnparenthesedExpression(otherExpression); + } + return isMove ? ASTNodes.createMoveTarget(rewrite, otherExpression) : ((Expression) rewrite.createCopyTarget(otherExpression)); } } else if (unparenthesedExpression instanceof InfixExpression) { @@ -207,7 +238,7 @@ public static Expression negate(final AST ast, final ASTRewrite rewrite, final E InfixExpression.Operator negatedOperator= ASTNodes.negatedInfixOperator(booleanOperation.getOperator()); if (negatedOperator != null) { - return getNegatedOperation(ast, rewrite, booleanOperation, negatedOperator, isMove); + return getNegatedOperation(ast, rewrite, booleanOperation, negatedOperator, isMove, unWrap); } } else if (unparenthesedExpression instanceof ConditionalExpression) { ConditionalExpression aConditionalExpression= (ConditionalExpression) unparenthesedExpression; @@ -232,7 +263,8 @@ public static Expression negate(final AST ast, final ASTRewrite rewrite, final E return not(ast, (Expression) rewrite.createCopyTarget(unparenthesedExpression)); } - private static Expression getNegatedOperation(final AST ast, final ASTRewrite rewrite, final InfixExpression booleanOperation, final InfixExpression.Operator negatedOperator, final boolean isMove) { + private static Expression getNegatedOperation(final AST ast, final ASTRewrite rewrite, final InfixExpression booleanOperation, final InfixExpression.Operator negatedOperator, + final boolean isMove, final boolean unWrap) { List allOperands= ASTNodes.allOperands(booleanOperation); List allTargetOperands; @@ -270,6 +302,10 @@ private static Expression getNegatedOperation(final AST ast, final ASTRewrite re newInfixExpression.setRightOperand(allTargetOperands.remove(0)); newInfixExpression.extendedOperands().addAll(allTargetOperands); + if (unWrap) { + return newInfixExpression; + } + // otherwise, put parentheses around expression ParenthesizedExpression parenthesizedExpression= ast.newParenthesizedExpression(); parenthesizedExpression.setExpression(newInfixExpression); return parenthesizedExpression; @@ -504,7 +540,8 @@ public static Type newReturnType(LambdaExpression lambdaExpression, AST ast, Imp * @param ast The AST to create the expression for * @param type The type of the returned expression * @param extraDimensions Extra dimensions to the type - * @return the Null-literal for reference types, a boolean-literal for a boolean type, a number + * @return {@code Optional.empty()} if the type is {@code java.util.Optional}, + * the Null-literal for reference types, a boolean-literal for a boolean type, a number * literal for primitive types or null if the type is void. */ public static Expression newDefaultExpression(AST ast, Type type, int extraDimensions) { @@ -518,6 +555,61 @@ public static Expression newDefaultExpression(AST ast, Type type, int extraDimen return ast.newNumberLiteral("0"); //$NON-NLS-1$ } } + if (extraDimensions == 0 && type.isParameterizedType()) { + // if the requested type is of type "java.util.Optional" don't return "null" + ParameterizedType parameterizedType= (ParameterizedType) type; + Type outerType= parameterizedType.getType(); + + if (outerType instanceof SimpleType) { + SimpleType simpleType= (SimpleType) outerType; + Name name= simpleType.getName(); + String fqn= name.getFullyQualifiedName(); + if ("java.util.Optional".equals(fqn)) { //$NON-NLS-1$ + MethodInvocation emptyCall= ast.newMethodInvocation(); + emptyCall.setExpression(ASTNodeFactory.newName(ast, name.getFullyQualifiedName())); + emptyCall.setName(ast.newSimpleName("empty")); //$NON-NLS-1$ + return emptyCall; + } + } + } + return ast.newNullLiteral(); + } + + /** + * Returns an expression that is assignable to the given type. null is + * returned if the type is the 'void' type. + * + * @param ast The AST to create the expression for + * @param type The type of the returned expression + * @param importedTypeBinding The binding of the return type that has been added to imports + * @param extraDimensions Extra dimensions to the type + * @return {@code Optional.empty()} if the type is {@code java.util.Optional}, + * the Null-literal for reference types, a boolean-literal for a boolean type, a number + * literal for primitive types or null if the type is void. + */ + public static Expression newDefaultExpression(AST ast, Type type, ITypeBinding importedTypeBinding, int extraDimensions) { + if (extraDimensions == 0 && type.isPrimitiveType()) { + PrimitiveType primitiveType= (PrimitiveType) type; + if (primitiveType.getPrimitiveTypeCode() == PrimitiveType.BOOLEAN) { + return ast.newBooleanLiteral(false); + } else if (primitiveType.getPrimitiveTypeCode() == PrimitiveType.VOID) { + return null; + } else { + return ast.newNumberLiteral("0"); //$NON-NLS-1$ + } + } + if (extraDimensions == 0 && type.isParameterizedType()) { + // if the requested type is of type "java.util.Optional" don't return "null" + if (importedTypeBinding != null) { + String name= importedTypeBinding.getErasure().getQualifiedName(); + if ("java.util.Optional".equals(name)) { //$NON-NLS-1$ + MethodInvocation emptyCall= ast.newMethodInvocation(); + emptyCall.setExpression(ASTNodeFactory.newName(ast, "Optional")); //$NON-NLS-1$ + emptyCall.setName(ast.newSimpleName("empty")); //$NON-NLS-1$ + return emptyCall; + } + } + } return ast.newNullLiteral(); } @@ -527,7 +619,8 @@ public static Expression newDefaultExpression(AST ast, Type type, int extraDimen * * @param ast The AST to create the expression for * @param type The type binding to which the returned expression is compatible to - * @return the Null-literal for reference types, a boolean-literal for a boolean type, a number + * @return {@code Optional.empty()} if the type is {@code java.util.Optional}, + * the Null-literal for reference types, a boolean-literal for a boolean type, a number * literal for primitive types or null if the type is void. */ public static Expression newDefaultExpression(AST ast, ITypeBinding type) { @@ -546,6 +639,14 @@ public static Expression newDefaultExpression(AST ast, ITypeBinding type) { if (nomatch) { return ast.newNumberLiteral("0");//$NON-NLS-1$ } + } else { + String name= type.getErasure().getQualifiedName(); + if ("java.util.Optional".equals(name)) { //$NON-NLS-1$ + MethodInvocation emptyCall= ast.newMethodInvocation(); + emptyCall.setExpression(ASTNodeFactory.newName(ast, name)); + emptyCall.setName(ast.newSimpleName("empty")); //$NON-NLS-1$ + return emptyCall; + } } return ast.newNullLiteral(); } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java index f709e8fc..365fbaf2 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -33,6 +33,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; @@ -94,10 +95,13 @@ import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IExtendedModifier; import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.IPackageBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.dom.IfStatement; +import org.eclipse.jdt.core.dom.ImportDeclaration; import org.eclipse.jdt.core.dom.InfixExpression; +import org.eclipse.jdt.core.dom.InstanceofExpression; import org.eclipse.jdt.core.dom.LabeledStatement; import org.eclipse.jdt.core.dom.LambdaExpression; import org.eclipse.jdt.core.dom.MemberValuePair; @@ -117,6 +121,7 @@ import org.eclipse.jdt.core.dom.PrimitiveType; import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.QualifiedType; +import org.eclipse.jdt.core.dom.RecordDeclaration; import org.eclipse.jdt.core.dom.ReturnStatement; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SimpleType; @@ -2472,6 +2477,30 @@ public static ASTNode getFirstAncestorOrNull(final ASTNode node, final Class T getFirstAncestorOrNull(final ASTNode node, final Class ancestorClass) { + if (node == null || node.getParent() == null) { + return null; + } + + ASTNode parent= node.getParent(); + + if (ancestorClass.isAssignableFrom(parent.getClass()) + ) { + return (T) parent; + } + + return getFirstAncestorOrNull(parent, ancestorClass); + } + /** * Returns the closest ancestor of node that is an instance of parentClass, or null if none. *

    @@ -3277,6 +3306,187 @@ public static boolean isExceptionExpected(final ASTNode node) { return false; } + /** + * Returns if another method or constructor has the given signature. + * It is useful to know if a refactoring of the given method or constructor is possible without conflict. + * The method or constructor in parameter does not need to match this signature (usually not). + * + * @param methodOrConstructor A method, super method, constructor or super constructor + * @param methodOrConstructorBinding The associated binding + * @param expectedArgumentTypes The argument types that should match + * @return True if another method or constructor has the given signature + */ + public static boolean hasConflictingMethodOrConstructor( + final ASTNode methodOrConstructor, + final IMethodBinding methodOrConstructorBinding, + final ITypeBinding[] expectedArgumentTypes) { + TypeDeclaration typeDeclaration= getTypedAncestor(methodOrConstructor, TypeDeclaration.class); + + if (typeDeclaration == null) { + return true; + } + + ITypeBinding type= typeDeclaration.resolveBinding(); + + if (type == null) { + return true; + } + + boolean inSameClass= true; + // Figure out the type where we need to start looking at methods in the hierarchy. + // If we have a new class instance or super method call or this expression or + // we have a static call that is qualified, we use the referenced class as the starting point. + // If we have a non-qualified method call, we use the class containing the call. + // Otherwise, we bail on the clean-up. + if (methodOrConstructor instanceof ClassInstanceCreation) { + type= ((ClassInstanceCreation) methodOrConstructor).resolveTypeBinding(); + inSameClass= type.isNested(); + } else if (methodOrConstructor instanceof MethodInvocation) { + MethodInvocation methodInvocation= (MethodInvocation) methodOrConstructor; + Expression expression= methodInvocation.getExpression(); + + if (expression == null) { + ASTNode root= methodOrConstructor.getRoot(); + + if (root instanceof CompilationUnit) { + CompilationUnit compilationUnit= (CompilationUnit) root; + List imports= compilationUnit.imports(); + String localPackage= null; + + if (compilationUnit.getPackage() != null && compilationUnit.getPackage().getName() != null) { + localPackage= compilationUnit.getPackage().getName().getFullyQualifiedName(); + } + + for (ImportDeclaration oneImport : imports) { + if (oneImport.isStatic() + && !oneImport.isOnDemand() + && oneImport.getName() instanceof QualifiedName) { + QualifiedName methodName= (QualifiedName) oneImport.getName(); + String methodIdentifier= methodName.getName().getIdentifier(); + ITypeBinding conflictingType= methodName.getQualifier().resolveTypeBinding(); + + if (conflictingType == null) { + return true; // Error on side of caution + } + + String importPackage= null; + + if (conflictingType.getPackage() != null) { + importPackage= conflictingType.getPackage().getName(); + } + + boolean inSamePackage= Objects.equals(localPackage, importPackage); + + for (IMethodBinding declaredMethod : conflictingType.getDeclaredMethods()) { + if (methodIdentifier.equals(declaredMethod.getName()) + && isMethodMatching(expectedArgumentTypes, methodOrConstructorBinding, false, inSamePackage, declaredMethod)) { + return true; + } + } + } + } + } + + if (Modifier.isStatic(methodOrConstructorBinding.getModifiers())) { + inSameClass= methodOrConstructorBinding.getDeclaringClass().isEqualTo(type); + type= methodOrConstructorBinding.getDeclaringClass(); + } + } else if (!(expression instanceof ThisExpression)) { + inSameClass= methodOrConstructorBinding.getDeclaringClass().isEqualTo(type); + type= expression.resolveTypeBinding(); + } + } else if (methodOrConstructor instanceof SuperMethodInvocation) { + inSameClass= type.isNested(); + type= type.getSuperclass(); + } else { + return true; // Error on side of caution + } + + if (type == null) { + return true; + } + + return hasEquivalentMethodForInheritedTypes(expectedArgumentTypes, methodOrConstructorBinding, type, type, inSameClass); + } + + private static boolean hasEquivalentMethodForInheritedTypes( + final ITypeBinding[] parameterTypesForConflictingMethod, + final IMethodBinding binding, + final ITypeBinding type, + final ITypeBinding origType, + final boolean wasInSameClass) { + ITypeBinding superType= type; + boolean inSameClass= wasInSameClass; + + while (superType != null) { + IPackageBinding packageBinding= superType.getPackage(); + boolean inSamePackage= packageBinding.isEqualTo(origType.getPackage()); + + if (hasEquivalentMethodForOneType(parameterTypesForConflictingMethod, binding, superType, inSameClass, inSamePackage)) { + return true; + } + + if (superType.isNested()) { + if (hasEquivalentMethodForInheritedTypes(parameterTypesForConflictingMethod, binding, superType.getDeclaringClass(), origType, inSameClass)) { + return true; + } + + superType= superType.getSuperclass(); + inSameClass&= superType.isNested(); + } else { + superType= superType.getSuperclass(); + inSameClass= false; + } + } + + return false; + } + + private static boolean hasEquivalentMethodForOneType( + final ITypeBinding[] parameterTypesForConflictingMethod, + final IMethodBinding binding, + final ITypeBinding type, + final boolean inSameClass, + final boolean inSamePackage) { + for (IMethodBinding method : type.getDeclaredMethods()) { + if (isMethodMatching(parameterTypesForConflictingMethod, binding, inSameClass, inSamePackage, method)) { + return true; + } + } + + return false; + } + + private static boolean isMethodMatching( + final ITypeBinding[] parameterTypesForConflictingMethod, + final IMethodBinding binding, + final boolean inSameClass, + final boolean inSamePackage, + final IMethodBinding testedMethod) { + int methodModifiers= testedMethod.getModifiers(); + ITypeBinding[] parameterTypes= testedMethod.getParameterTypes(); + + if (!binding.isEqualTo(testedMethod) + && parameterTypesForConflictingMethod.length == parameterTypes.length + && binding.getName().equals(testedMethod.getName()) + && (inSameClass || Modifier.isPublic(methodModifiers) || Modifier.isProtected(methodModifiers) + || (inSamePackage && !Modifier.isPrivate(methodModifiers)))) { + for (int i= 0; i < parameterTypesForConflictingMethod.length; i++) { + if (parameterTypesForConflictingMethod[i] == null || parameterTypes[i] == null) { + return true; + } + + if (!parameterTypesForConflictingMethod[i].isAssignmentCompatible(parameterTypes[i])) { + return false; + } + } + + return true; + } + + return false; + } + /** * Returns whether the provided method invocation invokes a method with the * provided method signature. The method signature is compared against the @@ -3845,7 +4055,11 @@ public static void replaceAndRemoveNLS(final ASTRewrite rewrite, final ASTNode v original= comment.matcher(original).replaceFirst(""); //$NON-NLS-1$ original= leadingspaces_start.matcher(original).replaceAll(""); //$NON-NLS-1$ original= leadingspaces.matcher(original).replaceAll("\n"); //$NON-NLS-1$ - String originalmodified=original.replace(visited.toString(), replace_with_Call.toString()); + String visitedString= buffer.substring(visited.getStartPosition(), visited.getStartPosition() + visited.getLength()); + // we are using the toString() method to get string representation of replace_with_Call so tweak string to + // add spaces between parameters + String replacementCallString= replace_with_Call.toString().replaceAll(",", ", "); //$NON-NLS-1$ //$NON-NLS-2$ + String originalmodified= original.replace(visitedString, replacementCallString); replacement= rewrite.createStringPlaceholder(originalmodified, st.getNodeType()); rewrite.replace(st, replacement, editGroup); } catch (JavaModelException e) { @@ -3968,10 +4182,10 @@ public static List getLeadingComments(ASTNode node) { List comments= new ArrayList<>(); CompilationUnit cu= (CompilationUnit)node.getRoot(); List commentList= cu.getCommentList(); - for (Comment comment : commentList) { - if (comment.getStartPosition() >= cu.getExtendedStartPosition(node) - && comment.getStartPosition() + comment.getLength() < node.getStartPosition()) { - comments.add(comment); + for (Comment commentFromList : commentList) { + if (commentFromList.getStartPosition() >= cu.getExtendedStartPosition(node) + && commentFromList.getStartPosition() + commentFromList.getLength() < node.getStartPosition()) { + comments.add(commentFromList); } } return comments; @@ -3989,13 +4203,123 @@ public static List getTrailingComments(ASTNode node) { List commentList= cu.getCommentList(); int extendedStart= cu.getExtendedStartPosition(node); int extendedLength= cu.getExtendedLength(node); - for (Comment comment : commentList) { - if (comment.getStartPosition() > node.getStartPosition() - && comment.getStartPosition() < extendedStart + extendedLength) { - comments.add(comment); + for (Comment commentFromList : commentList) { + if (commentFromList.getStartPosition() > node.getStartPosition() + && commentFromList.getStartPosition() < extendedStart + extendedLength) { + comments.add(commentFromList); } } return comments; } + /** + * Get the number of Type references in a Compilation Unit - used for determining + * if an import can be removed. + * + * @param typeBinding - binding of the type in question + * @param cu - compilation unit + * @return integer count of times type is referenced (may be 0 if bindings cannot be resolved) + */ + public static int getNumberOfTypeReferences(ITypeBinding typeBinding, CompilationUnit cu) { + class CounterVisitor extends ASTVisitor { + private int counter= 0; + private void checkType(Type type) { + if (type != null && !type.isParameterizedType()) { + ITypeBinding binding= type.resolveBinding(); + if (binding != null) { + if (binding.isArray()) { + binding= binding.getElementType(); + } + if (binding.isEqualTo(typeBinding)) { + ++counter; + } + } + } + } + public int getCounter() { + return counter; + } + @Override + public boolean visit(ArrayCreation node) { + Type type= node.getType(); + checkType(type); + return true; + } + @Override + public boolean visit(MethodDeclaration node) { + Type type= node.getReturnType2(); + checkType(type); + List exceptions= node.thrownExceptionTypes(); + for (Type t : exceptions) { + checkType(t); + } + return true; + } + @Override + public boolean visit(ClassInstanceCreation node) { + Type type= node.getType(); + checkType(type); + return true; + } + @Override + public boolean visit(SingleVariableDeclaration node) { + Type type= node.getType(); + checkType(type); + return true; + } + @Override + public boolean visit(CastExpression node) { + Type type= node.getType(); + checkType(type); + return true; + } + @Override + public boolean visit(VariableDeclarationExpression node) { + Type type= node.getType(); + checkType(type); + return true; + } + @Override + public boolean visit(InstanceofExpression node) { + Type type= node.getRightOperand(); + checkType(type); + return true; + } + @Override + public boolean visit(FieldDeclaration node) { + Type type= node.getType(); + checkType(type); + return true; + } + @Override + public boolean visit(ParameterizedType node) { + Type type= node.getType(); + checkType(type); + List types= node.typeArguments(); + for (Type t : types) { + checkType(t); + } + return true; + } + @Override + public boolean visit(TypeDeclaration node) { + List types= node.typeParameters(); + for (Type t : types) { + checkType(t); + } + return true; + } + @Override + public boolean visit(RecordDeclaration node) { + List types= node.typeParameters(); + for (Type t : types) { + checkType(t); + } + return true; + } + } + CounterVisitor visitor= new CounterVisitor(); + cu.accept(visitor); + return visitor.getCounter(); + } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/Bindings.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/Bindings.java index aa57f7d6..170be524 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/Bindings.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/Bindings.java @@ -603,23 +603,13 @@ public static boolean isVisibleInHierarchy(IMethodBinding member, IPackageBindin */ public static ITypeBinding[] getAllSuperTypes(ITypeBinding type) { Set result= new HashSet<>(); - collectSuperTypes(type, result); - result.remove(type); + visitHierarchy(type, t -> { + result.add(t); + return true; + }); return result.toArray(new ITypeBinding[result.size()]); } - private static void collectSuperTypes(ITypeBinding curr, Set collection) { - if (collection.add(curr)) { - for (ITypeBinding intf : curr.getInterfaces()) { - collectSuperTypes(intf, collection); - } - ITypeBinding superClass= curr.getSuperclass(); - if (superClass != null) { - collectSuperTypes(superClass, collection); - } - } - } - /** * Method to visit a type hierarchy defined by a given type. * The given type itself is not visited. @@ -631,11 +621,33 @@ private static void collectSuperTypes(ITypeBinding curr, Set colle * method returned false for a type */ public static boolean visitHierarchy(ITypeBinding type, TypeBindingVisitor visitor) { - boolean result= visitSuperclasses(type, visitor); - if (result) { - result= visitInterfaces(type, visitor); + return visitSuperTypes(type, new TypeBindingVisitor() { + + @Override + public boolean visit(ITypeBinding t) { + if (t == type) { + return true; + } + return visitor.visit(t); + } + }, new HashSet()); + } + + private static boolean visitSuperTypes(ITypeBinding type, TypeBindingVisitor visitor, HashSet visited) { + if (type != null && visited.add(type)) { + if (!visitor.visit(type)) { + return false; + } + if (!visitSuperTypes(type.getSuperclass(), visitor, visited)) { + return false; + } + for (ITypeBinding itfc : type.getInterfaces()) { + if (!visitSuperTypes(itfc, visitor, visited)) { + return false; + } + } } - return result; + return true; } /** diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/HierarchicalASTVisitor.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/HierarchicalASTVisitor.java index b2bd938c..bba874bc 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/HierarchicalASTVisitor.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/HierarchicalASTVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -379,6 +379,16 @@ public void endVisit(BooleanLiteral node) { endVisit((Expression)node); } + @Override + public boolean visit(CaseDefaultExpression node) { + return visit((Expression)node); + } + + @Override + public void endVisit(CaseDefaultExpression node) { + endVisit((Expression)node); + } + @Override public boolean visit(CastExpression node) { return visit((Expression)node); @@ -601,6 +611,26 @@ public void endVisit(SimpleName node) { //---- End Name Hierarchy ------------------------------------ + @Override + public boolean visit(RecordPattern node) { + return visit((Pattern)node); + } + + @Override + public void endVisit(RecordPattern node) { + endVisit((Pattern)node); + } + + @Override + public boolean visit(GuardedPattern node) { + return visit((Pattern)node); + } + + @Override + public void endVisit(GuardedPattern node) { + endVisit((Pattern)node); + } + @Override public boolean visit(NullLiteral node) { return visit((Expression)node); @@ -611,6 +641,16 @@ public void endVisit(NullLiteral node) { endVisit((Expression)node); } + @Override + public boolean visit(NullPattern node) { + return visit((Pattern)node); + } + + @Override + public void endVisit(NullPattern node) { + endVisit((Pattern)node); + } + @Override public boolean visit(NumberLiteral node) { return visit((Expression)node); @@ -621,6 +661,14 @@ public void endVisit(NumberLiteral node) { endVisit((Expression)node); } + public boolean visit(Pattern node) { + return visit((Expression)node); + } + + public void endVisit(Pattern node) { + endVisit((Expression)node); + } + @Override public boolean visit(ParenthesizedExpression node) { return visit((Expression)node); @@ -711,6 +759,16 @@ public void endVisit(TypeLiteral node) { endVisit((Expression)node); } + @Override + public boolean visit(TypePattern node) { + return visit((Pattern)node); + } + + @Override + public void endVisit(TypePattern node) { + endVisit((Pattern)node); + } + @Override public boolean visit(VariableDeclarationExpression node) { return visit((Expression)node); @@ -1119,26 +1177,71 @@ public void endVisit(WhileStatement node) { //---- End Statement Hierarchy ---------------------------------- + public boolean visit(AbstractTagElement node) { + return visit((ASTNode)node); + } + + public void endVisit(AbstractTagElement node) { + endVisit((ASTNode)node); + } + @Override public boolean visit(TagElement node) { - return visit((ASTNode)node); + return visit((AbstractTagElement)node); } @Override public void endVisit(TagElement node) { + endVisit((AbstractTagElement)node); + } + + public boolean visit(AbstractTextElement node) { + return visit((ASTNode)node); + } + + public void endVisit(AbstractTextElement node) { endVisit((ASTNode)node); } @Override public boolean visit(TextElement node) { - return visit((ASTNode)node); + return visit((AbstractTextElement)node); } @Override public void endVisit(TextElement node) { + endVisit((AbstractTextElement)node); + } + + @Override + public boolean visit(JavaDocTextElement node) { + return visit((AbstractTextElement)node); + } + + @Override + public void endVisit(JavaDocTextElement node) { + endVisit((AbstractTextElement)node); + } + + @Override + public boolean visit(TagProperty node) { + return visit((ASTNode)node); + } + + @Override + public void endVisit(TagProperty node) { endVisit((ASTNode)node); } + @Override + public boolean visit(JavaDocRegion node) { + return visit((AbstractTagElement)node); + } + + @Override + public void endVisit(JavaDocRegion node) { + endVisit((AbstractTagElement)node); + } //---- Begin Type Hierarchy -------------------------------------- public boolean visit(Type node) { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/LinkedNodeFinder.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/LinkedNodeFinder.java index 60739046..73db53b0 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/LinkedNodeFinder.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/LinkedNodeFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -28,6 +28,8 @@ import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.dom.LabeledStatement; +import org.eclipse.jdt.core.dom.ModuleDeclaration; +import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.NodeFinder; import org.eclipse.jdt.core.dom.RecordDeclaration; import org.eclipse.jdt.core.dom.SimpleName; @@ -226,6 +228,21 @@ public static SimpleName[] findByNode(ASTNode root, SimpleName name) { return new SimpleName[] { name }; } + public static Name[] findByNode(ASTNode root, Name name) { + Name[] names= findByProblems(root, name); + if (names != null) { + return names; + } + int parentKind= name.getParent().getNodeType(); + if (parentKind == ASTNode.LABELED_STATEMENT || parentKind == ASTNode.BREAK_STATEMENT || parentKind == ASTNode.CONTINUE_STATEMENT) { + ArrayList res= new ArrayList<>(); + QLabelFinder nodeFinder= new QLabelFinder(name, res); + root.accept(nodeFinder); + return res.toArray(new Name[res.size()]); + } + return new Name[] { name }; + } + private static final int FIELD= 1; @@ -266,6 +283,21 @@ private static int getNameNodeProblemKind(IProblem[] problems, SimpleName nameNo return 0; } + private static int getNameNodeProblemKind(IProblem[] problems, Name nameNode) { + int nameOffset= nameNode.getStartPosition(); + int nameInclEnd= nameOffset + nameNode.getLength() - 1; + + for (IProblem curr : problems) { + if (curr.getSourceStart() == nameOffset && curr.getSourceEnd() == nameInclEnd) { + int kind= getProblemKind(curr); + if (kind != 0) { + return kind; + } + } + } + return 0; + } + public static SimpleName[] findByProblems(ASTNode parent, SimpleName nameNode) { if (nameNode.getAST().apiLevel() >= ASTHelper.JLS10 && nameNode.isVar()) { @@ -308,6 +340,42 @@ public static SimpleName[] findByProblems(ASTNode parent, SimpleName nameNode) { return res.toArray(new SimpleName[res.size()]); } + public static Name[] findByProblems(ASTNode parent, Name nameNode) { + ArrayList res= new ArrayList<>(); + + ASTNode astRoot = parent.getRoot(); + if (!(astRoot instanceof CompilationUnit)) { + return null; + } + + IProblem[] problems= ((CompilationUnit) astRoot).getProblems(); + int nameNodeKind= getNameNodeProblemKind(problems, nameNode); + if (nameNodeKind == 0) { // no problem on node + return null; + } + + int bodyStart= parent.getStartPosition(); + int bodyEnd= bodyStart + parent.getLength(); + + String name= nameNode.getFullyQualifiedName(); + + for (IProblem curr : problems) { + int probStart= curr.getSourceStart(); + int probEnd= curr.getSourceEnd() + 1; + + if (probStart > bodyStart && probEnd < bodyEnd) { + int currKind= getProblemKind(curr); + if ((nameNodeKind & currKind) != 0) { + ASTNode node= NodeFinder.perform(parent, probStart, (probEnd - probStart)); + if (node instanceof Name && name.equals(((Name) node).getFullyQualifiedName())) { + res.add((Name) node); + } + } + } + } + return res.toArray(new Name[res.size()]); + } + private static class LabelFinder extends ASTVisitor { private SimpleName fLabel; @@ -357,6 +425,37 @@ public boolean visit(LabeledStatement node) { } } + private static class QLabelFinder extends ASTVisitor { + + private Name fLabel; + private ASTNode fDefiningLabel; + private ArrayList fResult; + + public QLabelFinder(Name label, ArrayList result) { + super(true); + fLabel= label; + fResult= result; + fDefiningLabel= null; + } + + private boolean isSameLabel(Name label) { + return label != null && fLabel.getFullyQualifiedName().equals(label.getFullyQualifiedName()); + } + + @Override + public boolean visit(ModuleDeclaration node) { + if (fDefiningLabel == null) { + Name label= node.getName(); + if (fLabel == label || isSameLabel(label) && ASTNodes.isParent(fLabel, node)) { + fDefiningLabel= node; + fResult.add(label); + } + } + node.getName().accept(this); + return false; + } + } + private static class BindingFinder extends ASTVisitor { private IBinding fBinding; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/TokenScanner.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/TokenScanner.java index 9bbfd1eb..b51d36f0 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/TokenScanner.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/TokenScanner.java @@ -31,8 +31,6 @@ import org.eclipse.jdt.core.compiler.InvalidInputException; import org.eclipse.jdt.core.manipulation.JavaManipulation; -import org.eclipse.jdt.internal.corext.dom.TokenScanner; - /** * Wraps a scanner and offers convenient methods for finding tokens */ diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/TypeAnnotationRewrite.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/TypeAnnotationRewrite.java similarity index 97% rename from org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/TypeAnnotationRewrite.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/TypeAnnotationRewrite.java index 6e82d67b..b8bb75f2 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/TypeAnnotationRewrite.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/TypeAnnotationRewrite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Till Brychcy and others. + * Copyright (c) 2017, 2021 Till Brychcy and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * Till Brychcy - initial API and implementation + * Red Hat Inc. - refactored to jdt.core.manipulation *******************************************************************************/ package org.eclipse.jdt.internal.corext.dom; @@ -30,15 +31,14 @@ import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ListRewrite; -import org.eclipse.jdt.internal.corext.util.JDTUIHelperClasses; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; /** * Rewrite helper for type annotations. * - * @see JDTUIHelperClasses * @since 3.13 */ +// @see JDTUIHelperClasses public class TypeAnnotationRewrite { /** diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractFix.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractFixCore.java similarity index 89% rename from org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractFix.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractFixCore.java index 5e330f63..81315acf 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractFix.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractFixCore.java @@ -17,11 +17,11 @@ import org.eclipse.core.runtime.IStatus; -public abstract class AbstractFix implements IProposableFix, ILinkedFixCore { +public abstract class AbstractFixCore implements IProposableFix, ILinkedFixCore { private final String fDisplayString; - protected AbstractFix(String displayString) { + protected AbstractFixCore(String displayString) { fDisplayString= displayString; } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractPrimitiveRatherThanWrapperFinder.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractPrimitiveRatherThanWrapperFinder.java index f4df3f29..b58d8cf7 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractPrimitiveRatherThanWrapperFinder.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractPrimitiveRatherThanWrapperFinder.java @@ -29,6 +29,7 @@ import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.InfixExpression; +import org.eclipse.jdt.core.dom.InfixExpression.Operator; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Name; @@ -429,6 +430,13 @@ private boolean isPrimitiveAllowed(final ASTNode node) { return getPrefixOutSafeOperators().contains(((PrefixExpression) parentNode).getOperator()); case ASTNode.INFIX_EXPRESSION: + InfixExpression infixExpression= (InfixExpression) parentNode; + Operator operator= infixExpression.getOperator(); + if (InfixExpression.Operator.EQUALS.equals(operator) || InfixExpression.Operator.NOT_EQUALS.equals(operator)) { + Expression leftOperand= infixExpression.getLeftOperand(); + Expression rightOperand= infixExpression.getRightOperand(); + return isNotNull(node.equals(leftOperand) ? rightOperand : leftOperand); + } return getInfixOutSafeOperators().contains(((InfixExpression) parentNode).getOperator()); case ASTNode.POSTFIX_EXPRESSION: diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractSerialVersionOperationCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractSerialVersionOperationCore.java index 13792b45..20a7ac5d 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractSerialVersionOperationCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AbstractSerialVersionOperationCore.java @@ -125,7 +125,7 @@ else if (node instanceof ParameterizedType) { } final String comment= CodeGeneration.getFieldComment(fUnit, declaration.getType().toString(), NAME_FIELD, StubUtility.getLineDelimiterUsed(fUnit)); - if (comment != null && comment.length() > 0 && !"/**\n *\n */\n".equals(comment)) { //$NON-NLS-1$ + if (comment != null && comment.length() > 0 && !comment.matches("[/\\* \t\n]*")) { //$NON-NLS-1$ final Javadoc doc= (Javadoc) rewrite.createStringPlaceholder(comment, ASTNode.JAVADOC); declaration.setJavadoc(doc); } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AddUnimplementedMethodsOperation.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AddUnimplementedMethodsOperation.java index 54ffc1a6..fbe22962 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AddUnimplementedMethodsOperation.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/AddUnimplementedMethodsOperation.java @@ -19,6 +19,7 @@ package org.eclipse.jdt.internal.corext.fix; import java.util.Arrays; +import java.util.function.Predicate; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; @@ -54,6 +55,7 @@ public class AddUnimplementedMethodsOperation extends CompilationUnitRewriteOperation { private ASTNode fTypeNode; + private Predicate fMethodFilter; /** * Create a {@link AddUnimplementedMethodsOperation} @@ -61,9 +63,11 @@ public class AddUnimplementedMethodsOperation extends CompilationUnitRewriteOper *

    • AnonymousClassDeclaration
    • *
    • AbstractTypeDeclaration
    • *
    • EnumConstantDeclaration
    + * @param methodFilter a filter for methods to ignore when looking for unimplemented methods */ - public AddUnimplementedMethodsOperation(ASTNode typeNode) { - fTypeNode= typeNode; + public AddUnimplementedMethodsOperation(ASTNode typeNode, Predicate methodFilter) { + this.fTypeNode= typeNode; + this.fMethodFilter= methodFilter; } @Override @@ -138,7 +142,7 @@ public IMethodBinding[] getMethodsToImplement() { private IMethodBinding[] getUnimplementedMethods(ASTNode typeNode) { ITypeBinding binding= null; - boolean implementAbstractsOfInput= false; + Predicate filter= StubUtility2Core.ignoreAbstractsOfInput(binding); if (typeNode instanceof AnonymousClassDeclaration) { AnonymousClassDeclaration decl= (AnonymousClassDeclaration) typeNode; binding= decl.resolveBinding(); @@ -153,14 +157,18 @@ private IMethodBinding[] getUnimplementedMethods(ASTNode typeNode) { IVariableBinding varBinding= enumConstantDeclaration.resolveVariable(); if (varBinding != null) { binding= varBinding.getDeclaringClass(); - implementAbstractsOfInput= true; + filter= m->false; } } } if (binding == null) return new IMethodBinding[0]; - IMethodBinding[] unimplementedMethods= StubUtility2Core.getUnimplementedMethods(binding, implementAbstractsOfInput); + if (fMethodFilter != null) { + filter= filter.or(fMethodFilter); + } + + IMethodBinding[] unimplementedMethods= StubUtility2Core.getUnimplementedMethods(binding, filter); Arrays.sort(unimplementedMethods, new MethodsSourcePositionComparator(binding)); return unimplementedMethods; } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ArrayWithCurlyFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ArrayWithCurlyFixCore.java index d21509cf..6403e6b6 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ArrayWithCurlyFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ArrayWithCurlyFixCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021 Fabrice TIERCELIN and others. + * Copyright (c) 2021, 2022 Fabrice TIERCELIN and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * Fabrice TIERCELIN - initial API and implementation + * Christian Femers - Bug 579471 *******************************************************************************/ package org.eclipse.jdt.internal.corext.fix; @@ -28,6 +29,8 @@ import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.VariableDeclaration; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer; import org.eclipse.jdt.core.manipulation.ICleanUpFixCore; @@ -75,12 +78,21 @@ private boolean isVoid(final ArrayCreation visited) { } private boolean isDestinationAllowed(final ASTNode visited) { - int parentType= visited.getParent().getNodeType(); + ASTNode parent= visited.getParent(); + int parentType= parent.getNodeType(); - return parentType == ASTNode.FIELD_DECLARATION + boolean correctParent= parentType == ASTNode.FIELD_DECLARATION || parentType == ASTNode.VARIABLE_DECLARATION_EXPRESSION || parentType == ASTNode.VARIABLE_DECLARATION_FRAGMENT || parentType == ASTNode.VARIABLE_DECLARATION_STATEMENT; + if (!correctParent) { + return false; + } + if (parent instanceof VariableDeclaration) { + Type type= ASTNodes.getType((VariableDeclaration) parent); + return type == null || !type.isVar(); + } + return true; } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java index e2c86e09..748afc2d 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -1110,7 +1110,8 @@ public class CleanUpConstants { public static final String CONSTANTS_FOR_SYSTEM_PROPERTY_LINE_SEPARATOR= "cleanup.system_property_line_separator"; //$NON-NLS-1$ /** - * Replace Boolean.parseBoolean(System.getProperty("arbitrarykey")) by

    + * Replace Boolean/Long/Integer conversions using System properties to methods designed + * for the purpose. For example, replace:

    Boolean.parseBoolean(System.getProperty("arbitrarykey"))

    by

    * Boolean.getBoolean("arbitrarykey") *

    * Possible values: {TRUE, FALSE} @@ -1120,7 +1121,8 @@ public class CleanUpConstants { * @see CleanUpOptionsCore#FALSE * @since 4.20 */ - public static final String CONSTANTS_FOR_SYSTEM_PROPERTY_BOOLEAN= "cleanup.system_property_boolean"; //$NON-NLS-1$ + public static final String CONSTANTS_FOR_SYSTEM_PROPERTY_BOXED= "cleanup.system_property_boolean"; //$NON-NLS-1$ + /** * Replaces Boolean.TRUE/Boolean.FALSE by true/false when used as primitive. *

    @@ -1214,7 +1216,7 @@ public class CleanUpConstants { * Replaces StringBuffer by StringBuilder. * * For detailed setting use
    - * {@link #STRINGBUILDER_FOR_LOCAL_VARS_ONLY}
    + * {@link #STRINGBUFFER_TO_STRINGBUILDER_FOR_LOCALS}
    *

    * Possible values: {TRUE, FALSE} *

    @@ -1225,6 +1227,16 @@ public class CleanUpConstants { */ public static final String STRINGBUFFER_TO_STRINGBUILDER= "cleanup.stringbuffer_to_stringbuilder"; //$NON-NLS-1$ + /** + * Replaces String concatenation by Text Block for Java 15 and higher. + * + * @see CleanUpOptionsCore#TRUE + * @see CleanUpOptionsCore#FALSE + * @since 4.22 + */ + + public static final String STRINGCONCAT_TO_TEXTBLOCK= "cleanup.stringconcat_to_textblock"; //$NON-NLS-1$ + /** * Only replace local var StringBuffer uses with StringBuilder. * @@ -1345,6 +1357,21 @@ public class CleanUpConstants { */ public static final String REMOVE_UNUSED_CODE_PRIVATE_METHODS= "cleanup.remove_unused_private_methods"; //$NON-NLS-1$ + /** + * Removes unused parameters for private methods.
    + * + *
    + * Possible values: {TRUE, FALSE}
    + * + *
    + * + * @see CleanUpOptionsCore#TRUE + * @see CleanUpOptionsCore#FALSE + * @since 3.3 + */ + public static final String REMOVE_UNUSED_CODE_METHOD_PARAMETERS= "cleanup.remove_unused_method_parameters"; //$NON-NLS-1$ + + /** * Removes unused local variables.
    *
    @@ -1754,6 +1781,19 @@ public class CleanUpConstants { */ public static final String OVERRIDDEN_ASSIGNMENT= "cleanup.overridden_assignment"; //$NON-NLS-1$ + /** + * Move the declaration of the variable to the location of the overriding assignment + * if necessary. + *

    + * Possible values: {TRUE, FALSE} + *

    + * + * @see CleanUpOptionsCore#TRUE + * @see CleanUpOptionsCore#FALSE + * @since 4.18 + */ + public static final String OVERRIDDEN_ASSIGNMENT_MOVE_DECL= "cleanup.overridden_assignment_move_decl"; //$NON-NLS-1$ + /** * Removes redundant semicolons.
    *
    diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CodeStyleFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CodeStyleFixCore.java index de3d50a9..66529a12 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CodeStyleFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CodeStyleFixCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 IBM Corporation and others. + * Copyright (c) 2019, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -44,6 +44,7 @@ import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.Name; +import org.eclipse.jdt.core.dom.PackageDeclaration; import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SimpleType; @@ -711,7 +712,19 @@ public static ToStaticAccessOperation[] createToStaticAccessOperations(Compilati ITypeBinding declaringTypeBinding= getDeclaringTypeBinding(accessBinding); if (declaringTypeBinding != null) { declaringTypeBinding= declaringTypeBinding.getTypeDeclaration(); // use generic to avoid any type arguments - + int modifiers= declaringTypeBinding.getModifiers(); + if (!Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers) && !Modifier.isPrivate(modifiers)) { + PackageDeclaration packageDecl= astRoot.getPackage(); + if (packageDecl == null) { + if (declaringTypeBinding.getPackage() != null) { + return null; + } + } else { + if (!declaringTypeBinding.getPackage().isEqualTo(packageDecl.resolveBinding())) { + return null; + } + } + } declaring= new ToStaticAccessOperation(declaringTypeBinding, qualifier, createdBlocks); } ToStaticAccessOperation instance= null; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CompilationUnitRewriteOperationsFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CompilationUnitRewriteOperationsFixCore.java index a7d3d1a9..b3c42797 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CompilationUnitRewriteOperationsFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CompilationUnitRewriteOperationsFixCore.java @@ -39,7 +39,7 @@ import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; -public class CompilationUnitRewriteOperationsFixCore extends AbstractFix { +public class CompilationUnitRewriteOperationsFixCore extends AbstractFixCore { public abstract static class CompilationUnitRewriteOperation { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ConvertForLoopOperation.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ConvertForLoopOperation.java index 6939e0b9..bf044ce8 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ConvertForLoopOperation.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ConvertForLoopOperation.java @@ -885,7 +885,7 @@ private void replaceAccess(MethodInvocation node) { if (fElementDeclaration != null && node.getLocationInParent() == VariableDeclarationFragment.INITIALIZER_PROPERTY) { VariableDeclarationFragment fragment= (VariableDeclarationFragment)node.getParent(); IBinding targetBinding= fragment.getName().resolveBinding(); - if (targetBinding != null) { + if (targetBinding != null && fragment.getName().getFullyQualifiedName().equals(parameterName)) { VariableDeclarationStatement statement= (VariableDeclarationStatement)fragment.getParent(); if (statement.fragments().size() == 1) { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ConvertIterableLoopOperation.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ConvertIterableLoopOperation.java index 13d92f12..4e47d618 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ConvertIterableLoopOperation.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ConvertIterableLoopOperation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2020 IBM Corporation and others. + * Copyright (c) 2005, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -262,7 +262,8 @@ protected Statement convert(CompilationUnitRewrite cuRewrite, final TextEditGrou list= astRewrite.getListRewrite(body, Block.STATEMENTS_PROPERTY); for (Expression expression : fOccurrences) { Statement parent= ASTNodes.getParent(expression, Statement.class); - if (parent != null && list.getRewrittenList().contains(parent)) { + if (parent != null && parent.getParent() instanceof Block) { + ListRewrite innerList= astRewrite.getListRewrite(parent.getParent(), Block.STATEMENTS_PROPERTY); List newComments= new ArrayList<>(); for (Comment comment : commentList) { CompilationUnit cu= (CompilationUnit)parent.getRoot(); @@ -275,14 +276,14 @@ protected Statement convert(CompilationUnitRewrite cuRewrite, final TextEditGrou } if (!newComments.isEmpty()) { ASTNode lastComment= newComments.get(0); - list.replace(parent, lastComment, group); + innerList.replace(parent, lastComment, group); for (int i= 1; i < newComments.size(); ++i) { ASTNode nextComment= newComments.get(i); - list.insertAfter(nextComment, lastComment, group); + innerList.insertAfter(nextComment, lastComment, group); lastComment= nextComment; } } else { - list.remove(parent, group); + innerList.remove(parent, group); } remover.registerRemovedNode(parent); } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/DoWhileRatherThanWhileFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/DoWhileRatherThanWhileFixCore.java index 35021d8a..5ec766d8 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/DoWhileRatherThanWhileFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/DoWhileRatherThanWhileFixCore.java @@ -384,4 +384,14 @@ public static ICleanUpFixCore createCleanUp(final CompilationUnit compilationUni protected DoWhileRatherThanWhileFixCore(final String name, final CompilationUnit compilationUnit, final CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { super(name, compilationUnit, fixRewriteOperations); } + + public static IProposableFix createDoWhileFix(WhileStatement switchStatement) { + CompilationUnit root= (CompilationUnit) switchStatement.getRoot(); + List operations= new ArrayList<>(); + DoWhileRatherThanWhileFinder finder= new DoWhileRatherThanWhileFinder(operations); + switchStatement.accept(finder); + if (operations.isEmpty()) + return null; + return new DoWhileRatherThanWhileFixCore(FixMessages.DoWhileRatherThanWhileFix_description, root, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operations.get(0) }); + } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java index f38e2bee..06674921 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java @@ -81,10 +81,12 @@ private FixMessages() { public static String UnusedCodeFix_RemoveConstructor_description; public static String UnusedCodeFix_RemoveType_description; public static String UnusedCodeFix_RemoveImport_description; + public static String UnusedCodeFix_RemoveParameter_description; public static String UnusedCodeFix_RemoveCast_description; public static String UnusedCodeFix_RemoveUnusedType_description; public static String UnusedCodeFix_RemoveUnusedTypeParameter_description; public static String UnusedCodeFix_RemoveUnusedConstructor_description; + public static String UnusedCodeFix_RemoveUnusedMethodParameter_description; public static String UnusedCodeFix_RemoveUnusedPrivateMethod_description; public static String UnusedCodeFix_RemoveUnusedField_description; public static String UnusedCodeFix_RemoveUnusedVariabl_description; @@ -179,6 +181,7 @@ private FixMessages() { public static String TypeAnnotationFix_remove; public static String ConstantsCleanUpFix_refactor; public static String StringBufferToStringBuilderFix_convert_msg; + public static String StringConcatToTextBlockFix_convert_msg; static { // initialize resource bundle diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties index 46c03082..c2ac4f9a 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties @@ -45,11 +45,13 @@ UnusedCodeFix_RemoveMethod_description=Remove method ''{0}'' UnusedCodeFix_RemoveConstructor_description=Remove constructor ''{0}'' UnusedCodeFix_RemoveUnusedType_description=Remove unused private type UnusedCodeFix_RemoveUnusedTypeParameter_description=Remove unused type parameter +UnusedCodeFix_RemoveUnusedMethodParameter_description=Remove unused method parameter UnusedCodeFix_RemoveUnusedField_description=Remove unused private field UnusedCodeFix_RemoveType_description=Remove type ''{0}'' UnusedCodeFix_RemoveCast_description=Remove cast UnusedCodeFix_change_name=Remove unused code UnusedCodeFix_RemoveImport_description=Remove unused import +UnusedCodeFix_RemoveParameter_description=Remove unused parameter ''{0}'' UnusedCodeFix_RemoveUnnecessaryArrayCreation_description=Remove unnecessary array creation Java50Fix_AddMissingAnnotation_description=Add missing {0} annotation @@ -158,6 +160,7 @@ RedundantComparatorFix_remove_comparator=Implicit comparator ArrayWithCurlyFix_description=Create array with curly ReturnExpressionFix_description=Remove variable assignment before return StringBufferToStringBuilderFix_convert_msg=Convert StringBuffer to StringBuilder +StringConcatToTextBlockFix_convert_msg=Convert String concatenation to Text Block OneIfRatherThanDuplicateBlocksThatFallThroughFix_description=Single 'if' statement rather than duplicate blocks that fall through PullOutIfFromIfElseFix_description=Pull out a duplicate 'if' from an if/else diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/Java50Fix.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/Java50FixCore.java similarity index 87% rename from org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/Java50Fix.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/Java50FixCore.java index 8846034c..c5fbfce0 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/Java50Fix.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/Java50FixCore.java @@ -50,7 +50,10 @@ import org.eclipse.jdt.core.dom.VariableDeclarationStatement; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ListRewrite; +import org.eclipse.jdt.core.manipulation.ICleanUpFixCore; +import org.eclipse.jdt.internal.core.manipulation.JavaManipulationPlugin; +import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder; import org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsConstraintCreator; import org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsConstraintsSolver; @@ -61,12 +64,8 @@ import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.internal.corext.util.Messages; -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; -import org.eclipse.jdt.ui.text.java.IProblemLocation; - -import org.eclipse.jdt.internal.ui.JavaPlugin; -import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation; -import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; +import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; +import org.eclipse.jdt.internal.ui.text.correction.ProblemLocationCore; /** * Fix which introduce new language constructs to pre Java50 code. @@ -76,7 +75,7 @@ * Add missing @Deprecated annotation * Convert for loop to enhanced for loop */ -public class Java50Fix extends CompilationUnitRewriteOperationsFix { +public class Java50FixCore extends CompilationUnitRewriteOperationsFixCore { private static final String OVERRIDE= "Override"; //$NON-NLS-1$ private static final String DEPRECATED= "Deprecated"; //$NON-NLS-1$ @@ -91,7 +90,7 @@ public AnnotationRewriteOperation(BodyDeclaration bodyDeclaration, String annota } @Override - public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException { + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore model) throws CoreException { AST ast= cuRewrite.getRoot().getAST(); ListRewrite listRewrite= cuRewrite.getASTRewrite().getListRewrite(fBodyDeclaration, fBodyDeclaration.getModifiersProperty()); Annotation newAnnotation= ast.newMarkerAnnotation(); @@ -110,7 +109,7 @@ public AddTypeParametersOperation(SimpleType[] types) { } @Override - public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel positionGroups) throws CoreException { + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore positionGroups) throws CoreException { InferTypeArgumentsTCModel model= new InferTypeArgumentsTCModel(); InferTypeArgumentsConstraintCreator creator= new InferTypeArgumentsConstraintCreator(model, true); @@ -131,7 +130,7 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel pos List args= type.typeArguments(); int j= 0; for (Type argType : args) { - LinkedProposalPositionGroup group= new LinkedProposalPositionGroup("G" + i + "_" + j); //$NON-NLS-1$ //$NON-NLS-2$ + LinkedProposalPositionGroupCore group= new LinkedProposalPositionGroupCore("G" + i + "_" + j); //$NON-NLS-1$ //$NON-NLS-2$ if (!positionGroups.hasLinkedPositions()) { group.addPosition(astRewrite.track(argType), true); } else { @@ -145,7 +144,7 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel pos } } - public static Java50Fix createAddOverrideAnnotationFix(CompilationUnit compilationUnit, IProblemLocation problem) { + public static Java50FixCore createAddOverrideAnnotationFix(CompilationUnit compilationUnit, IProblemLocationCore problem) { if (!isMissingOverrideAnnotationProblem(problem.getProblemId())) return null; @@ -160,7 +159,7 @@ public static boolean isMissingOverrideAnnotationProblem(int id) { return id == IProblem.MissingOverrideAnnotation || id == IProblem.MissingOverrideAnnotationForInterfaceMethodImplementation; } - public static Java50Fix createAddDeprectatedAnnotation(CompilationUnit compilationUnit, IProblemLocation problem) { + public static Java50FixCore createAddDeprectatedAnnotation(CompilationUnit compilationUnit, IProblemLocationCore problem) { if (!isMissingDeprecationProblem(problem.getProblemId())) return null; @@ -173,7 +172,7 @@ public static boolean isMissingDeprecationProblem(int id) { || id == IProblem.TypeMissingDeprecatedAnnotation; } - private static Java50Fix createFix(CompilationUnit compilationUnit, IProblemLocation problem, String annotation, String label) { + private static Java50FixCore createFix(CompilationUnit compilationUnit, IProblemLocationCore problem, String annotation, String label) { ICompilationUnit cu= (ICompilationUnit)compilationUnit.getJavaElement(); if (!JavaModelUtil.is50OrHigher(cu.getJavaProject())) return null; @@ -190,19 +189,19 @@ private static Java50Fix createFix(CompilationUnit compilationUnit, IProblemLoca AnnotationRewriteOperation operation= new AnnotationRewriteOperation(declaration, annotation); - return new Java50Fix(label, compilationUnit, new CompilationUnitRewriteOperation[] {operation}); + return new Java50FixCore(label, compilationUnit, new CompilationUnitRewriteOperation[] {operation}); } - public static Java50Fix createRawTypeReferenceFix(CompilationUnit compilationUnit, IProblemLocation problem) { + public static Java50FixCore createRawTypeReferenceFix(CompilationUnit compilationUnit, IProblemLocationCore problem) { List operations= new ArrayList<>(); - SimpleType node= createRawTypeReferenceOperations(compilationUnit, new IProblemLocation[] {problem}, operations); + SimpleType node= createRawTypeReferenceOperations(compilationUnit, new IProblemLocationCore[] {problem}, operations); if (operations.isEmpty()) return null; - return new Java50Fix(Messages.format(FixMessages.Java50Fix_AddTypeArguments_description, BasicElementLabels.getJavaElementName(node.getName().getFullyQualifiedName())), compilationUnit, operations.toArray(new CompilationUnitRewriteOperation[operations.size()])); + return new Java50FixCore(Messages.format(FixMessages.Java50Fix_AddTypeArguments_description, BasicElementLabels.getJavaElementName(node.getName().getFullyQualifiedName())), compilationUnit, operations.toArray(new CompilationUnitRewriteOperation[operations.size()])); } - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, + public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, boolean addOverrideAnnotation, boolean addOverrideInterfaceAnnotation, boolean addDeprecatedAnnotation, @@ -218,9 +217,9 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, List operations= new ArrayList<>(); IProblem[] problems= compilationUnit.getProblems(); - IProblemLocation[] locations= new IProblemLocation[problems.length]; + IProblemLocationCore[] locations= new IProblemLocationCore[problems.length]; for (int i= 0; i < problems.length; i++) { - locations[i]= new ProblemLocation(problems[i]); + locations[i]= new ProblemLocationCore(problems[i]); } if (addOverrideAnnotation) @@ -243,10 +242,10 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, } CompilationUnitRewriteOperation[] operationsArray= operations.toArray(new CompilationUnitRewriteOperation[operations.size()]); - return new Java50Fix(fixName, compilationUnit, operationsArray); + return new Java50FixCore(fixName, compilationUnit, operationsArray); } - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProblemLocation[] problems, + public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, IProblemLocationCore[] problems, boolean addOverrideAnnotation, boolean addOverrideInterfaceAnnotation, boolean addDeprecatedAnnotation, @@ -275,11 +274,11 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProble return null; CompilationUnitRewriteOperation[] operationsArray= operations.toArray(new CompilationUnitRewriteOperation[operations.size()]); - return new Java50Fix(FixMessages.Java50Fix_add_annotations_change_name, compilationUnit, operationsArray); + return new Java50FixCore(FixMessages.Java50Fix_add_annotations_change_name, compilationUnit, operationsArray); } - private static void createAddDeprecatedAnnotationOperations(CompilationUnit compilationUnit, IProblemLocation[] locations, List result) { - for (IProblemLocation problem : locations) { + private static void createAddDeprecatedAnnotationOperations(CompilationUnit compilationUnit, IProblemLocationCore[] locations, List result) { + for (IProblemLocationCore problem : locations) { if (isMissingDeprecationProblem(problem.getProblemId())) { ASTNode selectedNode= problem.getCoveringNode(compilationUnit); if (selectedNode != null) { @@ -295,8 +294,8 @@ private static void createAddDeprecatedAnnotationOperations(CompilationUnit comp } } - private static void createAddOverrideAnnotationOperations(CompilationUnit compilationUnit, boolean addOverrideInterfaceAnnotation, IProblemLocation[] locations, List result) { - for (IProblemLocation problem : locations) { + private static void createAddOverrideAnnotationOperations(CompilationUnit compilationUnit, boolean addOverrideInterfaceAnnotation, IProblemLocationCore[] locations, List result) { + for (IProblemLocationCore problem : locations) { int problemId= problem.getProblemId(); if (isMissingOverrideAnnotationProblem(problemId)) { @@ -316,12 +315,12 @@ private static void createAddOverrideAnnotationOperations(CompilationUnit compil } } - private static SimpleType createRawTypeReferenceOperations(CompilationUnit compilationUnit, IProblemLocation[] locations, List operations) { + private static SimpleType createRawTypeReferenceOperations(CompilationUnit compilationUnit, IProblemLocationCore[] locations, List operations) { if (hasFatalError(compilationUnit)) return null; List result= new ArrayList<>(); - for (IProblemLocation problem : locations) { + for (IProblemLocationCore problem : locations) { if (isRawTypeReferenceProblem(problem.getProblemId())) { ASTNode node= problem.getCoveredNode(compilationUnit); if (node instanceof ClassInstanceCreation) { @@ -361,7 +360,7 @@ private static boolean hasFatalError(CompilationUnit compilationUnit) { if (!((ICompilationUnit) compilationUnit.getJavaElement()).isStructureKnown()) return true; } catch (JavaModelException e) { - JavaPlugin.log(e); + JavaManipulationPlugin.log(e); return true; } @@ -506,7 +505,7 @@ private static ASTNode getDeclaringNode(ASTNode selectedNode) { return declaringNode; } - private Java50Fix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperation[] fixRewrites) { + private Java50FixCore(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperation[] fixRewrites) { super(name, compilationUnit, fixRewrites); } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFixCore.java index 31bc3997..4b770ba9 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFixCore.java @@ -554,10 +554,10 @@ public boolean visit(final SimpleName node) { if (actualFragment.getParent() instanceof FieldDeclaration) { FieldDeclaration fieldDeclaration= (FieldDeclaration) actualFragment.getParent(); - ASTNode declarationClass= ASTNodes.getFirstAncestorOrNull(fieldDeclaration, TypeDeclaration.class); + TypeDeclaration declarationClass= ASTNodes.getFirstAncestorOrNull(fieldDeclaration, TypeDeclaration.class); - if (declarationClass instanceof TypeDeclaration) { - TypeDeclaration typeDeclaration= (TypeDeclaration) declarationClass; + if (declarationClass != null) { + TypeDeclaration typeDeclaration= declarationClass; final List nextFields= new ArrayList<>(typeDeclaration.getFields().length); boolean isBefore= true; @@ -693,9 +693,9 @@ private static void collectInheritedTypes(final ITypeBinding anonymType, final S } } - private HashSet makeNamesUnique(HashSet excludedNames, MethodDeclaration methodDeclaration, ASTRewrite rewrite, TextEditGroup group) { + private HashSet makeNamesUnique(HashSet namesFromUpperScope, MethodDeclaration methodDeclaration, ASTRewrite rewrite, TextEditGroup group) { HashSet newNames= new HashSet<>(); - excludedNames.addAll(ASTNodes.getVisibleLocalVariablesInScope(methodDeclaration)); + namesFromUpperScope.addAll(ASTNodes.getVisibleLocalVariablesInScope(methodDeclaration)); List simpleNamesInMethod= getNamesInMethod(methodDeclaration); List namesInMethod= new ArrayList<>(); for (SimpleName name : simpleNamesInMethod) { @@ -705,10 +705,9 @@ private HashSet makeNamesUnique(HashSet excludedNames, MethodDec for (int i= 0; i < simpleNamesInMethod.size(); i++) { SimpleName name= simpleNamesInMethod.get(i); String identifier= namesInMethod.get(i); - HashSet allNamesToExclude= getNamesToExclude(excludedNames, namesInMethod, i); - if (allNamesToExclude.contains(identifier)) { - String newIdentifier= createName(identifier, allNamesToExclude); - excludedNames.add(newIdentifier); + if (namesFromUpperScope.contains(identifier)) { + String newIdentifier= createName(identifier, namesFromUpperScope, namesInMethod, newNames); + namesFromUpperScope.add(newIdentifier); newNames.add(newIdentifier); SimpleName[] references= LinkedNodeFinder.findByNode(name.getRoot(), name); for (SimpleName ref : references) { @@ -720,13 +719,6 @@ private HashSet makeNamesUnique(HashSet excludedNames, MethodDec return newNames; } - private HashSet getNamesToExclude(HashSet excludedNames, List namesInMethod, int i) { - HashSet allNamesToExclude= new HashSet<>(excludedNames); - allNamesToExclude.addAll(namesInMethod.subList(0, i)); - allNamesToExclude.addAll(namesInMethod.subList(i + 1, namesInMethod.size())); - return allNamesToExclude; - } - private List getNamesInMethod(MethodDeclaration methodDeclaration) { class NamesCollector extends HierarchicalASTVisitor { private int fTypeCounter; @@ -771,10 +763,10 @@ public boolean visit(VariableDeclaration node) { return namesCollector.fNames; } - private String createName(String candidate, HashSet excludedNames) { + private String createName(String candidate, HashSet excludedNames, List namesInMethod, HashSet newNames) { int i= 1; String result= candidate; - while (excludedNames.contains(result)) { + while (excludedNames.contains(result) || newNames.contains(result) || namesInMethod.contains(result)) { result= candidate + i++; } return result; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/LibStandardNames.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/LibStandardNames.java index faa47190..e1593603 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/LibStandardNames.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/LibStandardNames.java @@ -22,7 +22,12 @@ public class LibStandardNames { static final String METHOD_GET_DEFAULT= "getDefault"; //$NON-NLS-1$ static final String METHOD_LINE_SEPARATOR= "lineSeparator"; //$NON-NLS-1$ static final String METHOD_BOOLEAN= "getBoolean"; //$NON-NLS-1$ + static final String METHOD_INTEGER= "getInteger"; //$NON-NLS-1$ + static final String METHOD_LONG= "getLong"; //$NON-NLS-1$ static final String METHOD_PARSEBOOLEAN= "parseBoolean"; //$NON-NLS-1$ + static final String METHOD_PARSEINTEGER= "parseInt"; //$NON-NLS-1$ + static final String METHOD_PARSELONG= "parseLong"; //$NON-NLS-1$ static final String FIELD_PATH_SEPARATOR= "pathSeparator"; //$NON-NLS-1$ static final String FIELD_SEPARATOR= "separator"; //$NON-NLS-1$ + static final String METHOD_FOREACH= "forEach"; //$NON-NLS-1$ } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/PrimitiveCharRatherThanWrapperFinder.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/PrimitiveCharRatherThanWrapperFinder.java index ba17c847..a9df33a0 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/PrimitiveCharRatherThanWrapperFinder.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/PrimitiveCharRatherThanWrapperFinder.java @@ -18,9 +18,9 @@ import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.Assignment; +import org.eclipse.jdt.core.dom.CharacterLiteral; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.InfixExpression; -import org.eclipse.jdt.core.dom.NumberLiteral; import org.eclipse.jdt.core.dom.PostfixExpression; import org.eclipse.jdt.core.dom.PrefixExpression; @@ -38,7 +38,7 @@ public String getPrimitiveTypeName() { @Override public Class getLiteralClass() { - return NumberLiteral.class; + return CharacterLiteral.class; } @Override diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SealedClassFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SealedClassFixCore.java new file mode 100644 index 00000000..a6d32cdc --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SealedClassFixCore.java @@ -0,0 +1,306 @@ +/******************************************************************************* + * Copyright (c) 2022 Red Hat Inc. and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.fix; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.SimpleType; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.TypeDeclaration; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; + +import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; +import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; + +import org.eclipse.jdt.internal.ui.text.correction.CorrectionMessages; +import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; +import org.eclipse.jdt.internal.ui.util.ASTHelper; + +public class SealedClassFixCore extends CompilationUnitRewriteOperationsFixCore { + + public SealedClassFixCore(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperation operation) { + super(name, compilationUnit, operation); + } + + public static class AddTypeAsPermittedSubTypeProposalOperation extends CompilationUnitRewriteOperation { + + private TypeDeclaration fsealedType; + + private ITypeBinding fSubTypeBinding; + + private TypeDeclaration fSubType; + + public AddTypeAsPermittedSubTypeProposalOperation(TypeDeclaration sealedType, TypeDeclaration subType, ITypeBinding subTypeBinding) { + fsealedType= sealedType; + fSubType= subType; + fSubTypeBinding= subTypeBinding; + } + + @Override + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore model) throws CoreException { + AST ast= fsealedType.getAST(); + String subTypeName= fSubType.getName().getIdentifier(); + Type type= ast.newSimpleType(ast.newSimpleName(subTypeName)); + + ASTRewrite astRewrite= cuRewrite.getASTRewrite(); + astRewrite.getListRewrite(fsealedType, TypeDeclaration.PERMITS_TYPES_PROPERTY).insertLast(type, null); + + ImportRewrite importRewrite= cuRewrite.getImportRewrite(); + ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(fsealedType.getRoot(), importRewrite); + importRewrite.addImport(fSubTypeBinding, astRewrite.getAST(), importRewriteContext); + } + } + + public static class AddSealedAsDirectSuperTypeProposalOperation extends CompilationUnitRewriteOperation { + + private TypeDeclaration fPermittedTypeDeclaration; + + private TypeDeclaration fSealedType; + + public AddSealedAsDirectSuperTypeProposalOperation(TypeDeclaration permittedTypeDeclaration, TypeDeclaration sealedType) { + this.fPermittedTypeDeclaration= permittedTypeDeclaration; + this.fSealedType= sealedType; + } + + @Override + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore linkedModel) throws CoreException { + AST ast= fPermittedTypeDeclaration.getAST(); + String sealedTypeName= fSealedType.getName().getIdentifier(); + Type type= ast.newSimpleType(ast.newSimpleName(sealedTypeName)); + + boolean isSealedInterface= fSealedType.isInterface(); + + ASTRewrite astRewrite= cuRewrite.getASTRewrite(); + if (isSealedInterface) { + astRewrite.getListRewrite(fPermittedTypeDeclaration, TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY).insertLast(type, null); + } else { + astRewrite.set(fPermittedTypeDeclaration, TypeDeclaration.SUPERCLASS_TYPE_PROPERTY, type, null); + } + + ImportRewrite importRewrite= cuRewrite.getImportRewrite(); + ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(fPermittedTypeDeclaration.getRoot(), importRewrite); + importRewrite.addImport(fSealedType.resolveBinding(), astRewrite.getAST(), importRewriteContext); + } + } + + public static SealedClassFixCore addTypeAsPermittedSubTypeProposal(CompilationUnit cu, IProblemLocationCore problem) { + ASTNode selectedNode= problem.getCoveringNode(cu); + + IType sealedType= getSealedType(selectedNode); + if (sealedType == null) { + return null; + } + + while (selectedNode.getParent() instanceof Type) { + selectedNode= selectedNode.getParent(); + } + + TypeDeclaration subType= getDeclaringType(selectedNode); + if (subType == null) { + return null; + } + + ITypeBinding subTypeBinding= subType.resolveBinding(); + + ICompilationUnit compilationUnit= getCompilationUnitForSealedType(sealedType); + if (compilationUnit == null) { + return null; + } + CompilationUnitRewrite cuRewrite= new CompilationUnitRewrite(compilationUnit); + TypeDeclaration declaration; + try { + declaration= ASTNodeSearchUtil.getTypeDeclarationNode(sealedType, cuRewrite.getRoot()); + } catch (JavaModelException e) { + return null; + } + if (declaration == null) { + return null; + } + + AddTypeAsPermittedSubTypeProposalOperation op= new AddTypeAsPermittedSubTypeProposalOperation(declaration, subType, subTypeBinding); + + String subTypeName= subType.getName().getIdentifier(); + String sealedTypeName= sealedType.getElementName(); + String label= Messages.format(CorrectionMessages.LocalCorrectionsSubProcessor_declareSubClassAsPermitsSealedClass_description, new String[] { subTypeName, sealedTypeName }); + + return new SealedClassFixCore(label, cuRewrite.getRoot(), op); + } + + public static SealedClassFixCore addSealedAsDirectSuperTypeProposal(CompilationUnit cu, IProblemLocationCore problem) { + ASTNode selectedNode= problem.getCoveringNode(cu); + + TypeDeclaration sealedType= getSealedTypeNodeFromPermitsNode(selectedNode); + + if (sealedType == null) { + return null; + } + + IType permittedTypeElement= getPermittedType(selectedNode); + if (permittedTypeElement == null) { + return null; + } + + ICompilationUnit compilationUnit= permittedTypeElement.getCompilationUnit(); + if (compilationUnit == null) { + return null; + } + + CompilationUnitRewrite cuRewrite= new CompilationUnitRewrite(compilationUnit); + TypeDeclaration permittedTypeDeclaration; + try { + permittedTypeDeclaration= ASTNodeSearchUtil.getTypeDeclarationNode(permittedTypeElement, cuRewrite.getRoot()); + } catch (JavaModelException e) { + return null; + } + if (permittedTypeDeclaration == null) { + return null; + } + + boolean isSealedInterface= sealedType.isInterface(); + String permittedTypeName= permittedTypeDeclaration.getName().getIdentifier(); + String sealedTypeName= sealedType.getName().getIdentifier(); + String label; + if (isSealedInterface) { + label= Messages.format(CorrectionMessages.LocalCorrectionsSubProcessor_declareSealedAsDirectSuperInterface_description, new String[] { sealedTypeName, permittedTypeName }); + } else { + label= Messages.format(CorrectionMessages.LocalCorrectionsSubProcessor_declareSealedAsDirectSuperClass_description, new String[] { sealedTypeName, permittedTypeName }); + } + + AddSealedAsDirectSuperTypeProposalOperation op= new AddSealedAsDirectSuperTypeProposalOperation(permittedTypeDeclaration, sealedType); + return new SealedClassFixCore(label, cuRewrite.getRoot(), op); + } + + + /** + * @param selectedNode The selected node representing a type that is inherited by the class + * @return a TypeDeclaration representing the declaring type of the selected node or null if not applicable + */ + private static TypeDeclaration getDeclaringType(ASTNode selectedNode) { + if (selectedNode.getLocationInParent() != TypeDeclaration.SUPERCLASS_TYPE_PROPERTY + && selectedNode.getLocationInParent() != TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY) { + return null; + } + return (TypeDeclaration) selectedNode.getParent(); + } + + /** + * + * @param selectedNode The selected node representing a type that is inherited by the class + * @return an IType representing the sealed type from the inheriting class or null if not applicable + */ + public static IType getSealedType(ASTNode selectedNode) { + if (selectedNode == null) { + return null; + } + if (!ASTHelper.isSealedTypeSupportedInAST(selectedNode.getAST())) { + return null; + } + + while (selectedNode.getParent() instanceof Type) { + selectedNode= selectedNode.getParent(); + } + if (selectedNode.getLocationInParent() != TypeDeclaration.SUPERCLASS_TYPE_PROPERTY + && selectedNode.getLocationInParent() != TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY) { + return null; + } + IJavaElement sealedTypeElement= null; + if (selectedNode instanceof SimpleType) { + ITypeBinding typeBinding= ((SimpleType) selectedNode).resolveBinding(); + if (typeBinding != null) { + sealedTypeElement= typeBinding.getJavaElement(); + } + } + if (!(sealedTypeElement instanceof IType)) { + return null; + } + return (IType) sealedTypeElement; + } + + /** + * + * @param selectedNode The selected node representing a 'permits' node type + * @return a TypeDeclaration representing the sealed type or null if not applicable + */ + private static TypeDeclaration getSealedTypeNodeFromPermitsNode(ASTNode selectedNode) { + if (selectedNode == null) { + return null; + } + if (!ASTHelper.isSealedTypeSupportedInAST(selectedNode.getAST())) { + return null; + } + + while (selectedNode.getParent() instanceof Type) { + selectedNode= selectedNode.getParent(); + } + if (selectedNode.getLocationInParent() != TypeDeclaration.PERMITS_TYPES_PROPERTY) { + return null; + } + TypeDeclaration sealedType= (TypeDeclaration) selectedNode.getParent(); + return sealedType; + } + + public static ICompilationUnit getCompilationUnitForSealedType(IType sealedType) { + try { + if (sealedType.isBinary() || !sealedType.isSealed()) { + return null; + } + } catch (JavaModelException e) { + return null; + } + return sealedType.getCompilationUnit(); + } + + /** + * @param selectedNode The selected node representing a 'permits' node type + * @return an IType representing the permitted type node or null if not applicable + */ + public static IType getPermittedType(ASTNode selectedNode) { + if (selectedNode == null) { + return null; + } + if (!ASTHelper.isSealedTypeSupportedInAST(selectedNode.getAST())) { + return null; + } + + while (selectedNode.getParent() instanceof Type) { + selectedNode= selectedNode.getParent(); + } + if (selectedNode.getLocationInParent() != TypeDeclaration.PERMITS_TYPES_PROPERTY) { + return null; + } + + IJavaElement permittedTypeElement= null; + if (selectedNode instanceof SimpleType) { + ITypeBinding typeBinding= ((SimpleType) selectedNode).resolveBinding(); + if (typeBinding != null) { + permittedTypeElement= typeBinding.getJavaElement(); + } + } + if (!(permittedTypeElement instanceof IType)) { + return null; + } + return (IType) permittedTypeElement; + } +} diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringBufferToStringBuilderFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringBufferToStringBuilderFixCore.java index ba6128a5..a10d7208 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringBufferToStringBuilderFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringBufferToStringBuilderFixCore.java @@ -588,7 +588,7 @@ public boolean visit(ReturnStatement returnStatement) { Expression exp= returnStatement.getExpression(); if (exp != null) { MethodDeclaration methodDeclaration= - (MethodDeclaration)ASTNodes.getFirstAncestorOrNull(returnStatement, MethodDeclaration.class); + ASTNodes.getFirstAncestorOrNull(returnStatement, MethodDeclaration.class); if (methodDeclaration != null) { IMethodBinding returnStatementMethodBinding= methodDeclaration.resolveBinding(); if (returnStatementMethodBinding != null) { @@ -640,7 +640,7 @@ private boolean checkFieldAccess(ASTNode node, IVariableBinding fieldBinding) { } } } - Assignment assignment= (Assignment)ASTNodes.getFirstAncestorOrNull(node, Assignment.class); + Assignment assignment= ASTNodes.getFirstAncestorOrNull(node, Assignment.class); if (assignment != null) { Expression leftSide= assignment.getLeftHandSide(); if (leftSide instanceof Name) { @@ -752,7 +752,7 @@ public boolean visit(final ClassInstanceCreation visited) { Type type= visited.getType(); ITypeBinding typeBinding= type.resolveBinding(); if (isStringBufferType(typeBinding)) { - Assignment assignment= (Assignment)ASTNodes.getFirstAncestorOrNull(visited, Assignment.class); + Assignment assignment= ASTNodes.getFirstAncestorOrNull(visited, Assignment.class); if (assignment != null) { Expression leftSide= assignment.getLeftHandSide(); if (leftSide instanceof Name) { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringConcatToTextBlockFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringConcatToTextBlockFixCore.java new file mode 100644 index 00000000..c917acd3 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/StringConcatToTextBlockFixCore.java @@ -0,0 +1,333 @@ +/******************************************************************************* + * Copyright (c) 2021 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.fix; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.ArrayType; +import org.eclipse.jdt.core.dom.Assignment; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.InfixExpression; +import org.eclipse.jdt.core.dom.StringLiteral; +import org.eclipse.jdt.core.dom.TextBlock; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer; +import org.eclipse.jdt.core.manipulation.ICleanUpFixCore; + +import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; +import org.eclipse.jdt.internal.corext.util.JavaModelUtil; + +import org.eclipse.jdt.internal.ui.fix.MultiFixMessages; + +public class StringConcatToTextBlockFixCore extends CompilationUnitRewriteOperationsFixCore { + + private final static String JAVA_STRING= "java.lang.String"; //$NON-NLS-1$ + + public static final class StringConcatFinder extends ASTVisitor { + + private final List fOperations; + private final boolean fAllConcats; + + public StringConcatFinder(List operations, boolean allConcats) { + super(true); + fOperations= operations; + fAllConcats= allConcats; + } + + private boolean isStringType(Type type) { + if (type instanceof ArrayType) { + return false; + } + ITypeBinding typeBinding= type.resolveBinding(); + if (typeBinding == null || !typeBinding.getQualifiedName().equals(JAVA_STRING)) { + return false; + } + return true; + } + + @Override + public boolean visit(final VariableDeclarationStatement visited) { + Type type= visited.getType(); + if (!isStringType(type)) { + return false; + } + return true; + } + + @Override + public boolean visit(final FieldDeclaration visited) { + Type type= visited.getType(); + if (!isStringType(type)) { + return false; + } + return true; + } + + @Override + public boolean visit(final Assignment visited) { + ITypeBinding typeBinding= visited.resolveTypeBinding(); + if (typeBinding == null || !typeBinding.getQualifiedName().equals(JAVA_STRING)) { + return false; + } + return true; + } + + @Override + public boolean visit(final InfixExpression visited) { + if (visited.getOperator() != InfixExpression.Operator.PLUS + || visited.extendedOperands().isEmpty()) { + return false; + } + ITypeBinding typeBinding= visited.resolveTypeBinding(); + if (typeBinding == null || !typeBinding.getQualifiedName().equals(JAVA_STRING)) { + return false; + } + Expression leftHand= visited.getLeftOperand(); + if (!(leftHand instanceof StringLiteral)) { + return false; + } + StringLiteral leftLiteral= (StringLiteral)leftHand; + String literal= leftLiteral.getLiteralValue(); + if (!literal.isEmpty() && !fAllConcats && !literal.endsWith("\n")) { //$NON-NLS-1$ + return false; + } + Expression rightHand= visited.getRightOperand(); + if (!(rightHand instanceof StringLiteral)) { + return false; + } + StringLiteral rightLiteral= (StringLiteral)leftHand; + literal= rightLiteral.getLiteralValue(); + if (!literal.isEmpty() && !fAllConcats && !literal.endsWith("\n")) { //$NON-NLS-1$ + return false; + } + List extendedOperands= visited.extendedOperands(); + if (extendedOperands.isEmpty()) { + return false; + } + for (int i= 0; i < extendedOperands.size(); ++i) { + Expression operand= extendedOperands.get(i); + if (operand instanceof StringLiteral) { + StringLiteral stringLiteral= (StringLiteral)operand; + String string= stringLiteral.getLiteralValue(); + if (!string.isEmpty() && (fAllConcats || string.endsWith("\n") || i == extendedOperands.size() - 1)) { //$NON-NLS-1$ + continue; + } + } + return false; + } + fOperations.add(new ChangeStringConcatToTextBlock(visited)); + return false; + } + } + + public static class ChangeStringConcatToTextBlock extends CompilationUnitRewriteOperation { + + private final InfixExpression fInfix; + private final String fIndent; + + public ChangeStringConcatToTextBlock(final InfixExpression infix) { + this.fInfix= infix; + this.fIndent= "\t"; //$NON-NLS-1$ + } + + @Override + public void rewriteAST(final CompilationUnitRewrite cuRewrite, final LinkedProposalModelCore linkedModel) throws CoreException { + ASTRewrite rewrite= cuRewrite.getASTRewrite(); + TextEditGroup group= createTextEditGroup(MultiFixMessages.StringConcatToTextBlockCleanUp_description, cuRewrite); + rewrite.setTargetSourceRangeComputer(new TargetSourceRangeComputer() { + @Override + public SourceRange computeSourceRange(final ASTNode nodeWithComment) { + if (Boolean.TRUE.equals(nodeWithComment.getProperty(ASTNodes.UNTOUCH_COMMENT))) { + return new SourceRange(nodeWithComment.getStartPosition(), nodeWithComment.getLength()); + } + + return super.computeSourceRange(nodeWithComment); + } + }); + + StringBuilder buf= new StringBuilder(); + + Stream expressions= Stream.concat(Stream.of(fInfix.getLeftOperand(), fInfix.getRightOperand()), ((List) fInfix.extendedOperands()).stream()); + + List parts= new ArrayList<>(); + + expressions.forEach(new Consumer() { + @Override + public void accept(Expression t) { + String value= ((StringLiteral) t).getEscapedValue(); + parts.addAll(unescapeBlock(value.substring(1, value.length() - 1))); + } + }); + + buf.append("\"\"\"\n"); //$NON-NLS-1$ + boolean newLine= false; + for (String part : parts) { + if (buf.length() > 4) {// the first part has been added after the text block delimiter and newline + if (!newLine) { + // no line terminator in this part: merge the line by emitting a line continuation escape + buf.append("\\").append(System.lineSeparator()); //$NON-NLS-1$ + } + } + newLine= part.endsWith(System.lineSeparator()); + buf.append(fIndent).append(part); + } + + if (newLine) { + buf.append(fIndent); + } + buf.append("\"\"\""); //$NON-NLS-1$ + TextBlock textBlock= (TextBlock) rewrite.createStringPlaceholder(buf.toString(), ASTNode.TEXT_BLOCK); + rewrite.replace(fInfix, textBlock, group); + } + + /* + * Split a given string into parts of a text block. Transformations undertaken will be: + * + * 1. Split the text at newline boundaries. The newline will be replaced at the end + * of the first line being split with System.lineTerminator() + * 2. Transform any sequence of three or more double quotes in such that it's not interpreted as "end of text block" + * 3. Transform any trailing spaces into \s escapes + * 4. Transform any non-trailing \t characters into tab characters + */ + private List unescapeBlock(String escapedText) { + StringBuilder transformed= new StringBuilder(); + int readIndex= 0; + int bsIndex= 0; + + List parts= new ArrayList<>(); + + while ((bsIndex= escapedText.indexOf("\\", readIndex)) >= 0) { //$NON-NLS-1$ "\" + if (escapedText.startsWith("\\n", bsIndex)) { //$NON-NLS-1$ "\n" + transformed.append(escapedText.substring(readIndex, bsIndex)); + parts.add(escapeTrailingWhitespace(transformed.toString())+ System.lineSeparator()); + transformed= new StringBuilder(); + readIndex= bsIndex + 2; + } else if (escapedText.startsWith("\\\"", bsIndex)) { //$NON-NLS-1$ "\"" + // if there are more than three quotes in a row, escape the first quote of every triplet to + // avoid it being interpreted as a text block terminator. This code would be much simpler if + // we could escape the third quote of each triplet, but the text block spec recommends this way. + + transformed.append(escapedText.substring(readIndex, bsIndex)); + int quoteCount= 1; + while (escapedText.startsWith("\\\"", bsIndex + 2 * quoteCount)) { //$NON-NLS-1$ + quoteCount++; + } + int i= 0; + while (i < quoteCount / 3) { + transformed.append("\\\"\"\""); //$NON-NLS-1$ + i++; + } + + if (i > 0 && quoteCount % 3 != 0) { + transformed.append("\\"); //$NON-NLS-1$ + } + for (int j = 0; j < quoteCount % 3; j++) { + transformed.append("\""); //$NON-NLS-1$ + } + + readIndex= bsIndex + 2 * quoteCount; + } else if (escapedText.startsWith("\\t", bsIndex)) { //$NON-NLS-1$ "\t" + transformed.append(escapedText.substring(readIndex, bsIndex)); + transformed.append("\t"); //$NON-NLS-1$ + readIndex= bsIndex+2; + } else { + transformed.append(escapedText.substring(readIndex, bsIndex)); + transformed.append("\\").append(escapedText.charAt(bsIndex + 1)); //$NON-NLS-1$ + readIndex= bsIndex + 2; + } + } + if (readIndex < escapedText.length()) { + // there is text at the end of the string that is not followed by a newline + transformed.append(escapeTrailingWhitespace(escapedText.substring(readIndex))); + } + if (transformed.length() > 0) { + parts.add(transformed.toString()); + } + return parts; + } + + /* + * Escape spaces and tabs at the end of a line, because they would be trimmed from a text block + */ + private static String escapeTrailingWhitespace(String unescaped) { + if (unescaped.length() == 0) { + return ""; //$NON-NLS-1$ + } + int whitespaceStart= unescaped.length()-1; + StringBuilder trailingWhitespace= new StringBuilder(); + while (whitespaceStart > 0) { + if (unescaped.charAt(whitespaceStart) == ' ') { + whitespaceStart--; + trailingWhitespace.append("\\s"); //$NON-NLS-1$ + } else if (unescaped.charAt(whitespaceStart) == '\t') { + whitespaceStart--; + trailingWhitespace.append("\\t"); //$NON-NLS-1$ + } else { + break; + } + } + + return unescaped.substring(0, whitespaceStart + 1) + trailingWhitespace; + } + } + + public static ICleanUpFixCore createCleanUp(final CompilationUnit compilationUnit) { + if (!JavaModelUtil.is15OrHigher(compilationUnit.getJavaElement().getJavaProject())) + return null; + + List operations= new ArrayList<>(); + + StringConcatFinder finder= new StringConcatFinder(operations, true); + compilationUnit.accept(finder); + + if (operations.isEmpty()) { + return null; + } + + CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] ops= operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[0]); + return new StringBufferToStringBuilderFixCore(FixMessages.StringConcatToTextBlockFix_convert_msg, compilationUnit, ops); + } + + public static StringConcatToTextBlockFixCore createStringConcatToTextBlockFix(ASTNode exp) { + CompilationUnit root= (CompilationUnit) exp.getRoot(); + if (!JavaModelUtil.is15OrHigher(root.getJavaElement().getJavaProject())) + return null; + List operations= new ArrayList<>(); + StringConcatFinder finder= new StringConcatFinder(operations, true); + exp.accept(finder); + if (operations.isEmpty()) + return null; + return new StringConcatToTextBlockFixCore(FixMessages.StringConcatToTextBlockFix_convert_msg, root, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operations.get(0) }); + } + + protected StringConcatToTextBlockFixCore(final String name, final CompilationUnit compilationUnit, final CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { + super(name, compilationUnit, fixRewriteOperations); + } + +} diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFixCore.java index b89c7c73..6ca3f586 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFixCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2021 Red Hat Inc. and others. + * Copyright (c) 2020, 2022 Red Hat Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -89,7 +89,6 @@ public boolean visit(SwitchStatement node) { private boolean isInvalidStatement(Statement statement) { return statement instanceof ContinueStatement || statement instanceof ForStatement - || statement instanceof ReturnStatement || statement instanceof IfStatement || statement instanceof DoStatement || statement instanceof EnhancedForStatement @@ -100,6 +99,7 @@ private boolean isInvalidStatement(Statement statement) { } private SwitchExpressionsFixOperation getOperation(SwitchStatement switchStatement) { final List throwList= new ArrayList<>(); + final List returnList= new ArrayList<>(); boolean defaultFound= false; List currentBlock= null; SwitchCase currentCase= null; @@ -119,6 +119,15 @@ private SwitchExpressionsFixOperation getOperation(SwitchStatement switchStateme } currentBlock= new ArrayList<>(); currentCase= switchCase; + } else if (statement instanceof ReturnStatement) { + returnList.add(currentCase); + if (currentBlock == null) { + return null; + } + currentBlock.add(statement); + caseMap.put(currentCase, currentBlock); + currentBlock= null; + currentCase= null; } else if (isInvalidStatement(statement)) { return null; } else if (statement instanceof BreakStatement) { @@ -143,6 +152,7 @@ private SwitchExpressionsFixOperation getOperation(SwitchStatement switchStateme if (currentBlock == null) { return null; } + boolean blockComplete= false; if (statement instanceof Block) { Block block= (Block)statement; // allow one level of block with no invalid statements inside @@ -152,11 +162,27 @@ private SwitchExpressionsFixOperation getOperation(SwitchStatement switchStateme return null; } if (blockStatement instanceof ThrowStatement) { + if (blockIter.hasNext()) { + return null; + } + blockComplete= true; throwList.add(currentCase); } + if (blockStatement instanceof ReturnStatement) { + if (blockIter.hasNext()) { + return null; + } + blockComplete= true; + returnList.add(currentCase); + } } } currentBlock.add(statement); + if (blockComplete) { + caseMap.put(currentCase, currentBlock); + currentBlock= null; + currentCase= null; + } } } @@ -167,52 +193,73 @@ private SwitchExpressionsFixOperation getOperation(SwitchStatement switchStateme } caseMap.put(currentCase, currentBlock); } - String commonAssignmentName= null; IBinding assignmentBinding= null; - for (Map.Entry> entry : caseMap.entrySet()) { - SwitchCase entryCase= entry.getKey(); - List entryStatements= entry.getValue(); - if (throwList.contains(entryCase) || entryStatements.size() == 0) { - continue; - } - Statement lastStatement= entryStatements.get(entryStatements.size() - 1); - if (lastStatement instanceof Block) { - @SuppressWarnings("rawtypes") - List blockStatements= ((Block)lastStatement).statements(); - if (blockStatements.isEmpty()) { - continue; + boolean createReturnStatement= false; + + // returns are allowed only if every case ends in either a return or throws statement + if (returnList.size() > 0) { + createReturnStatement= true; + int caseCount= 0; + for (Map.Entry> entry : caseMap.entrySet()) { + List entryStatements= entry.getValue(); + if (entryStatements.size() > 0) { + ++caseCount; } - lastStatement= (Statement)(blockStatements.get(blockStatements.size() - 1)); - } - // case must end in an assignment - if (!(lastStatement instanceof ExpressionStatement) || !(((ExpressionStatement)lastStatement).getExpression() instanceof Assignment)) { - return null; } - Assignment assignment= (Assignment)((ExpressionStatement) lastStatement).getExpression(); - // must be simple assign operator - if (assignment.getOperator() != Assignment.Operator.ASSIGN) { + if ((returnList.size() + throwList.size()) < caseCount) { return null; } - if (commonAssignmentName == null) { - Expression exp= assignment.getLeftHandSide(); - if (exp instanceof Name) { - commonAssignmentName= ((Name)exp).getFullyQualifiedName(); - assignmentBinding= ((Name) exp).resolveBinding(); + } else { + for (Map.Entry> entry : caseMap.entrySet()) { + SwitchCase entryCase= entry.getKey(); + List entryStatements= entry.getValue(); + if (throwList.contains(entryCase) || entryStatements.size() == 0) { + continue; } - } else { - Expression exp= assignment.getLeftHandSide(); - if (exp instanceof Name) { - Name name= (Name)exp; - if (!name.getFullyQualifiedName().equals(commonAssignmentName)) { + Statement lastStatement= entryStatements.get(entryStatements.size() - 1); + if (lastStatement instanceof Block) { + @SuppressWarnings("rawtypes") + List blockStatements= ((Block)lastStatement).statements(); + if (blockStatements.isEmpty()) { + continue; + } + lastStatement= (Statement)(blockStatements.get(blockStatements.size() - 1)); + } + // case must end in an assignment + if (!(lastStatement instanceof ExpressionStatement) || !(((ExpressionStatement)lastStatement).getExpression() instanceof Assignment)) { + return null; + } + Assignment assignment= (Assignment)((ExpressionStatement) lastStatement).getExpression(); + // must be simple assign operator + if (assignment.getOperator() != Assignment.Operator.ASSIGN) { + return null; + } + if (commonAssignmentName == null) { + Expression exp= assignment.getLeftHandSide(); + if (exp instanceof Name) { + commonAssignmentName= ((Name)exp).getFullyQualifiedName(); + assignmentBinding= ((Name) exp).resolveBinding(); + } else { + return null; + } + } else { + Expression exp= assignment.getLeftHandSide(); + if (exp instanceof Name) { + Name name= (Name)exp; + if (!name.getFullyQualifiedName().equals(commonAssignmentName)) { + return null; + } + } else { return null; } } } + if (assignmentBinding == null) { + return null; + } } - if (assignmentBinding == null) { - return null; - } + // ensure either we have default case or else expression is enum and all constants specified ITypeBinding binding= switchStatement.getExpression().resolveTypeBinding(); if (binding != null && binding.isEnum()) { @@ -229,7 +276,7 @@ private SwitchExpressionsFixOperation getOperation(SwitchStatement switchStateme } else if (!defaultFound) { return null; } - return new SwitchExpressionsFixOperation(switchStatement, caseMap, commonAssignmentName, assignmentBinding); + return new SwitchExpressionsFixOperation(switchStatement, caseMap, createReturnStatement, commonAssignmentName, assignmentBinding); } } @@ -237,13 +284,15 @@ public static class SwitchExpressionsFixOperation extends CompilationUnitRewrite private final SwitchStatement switchStatement; private final Map> caseMap; + private final boolean createReturnStatement; private final String varName; private final IBinding assignmentBinding; public SwitchExpressionsFixOperation(SwitchStatement switchStatement, Map> caseMap, - String varName, IBinding assignmentBinding) { + boolean createReturnStatement, String varName, IBinding assignmentBinding) { this.switchStatement= switchStatement; this.caseMap= caseMap; + this.createReturnStatement= createReturnStatement; this.varName= varName; this.assignmentBinding= assignmentBinding; } @@ -260,149 +309,181 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore Expression newSwitchExpressionExpression= (Expression)rewrite.createCopyTarget(switchStatement.getExpression()); newSwitchExpression.setExpression(newSwitchExpressionExpression); SwitchCase lastSwitchCase= null; + + boolean forceOldStyle= false; + // if there are comments at end of case statements, we have to use old style cases + for (Map.Entry> entry : caseMap.entrySet()) { + SwitchCase oldSwitchCase= entry.getKey(); + List trailingComments= ASTNodes.getTrailingComments(oldSwitchCase); + if (trailingComments != null && !trailingComments.isEmpty()) { + forceOldStyle= true; + break; + } + } + // build switch expression for (Map.Entry> entry : caseMap.entrySet()) { SwitchCase oldSwitchCase= entry.getKey(); List oldStatements= entry.getValue(); if (oldStatements.isEmpty()) { - // fall-through, want all fall-through labels in single case - if (lastSwitchCase == null) { - lastSwitchCase= ast.newSwitchCase(); - lastSwitchCase.setSwitchLabeledRule(true); - newSwitchExpression.statements().add(lastSwitchCase); - } - for (Object obj : oldSwitchCase.expressions()) { - Expression oldExpression= (Expression)obj; - Expression newExpression= (Expression)rewrite.createCopyTarget(oldExpression); - lastSwitchCase.expressions().add(newExpression); + if (forceOldStyle) { + SwitchCase newSwitchCase= (SwitchCase)rewrite.createCopyTarget(oldSwitchCase); + newSwitchExpression.statements().add(newSwitchCase); + } else { + // fall-through, want all fall-through labels in single case + if (lastSwitchCase == null) { + lastSwitchCase= ast.newSwitchCase(); + lastSwitchCase.setSwitchLabeledRule(true); + newSwitchExpression.statements().add(lastSwitchCase); + } + for (Object obj : oldSwitchCase.expressions()) { + Expression oldExpression= (Expression)obj; + Expression newExpression= (Expression)rewrite.createCopyTarget(oldExpression); + lastSwitchCase.expressions().add(newExpression); + } } continue; } SwitchCase switchCase= null; - if (lastSwitchCase == null) { - SwitchCase newSwitchCase= ast.newSwitchCase(); + boolean needDuplicateDefault= false; + if (forceOldStyle) { + SwitchCase newSwitchCase= (SwitchCase)rewrite.createCopyTarget(oldSwitchCase); newSwitchExpression.statements().add(newSwitchCase); - newSwitchCase.setSwitchLabeledRule(true); - switchCase= newSwitchCase; } else { - switchCase= lastSwitchCase; - } - lastSwitchCase= null; - for (Object obj : oldSwitchCase.expressions()) { - Expression oldExpression= (Expression)obj; - Expression newExpression= (Expression)rewrite.createCopyTarget(oldExpression); - switchCase.expressions().add(newExpression); - } - if (oldStatements.size() == 1 && oldStatements.get(0) instanceof Block) { - oldStatements= ((Block)oldStatements.get(0)).statements(); - } - if (oldStatements.size() == 1) { - Statement oldStatement= oldStatements.get(0); - Statement newStatement= null; - if (oldStatement instanceof ThrowStatement) { - ThrowStatement throwStatement= (ThrowStatement)oldStatement; - newStatement= (Statement)rewrite.createCopyTarget(throwStatement); + if (lastSwitchCase == null) { + SwitchCase newSwitchCase= ast.newSwitchCase(); + newSwitchExpression.statements().add(newSwitchCase); + newSwitchCase.setSwitchLabeledRule(true); + switchCase= newSwitchCase; } else { - ExpressionStatement oldExpStatement= (ExpressionStatement)oldStatement; - Assignment oldAssignment= (Assignment)oldExpStatement.getExpression(); - Expression rhs= oldAssignment.getRightHandSide(); - // Ugly hack to tack on trailing comments - IBuffer buffer= cuRewrite.getCu().getBuffer(); - StringBuilder b= new StringBuilder(); - b.append(buffer.getText(rhs.getStartPosition(), rhs.getLength()) + ";"); //$NON-NLS-1$ - List trailingComments= ASTNodes.getTrailingComments(oldExpStatement); - for (Comment comment : trailingComments) { - b.append(" " + buffer.getText(comment.getStartPosition(), comment.getLength())); //$NON-NLS-1$ - } - newStatement= (Statement) rewrite.createStringPlaceholder(b.toString(), ASTNode.EXPRESSION_STATEMENT); + switchCase= lastSwitchCase; } - newSwitchExpression.statements().add(newStatement); - } else { - Block newBlock= ast.newBlock(); - int statementsLen= oldStatements.size(); - for (int i= 0; i < statementsLen - 1; ++i) { - Statement oldSwitchCaseStatement= oldStatements.get(i); - newBlock.statements().add(rewrite.createCopyTarget(oldSwitchCaseStatement)); + if (lastSwitchCase != null + && oldSwitchCase.expressions().isEmpty()) { + // Original switch had fall-through into default case so + // we will need to duplicate the statements from the default case + // to a new case statement that has all fall-through expressions + // and to a new default case that uses new syntax + needDuplicateDefault= true; } - ExpressionStatement oldExpStatement= (ExpressionStatement)oldStatements.get(statementsLen - 1); - Assignment oldAssignment= (Assignment)oldExpStatement.getExpression(); - Expression rhs= oldAssignment.getRightHandSide(); - IBuffer buffer= cuRewrite.getCu().getBuffer(); - StringBuilder b= new StringBuilder(); - List leadingComments= ASTNodes.getLeadingComments(oldExpStatement); - for (Comment comment : leadingComments) { - b.append(buffer.getText(comment.getStartPosition(), comment.getLength()) + "\n"); //$NON-NLS-1$ - } - b.append("yield "); //$NON-NLS-1$ - List trailingComments= ASTNodes.getTrailingComments(oldExpStatement); - b.append(buffer.getText(rhs.getStartPosition(), rhs.getLength()) + ";"); //$NON-NLS-1$ - for (Comment comment : trailingComments) { - b.append(" " + buffer.getText(comment.getStartPosition(), comment.getLength())); //$NON-NLS-1$ + lastSwitchCase= null; + for (Object obj : oldSwitchCase.expressions()) { + Expression oldExpression= (Expression)obj; + Expression newExpression= (Expression)rewrite.createCopyTarget(oldExpression); + switchCase.expressions().add(newExpression); } + } - YieldStatement newYield = (YieldStatement)rewrite.createStringPlaceholder(b.toString(), ASTNode.YIELD_STATEMENT); - Expression newYieldExpression= (Expression) rewrite.createStringPlaceholder(b.toString(), rhs.getNodeType()); - newYield.setExpression(newYieldExpression); - newBlock.statements().add(newYield); - newSwitchExpression.statements().add(newBlock); + while (true) { + if (oldStatements.size() == 1 && oldStatements.get(0) instanceof Block) { + oldStatements= ((Block)oldStatements.get(0)).statements(); + } + if (oldStatements.size() == 1) { + Statement oldStatement= oldStatements.get(0); + Statement newStatement= null; + if (oldStatement instanceof ThrowStatement) { + ThrowStatement throwStatement= (ThrowStatement)oldStatement; + newStatement= (Statement)rewrite.createCopyTarget(throwStatement); + } else if (oldStatement instanceof ReturnStatement && createReturnStatement) { + newStatement= getNewStatementFromReturn(cuRewrite, rewrite, (ReturnStatement)oldStatement); + } else if (forceOldStyle) { + newStatement= getNewYieldStatement(cuRewrite, rewrite, (ExpressionStatement)oldStatement); + } else { + newStatement= getNewStatementForCase(cuRewrite, rewrite, oldStatement); + } + newSwitchExpression.statements().add(newStatement); + } else { + Block newBlock= ast.newBlock(); + int statementsLen= oldStatements.size(); + for (int i= 0; i < statementsLen - 1; ++i) { + Statement oldSwitchCaseStatement= oldStatements.get(i); + newBlock.statements().add(rewrite.createCopyTarget(oldSwitchCaseStatement)); + } + Statement lastStatement= oldStatements.get(statementsLen - 1); + YieldStatement newYield= null; + if (lastStatement instanceof ReturnStatement) { + newYield= getNewYieldStatementFromReturn(cuRewrite, rewrite, (ReturnStatement)oldStatements.get(statementsLen-1)); + } else { + newYield= getNewYieldStatement(cuRewrite, rewrite, (ExpressionStatement)oldStatements.get(statementsLen-1)); + } + newBlock.statements().add(newYield); + newSwitchExpression.statements().add(newBlock); + } + if (needDuplicateDefault) { + needDuplicateDefault= false; + SwitchCase newSwitchCase= ast.newSwitchCase(); + newSwitchExpression.statements().add(newSwitchCase); + newSwitchCase.setSwitchLabeledRule(true); + switchCase= newSwitchCase; + } else { + break; + } } } - // see if we can make new switch expression the initializer of assignment variable - if (assignmentBinding instanceof IVariableBinding) { - VariableDeclarationStatement varDeclarationStatement= null; - int varIndex= -2; - IVariableBinding binding= (IVariableBinding)assignmentBinding; - if (!binding.isField() && !binding.isParameter() && !binding.isSynthetic()) { - ASTNode parent= switchStatement.getParent(); - if (parent instanceof Block) { - Block block= (Block)parent; - List statements= block.statements(); - ListRewrite listRewrite= rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY); - for (int i= 0; i < statements.size(); ++i) { - Statement statement= (Statement)statements.get(i); - if (statement instanceof VariableDeclarationStatement) { - VariableDeclarationStatement decl= (VariableDeclarationStatement)statement; - List fragments= decl.fragments(); - if (fragments.size() == 1) { // must be single var declaration - VariableDeclarationFragment fragment= (VariableDeclarationFragment)fragments.get(0); - if (fragment.getInitializer() == null) { // must not already be initialized - IVariableBinding fragBinding= fragment.resolveBinding(); - if (fragBinding != null && fragBinding.isEqualTo(binding)) { - varDeclarationStatement= decl; - varIndex= i; + Statement newExpressionStatement= null; + + if (createReturnStatement) { + ReturnStatement newReturnStatement= ast.newReturnStatement(); + newReturnStatement.setExpression(newSwitchExpression); + newExpressionStatement= newReturnStatement; + } else { + // see if we can make new switch expression the initializer of assignment variable + if (assignmentBinding instanceof IVariableBinding) { + VariableDeclarationStatement varDeclarationStatement= null; + int varIndex= -2; + IVariableBinding binding= (IVariableBinding)assignmentBinding; + if (!binding.isField() && !binding.isParameter() && !binding.isSynthetic()) { + ASTNode parent= switchStatement.getParent(); + if (parent instanceof Block) { + Block block= (Block)parent; + List statements= block.statements(); + ListRewrite listRewrite= rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY); + for (int i= 0; i < statements.size(); ++i) { + Statement statement= (Statement)statements.get(i); + if (statement instanceof VariableDeclarationStatement) { + VariableDeclarationStatement decl= (VariableDeclarationStatement)statement; + List fragments= decl.fragments(); + if (fragments.size() == 1) { // must be single var declaration + VariableDeclarationFragment fragment= (VariableDeclarationFragment)fragments.get(0); + if (fragment.getInitializer() == null) { // must not already be initialized + IVariableBinding fragBinding= fragment.resolveBinding(); + if (fragBinding != null && fragBinding.isEqualTo(binding)) { + varDeclarationStatement= decl; + varIndex= i; + } } } - } - } else if (statement instanceof SwitchStatement) { - if (statement.subtreeMatch(new ASTMatcher(), switchStatement)) { - // if previous statement declares assignment variable, we can set initializer - if (varIndex == i - 1) { - VariableDeclarationFragment newVarFragment= ast.newVariableDeclarationFragment(); - newVarFragment.setName(ast.newSimpleName(varName)); - newVarFragment.setInitializer(newSwitchExpression); - VariableDeclarationStatement newVar= ast.newVariableDeclarationStatement(newVarFragment); - ImportRewrite importRewrite= cuRewrite.getImportRewrite(); - newVar.setType(importRewrite.addImport(((IVariableBinding) assignmentBinding).getType(), ast)); - if (varDeclarationStatement != null && Modifier.isFinal(varDeclarationStatement.getModifiers())) { - newVar.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD)); + } else if (statement instanceof SwitchStatement) { + if (statement.subtreeMatch(new ASTMatcher(), switchStatement)) { + // if previous statement declares assignment variable, we can set initializer + if (varIndex == i - 1) { + VariableDeclarationFragment newVarFragment= ast.newVariableDeclarationFragment(); + newVarFragment.setName(ast.newSimpleName(varName)); + newVarFragment.setInitializer(newSwitchExpression); + VariableDeclarationStatement newVar= ast.newVariableDeclarationStatement(newVarFragment); + ImportRewrite importRewrite= cuRewrite.getImportRewrite(); + newVar.setType(importRewrite.addImport(((IVariableBinding) assignmentBinding).getType(), ast)); + if (varDeclarationStatement != null && Modifier.isFinal(varDeclarationStatement.getModifiers())) { + newVar.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD)); + } + replaceWithLeadingComments(cuRewrite, listRewrite, varDeclarationStatement, group, newVar); + listRewrite.remove(switchStatement, group); + return; } - replaceWithLeadingComments(cuRewrite, listRewrite, varDeclarationStatement, group, newVar); - listRewrite.remove(switchStatement, group); - return; + break; } - break; } } } } } + // otherwise just assign new switch expression to varName + Assignment newAssignment= ast.newAssignment(); + newExpressionStatement= ast.newExpressionStatement(newAssignment); + newAssignment.setLeftHandSide(ast.newName(varName)); + newAssignment.setRightHandSide(newSwitchExpression); } - // otherwise just assign new switch expression to varName - Assignment newAssignment= ast.newAssignment(); - ExpressionStatement newExpressionStatement= ast.newExpressionStatement(newAssignment); - newAssignment.setLeftHandSide(ast.newName(varName)); - newAssignment.setRightHandSide(newSwitchExpression); ASTNode parent= switchStatement.getParent(); if (parent instanceof Block) { @@ -413,6 +494,97 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore } } + private Statement getNewStatementFromReturn(CompilationUnitRewrite cuRewrite, final ASTRewrite rewrite, ReturnStatement oldStatement) throws JavaModelException { + Statement newStatement; + Expression exp= oldStatement.getExpression(); + // Ugly hack to tack on trailing comments + IBuffer buffer= cuRewrite.getCu().getBuffer(); + StringBuilder b= new StringBuilder(); + List leadingComments= ASTNodes.getLeadingComments(oldStatement); + for (Comment comment : leadingComments) { + if (comment.isLineComment()) { + b.append("/*" + buffer.getText(comment.getStartPosition() + 2, comment.getLength() - 2) + " */ "); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + b.append(buffer.getText(comment.getStartPosition(), comment.getLength()) + " "); //$NON-NLS-1$ + } + } + b.append(buffer.getText(exp.getStartPosition(), exp.getLength()) + ";"); //$NON-NLS-1$ + List trailingComments= ASTNodes.getTrailingComments(oldStatement); + for (Comment comment : trailingComments) { + b.append(" " + buffer.getText(comment.getStartPosition(), comment.getLength())); //$NON-NLS-1$ + } + newStatement= (Statement) rewrite.createStringPlaceholder(b.toString(), ASTNode.EXPRESSION_STATEMENT); + return newStatement; + } + + private Statement getNewStatementForCase(CompilationUnitRewrite cuRewrite, final ASTRewrite rewrite, Statement oldStatement) throws JavaModelException { + Statement newStatement; + ExpressionStatement oldExpStatement= (ExpressionStatement)oldStatement; + Assignment oldAssignment= (Assignment)oldExpStatement.getExpression(); + Expression rhs= oldAssignment.getRightHandSide(); + // Ugly hack to tack on trailing comments + IBuffer buffer= cuRewrite.getCu().getBuffer(); + StringBuilder b= new StringBuilder(); + List leadingComments= ASTNodes.getLeadingComments(oldExpStatement); + for (Comment comment : leadingComments) { + if (comment.isLineComment()) { + b.append("/*" + buffer.getText(comment.getStartPosition() + 2, comment.getLength() - 2) + " */ "); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + b.append(buffer.getText(comment.getStartPosition(), comment.getLength()) + " "); //$NON-NLS-1$ + } + } + b.append(buffer.getText(rhs.getStartPosition(), rhs.getLength()) + ";"); //$NON-NLS-1$ + List trailingComments= ASTNodes.getTrailingComments(oldExpStatement); + for (Comment comment : trailingComments) { + b.append(" " + buffer.getText(comment.getStartPosition(), comment.getLength())); //$NON-NLS-1$ + } + newStatement= (Statement) rewrite.createStringPlaceholder(b.toString(), ASTNode.EXPRESSION_STATEMENT); + return newStatement; + } + + private YieldStatement getNewYieldStatement(CompilationUnitRewrite cuRewrite, final ASTRewrite rewrite, ExpressionStatement oldExpStatement) throws JavaModelException { + Assignment oldAssignment= (Assignment)oldExpStatement.getExpression(); + Expression rhs= oldAssignment.getRightHandSide(); + IBuffer buffer= cuRewrite.getCu().getBuffer(); + StringBuilder b= new StringBuilder(); + List leadingComments= ASTNodes.getLeadingComments(oldExpStatement); + for (Comment comment : leadingComments) { + b.append(buffer.getText(comment.getStartPosition(), comment.getLength()) + "\n"); //$NON-NLS-1$ + } + b.append("yield "); //$NON-NLS-1$ + List trailingComments= ASTNodes.getTrailingComments(oldExpStatement); + b.append(buffer.getText(rhs.getStartPosition(), rhs.getLength()) + ";"); //$NON-NLS-1$ + for (Comment comment : trailingComments) { + b.append(" " + buffer.getText(comment.getStartPosition(), comment.getLength())); //$NON-NLS-1$ + } + + YieldStatement newYield = (YieldStatement)rewrite.createStringPlaceholder(b.toString(), ASTNode.YIELD_STATEMENT); + Expression newYieldExpression= (Expression) rewrite.createStringPlaceholder(b.toString(), rhs.getNodeType()); + newYield.setExpression(newYieldExpression); + return newYield; + } + + private YieldStatement getNewYieldStatementFromReturn(CompilationUnitRewrite cuRewrite, final ASTRewrite rewrite, ReturnStatement oldStatement) throws JavaModelException { + Expression exp= oldStatement.getExpression(); + IBuffer buffer= cuRewrite.getCu().getBuffer(); + StringBuilder b= new StringBuilder(); + List leadingComments= ASTNodes.getLeadingComments(oldStatement); + for (Comment comment : leadingComments) { + b.append(buffer.getText(comment.getStartPosition(), comment.getLength()) + "\n"); //$NON-NLS-1$ + } + b.append("yield "); //$NON-NLS-1$ + List trailingComments= ASTNodes.getTrailingComments(oldStatement); + b.append(buffer.getText(exp.getStartPosition(), exp.getLength()) + ";"); //$NON-NLS-1$ + for (Comment comment : trailingComments) { + b.append(" " + buffer.getText(comment.getStartPosition(), comment.getLength())); //$NON-NLS-1$ + } + + YieldStatement newYield = (YieldStatement)rewrite.createStringPlaceholder(b.toString(), ASTNode.YIELD_STATEMENT); + Expression newYieldExpression= (Expression) rewrite.createStringPlaceholder(b.toString(), exp.getNodeType()); + newYield.setExpression(newYieldExpression); + return newYield; + } + private void replaceWithLeadingComments(CompilationUnitRewrite cuRewrite, ListRewrite listRewrite, ASTNode oldNode, TextEditGroup group, ASTNode newNode) throws JavaModelException { ASTRewrite rewrite= cuRewrite.getASTRewrite(); @@ -437,6 +609,18 @@ private void replaceWithLeadingComments(CompilationUnitRewrite cuRewrite, ListRe } + public static SwitchExpressionsFixCore createConvertToSwitchExpressionFix(SwitchStatement switchStatement) { + CompilationUnit root= (CompilationUnit) switchStatement.getRoot(); + if (!JavaModelUtil.is14OrHigher(root.getJavaElement().getJavaProject())) + return null; + + List operations= new ArrayList<>(); + SwitchExpressionsFixCore.SwitchStatementsFinder finder= new SwitchExpressionsFixCore.SwitchStatementsFinder(operations); + switchStatement.accept(finder); + if (operations.isEmpty()) + return null; + return new SwitchExpressionsFixCore(FixMessages.SwitchExpressionsFix_convert_to_switch_expression, root, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operations.get(0) }); + } public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit) { if (!JavaModelUtil.is14OrHigher(compilationUnit.getJavaElement().getJavaProject())) diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchFixCore.java index d21c76ca..068b04ae 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchFixCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021 Fabrice TIERCELIN and others. + * Copyright (c) 2021, 2022 Fabrice TIERCELIN and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -18,7 +18,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Set; import org.eclipse.core.runtime.CoreException; @@ -39,11 +38,11 @@ import org.eclipse.jdt.core.dom.IfStatement; import org.eclipse.jdt.core.dom.InfixExpression; import org.eclipse.jdt.core.dom.Name; -import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.SuperFieldAccess; import org.eclipse.jdt.core.dom.SwitchCase; import org.eclipse.jdt.core.dom.SwitchStatement; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; import org.eclipse.jdt.core.dom.WhileStatement; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer; @@ -160,7 +159,6 @@ public boolean visit(final IfStatement visited) { List cases= new ArrayList<>(); Statement remainingStatement= null; - Set variableDeclarationIds= new HashSet<>(); IfStatement ifStatement= visited; boolean isFallingThrough= true; @@ -168,11 +166,6 @@ public boolean visit(final IfStatement visited) { IfStatement currentNode= ifStatement; while (ASTNodes.isSameVariable(switchExpression, variable.name)) { - if (detectDeclarationConflicts(currentNode.getThenStatement(), variableDeclarationIds)) { - // Cannot declare two variables with the same name in two cases - return true; - } - cases.add(new SwitchCaseSection(variable.constantValues, ASTNodes.asList(currentNode.getThenStatement()))); @@ -226,25 +219,6 @@ private boolean hasUnlabeledBreak(final IfStatement node) { return hasUnlabeledBreakVisitor.hasUnlabeledBreak; } - private boolean detectDeclarationConflicts(final Statement statement, final Set variableDeclarationIds) { - Set varNames= ASTNodes.getLocalVariableIdentifiers(statement, false); - boolean hasConflict= containsAny(variableDeclarationIds, varNames); - variableDeclarationIds.addAll(varNames); - return hasConflict; - } - - private boolean containsAny(final Set variableDeclarations, final Set varNames) { - for (SimpleName varName : varNames) { - for (SimpleName variableDeclaration : variableDeclarations) { - if (varName.getIdentifier() != null && Objects.equals(varName.getIdentifier(), variableDeclaration.getIdentifier())) { - return true; - } - } - } - - return false; - } - /** * Side-effect: removes the dead branches in a chain of if-elseif. * @@ -406,12 +380,19 @@ private void addCaseWithStatements(final ASTRewrite rewrite, final AST ast, fina switchStatements.add(ast.newSwitchCase()); } + List statementsList= switchStatement.statements(); boolean isBreakNeeded= true; + boolean needBlock= checkForLocalDeclarations(innerStatements); + Block block= null; + if (needBlock) { + block= ast.newBlock(); + statementsList= block.statements(); + } // Add the statement(s) for this case(s) if (!innerStatements.isEmpty()) { for (Statement statement : innerStatements) { - switchStatements.add(ASTNodes.createMoveTarget(rewrite, statement)); + statementsList.add(ASTNodes.createMoveTarget(rewrite, statement)); } isBreakNeeded= !ASTNodes.fallsThrough(innerStatements.get(innerStatements.size() - 1)); @@ -419,8 +400,21 @@ private void addCaseWithStatements(final ASTRewrite rewrite, final AST ast, fina // When required: end with a break if (isBreakNeeded) { - switchStatements.add(ast.newBreakStatement()); + statementsList.add(ast.newBreakStatement()); + } + + if (needBlock) { + switchStatements.add(block); + } + } + + private boolean checkForLocalDeclarations(final List statements) { + for (Statement statement : statements) { + if (statement instanceof VariableDeclarationStatement) { + return true; + } } + return false; } } @@ -468,5 +462,6 @@ private SwitchCaseSection(final List literalExpressions, final List< this.literalExpressions= literalExpressions; this.statements= statements; } + } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFixCore.java index 7c804392..cd4c8857 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFixCore.java @@ -141,7 +141,7 @@ public static TypeParametersFixCore createInsertInferredTypeArgumentsFix(Compila return new TypeParametersFixCore(FixMessages.TypeParametersFix_insert_inferred_type_arguments_name, compilationUnit, new CompilationUnitRewriteOperation[] { op }); } - public static TypeParametersFixCore createRemoveRedundantTypeArgumentsFix(CompilationUnit compilationUnit, IProblemLocationCore problem) { + public static IProposableFix createRemoveRedundantTypeArgumentsFix(CompilationUnit compilationUnit, IProblemLocationCore problem) { int id= problem.getProblemId(); if (id == IProblem.RedundantSpecificationOfTypeArguments) { ParameterizedType parameterizedType= getParameterizedType(compilationUnit, problem); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnimplementedCodeFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnimplementedCodeFixCore.java index fb95bc10..244e1223 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnimplementedCodeFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnimplementedCodeFixCore.java @@ -78,7 +78,7 @@ public static ICleanUpFixCore createCleanUp(CompilationUnit root, boolean addMis if (addMissingMethod) { ASTNode typeNode= getSelectedTypeNode(root, problem); if (typeNode != null && !isTypeBindingNull(typeNode)) { - operations.add(new AddUnimplementedMethodsOperation(typeNode)); + operations.add(new AddUnimplementedMethodsOperation(typeNode, null)); } } else { ASTNode typeNode= getSelectedTypeNode(root, problem); @@ -108,7 +108,7 @@ public static IProposableFix createAddUnimplementedMethodsFix(final CompilationU if (isTypeBindingNull(typeNode)) return null; - AddUnimplementedMethodsOperation operation= new AddUnimplementedMethodsOperation(typeNode); + AddUnimplementedMethodsOperation operation= new AddUnimplementedMethodsOperation(typeNode, null); if (operation.getMethodsToImplement().length > 0) { return new UnimplementedCodeFixCore(CorrectionMessages.UnimplementedMethodsCorrectionProposal_description, root, new CompilationUnitRewriteOperation[] { operation }); } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnusedCodeFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnusedCodeFixCore.java index cfe292e8..f7d69fcb 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnusedCodeFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnusedCodeFixCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 IBM Corporation and others. + * Copyright (c) 2019, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15,11 +15,18 @@ package org.eclipse.jdt.internal.corext.fix; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; import java.util.Hashtable; import java.util.LinkedHashSet; import java.util.List; import java.util.ListIterator; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.function.Predicate; import org.eclipse.core.runtime.CoreException; @@ -27,6 +34,7 @@ import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTMatcher; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.Assignment; @@ -36,11 +44,14 @@ import org.eclipse.jdt.core.dom.ClassInstanceCreation; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.ConditionalExpression; +import org.eclipse.jdt.core.dom.CreationReference; import org.eclipse.jdt.core.dom.EnhancedForStatement; import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ExpressionMethodReference; import org.eclipse.jdt.core.dom.ExpressionStatement; import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.ForStatement; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; @@ -50,6 +61,8 @@ import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.MethodReference; +import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.NodeFinder; import org.eclipse.jdt.core.dom.ParenthesizedExpression; import org.eclipse.jdt.core.dom.PostfixExpression; @@ -62,6 +75,7 @@ import org.eclipse.jdt.core.dom.TagElement; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclarationStatement; +import org.eclipse.jdt.core.dom.TypeMethodReference; import org.eclipse.jdt.core.dom.VariableDeclarationExpression; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.dom.VariableDeclarationStatement; @@ -74,6 +88,7 @@ import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder; +import org.eclipse.jdt.internal.corext.dom.ReplaceRewrite; import org.eclipse.jdt.internal.corext.dom.StatementRewrite; import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; import org.eclipse.jdt.internal.corext.util.Messages; @@ -184,6 +199,57 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore } } + public static class RemoveUnusedParameterOperation extends CompilationUnitRewriteOperation { + private SingleVariableDeclaration parameter; + private String newName; + + public RemoveUnusedParameterOperation(SingleVariableDeclaration parameter, String newName) { + this.parameter= parameter; + this.newName= newName; + } + + @Override + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore linkedModel) throws CoreException { + // find the corresponding name in the AST computed for rewrite + SingleVariableDeclaration declaration= (SingleVariableDeclaration) NodeFinder.perform(cuRewrite.getRoot(), parameter.getStartPosition(), parameter.getLength()); + TextEditGroup group= createTextEditGroup(FixMessages.UnusedCodeFix_RemoveUnusedMethodParameter_description, cuRewrite); + + + MethodDeclaration method= ASTNodes.getTypedAncestor(parameter, MethodDeclaration.class); + + int argumentIndex= method.parameters().indexOf(declaration); + + SimpleName[] linkedNodes= LinkedNodeFinder.findByBinding(cuRewrite.getRoot(), method.resolveBinding()); + for (SimpleName linkedName : linkedNodes) { + ASTNode parent= linkedName.getParent(); + if (parent.getNodeType() == ASTNode.METHOD_INVOCATION) { + MethodInvocation invocation= (MethodInvocation) parent; + ASTNode argument= (ASTNode) invocation.arguments().get(argumentIndex); + cuRewrite.getASTRewrite().remove(argument, group); + } + if (!linkedName.getFullyQualifiedName().equals(newName)) { + SimpleName newNameNode= linkedName.getAST().newSimpleName(newName); + cuRewrite.getASTRewrite().replace(linkedName, newNameNode, group); + } + } + + + } + } + + + private static void removeParamTag(ASTRewrite rewrite, SingleVariableDeclaration varDecl, TextEditGroup group) { + if (varDecl.getParent() instanceof MethodDeclaration) { + Javadoc javadoc= ((MethodDeclaration) varDecl.getParent()).getJavadoc(); + if (javadoc != null) { + TagElement tagElement= JavadocTagsSubProcessorCore.findParamTag(javadoc, varDecl.getName().getIdentifier()); + if (tagElement != null) { + rewrite.remove(tagElement, group); + } + } + } + } + public static class RemoveUnusedMemberOperation extends CompilationUnitRewriteOperation { private final SimpleName[] fUnusedNames; @@ -259,20 +325,9 @@ private String getDisplayString(IBinding binding) { } } - private void removeParamTag(ASTRewrite rewrite, SingleVariableDeclaration varDecl, TextEditGroup group) { - if (varDecl.getParent() instanceof MethodDeclaration) { - Javadoc javadoc= ((MethodDeclaration) varDecl.getParent()).getJavadoc(); - if (javadoc != null) { - TagElement tagElement= JavadocTagsSubProcessorCore.findParamTag(javadoc, varDecl.getName().getIdentifier()); - if (tagElement != null) { - rewrite.remove(tagElement, group); - } - } - } - } - /** * Remove the field or variable declaration including the initializer. + * * @param rewrite the AST rewriter to use * @param reference a reference to the variable to remove * @param group the text edit group to use @@ -294,7 +349,7 @@ private void removeVariableReferences(ASTRewrite rewrite, SimpleName reference, ASTNode assignParent= assignment.getParent(); if (assignParent.getNodeType() == ASTNode.EXPRESSION_STATEMENT && rightHand.getNodeType() != ASTNode.ASSIGNMENT) { removeVariableWithInitializer(rewrite, rightHand, assignParent, group); - } else { + } else { rewrite.replace(assignment, rewrite.createCopyTarget(rightHand), group); } } else if (nameParentType == ASTNode.SINGLE_VARIABLE_DECLARATION) { @@ -366,6 +421,16 @@ private void removeVariableReferences(ASTRewrite rewrite, SimpleName reference, return; } if (sideEffectInitializer) { + if (varDecl.getLocationInParent() == ForStatement.INITIALIZERS_PROPERTY) { + Expression[] exps= new Expression[sideEffects.size()]; + for (int i= 0; i < exps.length; i++) { + Expression sideEffect= sideEffects.get(i); + Expression movedInit= (Expression) rewrite.createMoveTarget(sideEffect); + exps[i]= movedInit; + } + ReplaceRewrite replaceRewrite= ReplaceRewrite.create(rewrite, new ASTNode[] { varDecl }); + replaceRewrite.replace(exps, group); + } else { Statement[] wrapped= new Statement[sideEffects.size()]; for (int i= 0; i < wrapped.length; i++) { Expression sideEffect= sideEffects.get(i); @@ -374,6 +439,7 @@ private void removeVariableReferences(ASTRewrite rewrite, SimpleName reference, } StatementRewrite statementRewrite= new StatementRewrite(rewrite, new ASTNode[] { varDecl }); statementRewrite.replace(wrapped, group); + } } else { rewrite.remove(varDecl, group); } @@ -383,7 +449,7 @@ private void removeVariableReferences(ASTRewrite rewrite, SimpleName reference, return; } //multiple declarations in one line - ASTNode declaration = parent.getParent(); + ASTNode declaration= parent.getParent(); if (declaration instanceof FieldDeclaration) { rewrite.remove(frag, group); return; @@ -395,13 +461,13 @@ private void removeVariableReferences(ASTRewrite rewrite, SimpleName reference, } if (declaration instanceof VariableDeclarationExpression) { //keep constructors and method invocations - if (!sideEffectInitializer){ + if (!sideEffectInitializer) { rewrite.remove(frag, group); } } } } else if (nameParentType == ASTNode.POSTFIX_EXPRESSION || nameParentType == ASTNode.PREFIX_EXPRESSION) { - Expression expression= (Expression)parent; + Expression expression= (Expression) parent; ASTNode expressionParent= expression.getParent(); if (expressionParent.getNodeType() == ASTNode.EXPRESSION_STATEMENT) { removeStatement(rewrite, expressionParent, group); @@ -455,7 +521,7 @@ private void splitUpDeclarations(ASTRewrite rewrite, TextEditGroup group, Variab VariableDeclarationStatement newDeclaration= null; List fragments= originalStatement.fragments(); int fragIndex= fragments.indexOf(frag); - ListIterator fragmentIterator= fragments.listIterator(fragIndex+1); + ListIterator fragmentIterator= fragments.listIterator(fragIndex + 1); while (fragmentIterator.hasNext()) { VariableDeclarationFragment currentFragment= fragmentIterator.next(); VariableDeclarationFragment movedFragment= (VariableDeclarationFragment) rewrite.createMoveTarget(currentFragment); @@ -467,9 +533,9 @@ private void splitUpDeclarations(ASTRewrite rewrite, TextEditGroup group, Variab newDeclaration.fragments().add(movedFragment); } } - if (newDeclaration != null){ + if (newDeclaration != null) { statementRewrite.insertAfter(newDeclaration, previousStatement, group); - if (originalStatement.fragments().size() == newDeclaration.fragments().size() + 1){ + if (originalStatement.fragments().size() == newDeclaration.fragments().size() + 1) { rewrite.remove(originalStatement, group); } } @@ -487,8 +553,13 @@ private void removeVariableWithInitializer(ASTRewrite rewrite, ASTNode initializ removeStatement(rewrite, statementNode, group); fRemovedAssignmentsCount++; } else { - ASTNode initNode = rewrite.createMoveTarget(initializerNode); - ExpressionStatement statement = rewrite.getAST().newExpressionStatement((Expression) initNode); + // Can't create a field access expression statement so remove right-hand field accesses + ASTNode nodeToMove= initializerNode; + while (nodeToMove instanceof FieldAccess) { + nodeToMove= ((FieldAccess) nodeToMove).getExpression(); + } + ASTNode initNode= rewrite.createMoveTarget(nodeToMove); + ExpressionStatement statement= rewrite.getAST().newExpressionStatement((Expression) initNode); rewrite.replace(statementNode, statement, null); fAlteredAssignmentsCount++; } @@ -504,7 +575,7 @@ private void removeStatement(ASTRewrite rewrite, ASTNode statementNode, TextEdit @Override public String getAdditionalInfo() { - StringBuilder sb=new StringBuilder(); + StringBuilder sb= new StringBuilder(); if (fRemovedAssignmentsCount == 1) { sb.append(FixMessages.UnusedCodeFix_RemoveFieldOrLocal_RemovedAssignments_preview_singular); } else if (fRemovedAssignmentsCount > 1) { @@ -515,7 +586,7 @@ public String getAdditionalInfo() { } else if (fAlteredAssignmentsCount > 1) { sb.append(Messages.format(FixMessages.UnusedCodeFix_RemoveFieldOrLocal_AlteredAssignments_preview_plural, String.valueOf(fAlteredAssignmentsCount))); } - if (sb.length()>0) { + if (sb.length() > 0) { return sb.toString(); } else return null; @@ -546,6 +617,21 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore } } + Expression exp= cast; + while (exp.getParent() instanceof ParenthesizedExpression) { + exp= (Expression)exp.getParent(); + } + if (exp.getLocationInParent() == Assignment.RIGHT_HAND_SIDE_PROPERTY) { + Assignment assignment= (Assignment)exp.getParent(); + if (assignment.getLocationInParent() == ExpressionStatement.EXPRESSION_PROPERTY) { + ExpressionStatement stmt= (ExpressionStatement)assignment.getParent(); + Expression lexp= assignment.getLeftHandSide(); + if (lexp.subtreeMatch(new ASTMatcher(), expression)) { + rewrite.remove(stmt, group); + return; + } + } + } replaceCast(cast, expression, rewrite, group); } } @@ -597,6 +683,22 @@ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore } } + Expression exp= castExpression; + while (exp.getParent() instanceof ParenthesizedExpression) { + exp= (Expression)exp.getParent(); + } + if (exp.getLocationInParent() == Assignment.RIGHT_HAND_SIDE_PROPERTY) { + Assignment assignment= (Assignment)exp.getParent(); + if (assignment.getLocationInParent() == ExpressionStatement.EXPRESSION_PROPERTY) { + ExpressionStatement stmt= (ExpressionStatement)assignment.getParent(); + Expression lexp= assignment.getLeftHandSide(); + if (lexp.subtreeMatch(new ASTMatcher(), downChild)) { + rewrite.remove(stmt, group); + continue; + } + } + } + // downChild is the innermost CastExpression's expression, stripped of a necessary surrounding ParenthesizedExpression // Move either downChild (if it doesn't need parentheses), or a parenthesized version if necessary @@ -613,7 +715,7 @@ public static UnusedCodeFixCore createRemoveUnusedImportFix(CompilationUnit comp RemoveImportOperation operation= new RemoveImportOperation(node); Map options= new Hashtable<>(); options.put(CleanUpConstants.REMOVE_UNUSED_CODE_IMPORTS, CleanUpOptionsCore.TRUE); - return new UnusedCodeFixCore(label, compilationUnit, new CompilationUnitRewriteOperation[] {operation}, options); + return new UnusedCodeFixCore(label, compilationUnit, new CompilationUnitRewriteOperation[] { operation }, options); } } return null; @@ -642,6 +744,35 @@ public static UnusedCodeFixCore createUnusedMemberFix(CompilationUnit compilatio return null; } + public static UnusedCodeFixCore createUnusedParameterFix(CompilationUnit compilationUnit, IProblemLocationCore problem) { + if (isUnusedParameter(problem)) { + SimpleName name= getUnusedName(compilationUnit, problem); + if (name != null) { + SingleVariableDeclaration parameter= ASTNodes.getTypedAncestor(name, SingleVariableDeclaration.class); + IBinding binding= name.resolveBinding(); + + MethodDeclaration method= ASTNodes.getTypedAncestor(parameter, MethodDeclaration.class); + if (method != null) { + IMethodBinding methodBinding= method.resolveBinding(); + if (methodBinding != null && Modifier.isPrivate(methodBinding.getModifiers())) { + MethodReferenceFinder refFinder= new MethodReferenceFinder(methodBinding); + method.getRoot().accept(refFinder); + + if (!refFinder.hasReference()) { + String newName= findSafeRename(method, methodBinding, Arrays.asList(name)); + String label= Messages.format(FixMessages.UnusedCodeFix_RemoveParameter_description, name); + RemoveUnusedMemberOperation removeUsagesOperation= new RemoveUnusedMemberOperation(new SimpleName[] { name }, false); + RemoveUnusedParameterOperation removeInvocationsOperation= new RemoveUnusedParameterOperation(parameter, newName); + return new UnusedCodeFixCore(label, compilationUnit, new CompilationUnitRewriteOperation[] { removeInvocationsOperation, removeUsagesOperation }, + getCleanUpOptions(binding, false)); + } + } + } + } + } + return null; + } + public static UnusedCodeFixCore createUnusedTypeParameterFix(CompilationUnit compilationUnit, IProblemLocationCore problemLoc) { if (problemLoc.getProblemId() == IProblem.UnusedTypeParameter) { SimpleName name= getUnusedName(compilationUnit, problemLoc); @@ -660,7 +791,11 @@ public static UnusedCodeFixCore createUnusedTypeParameterFix(CompilationUnit com public static boolean isUnusedMember(IProblemLocationCore problem) { int id= problem.getProblemId(); return id == IProblem.UnusedPrivateMethod || id == IProblem.UnusedPrivateConstructor || id == IProblem.UnusedPrivateField || id == IProblem.UnusedPrivateType - || id == IProblem.LocalVariableIsNeverUsed || id == IProblem.ArgumentIsNeverUsed; + || id == IProblem.LocalVariableIsNeverUsed; + } + + public static boolean isUnusedParameter(IProblemLocationCore problem) { + return problem.getProblemId() == IProblem.ArgumentIsNeverUsed; } public static UnusedCodeFixCore createRemoveUnusedCastFix(CompilationUnit compilationUnit, IProblemLocationCore problem) { @@ -674,7 +809,7 @@ public static UnusedCodeFixCore createRemoveUnusedCastFix(CompilationUnit compil if (!(curr instanceof CastExpression)) return null; - return new UnusedCodeFixCore(FixMessages.UnusedCodeFix_RemoveCast_description, compilationUnit, new CompilationUnitRewriteOperation[] {new RemoveCastOperation((CastExpression)curr)}); + return new UnusedCodeFixCore(FixMessages.UnusedCodeFix_RemoveCast_description, compilationUnit, new CompilationUnitRewriteOperation[] { new RemoveCastOperation((CastExpression) curr) }); } public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, @@ -684,7 +819,8 @@ public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, boolean removeUnusedPrivateTypes, boolean removeUnusedLocalVariables, boolean removeUnusedImports, - boolean removeUnusedCast) { + boolean removeUnusedCast, + boolean removeUnusedParameter) { IProblem[] problems= compilationUnit.getProblems(); IProblemLocationCore[] locations= new IProblemLocationCore[problems.length]; @@ -699,7 +835,44 @@ public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, removeUnusedPrivateTypes, removeUnusedLocalVariables, removeUnusedImports, - removeUnusedCast); + removeUnusedCast, + removeUnusedParameter); + } + + private static class MethodReferenceFinder extends ASTVisitor { + private IMethodBinding binding; + private boolean hasReference= false; + + public MethodReferenceFinder(IMethodBinding binding) { + this.binding= binding; + } + + private boolean markMethodReference(MethodReference ref) { + if (ref.resolveMethodBinding() == binding) { + this.hasReference= true; + return false; + } + return true; + } + + public boolean hasReference() { + return hasReference; + } + + @Override + public boolean visit(CreationReference node) { + return markMethodReference(node); + } + + @Override + public boolean visit(ExpressionMethodReference node) { + return markMethodReference(node); + } + + @Override + public boolean visit(TypeMethodReference node) { + return markMethodReference(node); + } } public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, IProblemLocationCore[] problems, @@ -709,17 +882,19 @@ public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, IPr boolean removeUnusedPrivateTypes, boolean removeUnusedLocalVariables, boolean removeUnusedImports, - boolean removeUnusedCast) { + boolean removeUnusedCast, + boolean removeUnusedParameter) { List result= new ArrayList<>(); Hashtable> variableDeclarations= new Hashtable<>(); LinkedHashSet unnecessaryCasts= new LinkedHashSet<>(); + Set removedMembers= new HashSet<>(); + Map> parametersToRemove= new HashMap<>(); for (IProblemLocationCore problem : problems) { int id= problem.getProblemId(); if (removeUnusedImports && (id == IProblem.UnusedImport || id == IProblem.DuplicateImport || id == IProblem.ConflictingImport || - id == IProblem.CannotImportPackage || id == IProblem.ImportNotFound)) - { + id == IProblem.CannotImportPackage || id == IProblem.ImportNotFound)) { ImportDeclaration node= UnusedCodeFixCore.getImportDeclaration(problem, compilationUnit); if (node != null) { result.add(new RemoveImportOperation(node)); @@ -727,18 +902,19 @@ public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, IPr } if ((removeUnusedPrivateMethods && id == IProblem.UnusedPrivateMethod) || (removeUnusedPrivateConstructors && id == IProblem.UnusedPrivateConstructor) || - (removeUnusedPrivateTypes && id == IProblem.UnusedPrivateType)) { + (removeUnusedPrivateTypes && id == IProblem.UnusedPrivateType)) { SimpleName name= getUnusedName(compilationUnit, problem); if (name != null) { IBinding binding= name.resolveBinding(); if (binding != null) { - result.add(new RemoveUnusedMemberOperation(new SimpleName[] {name}, false)); + removedMembers.add(name); + result.add(new RemoveUnusedMemberOperation(new SimpleName[] { name }, false)); } } } - if ((removeUnusedLocalVariables && id == IProblem.LocalVariableIsNeverUsed) || (removeUnusedPrivateFields && id == IProblem.UnusedPrivateField)) { + if ((removeUnusedLocalVariables && id == IProblem.LocalVariableIsNeverUsed) || (removeUnusedPrivateFields && id == IProblem.UnusedPrivateField)) { SimpleName name= getUnusedName(compilationUnit, problem); if (name != null) { IBinding binding= name.resolveBinding(); @@ -751,7 +927,7 @@ public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, IPr } variableDeclarations.get(varDecl).add(name); } else { - result.add(new RemoveUnusedMemberOperation(new SimpleName[] {name}, false)); + result.add(new RemoveUnusedMemberOperation(new SimpleName[] { name }, false)); } } } @@ -766,6 +942,12 @@ public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, IPr unnecessaryCasts.add((CastExpression) curr); } } + + if (removeUnusedParameter && id == IProblem.ArgumentIsNeverUsed) { + SimpleName parameter= getUnusedName(compilationUnit, problem); + MethodDeclaration method= ASTNodes.getTypedAncestor(parameter, MethodDeclaration.class); + parametersToRemove.computeIfAbsent(method, (MethodDeclaration key) -> new LinkedHashSet<>()).add(parameter); + } } for (List names : variableDeclarations.values()) { result.add(new RemoveUnusedMemberOperation(names.toArray(new SimpleName[0]), false)); @@ -773,12 +955,95 @@ public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit, IPr if (unnecessaryCasts.size() > 0) result.add(new RemoveAllCastOperation(unnecessaryCasts)); + for (Entry> entry : parametersToRemove.entrySet()) { + MethodDeclaration method= entry.getKey(); + IMethodBinding methodBinding= method.resolveBinding(); + if (methodBinding != null) { + Set namesToRemove= entry.getValue(); + + // make sure the method is not used in a reference like Foo::bar + MethodReferenceFinder refFinder= new MethodReferenceFinder(methodBinding); + method.getRoot().accept(refFinder); + + if (!refFinder.hasReference()) { + String newName= findSafeRename(method, methodBinding, namesToRemove); + + for (SimpleName parameterName : entry.getValue()) { + SingleVariableDeclaration parameter= ASTNodes.getTypedAncestor(parameterName, SingleVariableDeclaration.class); + if (Modifier.isPrivate(methodBinding.getModifiers()) && !removedMembers.contains(method.getName())) { + result.add(new RemoveUnusedMemberOperation(new SimpleName[] { parameterName }, false)); + result.add(new RemoveUnusedParameterOperation(parameter, newName)); + } + } + } + } + + } + if (result.isEmpty()) return null; return new UnusedCodeFixCore(FixMessages.UnusedCodeFix_change_name, compilationUnit, result.toArray(new CompilationUnitRewriteOperation[result.size()])); } + /* + * If removing parameters from a method creates a conflict with other methods, find + * a new name for the method that will not conflict. + * Returns that original name if no conflict is found + */ + private static String findSafeRename(MethodDeclaration method, IMethodBinding methodBinding, Collection namesToRemove) { + int newParameterCount= method.parameters().size() - namesToRemove.size(); + + Set potentialConflicts= new HashSet<>(); + + walkVisibleMethods(methodBinding.getDeclaringClass(), m -> { + if (Modifier.isPrivate(m.getModifiers()) && m.getDeclaringClass() != methodBinding.getDeclaringClass()) { + // it's a private method not in the class we're cleaning up, so not a problem + return true; + } + if (m.getName().startsWith(methodBinding.getName()) && m.getParameterTypes().length == newParameterCount) { + // this method may conflict with a rename we might propose + potentialConflicts.add(m.getName()); + } + return true; + }); + int i= 1; + String newMethodName = methodBinding.getName(); + while (potentialConflicts.contains(newMethodName)) { + newMethodName= methodBinding.getName()+i++; + } + return newMethodName; + } + + private static boolean walkVisibleMethods(ITypeBinding clazz, Predicate handler) { + if (clazz == null) { + return true; + } + if (!walkMethodsInType(clazz, handler)) { + return false; + } + + if (!walkVisibleMethods(clazz.getSuperclass(), handler)) { + return false; + } + + for (ITypeBinding itfc : clazz.getInterfaces()) { + if (!walkVisibleMethods(itfc, handler)) { + return false; + } + } + return true; + } + + private static boolean walkMethodsInType(ITypeBinding clazz, Predicate handler) { + for (IMethodBinding method : clazz.getDeclaredMethods()) { + if (!handler.test(method)) { + return false; + } + } + return true; + } + public static boolean isFormalParameterInEnhancedForStatement(SimpleName name) { return name.getParent() instanceof SingleVariableDeclaration && name.getParent().getLocationInParent() == EnhancedForStatement.PARAMETER_PROPERTY; } @@ -808,7 +1073,7 @@ private static boolean hasSideEffect(SimpleName reference) { Assignment assignment= (Assignment) parent; node= assignment.getRightHandSide(); } else if (nameParentType == ASTNode.SINGLE_VARIABLE_DECLARATION) { - SingleVariableDeclaration decl= (SingleVariableDeclaration)parent; + SingleVariableDeclaration decl= (SingleVariableDeclaration) parent; node= decl.getInitializer(); if (node == null) return false; @@ -878,6 +1143,7 @@ public static Map getCleanUpOptions(IBinding binding, boolean re result.put(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_FELDS, CleanUpOptionsCore.TRUE); result.put(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES, CleanUpOptionsCore.TRUE); + result.put(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS, CleanUpOptionsCore.TRUE); break; default: break; @@ -891,7 +1157,7 @@ public static ImportDeclaration getImportDeclaration(IProblemLocationCore proble if (selectedNode != null) { ASTNode node= ASTNodes.getParent(selectedNode, ASTNode.IMPORT_DECLARATION); if (node instanceof ImportDeclaration) { - return (ImportDeclaration)node; + return (ImportDeclaration) node; } } return null; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UpdateProperty.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UpdateProperty.java index 0226c6ac..0c06116c 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UpdateProperty.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UpdateProperty.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2021 IBM Corporation and others. + * Copyright (c) 2021, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -21,13 +21,18 @@ import static org.eclipse.jdt.internal.corext.fix.LibStandardNames.METHOD_GET_DEFAULT; import static org.eclipse.jdt.internal.corext.fix.LibStandardNames.METHOD_GET_PROPERTY; import static org.eclipse.jdt.internal.corext.fix.LibStandardNames.METHOD_GET_SEPARATOR; +import static org.eclipse.jdt.internal.corext.fix.LibStandardNames.METHOD_INTEGER; import static org.eclipse.jdt.internal.corext.fix.LibStandardNames.METHOD_LINE_SEPARATOR; +import static org.eclipse.jdt.internal.corext.fix.LibStandardNames.METHOD_LONG; import static org.eclipse.jdt.internal.corext.fix.LibStandardNames.METHOD_PARSEBOOLEAN; +import static org.eclipse.jdt.internal.corext.fix.LibStandardNames.METHOD_PARSEINTEGER; +import static org.eclipse.jdt.internal.corext.fix.LibStandardNames.METHOD_PARSELONG; import static org.eclipse.jdt.internal.ui.fix.MultiFixMessages.ConstantsCleanUp_description; import java.io.File; import java.nio.charset.Charset; import java.nio.file.FileSystems; +import java.util.List; import java.util.Set; import org.eclipse.core.runtime.CoreException; @@ -41,6 +46,8 @@ import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.NumberLiteral; +import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer; @@ -138,7 +145,41 @@ public enum UpdateProperty { Boolean.class, null, UpdateProperty::parseboolean_visitor, - UpdateProperty::booleanRewrite); + UpdateProperty::boolintlongRewrite), + /** + * Change + * Integer.parseInt(System.getProperty("arbitrarykey")); + * to + * Integer.getInteger("arbitrarykey"); + * + * Currently Integer.parseInt(System.getProperty("arbitrarykey", "false")) is not supported + */ + INTEGER_PROPERTY(null, + null, + METHOD_INTEGER, + null, + Integer.class, + null, + UpdateProperty::parseinteger_visitor, + UpdateProperty::boolintlongRewrite), + /** + * Change + * Long.parseLong(System.getProperty("arbitrarykey")); + * to + * Long.getLong("arbitrarykey"); + * + * Currently Long.parseLong(System.getProperty("arbitrarykey", "false")) is not supported + */ + LONG_PROPERTY(null, + null, + METHOD_LONG, + null, + Long.class, + null, + UpdateProperty::parselong_visitor, + UpdateProperty::boolintlongRewrite); + + public static Object UNUSED= new Object(); String key; Class cl; @@ -180,7 +221,7 @@ public boolean visit(final MethodInvocation visited) { Expression expression= (Expression) visited.arguments().get(0); Object propertykey= expression.resolveConstantExpressionValue(); if (propertykey instanceof String && upp.key.equals(propertykey)) { - operations.add(upp.rewrite(visited, null, expression)); + operations.add(upp.rewrite(visited, null, expression,null)); nodesprocessed.add(visited); return false; } @@ -208,7 +249,66 @@ public boolean visit(final MethodInvocation visited) { if (propertykey instanceof String && visited.getParent() instanceof MethodInvocation) { MethodInvocation parent=(MethodInvocation) visited.getParent(); if (ASTNodes.usesGivenSignature(parent, Boolean.class.getCanonicalName(), METHOD_PARSEBOOLEAN, String.class.getCanonicalName())) { - operations.add(upp.rewrite(parent, (String) propertykey,expression)); + operations.add(upp.rewrite(parent, (String) propertykey,expression, null)); + nodesprocessed.add(visited); + return false; + } + } + } else if (ASTNodes.usesGivenSignature(visited, System.class.getCanonicalName(), METHOD_GET_PROPERTY, String.class.getCanonicalName(), String.class.getCanonicalName())) { + Expression expression= (Expression) visited.arguments().get(0); + Expression expression2= (Expression) visited.arguments().get(1); + Object propertykey= expression.resolveConstantExpressionValue(); + Object propertykey2= expression2.resolveConstantExpressionValue(); + if (propertykey instanceof String && propertykey2 instanceof String && visited.getParent() instanceof MethodInvocation) { + MethodInvocation parent=(MethodInvocation) visited.getParent(); + if (ASTNodes.usesGivenSignature(parent, Boolean.class.getCanonicalName(), METHOD_PARSEBOOLEAN, String.class.getCanonicalName()) && ((String)propertykey2).toLowerCase().equals("false")) { //$NON-NLS-1$ + operations.add(upp.rewrite(parent, (String) propertykey,expression, UNUSED)); + nodesprocessed.add(visited); + return false; + } + } + } + return true; + } + }); + } + + static void parseinteger_visitor(final UpdateProperty upp, final CompilationUnit compilationUnit, final Set operations, final Set nodesprocessed) { + compilationUnit.accept(new ASTVisitor() { + @Override + public boolean visit(final MethodInvocation visited) { + if(nodesprocessed.contains(visited)) { + return false; + } + /** + * look for + * Integer.parseInteger(System.getProperty("arbitrarykey")); + * (has to be done after completing the specific search) + */ + if (ASTNodes.usesGivenSignature(visited, System.class.getCanonicalName(), METHOD_GET_PROPERTY, String.class.getCanonicalName())) { + Expression expression= (Expression) visited.arguments().get(0); + Object propertykey= expression.resolveConstantExpressionValue(); + if (propertykey instanceof String && visited.getParent() instanceof MethodInvocation) { + MethodInvocation parent=(MethodInvocation) visited.getParent(); + if (ASTNodes.usesGivenSignature(parent, Integer.class.getCanonicalName(), METHOD_PARSEINTEGER, String.class.getCanonicalName())) { + operations.add(upp.rewrite(parent, (String) propertykey,expression, null)); + nodesprocessed.add(visited); + return false; + } + } + } else if (ASTNodes.usesGivenSignature(visited, System.class.getCanonicalName(), METHOD_GET_PROPERTY, String.class.getCanonicalName(), String.class.getCanonicalName())) { + Expression expression= (Expression) visited.arguments().get(0); + Expression expression2= (Expression) visited.arguments().get(1); + Object propertykey= expression.resolveConstantExpressionValue(); + Object propertykey2= expression2.resolveConstantExpressionValue(); + if (propertykey instanceof String && propertykey2 instanceof String && visited.getParent() instanceof MethodInvocation) { + MethodInvocation parent=(MethodInvocation) visited.getParent(); + if (ASTNodes.usesGivenSignature(parent, Integer.class.getCanonicalName(), METHOD_PARSEINTEGER, String.class.getCanonicalName())&& ((String)propertykey2).toLowerCase().equals("0")) { //$NON-NLS-1$ + operations.add(upp.rewrite(parent, (String) propertykey,expression, UNUSED)); + nodesprocessed.add(visited); + return false; + } else if (ASTNodes.usesGivenSignature(parent, Integer.class.getCanonicalName(), METHOD_PARSEINTEGER, String.class.getCanonicalName())) { + operations.add(upp.rewrite(parent, (String) propertykey,expression,Integer.valueOf((String)propertykey2))); nodesprocessed.add(visited); return false; } @@ -219,24 +319,69 @@ public boolean visit(final MethodInvocation visited) { }); } + static void parselong_visitor(final UpdateProperty upp, final CompilationUnit compilationUnit, final Set operations, final Set nodesprocessed) { + compilationUnit.accept(new ASTVisitor() { + @Override + public boolean visit(final MethodInvocation visited) { + if(nodesprocessed.contains(visited)) { + return false; + } + /** + * look for + * Integer.parseInteger(System.getProperty("arbitrarykey")); + * (has to be done after completing the specific search) + */ + if (ASTNodes.usesGivenSignature(visited, System.class.getCanonicalName(), METHOD_GET_PROPERTY, String.class.getCanonicalName())) { + Expression expression= (Expression) visited.arguments().get(0); + Object propertykey= expression.resolveConstantExpressionValue(); + if (propertykey instanceof String && visited.getParent() instanceof MethodInvocation) { + MethodInvocation parent=(MethodInvocation) visited.getParent(); + if (ASTNodes.usesGivenSignature(parent, Long.class.getCanonicalName(), METHOD_PARSELONG, String.class.getCanonicalName())) { + operations.add(upp.rewrite(parent, (String) propertykey,expression, null)); + nodesprocessed.add(visited); + return false; + } + } + } else if (ASTNodes.usesGivenSignature(visited, System.class.getCanonicalName(), METHOD_GET_PROPERTY, String.class.getCanonicalName(), String.class.getCanonicalName())) { + Expression expression= (Expression) visited.arguments().get(0); + Expression expression2= (Expression) visited.arguments().get(1); + Object propertykey= expression.resolveConstantExpressionValue(); + Object propertykey2= expression2.resolveConstantExpressionValue(); + if (propertykey instanceof String && propertykey2 instanceof String && visited.getParent() instanceof MethodInvocation) { + MethodInvocation parent=(MethodInvocation) visited.getParent(); + if (ASTNodes.usesGivenSignature(parent, Long.class.getCanonicalName(), METHOD_PARSELONG, String.class.getCanonicalName()) && ((String)propertykey2).toLowerCase().equals("0")) { //$NON-NLS-1$ + operations.add(upp.rewrite(parent, (String) propertykey,expression, UNUSED)); + nodesprocessed.add(visited); + return false; + } else if (ASTNodes.usesGivenSignature(parent, Long.class.getCanonicalName(), METHOD_PARSELONG, String.class.getCanonicalName())) { + operations.add(upp.rewrite(parent, (String) propertykey,expression,Long.valueOf((String)propertykey2))); + nodesprocessed.add(visited); + return false; + } + } + } + return true; + } + }); + } interface IRewriter { void computeRewriter(final UpdateProperty upp,final MethodInvocation visited, final String propertykey, - final Expression expression, final CompilationUnitRewrite cuRewrite, final TextEditGroup group) throws CoreException; + final Expression expression, final CompilationUnitRewrite cuRewrite, final TextEditGroup group, Object object) throws CoreException; } - CompilationUnitRewriteOperation rewrite(final MethodInvocation visited, final String propertykey, final Expression expression) { + CompilationUnitRewriteOperation rewrite(final MethodInvocation visited, final String propertykey, final Expression expression, final Object object) { return new CompilationUnitRewriteOperation() { @Override public void rewriteAST(final CompilationUnitRewrite cuRewrite, final LinkedProposalModelCore linkedModel) throws CoreException { TextEditGroup group= createTextEditGroup(Messages.format(ConstantsCleanUp_description,UpdateProperty.this.toString()), cuRewrite); cuRewrite.getASTRewrite().setTargetSourceRangeComputer(computer); - myrewriter.computeRewriter(UpdateProperty.this, visited, propertykey, expression, cuRewrite, group); + myrewriter.computeRewriter(UpdateProperty.this, visited, propertykey, expression, cuRewrite, group, object); } }; } - private static void booleanRewrite(UpdateProperty upp,final MethodInvocation visited, final String propertykey, Expression expression, final CompilationUnitRewrite cuRewrite, - TextEditGroup group) { + private static void boolintlongRewrite(UpdateProperty upp,final MethodInvocation visited, final String propertykey, Expression expression, final CompilationUnitRewrite cuRewrite, + TextEditGroup group, Object object) throws CoreException { ASTRewrite rewrite= cuRewrite.getASTRewrite(); AST ast= cuRewrite.getRoot().getAST(); /** @@ -250,13 +395,27 @@ private static void booleanRewrite(UpdateProperty upp,final MethodInvocation vis MethodInvocation newMethodInvocation= ast.newMethodInvocation(); newMethodInvocation.setExpression(ASTNodeFactory.newName(ast, upp.alternativecl.getSimpleName())); newMethodInvocation.setName(ast.newSimpleName(upp.simplename)); - newMethodInvocation.arguments().add(ASTNodes.createMoveTarget(cuRewrite.getASTRewrite(), ASTNodes.getUnparenthesedExpression(expression))); - ASTNode replace_with_Call= newMethodInvocation; - ASTNodes.replaceButKeepComment(rewrite, visited, replace_with_Call, group); + List arguments= newMethodInvocation.arguments(); + if (object != null) { + StringLiteral sl= ast.newStringLiteral(); + sl.setLiteralValue(propertykey); + arguments.add(sl); + if (object != UNUSED) { + NumberLiteral newNumberLiteral= ast.newNumberLiteral(); + newNumberLiteral.setToken(object.toString()); + arguments.add(newNumberLiteral); + } + ASTNode replace_with_Call= newMethodInvocation; + ASTNodes.replaceAndRemoveNLS(rewrite, visited, replace_with_Call, group, cuRewrite); + } else { + arguments.add(ASTNodes.createMoveTarget(cuRewrite.getASTRewrite(), ASTNodes.getUnparenthesedExpression(expression))); + ASTNode replace_with_Call= newMethodInvocation; + ASTNodes.replaceButKeepComment(rewrite, visited, replace_with_Call, group); + } } private static void defaultRewrite(UpdateProperty upp, final MethodInvocation visited, final String propertykey, Expression expression, - final CompilationUnitRewrite cuRewrite,final TextEditGroup group) throws CoreException { + final CompilationUnitRewrite cuRewrite,final TextEditGroup group, Object object) throws CoreException { ASTRewrite rewrite= cuRewrite.getASTRewrite(); AST ast= cuRewrite.getRoot().getAST(); ASTNode replace_with_Call; @@ -314,7 +473,7 @@ private static void defaultRewrite(UpdateProperty upp, final MethodInvocation vi } private static void pathRewrite(UpdateProperty upp, final MethodInvocation visited, final String propertykey, Expression expression, - final CompilationUnitRewrite cuRewrite,final TextEditGroup group) throws CoreException { + final CompilationUnitRewrite cuRewrite,final TextEditGroup group, Object object) throws CoreException { ASTRewrite rewrite= cuRewrite.getASTRewrite(); AST ast= cuRewrite.getRoot().getAST(); ASTNode replace_with_Call; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UseIteratorToForLoopFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UseIteratorToForLoopFixCore.java new file mode 100644 index 00000000..732bb05a --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UseIteratorToForLoopFixCore.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.fix; + +import java.util.Set; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; + +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation; +import org.eclipse.jdt.internal.corext.fix.helper.AbstractTool; +import org.eclipse.jdt.internal.corext.fix.helper.WhileLoopToChangeHit; +import org.eclipse.jdt.internal.corext.fix.helper.WhileToForEach; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; +import org.eclipse.jdt.internal.corext.refactoring.util.TightSourceRangeComputer; + +import org.eclipse.jdt.internal.ui.fix.MultiFixMessages; + +public enum UseIteratorToForLoopFixCore { + + LOOP(new WhileToForEach()); + + AbstractTool iteratortofor; + + @SuppressWarnings("unchecked") + UseIteratorToForLoopFixCore(AbstractTool explicitencoding) { + this.iteratortofor= (AbstractTool) explicitencoding; + } + + public String getPreview(boolean i) { + return iteratortofor.getPreview(i); + } + + /** + * Compute set of CompilationUnitRewriteOperation to refactor supported situations + * + * @param compilationUnit unit to search in + * @param operations set of all CompilationUnitRewriteOperations created already + * @param nodesprocessed list to remember nodes already processed + * @param createForOnlyIfVarUsed true if for loop should be created only only if loop var used within + */ + public void findOperations(final CompilationUnit compilationUnit, final Set operations, + final Set nodesprocessed, boolean createForOnlyIfVarUsed) { + iteratortofor.find(this, compilationUnit, operations, nodesprocessed, createForOnlyIfVarUsed); + } + + public CompilationUnitRewriteOperation rewrite(final WhileLoopToChangeHit hit) { + return new CompilationUnitRewriteOperation() { + @Override + public void rewriteAST(final CompilationUnitRewrite cuRewrite, final LinkedProposalModelCore linkedModel) throws CoreException { + TextEditGroup group= createTextEditGroup(MultiFixMessages.Java50CleanUp_ConvertToEnhancedForLoop_description, cuRewrite); + TightSourceRangeComputer rangeComputer; + ASTRewrite rewrite= cuRewrite.getASTRewrite(); + if (rewrite.getExtendedSourceRangeComputer() instanceof TightSourceRangeComputer) { + rangeComputer= (TightSourceRangeComputer)rewrite.getExtendedSourceRangeComputer(); + } else { + rangeComputer= new TightSourceRangeComputer(); + } + rangeComputer.addTightSourceNode(hit.whileStatement); + rewrite.setTargetSourceRangeComputer(rangeComputer); + iteratortofor.rewrite(UseIteratorToForLoopFixCore.this, hit, cuRewrite, group); + } + }; + } + +} diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ValueOfRatherThanInstantiationFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ValueOfRatherThanInstantiationFixCore.java index 7cbd897c..6f3f6115 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ValueOfRatherThanInstantiationFixCore.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ValueOfRatherThanInstantiationFixCore.java @@ -29,6 +29,7 @@ import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.ParenthesizedExpression; import org.eclipse.jdt.core.dom.PrimitiveType; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer; @@ -74,7 +75,8 @@ public boolean visit(final ClassInstanceCreation visited) { ITypeBinding destinationTypeBinding= ASTNodes.getTargetType(visited); if (destinationTypeBinding != null - && destinationTypeBinding.isPrimitive()) { + && destinationTypeBinding.isPrimitive() + && !ASTNodes.hasType(arg0, String.class.getCanonicalName())) { fResult.add(new ValueOfRatherThanInstantiationWithTheSingleArgumentFixOperation(visited)); return false; } @@ -121,10 +123,40 @@ public SourceRange computeSourceRange(final ASTNode nodeWithComment) { MethodInvocation valueOfMethod= ast.newMethodInvocation(); valueOfMethod.setExpression(ASTNodeFactory.newName(ast, typeBinding.getName())); valueOfMethod.setName(ast.newSimpleName("valueOf")); //$NON-NLS-1$ - CastExpression newCastExpression= ast.newCastExpression(); - newCastExpression.setType(ast.newPrimitiveType(PrimitiveType.FLOAT)); - newCastExpression.setExpression(ASTNodes.createMoveTarget(rewrite, ASTNodes.getUnparenthesedExpression(arg0))); - valueOfMethod.arguments().add(newCastExpression); + + // remove all casts and parentheses from the argument + Expression newArgument= arg0; + while (true) { + if (newArgument instanceof CastExpression) { + newArgument= ((CastExpression) newArgument).getExpression(); + continue; + } + if (newArgument instanceof ParenthesizedExpression) { + newArgument= ((ParenthesizedExpression) newArgument).getExpression(); + continue; + } + break; + } + + if (!ASTNodes.hasType(newArgument, float.class.getSimpleName())) { + CastExpression newCastExpression= ast.newCastExpression(); + newCastExpression.setType(ast.newPrimitiveType(PrimitiveType.FLOAT)); + + Expression moveTarget= ASTNodes.createMoveTarget(rewrite, newArgument); + + if (newArgument.getNodeType() == ASTNode.INFIX_EXPRESSION || newArgument.getNodeType() == ASTNode.ASSIGNMENT) { + // those expressions could be numeric and have less precedence than a cast, so need to put parens + ParenthesizedExpression parens= ast.newParenthesizedExpression(); + parens.setExpression(moveTarget); + moveTarget= parens; + } + + newCastExpression.setExpression(moveTarget); + newArgument= newCastExpression; + } + valueOfMethod.arguments().add(newArgument); + + ASTNodes.replaceButKeepComment(rewrite, visited, valueOfMethod, group); } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/AbstractTool.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/AbstractTool.java new file mode 100644 index 00000000..15c6eb86 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/AbstractTool.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.fix.helper; + +import java.util.Collection; +import java.util.Set; + +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.Name; + +import org.eclipse.jdt.internal.corext.dom.AbortSearchException; +import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation; +import org.eclipse.jdt.internal.corext.fix.UseIteratorToForLoopFixCore; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; + +/** + * @param Type found in Visitor + */ +public abstract class AbstractTool { + + protected static boolean isOfType(ITypeBinding typeBinding, String typename) { + if (typeBinding == null) { + throw new AbortSearchException(); + } + if (typeBinding.isArray()) { + typeBinding= typeBinding.getElementType(); + } + return typeBinding.getQualifiedName().equals(typename); + } + + public abstract void find(UseIteratorToForLoopFixCore fixcore, CompilationUnit compilationUnit, Set operations, + Set nodesprocessed, boolean createForIfVarNotUsed); + + public abstract void rewrite(UseIteratorToForLoopFixCore useExplicitEncodingFixCore, T holder, CompilationUnitRewrite cuRewrite, + TextEditGroup group); + + /** + * Adds an import to the class. This method should be used for every class reference added to + * the generated code. + * + * @param typeName a fully qualified name of a type + * @param cuRewrite CompilationUnitRewrite + * @param ast AST + * @return simple name of a class if the import was added and fully qualified name if there was + * a conflict + */ + protected Name addImport(String typeName, final CompilationUnitRewrite cuRewrite, AST ast) { + String importedName= cuRewrite.getImportRewrite().addImport(typeName); + return ast.newName(importedName); + } + + + public abstract String getPreview(boolean afterRefactoring); + + public static Collection getUsedVariableNames(ASTNode node) { + CompilationUnit root= (CompilationUnit) node.getRoot(); + Collection res= (new ScopeAnalyzer(root)).getUsedVariableNames(node.getStartPosition(), node.getLength()); + return res; + } +} diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/WhileLoopToChangeHit.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/WhileLoopToChangeHit.java new file mode 100644 index 00000000..fcb92d9c --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/WhileLoopToChangeHit.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.fix.helper; + +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.eclipse.jdt.core.dom.WhileStatement; + +public class WhileLoopToChangeHit { + + public boolean self; + public VariableDeclarationStatement iteratorDeclaration; + public Statement iteratorCall; + public Expression collectionExpression; + public String loopVarName; + public MethodInvocation loopVarDeclaration; + public WhileStatement whileStatement; + public boolean nextWithoutVariableDeclaration; + public boolean nextFound; + public String iteratorName; + public boolean isInvalid; + + public WhileLoopToChangeHit(boolean isInvalid) { + this.isInvalid= isInvalid; + } + + public WhileLoopToChangeHit() { + + } + +} diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/WhileToForEach.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/WhileToForEach.java new file mode 100644 index 00000000..fad20cf8 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/helper/WhileToForEach.java @@ -0,0 +1,535 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + * Red Hat Inc. - additional support + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.fix.helper; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.Assignment; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.EnhancedForStatement; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ExpressionStatement; +import org.eclipse.jdt.core.dom.IBinding; +import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.IVariableBinding; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.Name; +import org.eclipse.jdt.core.dom.ParameterizedType; +import org.eclipse.jdt.core.dom.ParenthesizedExpression; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; +import org.eclipse.jdt.core.dom.ThisExpression; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.eclipse.jdt.core.dom.WhileStatement; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation; + +import org.eclipse.jdt.internal.common.HelperVisitor; +import org.eclipse.jdt.internal.common.ReferenceHolder; +import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; +import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.dom.AbortSearchException; +import org.eclipse.jdt.internal.corext.dom.Bindings; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation; +import org.eclipse.jdt.internal.corext.fix.ConvertLoopOperation; +import org.eclipse.jdt.internal.corext.fix.UseIteratorToForLoopFixCore; +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; +import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRemover; + +/** + * Find: while (it.hasNext()){ System.out.println(it.next()); } + * + * Rewrite: for(Object o:collection) { System.out.println(o); }); + * + */ +public class WhileToForEach extends AbstractTool { + + @Override + public void find(UseIteratorToForLoopFixCore fixcore, CompilationUnit compilationUnit, + Set operations, Set nodesprocessed, boolean createForOnlyIfVarUsed) { + ReferenceHolder dataholder= new ReferenceHolder<>(); + Map operationsMap= new LinkedHashMap<>(); + WhileLoopToChangeHit invalidHit= new WhileLoopToChangeHit(true); + HelperVisitor.callVariableDeclarationStatementVisitor(Iterator.class, compilationUnit, dataholder, nodesprocessed, (init_iterator, holder_a) -> { + List computeVarName= computeVarName(init_iterator); + MethodInvocation iteratorCall= computeIteratorCall(init_iterator); + if (computeVarName != null && iteratorCall != null) { + Statement iteratorAssignment= ASTNodes.getFirstAncestorOrNull(iteratorCall, Statement.class); + HelperVisitor.callWhileStatementVisitor(init_iterator.getParent(), dataholder, nodesprocessed, (whilestatement, holder) -> { + String name= computeNextVarname(whilestatement); + if (computeVarName.get(0).equals(name) && iteratorCall.getStartPosition() < whilestatement.getStartPosition()) { + final HelperVisitor, ASTNode, WhileLoopToChangeHit> helperVisitor= holder.getHelperVisitor(); + if (helperVisitor.nodesprocessed.size() > 0) { + boolean invalidated= false; + for (ASTNode astNode : helperVisitor.nodesprocessed) { + WhileLoopToChangeHit oldHit= operationsMap.get(astNode); + if (oldHit != null && oldHit.iteratorDeclaration == init_iterator) { + operationsMap.put(astNode, invalidHit); + invalidated= true; + } + } + if (invalidated) { + return true; + } + } + WhileLoopToChangeHit hit= holder.computeIfAbsent(whilestatement, k -> new WhileLoopToChangeHit()); + if (!createForOnlyIfVarUsed) { + hit.iteratorDeclaration= init_iterator; + hit.iteratorCall= iteratorAssignment; + hit.iteratorName= name; + if (computeVarName.size() == 1) { + hit.self= true; + } else { + hit.collectionExpression= (Expression) computeVarName.get(1); + } + hit.whileStatement= whilestatement; + if (hit.self) { + hit.loopVarName= ConvertLoopOperation.modifybasename("i"); //$NON-NLS-1$ + } else { + if (hit.collectionExpression instanceof SimpleName) { + hit.loopVarName= ConvertLoopOperation.modifybasename(((SimpleName)hit.collectionExpression).getIdentifier()); + } else { + hit.loopVarName= ConvertLoopOperation.modifybasename("element"); //$NON-NLS-1$ + } + } + operationsMap.put(whilestatement, hit); + } + HelperVisitor.callMethodInvocationVisitor(whilestatement.getBody(), dataholder, nodesprocessed, (mi, holder2) -> { + SimpleName sn= ASTNodes.as(mi.getExpression(), SimpleName.class); + if (sn != null) { + String identifier= sn.getIdentifier(); + if (!name.equals(identifier)) + return true; + String method= mi.getName().getFullyQualifiedName(); + WhileLoopToChangeHit previousHit= operationsMap.get(whilestatement); + if (previousHit != null && (previousHit == invalidHit || previousHit.nextFound || !method.equals("next"))) { //$NON-NLS-1$ + operationsMap.put(whilestatement, invalidHit); + return true; + } + if (ASTNodes.getFirstAncestorOrNull(mi, ExpressionStatement.class) != null + && createForOnlyIfVarUsed) { + operationsMap.put(whilestatement, invalidHit); + return true; + } + hit.nextFound= true; + hit.iteratorName= name; + hit.iteratorDeclaration= init_iterator; + hit.iteratorCall= iteratorAssignment; + hit.whileStatement= whilestatement; + hit.loopVarDeclaration= mi; + if (computeVarName.size() == 1) { + hit.self= true; + } else { + hit.collectionExpression= (Expression) computeVarName.get(1); + } + VariableDeclarationStatement typedAncestor= ASTNodes.getTypedAncestor(mi, VariableDeclarationStatement.class); + if (typedAncestor != null) { + ITypeBinding iteratorTypeArgument= computeTypeArgument(init_iterator); + ITypeBinding varTypeBinding= typedAncestor.getType().resolveBinding(); + if (varTypeBinding == null || iteratorTypeArgument == null || + (!varTypeBinding.isEqualTo(iteratorTypeArgument) && !Bindings.isSuperType(varTypeBinding, iteratorTypeArgument))) { + operationsMap.put(whilestatement, invalidHit); + return true; + } + VariableDeclarationFragment vdf= (VariableDeclarationFragment) typedAncestor.fragments().get(0); + hit.loopVarName= vdf.getName().getIdentifier(); + } else { + if (hit.self) { + hit.loopVarName= ConvertLoopOperation.modifybasename("i"); //$NON-NLS-1$ + } else { + if (hit.collectionExpression instanceof SimpleName) { + hit.loopVarName= ConvertLoopOperation.modifybasename(((SimpleName)hit.collectionExpression).getIdentifier()); + } else { + hit.loopVarName= ConvertLoopOperation.modifybasename("element"); //$NON-NLS-1$ + } + } + hit.nextWithoutVariableDeclaration= true; + } + operationsMap.put(whilestatement, hit); + helperVisitor.nodesprocessed.add(whilestatement); + holder2.remove(whilestatement); + return true; + } + return true; + }); + } + return true; + }); + } + return true; + }); + for (WhileLoopToChangeHit hit : operationsMap.values()) { + if (!hit.isInvalid && validate(hit)) { + operations.add(fixcore.rewrite(hit)); + } + } + } + + private static boolean validate(final WhileLoopToChangeHit hit) { + ASTNode iterDeclarationParent= hit.iteratorDeclaration.getParent(); + List descs= iterDeclarationParent.structuralPropertiesForType(); + boolean hasStatements= false; + for (StructuralPropertyDescriptor desc : descs) { + if (desc.getId().equals("statements")) { //$NON-NLS-1$ + hasStatements= true; + break; + } + } + if (!hasStatements) { + return false; + } + ReferenceHolder dataholder= new ReferenceHolder<>(); + Set nodesprocessed= new HashSet<>(); + VariableDeclarationFragment iterDeclFragment= (VariableDeclarationFragment) hit.iteratorDeclaration.fragments().get(0); + IVariableBinding iterBinding= iterDeclFragment.resolveBinding(); + if (iterBinding == null) { + return false; + } + HelperVisitor.callMethodInvocationVisitor(iterDeclarationParent, dataholder, nodesprocessed, (mi, holder2) -> { + SimpleName sn= ASTNodes.as(mi.getExpression(), SimpleName.class); + if (sn != null && sn.getIdentifier().equals(hit.iteratorName)) { + if (mi.getStartPosition() < hit.whileStatement.getStartPosition()) { + hit.isInvalid= true; + return false; + } + } else if (mi.getName().getIdentifier().equals("iterator")) { //$NON-NLS-1$ + Assignment assignment= ASTNodes.getFirstAncestorOrNull(mi, Assignment.class); + if (assignment != null) { + Expression leftSide= assignment.getLeftHandSide(); + SimpleName assignedVar= ASTNodes.as(leftSide, SimpleName.class); + if (assignedVar != null && assignedVar.getIdentifier().equals(hit.iteratorName)) { + Statement stmt= ASTNodes.getFirstAncestorOrNull(assignment, Statement.class); + if (stmt == null || stmt.getParent() != hit.whileStatement.getParent()) { + hit.isInvalid= true; + return false; + } + } + } + } + return true; + }); + return !hit.isInvalid; + } + private static String computeNextVarname(WhileStatement whilestatement) { + String name= null; + Expression exp= whilestatement.getExpression(); + if (exp instanceof MethodInvocation) { + MethodInvocation mi= (MethodInvocation) exp; + if (mi.getName().getIdentifier().equals("hasNext")) { //$NON-NLS-1$ + SimpleName variable= ASTNodes.as(mi.getExpression(), SimpleName.class); + if (variable != null) { + IBinding resolveBinding= variable.resolveBinding(); + name= resolveBinding.getName(); + } + } + } + return name; + } + + private static List computeVarName(VariableDeclarationStatement node_a) { + List objectList= new ArrayList<>(); + if (node_a.fragments().size() > 1) { + return null; + } + VariableDeclarationFragment bli= (VariableDeclarationFragment) node_a.fragments().get(0); + objectList.add(bli.getName().getIdentifier()); + Expression exp= bli.getInitializer(); + if (exp == null) { + exp= computeIteratorCall(node_a); + } + MethodInvocation mi= ASTNodes.as(exp, MethodInvocation.class); + if (mi == null || !mi.getName().getIdentifier().equals("iterator")) { //$NON-NLS-1$ + return null; + } + ITypeBinding iterableAncestor= null; + IMethodBinding miBinding= mi.resolveMethodBinding(); + if (miBinding != null) { + iterableAncestor= ASTNodes.findImplementedType(miBinding.getDeclaringClass(), Iterable.class.getCanonicalName()); + } + if (iterableAncestor == null || iterableAncestor.isRawType()) { + return null; + } + Expression sn= ASTNodes.as(mi.getExpression(), Expression.class); + if (sn != null) { + objectList.add(sn); + } + return objectList; + } + + private static MethodInvocation computeIteratorCall(VariableDeclarationStatement node_a) { + VariableDeclarationFragment bli= (VariableDeclarationFragment) node_a.fragments().get(0); + Expression exp= bli.getInitializer(); + IBinding bliBinding= bli.getName().resolveBinding(); + if (bliBinding == null) { + return null; + } + ASTNode parent= node_a.getParent(); + ReferenceHolder dataholder= new ReferenceHolder<>(); + if (exp != null && exp instanceof MethodInvocation) { + dataholder.put(node_a, exp); + } + Set nodesprocessed= new HashSet<>(); + final Object Invalid= new Object(); + try { + HelperVisitor.callAssignmentVisitor(parent, dataholder, nodesprocessed, (assignment, holder2) -> { + if (assignment.getStartPosition() > node_a.getStartPosition()) { + Expression leftSide= assignment.getLeftHandSide(); + SimpleName sn= ASTNodes.as(leftSide, SimpleName.class); + if (sn != null) { + IBinding binding= sn.resolveBinding(); + if (binding.isEqualTo(bliBinding)) { + MethodInvocation mi= ASTNodes.as(assignment.getRightHandSide(), MethodInvocation.class); + if (mi == null || !mi.getName().getIdentifier().equals("iterator")) { //$NON-NLS-1$ + dataholder.put(node_a, Invalid); + throw new AbortSearchException(); + } else { + if (dataholder.get(node_a) != null) { + dataholder.put(node_a, Invalid); + throw new AbortSearchException(); + } + dataholder.put(node_a, mi); + } + } + } + } + return true; + }); + } catch (AbortSearchException e) { + // do nothing + } + Object holderObject= dataholder.get(node_a); + if (holderObject == Invalid || holderObject == null) { + return null; + } else { + return (MethodInvocation)holderObject; + } + } + + private static ITypeBinding computeTypeArgument(VariableDeclarationStatement node_a) { + VariableDeclarationFragment bli= (VariableDeclarationFragment) node_a.fragments().get(0); + Expression exp= bli.getInitializer(); + if (exp == null) { + IBinding bliBinding= bli.getName().resolveBinding(); + if (bliBinding == null) { + return null; + } + ASTNode parent= node_a.getParent(); + ReferenceHolder dataholder= new ReferenceHolder<>(); + Set nodesprocessed= new HashSet<>(); + final Object Invalid= new Object(); + try { + HelperVisitor.callAssignmentVisitor(parent, dataholder, nodesprocessed, (assignment, holder2) -> { + if (assignment.getStartPosition() > node_a.getStartPosition()) { + Expression leftSide= assignment.getLeftHandSide(); + SimpleName sn= ASTNodes.as(leftSide, SimpleName.class); + if (sn != null) { + IBinding binding= sn.resolveBinding(); + if (binding.isEqualTo(bliBinding)) { + MethodInvocation mi= ASTNodes.as(assignment.getRightHandSide(), MethodInvocation.class); + if (mi == null || !mi.getName().getIdentifier().equals("iterator")) { //$NON-NLS-1$ + dataholder.put(node_a, Invalid); + throw new AbortSearchException(); + } else { + dataholder.put(node_a, mi); + } + } + } + } + return true; + }); + } catch (AbortSearchException e) { + // do nothing + } + Object holderObject= dataholder.get(node_a); + if (holderObject == Invalid || holderObject == null) { + return null; + } else { + exp= (Expression)dataholder.get(node_a); + } + } + MethodInvocation mi= ASTNodes.as(exp, MethodInvocation.class); + if (mi != null && mi.getName().toString().equals("iterator")) { //$NON-NLS-1$ + ITypeBinding iterableAncestor= null; + IMethodBinding miBinding= mi.resolveMethodBinding(); + if (miBinding != null) { + iterableAncestor= ASTNodes.findImplementedType(miBinding.getDeclaringClass(), Iterable.class.getCanonicalName()); + } + if (iterableAncestor != null) { + ITypeBinding[] typeArgs= iterableAncestor.getTypeArguments(); + if (typeArgs.length > 0) { + return typeArgs[0]; + } + } + } else { + ITypeBinding varTypeBinding= node_a.getType().resolveBinding(); + if (varTypeBinding != null) { + ITypeBinding[] typeArgs= varTypeBinding.getTypeArguments(); + if (typeArgs.length > 0) { + return typeArgs[0]; + } + } + } + return node_a.getAST().resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ + } + + @Override + public void rewrite(UseIteratorToForLoopFixCore upp, final WhileLoopToChangeHit hit, final CompilationUnitRewrite cuRewrite, + TextEditGroup group) { + ASTRewrite rewrite= cuRewrite.getASTRewrite(); + AST ast= cuRewrite.getRoot().getAST(); + + ImportRewrite importRewrite= cuRewrite.getImportRewrite(); + ImportRemover remover= cuRewrite.getImportRemover(); + + EnhancedForStatement newEnhancedForStatement= ast.newEnhancedForStatement(); + + SingleVariableDeclaration result= ast.newSingleVariableDeclaration(); + + SimpleName name= ast.newSimpleName(hit.loopVarName); + result.setName(name); + + String looptargettype; + Type type; + ITypeBinding varBinding= null; + if (hit.nextWithoutVariableDeclaration || !hit.nextFound) { + type= null; + } else { + Expression expression= hit.loopVarDeclaration.getExpression(); + SimpleName variable= ASTNodes.as(expression, SimpleName.class); + looptargettype= variable.resolveTypeBinding().getErasure().getQualifiedName(); + VariableDeclarationStatement typedAncestor= ASTNodes.getTypedAncestor(hit.loopVarDeclaration, VariableDeclarationStatement.class); + type= typedAncestor.getType(); + varBinding= type.resolveBinding(); + } + if (type == null || varBinding == null) { + looptargettype= "java.lang.Object"; //$NON-NLS-1$ + ITypeBinding binding= computeTypeArgument(hit.iteratorDeclaration); + Type parameterizedType= null; + if (binding != null) { + looptargettype= binding.getErasure().getQualifiedName(); + if (binding.isParameterizedType()) { + parameterizedType= handleParameterizedType(binding, ast, cuRewrite); + } + } + if (parameterizedType == null) { + parameterizedType= ast.newSimpleType(addImport(looptargettype, cuRewrite, ast)); + } + result.setType(parameterizedType); + } else { + Type importType= importType(varBinding, hit.iteratorDeclaration, importRewrite, (CompilationUnit) hit.iteratorDeclaration.getRoot(), TypeLocation.LOCAL_VARIABLE); + remover.registerAddedImports(importType); + + result.setType(importType); + } + newEnhancedForStatement.setParameter(result); + if (hit.self) { + ThisExpression newThisExpression= ast.newThisExpression(); + newEnhancedForStatement.setExpression(newThisExpression); + } else { + Expression loopExpression= (Expression) rewrite.createCopyTarget(hit.collectionExpression); + newEnhancedForStatement.setExpression(loopExpression); + } + ASTNodes.removeButKeepComment(rewrite, hit.iteratorDeclaration, group); + remover.registerRemovedNode(hit.iteratorDeclaration.getType()); + if (hit.iteratorCall != hit.iteratorDeclaration) { + ASTNodes.removeButKeepComment(rewrite, hit.iteratorCall, group); + remover.registerRemovedNode(hit.iteratorCall); + } + if (hit.nextFound) { + if (hit.nextWithoutVariableDeclaration) { + // remove it.next(); expression statements + ASTNode loopVarDeclaration= hit.loopVarDeclaration; + while (loopVarDeclaration.getParent() instanceof ParenthesizedExpression) { + loopVarDeclaration= loopVarDeclaration.getParent(); + } + if (loopVarDeclaration.getLocationInParent() == ExpressionStatement.EXPRESSION_PROPERTY) { + rewrite.remove(loopVarDeclaration.getParent(), group); + remover.registerRemovedNode(loopVarDeclaration); + } else { + ASTNodes.replaceButKeepComment(rewrite, hit.loopVarDeclaration, name, group); + remover.registerRemovedNode(hit.loopVarDeclaration); + } + } else { + ASTNode node= ASTNodes.getTypedAncestor(hit.loopVarDeclaration, VariableDeclarationStatement.class); + ASTNodes.removeButKeepComment(rewrite, node, group); + remover.registerRemovedNode(node); + } + } + newEnhancedForStatement.setBody(ASTNodes.createMoveTarget(rewrite, hit.whileStatement.getBody())); + ASTNodes.replaceButKeepComment(rewrite, hit.whileStatement, newEnhancedForStatement, group); + remover.registerRemovedNode(hit.whileStatement.getExpression()); + remover.applyRemoves(importRewrite); + } + + private Type handleParameterizedType(ITypeBinding binding, AST ast, CompilationUnitRewrite cuRewrite) { + String loopTargetType= binding.getErasure().getQualifiedName(); + Type type= ast.newSimpleType(addImport(loopTargetType, cuRewrite, ast)); + if (binding.isParameterizedType()) { + ParameterizedType pType= ast.newParameterizedType(type); + Collection typeArgs= new ArrayList<>(); + ITypeBinding[] args= binding.getTypeArguments(); + for (ITypeBinding arg : args) { + Type argType= null; + if (arg.isParameterizedType()) { + argType= handleParameterizedType(arg, ast, cuRewrite); + } else { + String argumentType= arg.getQualifiedName(); + Name argumentTypeName; + if (!arg.isTypeVariable()) { + argumentTypeName= addImport(argumentType, cuRewrite, ast); + } else { + argumentTypeName= ast.newName(argumentType); + } + argType= ast.newSimpleType(argumentTypeName); + } + typeArgs.add(argType); + } + pType.typeArguments().addAll(typeArgs); + type= pType; + } + return type; + } + + private Type importType(final ITypeBinding toImport, final ASTNode accessor, ImportRewrite imports, final CompilationUnit compilationUnit, TypeLocation location) { + ImportRewriteContext importContext= new ContextSensitiveImportRewriteContext(compilationUnit, accessor.getStartPosition(), imports); + return imports.addImport(toImport, compilationUnit.getAST(), importContext, location); + } + + @Override + public String getPreview(boolean afterRefactoring) { + if (afterRefactoring) { + return "\nfor (String s : strings) {\n\n System.out.println(s);\n}\n\n"; //$NON-NLS-1$ + } + return "Iterator it = lists.iterator();\nwhile (it.hasNext()) {\n String s = (String) it.next();\n System.out.println(s);\n}\n\n"; //$NON-NLS-1$ + } +} diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringCoreMessages.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringCoreMessages.java index c34e74c6..11051d0d 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringCoreMessages.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringCoreMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15,7 +15,8 @@ * Yves Joan - [reorg] Copy action should NOT add 'copy of' prefix - https://bugs.eclipse.org/bugs/show_bug.cgi?id=151668 * Red Hat Inc. - copied to jdt.core.manipulation * Pierre-Yves B. - [inline] Allow inlining of local variable initialized to null. - https://bugs.eclipse.org/93850 - *******************************************************************************/ + * Nikolay Metchev - - [inline] Inline Local Variable does not qualify accesses to obscured types - https://bugs.eclipse.org/367536 + ********************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring; import org.eclipse.osgi.util.NLS; @@ -886,6 +887,8 @@ public final class RefactoringCoreMessages extends NLS { public static String InlineTemRefactoring_error_message_fieldsCannotBeInlined; + public static String InlineTemRefactoring_error_message_inliningClashes; + public static String IntroduceFactory_addFactoryMethod; public static String IntroduceFactory_callSitesInBinaryClass; @@ -2292,6 +2295,8 @@ public final class RefactoringCoreMessages extends NLS { public static String SelfEncapsulateField_setter_pattern; + public static String SelfEncapsulateField_subtype_method_exists; + public static String SelfEncapsulateField_type_not_resolveable; public static String SelfEncapsulateField_use_accessors; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringScopeFactory.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringScopeFactory.java index b48026ce..33d00fd6 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringScopeFactory.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringScopeFactory.java @@ -15,8 +15,10 @@ package org.eclipse.jdt.internal.corext.refactoring; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -176,6 +178,26 @@ public static IJavaSearchScope create(IMember[] members, boolean sourceReference return create(candidate, true, sourceReferencesOnly); } + /** + * Creates a new search scope comprising members. + * Includes the scopes of all projects that elements in {@code members} belong to. + * + * @param members the members + * @param sourceReferencesOnly consider references in source only (no references in binary) + * @return the search scope + * @throws JavaModelException if an error occurs + */ + public static IJavaSearchScope createProjectsScope(IMember[] members, boolean sourceReferencesOnly) throws JavaModelException { + Assert.isTrue(members != null && members.length > 0); + Set scopeElements = new LinkedHashSet<>(); + for (IMember member : members) { + IJavaProject javaProject= member.getJavaProject(); + IJavaElement[] projectScopeElements = getAllScopeElements(javaProject, sourceReferencesOnly); + scopeElements.addAll(Arrays.asList(projectScopeElements)); + } + return SearchEngine.createJavaSearchScope(scopeElements.toArray(IJavaElement[]::new), false); + } + /** * Creates a new search scope with all projects possibly referenced * from the given javaElements. diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringSearchEngine2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringSearchEngine2.java index 22572f7c..8ed78d03 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringSearchEngine2.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/RefactoringSearchEngine2.java @@ -674,10 +674,15 @@ public void setPattern(final IJavaElement[] elements, final int limitTo) { Assert.isNotNull(elements); Assert.isTrue(elements.length > 0); SearchPattern pattern= SearchPattern.createPattern(elements[0], limitTo, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + Assert.isNotNull(pattern); IJavaElement element= null; for (int index= 1; index < elements.length; index++) { element= elements[index]; - pattern= SearchPattern.createOrPattern(pattern, SearchPattern.createPattern(element, limitTo, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); + SearchPattern searchPattern= SearchPattern.createPattern(element, limitTo, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (searchPattern == null) { + continue; + } + pattern= SearchPattern.createOrPattern(pattern, searchPattern); } setPattern(pattern); } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/changes/DynamicValidationStateChange.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/changes/DynamicValidationStateChange.java index cbdf2bcf..4abd346b 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/changes/DynamicValidationStateChange.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/changes/DynamicValidationStateChange.java @@ -147,4 +147,10 @@ public void setSchedulingRule(ISchedulingRule schedulingRule) { public ISchedulingRule getSchedulingRule() { return fSchedulingRule; } + + @Override + public String toString() { + return String.valueOf(this.getFilenumber()); + } + } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/CallInliner.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/CallInliner.java index 8fda5b76..7807bc3a 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/CallInliner.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/CallInliner.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -78,12 +78,14 @@ import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.SuperFieldAccess; +import org.eclipse.jdt.core.dom.SwitchExpression; import org.eclipse.jdt.core.dom.SwitchStatement; import org.eclipse.jdt.core.dom.ThisExpression; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.dom.VariableDeclarationStatement; import org.eclipse.jdt.core.dom.WhileStatement; +import org.eclipse.jdt.core.dom.YieldStatement; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; @@ -135,6 +137,7 @@ public class CallInliner { private CodeScopeBuilder.Scope fInvocationScope; private boolean fFieldInitializer; private List fLocals; + private Block fBlock; private CallContext fContext; private class InlineEvaluator extends HierarchicalASTVisitor { @@ -206,6 +209,7 @@ public CallInliner(ICompilationUnit unit, CompilationUnit targetAstRoot, SourceP fRewrite= ASTRewrite.create(targetAstRoot.getAST()); fRewrite.setTargetSourceRangeComputer(new NoCommentSourceRangeComputer()); fTypeEnvironment= new TypeEnvironment(); + fBlock = null; } public void dispose() { @@ -280,7 +284,9 @@ private void initializeRewriteState() { private void initializeTargetNode() { ASTNode parent= fInvocation.getParent(); int nodeType= parent.getNodeType(); - if (nodeType == ASTNode.EXPRESSION_STATEMENT || nodeType == ASTNode.RETURN_STATEMENT) { + if (nodeType == ASTNode.EXPRESSION_STATEMENT + || nodeType == ASTNode.RETURN_STATEMENT + || nodeType == ASTNode.YIELD_STATEMENT) { fTargetNode= parent; } else { fTargetNode= fInvocation; @@ -562,14 +568,47 @@ private void computeReceiver() throws BadLocationException { } private void addNewLocals(TextEditGroup textEditGroup) { + fBlock = null; if (fLocals.isEmpty()) return; - for (VariableDeclarationStatement variableDeclarationStatement : fLocals) { - ASTNode element= variableDeclarationStatement; - fListRewrite.insertAt(element, fInsertionIndex++, textEditGroup); + if (needToCreateBlockStatement()) { + Block block= fTargetNode.getAST().newBlock(); + + for (VariableDeclarationStatement variableDeclarationStatement : fLocals) { + ASTNode element= variableDeclarationStatement; + block.statements().add(element); + } + fRewrite.replace(fTargetNode, block, textEditGroup); + fBlock = block; + } + else { + for (VariableDeclarationStatement variableDeclarationStatement : fLocals) { + ASTNode element= variableDeclarationStatement; + fListRewrite.insertAt(element, fInsertionIndex++, textEditGroup); + } } } + private boolean needToCreateBlockStatement() { + boolean need = false; + if (fContext != null && ASTNode.YIELD_STATEMENT == fContext.callMode) { + if (fTargetNode != null && fTargetNode instanceof YieldStatement) { + ASTNode parent = fTargetNode; + while (parent != null) { + if (parent instanceof SwitchExpression) { + need = true; + break; + } + if (parent instanceof Block) { + break; + } + parent = parent.getParent(); + } + } + } + return need; + } + private void replaceCall(RefactoringStatus status, String[] blocks, TextEditGroup textEditGroup) { // Inline empty body if (blocks.length == 0 && fTargetNode != null) { @@ -632,6 +671,12 @@ private void replaceCall(RefactoringStatus status, String[] blocks, TextEditGrou pExp.setExpression((Expression)node); node= pExp; } + } else if (fContext.callMode == ASTNode.YIELD_STATEMENT) { + if (fBlock != null) { + node= fRewrite.createStringPlaceholder(block, ASTNode.BLOCK); + } else { + node= fRewrite.createStringPlaceholder(block, ASTNode.YIELD_STATEMENT); + } } else { node= fRewrite.createStringPlaceholder(block, ASTNode.RETURN_STATEMENT); } @@ -640,6 +685,8 @@ private void replaceCall(RefactoringStatus status, String[] blocks, TextEditGrou if (node != null) { if (fTargetNode == null) { fListRewrite.insertAt(node, fInsertionIndex++, textEditGroup); + } else if (fBlock != null) { + fBlock.statements().add(node); } else { fRewrite.replace(fTargetNode, node, textEditGroup); } @@ -740,6 +787,10 @@ public boolean visit(Name node) { }); } } + // if there is only 1 argument that has assignment and no others use it, there is no issue + if (result.size() == 1) { + return new HashSet<>(); + } return result; } @@ -769,6 +820,10 @@ private void initializeInsertionPoint(int nos) { SwitchStatement switchStatement= (SwitchStatement)container; fListRewrite= fRewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY); fInsertionIndex= fListRewrite.getRewrittenList().indexOf(parentStatement); + } else if (type == ASTNode.SWITCH_EXPRESSION) { + SwitchExpression switchExpression= (SwitchExpression)container; + fListRewrite= fRewrite.getListRewrite(switchExpression, SwitchExpression.STATEMENTS_PROPERTY); + fInsertionIndex= fListRewrite.getRewrittenList().indexOf(parentStatement); } else if (isControlStatement(container) || type == ASTNode.LABELED_STATEMENT) { fNeedsStatement= true; if (nos > 1 || needsBlockAroundDanglingIf()) { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/ConvertAnonymousToNestedRefactoring.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/ConvertAnonymousToNestedRefactoring.java index 26b0159c..1a59fb63 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/ConvertAnonymousToNestedRefactoring.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/ConvertAnonymousToNestedRefactoring.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -85,6 +85,7 @@ import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.TypeParameter; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; import org.eclipse.jdt.core.manipulation.CodeGeneration; @@ -472,7 +473,8 @@ public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreEx public CompilationUnitChange createCompilationUnitChange(IProgressMonitor pm) throws CoreException { final CompilationUnitRewrite rewrite= new CompilationUnitRewrite(fCu, fCompilationUnitNode); final ITypeBinding[] typeParameters= getTypeParameters(); - addNestedClass(rewrite, typeParameters); + final ITypeBinding[] impliedSuperParameters= getImpliedClassCreationTypeParameters(); + addNestedClass(rewrite, typeParameters, impliedSuperParameters); modifyConstructorCall(rewrite, typeParameters); return rewrite.createChange(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_name, false, pm); } @@ -488,6 +490,39 @@ public Change createChange(IProgressMonitor pm) throws CoreException { return result; } + private ITypeBinding[] getImpliedClassCreationTypeParameters() { + final ClassInstanceCreation creation= (ClassInstanceCreation) fAnonymousInnerClassNode.getParent(); + // In assignments and variable declaration statements, a type parameter might exist in the + // left side of the statement and implied in the class creation (e.g. Set x= new HashSet<>();) + ASTNode nodeOfInterest= ASTNodes.getFirstAncestorOrNull(creation, Assignment.class, FieldDeclaration.class, VariableDeclarationStatement.class); + if (nodeOfInterest instanceof Assignment) { + Assignment assignment= (Assignment)nodeOfInterest; + ITypeBinding typeBinding= assignment.resolveTypeBinding(); + if (typeBinding != null && typeBinding.isParameterizedType()) { + return typeBinding.getTypeArguments(); + } + } else if (nodeOfInterest instanceof FieldDeclaration) { + FieldDeclaration fieldDeclaration= (FieldDeclaration)nodeOfInterest; + Type fieldType= fieldDeclaration.getType(); + if (fieldType.isParameterizedType()) { + ITypeBinding typeBinding= fieldType.resolveBinding(); + if (typeBinding != null) { + return typeBinding.getTypeArguments(); + } + } + } else if (nodeOfInterest instanceof VariableDeclarationStatement) { + VariableDeclarationStatement vds= (VariableDeclarationStatement)nodeOfInterest; + Type vdsType= vds.getType(); + if (vdsType.isParameterizedType()) { + ITypeBinding typeBinding= vdsType.resolveBinding(); + if (typeBinding != null) { + return typeBinding.getTypeArguments(); + } + } + } + return new ITypeBinding[0]; + } + private ITypeBinding[] getTypeParameters() { final List parameters= new ArrayList<>(4); final ClassInstanceCreation creation= (ClassInstanceCreation) fAnonymousInnerClassNode.getParent(); @@ -650,12 +685,12 @@ private void copyArguments(CompilationUnitRewrite rewrite, ClassInstanceCreation } } - private void addNestedClass(CompilationUnitRewrite rewrite, ITypeBinding[] typeParameters) throws CoreException { + private void addNestedClass(CompilationUnitRewrite rewrite, ITypeBinding[] typeParameters, ITypeBinding[] impliedSuperTypeParameters) throws CoreException { final AbstractTypeDeclaration declarations= ASTNodes.getParent(fAnonymousInnerClassNode, AbstractTypeDeclaration.class); int index= findIndexOfFistNestedClass(declarations.bodyDeclarations()); if (index == -1) index= 0; - rewrite.getASTRewrite().getListRewrite(declarations, declarations.getBodyDeclarationsProperty()).insertAt(createNewNestedClass(rewrite, typeParameters), index, null); + rewrite.getASTRewrite().getListRewrite(declarations, declarations.getBodyDeclarationsProperty()).insertAt(createNewNestedClass(rewrite, typeParameters, impliedSuperTypeParameters), index, null); } private static int findIndexOfFistNestedClass(List list) { @@ -673,7 +708,7 @@ private static boolean isNestedType(BodyDeclaration each) { return (each.getParent() instanceof AbstractTypeDeclaration); } - private AbstractTypeDeclaration createNewNestedClass(CompilationUnitRewrite rewrite, ITypeBinding[] typeParameters) throws CoreException { + private AbstractTypeDeclaration createNewNestedClass(CompilationUnitRewrite rewrite, ITypeBinding[] typeParameters, ITypeBinding[] impliedSuperTypeParameters) throws CoreException { final AST ast= fAnonymousInnerClassNode.getAST(); final TypeDeclaration newDeclaration= ast.newTypeDeclaration(); @@ -688,7 +723,7 @@ private AbstractTypeDeclaration createNewNestedClass(CompilationUnitRewrite rewr parameter.setName(ast.newSimpleName(typeParameter.getName())); newDeclaration.typeParameters().add(parameter); } - setSuperType(newDeclaration); + setSuperType(rewrite, newDeclaration, impliedSuperTypeParameters); IJavaProject project= fCu.getJavaProject(); @@ -1058,20 +1093,33 @@ private SingleVariableDeclaration newParameterDeclaration(AST ast, ImportRewrite return param; } - private void setSuperType(TypeDeclaration declaration) { - ClassInstanceCreation classInstanceCreation= (ClassInstanceCreation) fAnonymousInnerClassNode.getParent(); + private void setSuperType(CompilationUnitRewrite rewrite, TypeDeclaration declaration, ITypeBinding[] impliedSuperTypeParameters) { + ClassInstanceCreation classInstanceCreation= (ClassInstanceCreation) fAnonymousInnerClassNode.getParent(); ITypeBinding binding= classInstanceCreation.resolveTypeBinding(); - if (binding == null) - return; - Type newType= (Type) ASTNode.copySubtree(fAnonymousInnerClassNode.getAST(), classInstanceCreation.getType()); + if (binding == null) + return; + Type newType= null; + if (impliedSuperTypeParameters.length == 0 || !classInstanceCreation.getType().isParameterizedType()) { + newType= (Type) ASTNode.copySubtree(fAnonymousInnerClassNode.getAST(), classInstanceCreation.getType()); + } else { + ImportRewrite importRewriter= rewrite.getImportRewrite(); + AST ast= fAnonymousInnerClassNode.getAST(); + Type oldType= classInstanceCreation.getType(); + Type newBaseType= (Type) ASTNode.copySubtree(ast, ((ParameterizedType) oldType).getType()); + newType= ast.newParameterizedType(newBaseType); + for (ITypeBinding impliedTypeBinding : impliedSuperTypeParameters) { + Type type= importRewriter.addImport(impliedTypeBinding, ast); + ((ParameterizedType) newType).typeArguments().add(type); + } + } if ("java.lang.Object".equals(binding.getSuperclass().getQualifiedName())) { //$NON-NLS-1$ - Assert.isTrue(binding.getInterfaces().length <= 1); - if (binding.getInterfaces().length == 0) - return; - declaration.superInterfaceTypes().add(0, newType); - } else { - declaration.setSuperclassType(newType); - } + Assert.isTrue(binding.getInterfaces().length <= 1); + if (binding.getInterfaces().length == 0) + return; + declaration.superInterfaceTypes().add(0, newType); + } else { + declaration.setSuperclassType(newType); + } } private ITypeBinding getSuperTypeBinding() { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/InlineConstantRefactoring.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/InlineConstantRefactoring.java index d9097b3f..bed6c9a8 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/InlineConstantRefactoring.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/InlineConstantRefactoring.java @@ -921,7 +921,11 @@ private CompilationUnitRewrite getCuRewrite(ICompilationUnit cu) { } private SearchResultGroup[] findReferences(IProgressMonitor pm, RefactoringStatus status) throws JavaModelException { - final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(fField, IJavaSearchConstants.REFERENCES)); + SearchPattern pattern= SearchPattern.createPattern(fField, IJavaSearchConstants.REFERENCES); + if (pattern == null) { + return new SearchResultGroup[0]; + } + final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(pattern); engine.setFiltering(true, true); engine.setScope(RefactoringScopeFactory.create(fField)); engine.setStatus(status); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/InlineTempRefactoring.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/InlineTempRefactoring.java index 35994865..3be87183 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/InlineTempRefactoring.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/InlineTempRefactoring.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -13,11 +13,19 @@ * Pierre-Yves B. - [inline] Allow inlining of local variable initialized to null. - https://bugs.eclipse.org/93850 * Microsoft Corporation - copied to jdt.core.manipulation * Microsoft Corporation - read formatting options from the compilation unit - *******************************************************************************/ + * Nikolay Metchev - - [inline] Inline Local Variable does not qualify accesses to obscured types - https://bugs.eclipse.org/367536 + ********************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.code; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import java.util.StringTokenizer; import org.eclipse.core.runtime.Assert; @@ -50,7 +58,9 @@ import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.SourceRange; import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTMatcher; import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.ArrayCreation; import org.eclipse.jdt.core.dom.ArrayInitializer; import org.eclipse.jdt.core.dom.ArrayType; @@ -59,8 +69,10 @@ import org.eclipse.jdt.core.dom.CatchClause; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.ForStatement; +import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; @@ -69,10 +81,12 @@ import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.ParenthesizedExpression; +import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.TryStatement; import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationExpression; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; @@ -95,6 +109,7 @@ import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; import org.eclipse.jdt.internal.corext.refactoring.Checks; import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments; @@ -225,12 +240,38 @@ public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws Core result.merge(checkSelection(selected, declaration)); + result.merge(checkClashes(declaration)); + return result; } finally { pm.done(); } } + private RefactoringStatus checkClashes(VariableDeclaration declaration) { + for (SimpleName reference : getReferences()) { + Set newVariables= getNewVariables(reference); + final List initializerNames= getInitializerNames(declaration.getInitializer()); + for (Name name : initializerNames) { + if (clashesWithNewVariables(newVariables, name)) { + List alternativeQualifications= getAlternativeQualifications(reference, name); + boolean inlinable= false; + for (Expression alternative : alternativeQualifications) { + if (!clashesWithNewVariables(newVariables, alternative)) { + inlinable= true; + break; + } + } + if (!inlinable) { + return RefactoringStatus.createFatalErrorStatus( + Messages.format(RefactoringCoreMessages.InlineTemRefactoring_error_message_inliningClashes, name)); + } + } + } + } + return null; + } + private RefactoringStatus checkSelection(ASTNode selectedNode, VariableDeclaration decl) { ASTNode parent= decl.getParent(); if (parent instanceof MethodDeclaration) { @@ -344,7 +385,7 @@ private void inlineTemp(CompilationUnitRewrite cuRewrite) throws JavaModelExcept ASTRewrite rewrite= cuRewrite.getASTRewrite(); for (SimpleName curr : getReferences()) { - ASTNode initializerCopy= getInitializerSource(cuRewrite, curr); + ASTNode initializerCopy= getInitializerSource(cuRewrite, curr, groupDesc); rewrite.replace(curr, initializerCopy, groupDesc); } } @@ -365,8 +406,8 @@ private void removeTemp(CompilationUnitRewrite cuRewrite) { } } - private Expression getInitializerSource(CompilationUnitRewrite rewrite, SimpleName reference) throws JavaModelException { - Expression copy= getModifiedInitializerSource(rewrite, reference); + private Expression getInitializerSource(CompilationUnitRewrite rewrite, SimpleName reference, TextEditGroup groupDesc) throws JavaModelException { + Expression copy= getModifiedInitializerSource(rewrite, reference, groupDesc); if (NecessaryParenthesesChecker.needsParentheses(copy, reference.getParent(), reference.getLocationInParent())) { ParenthesizedExpression parentExpr= rewrite.getAST().newParenthesizedExpression(); parentExpr.setExpression(copy); @@ -375,10 +416,16 @@ private Expression getInitializerSource(CompilationUnitRewrite rewrite, SimpleNa return copy; } - private Expression getModifiedInitializerSource(CompilationUnitRewrite rewrite, SimpleName reference) throws JavaModelException { + private Expression getModifiedInitializerSource(CompilationUnitRewrite rewrite, SimpleName reference, TextEditGroup groupDesc) throws JavaModelException { VariableDeclaration varDecl= getVariableDeclaration(); Expression initializer= varDecl.getInitializer(); - + List initializerNames= getInitializerNames(initializer); + if (!initializerNames.isEmpty()) { + Map replacements= getClashingReplacements(reference, initializerNames); + if (!replacements.isEmpty()) { + return replaceClashingNames(rewrite, groupDesc, initializer, replacements); + } + } ASTNode referenceContext= reference.getParent(); if (Invocations.isResolvedTypeInferredFromExpectedType(initializer)) { if (!(referenceContext instanceof VariableDeclarationFragment) @@ -424,6 +471,240 @@ private Expression getModifiedInitializerSource(CompilationUnitRewrite rewrite, return copy; } + private List getInitializerNames(final Expression initializer) { + ScopeAnalyzer scopeAnalyzer= new ScopeAnalyzer(fASTRoot); + VariableDeclaration var= getVariableDeclaration(); + int end = var.getStartPosition(); + final Set declarationsAtInitializer= new HashSet<>(Arrays.asList(scopeAnalyzer.getDeclarationsInScope(end, ScopeAnalyzer.VARIABLES))); + final List initializerNames= new ArrayList<>(); + if (initializer != null) { + initializer.accept(new ASTVisitor() { + @Override + public boolean visit(QualifiedName node) { + IBinding binding= node.resolveBinding(); + if (binding instanceof IVariableBinding) { + initializerNames.add(node); + } + return false; + } + + @Override + public boolean visit(SimpleName node) { + IBinding binding= node.resolveBinding(); + if (binding instanceof IVariableBinding) { + if (declarationsAtInitializer.contains(binding)) { + initializerNames.add(node); + } + } + return false; + } + }); + } + return initializerNames; + } + + private Expression replaceClashingNames(final CompilationUnitRewrite rewrite, final TextEditGroup groupDesc, Expression initializer, final Map replacements) { + final Expression copyOfInitializer= (Expression) ASTNode.copySubtree(fASTRoot.getAST(), initializer); + final ASTMatcher astMatcher= new ASTMatcher(); + copyOfInitializer.accept(new ASTVisitor() { + @Override + public boolean visit(QualifiedName copyOfInitializerNode) { + return replace(copyOfInitializerNode); + } + + @Override + public boolean visit(SimpleName node) { + return replace(node); + } + + private boolean replace(Name copyOfInitializerNode) { + Set> replacementKeySet= replacements.entrySet(); + for (Iterator> replacementIterator= replacementKeySet.iterator(); replacementIterator.hasNext();) { + Entry replacement= replacementIterator.next(); + Name key= replacement.getKey(); + if (key instanceof QualifiedName && astMatcher.match((QualifiedName) key, copyOfInitializerNode) || + key instanceof SimpleName && astMatcher.match((SimpleName) key, copyOfInitializerNode)) { + if (copyOfInitializerNode != copyOfInitializer) { + rewrite.getASTRewrite().replace(copyOfInitializerNode, replacement.getValue(), groupDesc); + replacementIterator.remove(); + } + return false; + } + } + return false; + } + }); + if (!replacements.isEmpty()) { // the whole initializer was replaced + return replacements.values().iterator().next(); + } + return copyOfInitializer; + } + + private Map getClashingReplacements(SimpleName reference, List initializerNames) { + Set newVariables= getNewVariables(reference); + final Map replacements= new HashMap<>(); + for (Name initializerName : initializerNames) { + if (clashesWithNewVariables(newVariables, initializerName)) { + List alternativeQualifications= getAlternativeQualifications(reference, initializerName); + for (Expression alternative : alternativeQualifications) { + if (!clashesWithNewVariables(newVariables, alternative)) { + replacements.put(initializerName, alternative); + break; + } + } + } + } + return replacements; + } + + private List getAlternativeQualifications(SimpleName reference, Name initializerName) { + List ans= new ArrayList<>(); + if (initializerName instanceof SimpleName) { + SimpleName simpleNameInitializer= ((SimpleName) initializerName); + IBinding resolveBinding= simpleNameInitializer.resolveBinding(); + if (resolveBinding instanceof IVariableBinding) { + IVariableBinding resolvedVariableBinding= (IVariableBinding) resolveBinding; + boolean isStatic= Modifier.isStatic(resolvedVariableBinding.getModifiers()); + if (isStatic) { + ans.add(createFullyQualifiedName(simpleNameInitializer, resolvedVariableBinding.getDeclaringClass(), false)); + ans.add(createFullyQualifiedName(simpleNameInitializer, resolvedVariableBinding.getDeclaringClass(), true)); + } else { + AST ast= fASTRoot.getAST(); + FieldAccess newFieldAccess= ast.newFieldAccess(); + newFieldAccess.setExpression(ast.newThisExpression()); + newFieldAccess.setName((SimpleName) ASTNode.copySubtree(ast, simpleNameInitializer)); + ans.add(newFieldAccess); + } + } + } else if (initializerName instanceof QualifiedName){ + QualifiedName initializerQualifiedName = (QualifiedName) initializerName; + SimpleName simpleName= initializerQualifiedName.getName(); + int i= findCommonDeclaringClassIndex(reference, initializerQualifiedName); + ITypeBinding initializerQualifiedNameTypeBinding= initializerQualifiedName.getQualifier().resolveTypeBinding(); + ans.add(createFullyQualifiedName(simpleName, initializerQualifiedNameTypeBinding, false)); + ans.add(createFullyQualifiedName(simpleName, initializerQualifiedNameTypeBinding, i, false)); + ans.add(createFullyQualifiedName(simpleName, initializerQualifiedNameTypeBinding, true)); + ans.add(createFullyQualifiedName(simpleName, initializerQualifiedNameTypeBinding, i, true)); + } + return ans; + } + + /** + * @param reference the reference being inlined + * @param initializerQualifiedName the qualified name from the initializer being inlined + * @return the number of declaring classes to skip from the fully qualified name of + * initializerQualifiedName in order to get to the declaring class of the passed in + * reference. + */ + private int findCommonDeclaringClassIndex(SimpleName reference, QualifiedName initializerQualifiedName) { + final List initializerSimpleNames= new ArrayList<>(); + initializerQualifiedName.accept(new ASTVisitor() { + @Override + public boolean visit(QualifiedName qualifiedName) { + initializerSimpleNames.add(0, qualifiedName.getName()); + qualifiedName.getQualifier().accept(this); + return false; + } + + @Override + public boolean visit(SimpleName simpleName) { + initializerSimpleNames.add(0, simpleName); + return false; + } + }); + TypeDeclaration typeDeclaration= (TypeDeclaration) ASTNodes.getParent(reference, ASTNode.TYPE_DECLARATION); + ITypeBinding declaringClassBinding= typeDeclaration.resolveBinding(); + int i= 1; + while (i < initializerSimpleNames.size() && declaringClassBinding != getDeclaringClass(initializerSimpleNames.get(i))) { + i++; + } + return i; + } + + private ITypeBinding getDeclaringClass(SimpleName simpleName) { + IBinding resolveBinding= simpleName.resolveBinding(); + if (resolveBinding instanceof ITypeBinding) { + return ((ITypeBinding) resolveBinding).getDeclaringClass(); + } else if (resolveBinding instanceof IVariableBinding) { + return ((IVariableBinding) resolveBinding).getDeclaringClass(); + } + return null; + } + + private boolean clashesWithNewVariables(Set newVariables, Expression name) { + if (name instanceof QualifiedName) { + return clashesWithNewVariables(newVariables, (QualifiedName) name); + } else if (name instanceof SimpleName) { + return clashesWithNewVariables(newVariables, (SimpleName) name); + } + return false; + } + + private boolean clashesWithNewVariables(Set newVariables, QualifiedName qualifiedName) { + return clashesWithNewVariables(newVariables, ASTNodes.getLeftMostSimpleName(qualifiedName)); + } + + private boolean clashesWithNewVariables(Set newVariables, SimpleName leftMostSimpleName) { + String leftMostSimpleNameIdentifier= leftMostSimpleName.getIdentifier(); + for (IVariableBinding newVariable : newVariables) { + if (newVariable.getName().equals(leftMostSimpleNameIdentifier)) { + return true; + } + } + return false; + } + + /** + * @param reference the reference being inlined + * @return A set of bindings representing any variables that have come into scope for the + * variable declaration after it has been inlined to the passed in reference. + */ + private Set getNewVariables(SimpleName reference) { + ScopeAnalyzer scopeAnalyzer= new ScopeAnalyzer(fASTRoot); + IBinding[] declarationsAtReference= scopeAnalyzer.getDeclarationsInScope(reference.getStartPosition(), ScopeAnalyzer.VARIABLES); + Set newVariables= new HashSet<>(declarationsAtReference.length); + for (IBinding newVariable : declarationsAtReference) { + newVariables.add((IVariableBinding) newVariable); + } + VariableDeclaration var= getVariableDeclaration(); + int endPosition= var.getStartPosition() + var.getLength(); + for (IBinding oldVariable : scopeAnalyzer.getDeclarationsInScope(endPosition, ScopeAnalyzer.VARIABLES)) { + newVariables.remove(oldVariable); + } + return newVariables; + } + + private Name createFullyQualifiedName(SimpleName simpleName, ITypeBinding declaringClass, boolean addPackage) { + return createFullyQualifiedName(simpleName, declaringClass, 0, addPackage); + } + + private Name createFullyQualifiedName(SimpleName simpleName, ITypeBinding declaringClass, int numberOfClassesToSkip, boolean addPackage) { + AST ast= fASTRoot.getAST(); + List declaringClasses = new ArrayList<>(); + while (declaringClass != null) { + declaringClasses.add(declaringClass); + declaringClass= declaringClass.getDeclaringClass(); + } + for (int i= 0; i < numberOfClassesToSkip; i++) { + if (declaringClasses.size() > 0) { + declaringClasses.remove(declaringClasses.size() - 1); + } else { + break; + } + } + StringBuilder qualifiedName = new StringBuilder(); + if (addPackage && declaringClasses.size() > 0) { + qualifiedName.append(declaringClasses.get(declaringClasses.size() - 1).getPackage().getName()); + qualifiedName.append('.'); + } + for (int i= declaringClasses.size() - 1; i >= 0; i--) { + qualifiedName.append(declaringClasses.get(i).getName()); + qualifiedName.append('.'); + } + qualifiedName.append(simpleName.getFullyQualifiedName()); + return ast.newName(qualifiedName.toString()); + } + private String createParameterizedInvocation(Expression invocation, ITypeBinding[] typeArguments, CompilationUnitRewrite cuRewrite) throws JavaModelException { ASTRewrite rewrite= ASTRewrite.create(invocation.getAST()); ListRewrite typeArgsRewrite= Invocations.getInferredTypeArgumentsRewrite(rewrite, invocation); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/SourceProvider.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/SourceProvider.java index 6d6e152d..f5128b03 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/SourceProvider.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/SourceProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -23,6 +23,7 @@ package org.eclipse.jdt.internal.corext.refactoring.code; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; @@ -50,6 +51,7 @@ import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.AST; @@ -82,8 +84,10 @@ import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; +import org.eclipse.jdt.core.dom.SwitchCase; import org.eclipse.jdt.core.dom.ThisExpression; import org.eclipse.jdt.core.dom.WhileStatement; +import org.eclipse.jdt.core.dom.YieldStatement; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; @@ -367,10 +371,11 @@ public String[] getCodeBlocks(CallContext context, ImportRewrite importRewrite) updateStaticReferences(rewriter, context); updateTypeVariables(rewriter, context); updateMethodTypeVariable(rewriter, context); - + updateReturnStatements(rewriter, context); List ranges= null; if (hasReturnValue()) { - if (context.callMode == ASTNode.RETURN_STATEMENT) { + if (context.callMode == ASTNode.RETURN_STATEMENT + || context.callMode == ASTNode.YIELD_STATEMENT) { ranges= getStatementRanges(); } else { ranges= getExpressionRanges(); @@ -509,11 +514,13 @@ private void updateImplicitReceivers(ASTRewrite rewriter, CallContext context) { if (vb.isField()) { Expression receiver= createReceiver(rewriter, context, vb, importRewriteContext); if (receiver != null) { - FieldAccess access= node.getAST().newFieldAccess(); - ASTNode target= rewriter.createMoveTarget(node); - access.setName((SimpleName)target); - access.setExpression(receiver); - rewriter.replace(node, access, null); + if (!vb.isEnumConstant() || node.getLocationInParent() != SwitchCase.EXPRESSIONS2_PROPERTY) { + FieldAccess access= node.getAST().newFieldAccess(); + ASTNode target= rewriter.createMoveTarget(node); + access.setName((SimpleName)target); + access.setExpression(receiver); + rewriter.replace(node, access, null); + } } } } @@ -533,9 +540,22 @@ private void updateTypeReferences(ASTRewrite rewriter, CallContext context) { if (binding.isParameterizedType()) { binding= binding.getTypeDeclaration(); } - String s= importer.addImport(binding); - if (!ASTNodes.asString(element).equals(s)) { - rewriter.replace(element, rewriter.createStringPlaceholder(s, ASTNode.SIMPLE_NAME), null); + String[] bindingNameComponents= Bindings.getNameComponents(binding); + try { + IType[] types= context.compilationUnit.getAllTypes(); + for (IType type : types) { + String typeName= type.getFullyQualifiedName(); + String[] typeNameComponents= typeName.split("\\.|\\$"); //$NON-NLS-1$ + if (Arrays.equals(bindingNameComponents, typeNameComponents)) { + return; + } + } + String s= importer.addImport(binding); + if (!ASTNodes.asString(element).equals(s)) { + rewriter.replace(element, rewriter.createStringPlaceholder(s, ASTNode.SIMPLE_NAME), null); + } + } catch (JavaModelException e) { + // do nothing } } } @@ -574,6 +594,11 @@ private String getReceiver(CallContext context, int modifiers, ImportRewriteCont String receiver= context.receiver; ITypeBinding invocationType= ASTNodes.getEnclosingType(context.invocation); ITypeBinding sourceType= fDeclaration.resolveBinding().getDeclaringClass(); + + if (invocationType != null && invocationType.getName().equals(receiver)) { + return null; + } + if (!context.receiverIsStatic && Modifier.isStatic(modifiers)) { if ("this".equals(receiver) && invocationType != null && Bindings.equals(invocationType, sourceType)) { //$NON-NLS-1$ receiver= null; @@ -598,6 +623,23 @@ private void updateMethodTypeVariable(ASTRewrite rewriter, CallContext context) rewriteReferences(rewriter, method.getTypeArguments(), fAnalyzer.getMethodTypeParameterReferences()); } + private void updateReturnStatements(ASTRewrite rewriter, CallContext context) { + if (rewriter != null && context != null && context.callMode == ASTNode.YIELD_STATEMENT) { + Block nodeToVisit= fDeclaration.getBody(); + ASTVisitor visitor= new ASTVisitor() { + @Override + public boolean visit(ReturnStatement node) { + Expression exp= node.getExpression(); + YieldStatement yStmt= rewriter.getAST().newYieldStatement(); + yStmt.setExpression((Expression) rewriter.createMoveTarget(exp)); + rewriter.replace(node, yStmt, null); + return false; + } + }; + nodeToVisit.accept(visitor); + } + } + private void rewriteReferences(ASTRewrite rewriter, ITypeBinding[] typeArguments, List typeParameterReferences) { if (typeArguments.length == 0) return; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/TargetProvider.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/TargetProvider.java index 426eac44..39e530f8 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/TargetProvider.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/code/TargetProvider.java @@ -452,6 +452,7 @@ public ICompilationUnit[] getAffectedCompilationUnits(final RefactoringStatus st Assert.isTrue(method != null); SearchPattern pattern= SearchPattern.createPattern(method, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + Assert.isNotNull(pattern); IJavaSearchScope scope= RefactoringScopeFactory.create(method, true, false); final HashSet affectedCompilationUnits= new HashSet<>(); CollectingSearchRequestor requestor= new CollectingSearchRequestor(binaryRefs) { diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/ElementStructureEnvironment.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/ElementStructureEnvironment.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/ElementStructureEnvironment.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/ElementStructureEnvironment.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintCreator.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintCreator.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintCreator.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintCreator.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintsSolver.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintsSolver.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintsSolver.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsConstraintsSolver.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsRefactoring.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsRefactoring.java similarity index 96% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsRefactoring.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsRefactoring.java index ea67a792..23768f34 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsRefactoring.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsRefactoring.java @@ -46,6 +46,7 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.compiler.IProblem; +import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.ASTRequestor; @@ -65,8 +66,11 @@ import org.eclipse.jdt.core.refactoring.IJavaRefactorings; import org.eclipse.jdt.core.refactoring.descriptors.InferTypeArgumentsDescriptor; +import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore; +import org.eclipse.jdt.internal.core.manipulation.JavaManipulationPlugin; import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory; +import org.eclipse.jdt.internal.corext.CorextCore; import org.eclipse.jdt.internal.corext.SourceRangeFactory; import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; import org.eclipse.jdt.internal.corext.refactoring.Checks; @@ -91,10 +95,7 @@ import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.internal.corext.util.Messages; -import org.eclipse.jdt.ui.JavaElementLabels; - import org.eclipse.jdt.internal.ui.IJavaStatusConstants; -import org.eclipse.jdt.internal.ui.JavaPlugin; public class InferTypeArgumentsRefactoring extends Refactoring { @@ -198,7 +199,7 @@ public void acceptAST(final ICompilationUnit source, final CompilationUnit ast) public void run() throws Exception { for (IProblem problem : ast.getProblems()) { if (problem.isError()) { - String cuName= JavaElementLabels.getElementLabel(source, JavaElementLabels.CU_QUALIFIED); + String cuName= JavaElementLabelsCore.getElementLabel(source, JavaElementLabelsCore.CU_QUALIFIED); String msg= Messages.format(RefactoringCoreMessages.InferTypeArgumentsRefactoring_error_in_cu_skipped, new Object[] {cuName}); result.addError(msg, JavaStatusContext.create(source, SourceRangeFactory.create(problem))); return; @@ -209,9 +210,9 @@ public void run() throws Exception { @Override public void handleException(Throwable exception) { - String cuName= JavaElementLabels.getElementLabel(source, JavaElementLabels.CU_QUALIFIED); + String cuName= JavaElementLabelsCore.getElementLabel(source, JavaElementLabelsCore.CU_QUALIFIED); String msg= Messages.format(RefactoringCoreMessages.InferTypeArgumentsRefactoring_internal_error, new Object[] {cuName}); - JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IJavaStatusConstants.INTERNAL_ERROR, msg, null)); + JavaManipulationPlugin.log(new Status(IStatus.ERROR, CorextCore.getPluginId(), IJavaStatusConstants.INTERNAL_ERROR, msg, null)); String msg2= Messages.format(RefactoringCoreMessages.InferTypeArgumentsRefactoring_error_skipped, new Object[] {cuName}); result.addError(msg2, JavaStatusContext.create(source)); } @@ -419,7 +420,14 @@ private static Type[] getTypeArguments(Type baseType, ArrayList nestedTypeArgumentCvs= getTypeArgumentCvs(elementCv, tCModel); Type[] nestedTypeArguments= getTypeArguments(typeArgument, nestedTypeArgumentCvs, rewrite, tCModel, leaveUnconstraindRaw); //recursion if (nestedTypeArguments != null) { @@ -541,7 +549,7 @@ public final ChangeDescriptor getDescriptor() { final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(name, this, header); final String[] settings= new String[fElements.length]; for (int index= 0; index < settings.length; index++) - settings[index]= JavaElementLabels.getTextLabel(fElements[index], JavaElementLabels.ALL_FULLY_QUALIFIED); + settings[index]= JavaElementLabelsCore.getTextLabel(fElements[index], JavaElementLabelsCore.ALL_FULLY_QUALIFIED); comment.addSetting(JDTRefactoringDescriptorComment.createCompositeSetting(RefactoringCoreMessages.InferTypeArgumentsRefactoring_original_elements, settings)); if (fAssumeCloneReturnsSameType) comment.addSetting(RefactoringCoreMessages.InferTypeArgumentsRefactoring_assume_clone); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java similarity index 98% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java index 0f5998bc..987441aa 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsTCModel.java @@ -37,6 +37,7 @@ import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.internal.core.manipulation.JavaManipulationPlugin; import org.eclipse.jdt.internal.corext.dom.Bindings; import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.CompilationUnitRange; import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ArrayType; @@ -62,8 +63,6 @@ import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.VariableVariable2; import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; -import org.eclipse.jdt.internal.ui.JavaPlugin; - public class InferTypeArgumentsTCModel { private static final String INDEXED_COLLECTION_ELEMENTS= "IndexedCollectionElements"; //$NON-NLS-1$ private static final String ARRAY_ELEMENT= "ArrayElement"; //$NON-NLS-1$ @@ -320,7 +319,7 @@ public VariableVariable2 makeVariableVariable(IVariableBinding variableBinding) fCuScopedConstraintVariables.add(storedCv); makeElementVariables(storedCv, type); makeArrayElementVariable(storedCv); - if (JavaPlugin.DEBUG_TYPE_CONSTRAINTS) + if (JavaManipulationPlugin.DEBUG_TYPE_CONSTRAINTS) storedCv.setData(ConstraintVariable2.TO_STRING, '[' + variableBinding.getName() + ']'); } return storedCv; @@ -348,7 +347,7 @@ public TypeVariable2 makeTypeVariable(Type type) { if (isAGenericType(ttype)) makeElementVariables(storedCv, ttype); makeArrayElementVariable(storedCv); - if (JavaPlugin.DEBUG_TYPE_CONSTRAINTS) + if (JavaManipulationPlugin.DEBUG_TYPE_CONSTRAINTS) storedCv.setData(ConstraintVariable2.TO_STRING, type.toString()); } return storedCv; @@ -361,7 +360,7 @@ public IndependentTypeVariable2 makeIndependentTypeVariable(TypeVariable type) { fCuScopedConstraintVariables.add(storedCv); // if (isAGenericType(typeBinding)) // would lead to infinite recursion! // makeElementVariables(storedCv, typeBinding); - if (JavaPlugin.DEBUG_TYPE_CONSTRAINTS) + if (JavaManipulationPlugin.DEBUG_TYPE_CONSTRAINTS) storedCv.setData(ConstraintVariable2.TO_STRING, "IndependentType(" + type.getPrettySignature() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } return storedCv; @@ -382,7 +381,7 @@ private ParameterizedTypeVariable2 makeParameterizedTypeVariable(TType type) { if (cv == storedCv) { fCuScopedConstraintVariables.add(storedCv); makeElementVariables(storedCv, type); - if (JavaPlugin.DEBUG_TYPE_CONSTRAINTS) + if (JavaManipulationPlugin.DEBUG_TYPE_CONSTRAINTS) storedCv.setData(ConstraintVariable2.TO_STRING, "ParameterizedType(" + type.getPrettySignature() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } return storedCv; @@ -401,7 +400,7 @@ private ArrayTypeVariable2 makeArrayTypeVariable(ArrayType type) { if (cv == storedCv) { fCuScopedConstraintVariables.add(storedCv); makeArrayElementVariable(storedCv); - if (JavaPlugin.DEBUG_TYPE_CONSTRAINTS) + if (JavaManipulationPlugin.DEBUG_TYPE_CONSTRAINTS) storedCv.setData(ConstraintVariable2.TO_STRING, "ArrayType(" + type.getPrettySignature() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } return storedCv; @@ -421,7 +420,7 @@ public ParameterTypeVariable2 makeParameterTypeVariable(IMethodBinding methodBin fCuScopedConstraintVariables.add(cv); makeElementVariables(storedCv, type); makeArrayElementVariable(storedCv); - if (JavaPlugin.DEBUG_TYPE_CONSTRAINTS) + if (JavaManipulationPlugin.DEBUG_TYPE_CONSTRAINTS) storedCv.setData(ConstraintVariable2.TO_STRING, "[Parameter(" + parameterIndex + "," + Bindings.asString(methodBinding) + ")]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } return storedCv; @@ -457,7 +456,7 @@ public ReturnTypeVariable2 makeReturnTypeVariable(IMethodBinding methodBinding) if (cv == storedCv) { makeElementVariables(storedCv, returnType); makeArrayElementVariable(storedCv); - if (JavaPlugin.DEBUG_TYPE_CONSTRAINTS) + if (JavaManipulationPlugin.DEBUG_TYPE_CONSTRAINTS) storedCv.setData(ConstraintVariable2.TO_STRING, "[ReturnType(" + Bindings.asString(methodBinding) + ")]"); //$NON-NLS-1$ //$NON-NLS-2$ } return storedCv; diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsUpdate.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsUpdate.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsUpdate.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/InferTypeArgumentsUpdate.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/ParametricStructureComputer.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/ParametricStructureComputer.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/generics/ParametricStructureComputer.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/generics/ParametricStructureComputer.java diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/refactoring.properties b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/refactoring.properties index 094d3419..572441dd 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/refactoring.properties +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/refactoring.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2021 IBM Corporation and others. +# Copyright (c) 2000, 2022 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -16,6 +16,7 @@ # Yves Joan - [reorg] Copy action should NOT add 'copy of' prefix - https://bugs.eclipse.org/bugs/show_bug.cgi?id=151668 # Red Hat Inc. - copied to jdt.core.manipulation # Pierre-Yves B. - [inline] Allow inlining of local variable initialized to null. - https://bugs.eclipse.org/93850 +# Nikolay Metchev - - [inline] Inline Local Variable does not qualify accesses to obscured types - https://bugs.eclipse.org/367536 ############################################################################### # NLS properties for the Refactoring Core @@ -228,6 +229,7 @@ SelfEncapsulateFieldRefactoring_methoddoesnotexist_status_fatalError=Method {0}( SelfEncapsulateField_name=Encapsulate Field SelfEncapsulateField_method_exists=A method ''{0}'' already exists in type ''{1}''. +SelfEncapsulateField_subtype_method_exists=A method ''{0}'' already exists in sub-type ''{1}''. SelfEncapsulateField_use_accessors=Use getter and setter methods in declaring type SelfEncapsulateField_compiler_errors_field=Cannot analyze field ''{0}'' due to the following compile error: {1} SelfEncapsulateField_compiler_errors_update={0} contains compile errors. This may affect field access update. @@ -743,6 +745,7 @@ RenameAnalyzeUtil_reference_shadowed=Problem in ''{0}''. The reference to ''{1}' CopyRefactoring_update_ref=Update type reference CodeRefactoringUtil_error_message=The body of the method ''{0}'' cannot be analyzed because of compilation errors in that method. To perform the operation you will need to fix the errors. InlineTemRefactoring_error_message_fieldsCannotBeInlined=Cannot inline fields +InlineTemRefactoring_error_message_inliningClashes=The expression ''{0}'' cannot be inlined without causing semantic changes due to clashing variable names HierarchyRefactoring_initializer=initializer HierarchyRefactoring_add_member=Add member declaration diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/MethodChecks.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/rename/MethodChecks.java similarity index 91% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/MethodChecks.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/rename/MethodChecks.java index d1a16a41..4517b3ca 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/MethodChecks.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/rename/MethodChecks.java @@ -27,7 +27,8 @@ import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.Modifier; -import org.eclipse.jdt.internal.corext.Corext; +import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore; +import org.eclipse.jdt.internal.corext.CorextCore; import org.eclipse.jdt.internal.corext.refactoring.Checks; import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; import org.eclipse.jdt.internal.corext.refactoring.base.RefactoringStatusCodes; @@ -37,8 +38,6 @@ import org.eclipse.jdt.internal.corext.util.Messages; import org.eclipse.jdt.internal.corext.util.MethodOverrideTester; -import org.eclipse.jdt.ui.JavaElementLabels; - public class MethodChecks { //no instances @@ -87,8 +86,8 @@ public static RefactoringStatus checkIfOverridesAnother(IMethod method, ITypeHie RefactoringStatusContext context= JavaStatusContext.create(overrides); String message= Messages.format(RefactoringCoreMessages.MethodChecks_overrides, - new String[]{JavaElementUtil.createMethodSignature(overrides), JavaElementLabels.getElementLabel(overrides.getDeclaringType(), JavaElementLabels.ALL_FULLY_QUALIFIED)}); - return RefactoringStatus.createStatus(RefactoringStatus.FATAL, message, context, Corext.getPluginId(), RefactoringStatusCodes.OVERRIDES_ANOTHER_METHOD, overrides); + new String[]{JavaElementUtil.createMethodSignature(overrides), JavaElementLabelsCore.getElementLabel(overrides.getDeclaringType(), JavaElementLabelsCore.ALL_FULLY_QUALIFIED)}); + return RefactoringStatus.createStatus(RefactoringStatus.FATAL, message, context, CorextCore.getPluginId(), RefactoringStatusCodes.OVERRIDES_ANOTHER_METHOD, overrides); } public static RefactoringStatus checkIfComesFromInterface(IMethod method, ITypeHierarchy hierarchy, IProgressMonitor monitor) throws JavaModelException { @@ -99,8 +98,8 @@ public static RefactoringStatus checkIfComesFromInterface(IMethod method, ITypeH RefactoringStatusContext context= JavaStatusContext.create(inInterface); String message= Messages.format(RefactoringCoreMessages.MethodChecks_implements, - new String[]{JavaElementUtil.createMethodSignature(inInterface), JavaElementLabels.getElementLabel(inInterface.getDeclaringType(), JavaElementLabels.ALL_FULLY_QUALIFIED)}); - return RefactoringStatus.createStatus(RefactoringStatus.FATAL, message, context, Corext.getPluginId(), RefactoringStatusCodes.METHOD_DECLARED_IN_INTERFACE, inInterface); + new String[]{JavaElementUtil.createMethodSignature(inInterface), JavaElementLabelsCore.getElementLabel(inInterface.getDeclaringType(), JavaElementLabelsCore.ALL_FULLY_QUALIFIED)}); + return RefactoringStatus.createStatus(RefactoringStatus.FATAL, message, context, CorextCore.getPluginId(), RefactoringStatusCodes.METHOD_DECLARED_IN_INTERFACE, inInterface); } public static IMethod isDeclaredInInterface(IMethod method, ITypeHierarchy hierarchy, IProgressMonitor monitor) throws JavaModelException { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/ConstructorReferenceFinder.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/ConstructorReferenceFinder.java index fbbe84b9..53e1aac4 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/ConstructorReferenceFinder.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/ConstructorReferenceFinder.java @@ -181,6 +181,9 @@ private SearchResultGroup[] getImplicitConstructorReferences(IProgressMonitor pm private List getImplicitConstructorReferencesInClassCreations(WorkingCopyOwner owner, IProgressMonitor pm, RefactoringStatus status) throws JavaModelException { //XXX workaround for jdt core bug 23112 SearchPattern pattern= SearchPattern.createPattern(fType, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return List.of(); + } IJavaSearchScope scope= RefactoringScopeFactory.create(fType); SearchResultGroup[] refs= RefactoringSearchEngine.search(pattern, owner, scope, pm, status); List result= new ArrayList<>(); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/ImportRemover.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/ImportRemover.java index 13d50f9b..1158fb43 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/ImportRemover.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/ImportRemover.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -21,6 +21,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.dom.ASTNode; @@ -56,6 +57,7 @@ * {@link ImportRewrite#addImport(ITypeBinding)} etc. */ public class ImportRemover { + private static class StaticImportData { private boolean fField; @@ -72,8 +74,16 @@ private StaticImportData(String qualifier, String member, boolean field) { private static final String REMOVED= "removed"; //$NON-NLS-1$ private static final String RETAINED= "retained"; //$NON-NLS-1$ - - private final String PROPERTY_KEY= String.valueOf(System.currentTimeMillis()); + /** + * Namespace for the property key + */ + private static final String PROPERTY_KEY_CLASS_ID= "IR"; //$NON-NLS-1$ + /** + * Provides thread-safe uniqueness for the propertyKey + */ + private static final AtomicInteger PROPERTY_KEY_COUNTER = new AtomicInteger(); + + private final String propertyKey; private final IJavaProject fProject; private final CompilationUnit fRoot; @@ -85,6 +95,7 @@ private StaticImportData(String qualifier, String member, boolean field) { public ImportRemover(IJavaProject project, CompilationUnit root) { fProject= project; fRoot= root; + propertyKey= PROPERTY_KEY_CLASS_ID + PROPERTY_KEY_COUNTER.getAndIncrement(); } private void divideTypeRefs(List importNames, List staticNames, List removedRefs, List unremovedRefs) { @@ -93,7 +104,7 @@ private void divideTypeRefs(List importNames, List stati int fRemovingStart= -1; @Override public void preVisit(ASTNode node) { - Object property= node.getProperty(PROPERTY_KEY); + Object property= node.getProperty(propertyKey); if (property == REMOVED) { if (fRemovingStart == -1) { fRemovingStart= node.getStartPosition(); @@ -103,7 +114,7 @@ public void preVisit(ASTNode node) { * an intermediate RETAINED node. * Drop REMOVED property to prevent problems later (premature end of REMOVED section). */ - node.setProperty(PROPERTY_KEY, null); + node.setProperty(propertyKey, null); } } else if (property == RETAINED) { if (fRemovingStart != -1) { @@ -115,14 +126,14 @@ public void preVisit(ASTNode node) { * an intermediate REMOVED node and must have an enclosing REMOVED node. * Drop RETAINED property to prevent problems later (premature restart of REMOVED section). */ - node.setProperty(PROPERTY_KEY, null); + node.setProperty(propertyKey, null); } } super.preVisit(node); } @Override public void postVisit(ASTNode node) { - Object property= node.getProperty(PROPERTY_KEY); + Object property= node.getProperty(propertyKey); if (property == RETAINED) { int end= node.getStartPosition() + node.getLength(); fRemovingStart= end; @@ -288,11 +299,11 @@ public void registerAddedStaticImport(IBinding binding) { public void registerRemovedNode(ASTNode removed) { fHasRemovedNodes= true; - removed.setProperty(PROPERTY_KEY, REMOVED); + removed.setProperty(propertyKey, REMOVED); } public void registerRetainedNode(ASTNode retained) { - retained.setProperty(PROPERTY_KEY, RETAINED); + retained.setProperty(propertyKey, RETAINED); } public void applyRemoves(ImportRewrite importRewrite) { diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MemberVisibilityAdjustor.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MemberVisibilityAdjustor.java index 6aac32c8..7c23511f 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MemberVisibilityAdjustor.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MemberVisibilityAdjustor.java @@ -551,7 +551,11 @@ private boolean isInsideMovedMember(final IJavaElement element) { * @throws JavaModelException if an error occurs during search */ private SearchResultGroup[] findReferences(final IMember member, final IProgressMonitor monitor) throws JavaModelException { - final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); + SearchPattern pattern= SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return new SearchResultGroup[0]; + } + final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(pattern); engine.setOwner(fOwner); engine.setFiltering(true, true); engine.setScope(RefactoringScopeFactory.create(member)); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInnerToTopRefactoring.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInnerToTopRefactoring.java index 30498314..17ff5560 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInnerToTopRefactoring.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInnerToTopRefactoring.java @@ -1138,7 +1138,11 @@ private String createSourceForNewCu(final ICompilationUnit unit, final IProgress } private Map createTypeReferencesMapping(IProgressMonitor pm, RefactoringStatus status) throws JavaModelException { - final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(fType, IJavaSearchConstants.ALL_OCCURRENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); + SearchPattern pattern= SearchPattern.createPattern(fType, IJavaSearchConstants.ALL_OCCURRENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return Map.of(); + } + final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(pattern); engine.setFiltering(true, true); engine.setScope(RefactoringScopeFactory.create(fType)); engine.setStatus(status); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java index 3ed10854..5bbfa17f 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveInstanceMethodProcessor.java @@ -1540,6 +1540,9 @@ protected SearchResultGroup[] computeMethodReferences(final IProgressMonitor mon monitor.beginTask("", 1); //$NON-NLS-1$ monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking); SearchPattern pattern= SearchPattern.createPattern(fMethod, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return new SearchResultGroup[0]; + } IJavaSearchScope scope= RefactoringScopeFactory.create(fMethod, true, false); String binaryRefsDescription= Messages.format(RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description , BasicElementLabels.getJavaElementName(fMethod.getElementName())); diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveStaticMembersProcessor.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveStaticMembersProcessor.java index 529fc598..27565c8f 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveStaticMembersProcessor.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/structure/MoveStaticMembersProcessor.java @@ -631,7 +631,11 @@ private String getQualifiedTypeLabel(IType accessingType) { } private static SearchResultGroup[] getReferences(IMember member, IProgressMonitor monitor, RefactoringStatus status) throws JavaModelException { - final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); + SearchPattern pattern= SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return new SearchResultGroup[0]; + } + final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(pattern); engine.setFiltering(true, true); engine.setScope(RefactoringScopeFactory.create(member)); engine.setStatus(status); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java similarity index 96% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java index 90c0e932..10b5a435 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Red Hat Inc. - refactored to jdt.core.manipulation *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.surround; @@ -43,8 +44,11 @@ import org.eclipse.jdt.internal.corext.dom.Selection; import org.eclipse.jdt.internal.corext.refactoring.util.AbstractExceptionAnalyzer; -import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessor; +import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessorUtil; +/** + * @since 1.16 + */ public class ExceptionAnalyzer extends AbstractExceptionAnalyzer { private Selection fSelection; @@ -207,7 +211,7 @@ private boolean handleMethodReference(MethodReference node) { IMethodBinding referredMethodBinding= node.resolveMethodBinding(); if (referredMethodBinding == null) return false; - IMethodBinding functionalMethod= QuickAssistProcessor.getFunctionalMethodForMethodReference(node); + IMethodBinding functionalMethod= QuickAssistProcessorUtil.getFunctionalMethodForMethodReference(node); if (functionalMethod == null || functionalMethod.isGenericMethod()) { // generic lambda expressions are not allowed return false; } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java similarity index 89% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java index a45e1523..41d0e638 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java @@ -60,6 +60,7 @@ public SurroundWithTryWithResourcesAnalyzer(ICompilationUnit unit, Selection sel } public ITypeBinding[] getExceptions(Selection selection) { + fExceptions= new ITypeBinding[0]; if (fEnclosingNode != null && !getStatus().hasFatalError()) { fExceptions= ExceptionAnalyzer.perform(fEnclosingNode, selection, false); if (fExceptions == null || fExceptions.length == 0) { @@ -110,25 +111,27 @@ public ITypeBinding[] getCaughtExceptions() { public ITypeBinding[] getThrownExceptions() { List exceptions= new ArrayList<>(); - if (fEnclosingNode.getNodeType() == ASTNode.METHOD_DECLARATION) { - List thrownExceptions= ((MethodDeclaration) fEnclosingNode).thrownExceptionTypes(); - for (Type type : thrownExceptions) { - ITypeBinding thrownException= type.resolveBinding(); - if (thrownException != null) { - exceptions.add(thrownException); + if (fEnclosingNode != null) { + if (fEnclosingNode.getNodeType() == ASTNode.METHOD_DECLARATION) { + List thrownExceptions= ((MethodDeclaration) fEnclosingNode).thrownExceptionTypes(); + for (Type type : thrownExceptions) { + ITypeBinding thrownException= type.resolveBinding(); + if (thrownException != null) { + exceptions.add(thrownException); + } } - } - } else { - ITypeBinding typeBinding= null; - if (fEnclosingNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY) { - typeBinding= ((LambdaExpression) fEnclosingNode.getParent()).resolveTypeBinding(); - } else if (fEnclosingNode instanceof MethodReference) { - typeBinding= ((MethodReference) fEnclosingNode).resolveTypeBinding(); - } - if (typeBinding != null) { - IMethodBinding methodBinding= typeBinding.getFunctionalInterfaceMethod(); - if (methodBinding != null) { - Collections.addAll(exceptions, methodBinding.getExceptionTypes()); + } else { + ITypeBinding typeBinding= null; + if (fEnclosingNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY) { + typeBinding= ((LambdaExpression) fEnclosingNode.getParent()).resolveTypeBinding(); + } else if (fEnclosingNode instanceof MethodReference) { + typeBinding= ((MethodReference) fEnclosingNode).resolveTypeBinding(); + } + if (typeBinding != null) { + IMethodBinding methodBinding= typeBinding.getFunctionalInterfaceMethod(); + if (methodBinding != null) { + Collections.addAll(exceptions, methodBinding.getExceptionTypes()); + } } } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoringCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoringCore.java new file mode 100644 index 00000000..46136206 --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoringCore.java @@ -0,0 +1,683 @@ +/******************************************************************************* + * Copyright (c) 2021 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial code based on SurroundWithTryCatchRefactoring + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.refactoring.surround; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; + +import org.eclipse.text.edits.MultiTextEdit; +import org.eclipse.text.edits.TextEdit; +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.TextFileChange; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.Assignment; +import org.eclipse.jdt.core.dom.Block; +import org.eclipse.jdt.core.dom.BodyDeclaration; +import org.eclipse.jdt.core.dom.CatchClause; +import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ExpressionStatement; +import org.eclipse.jdt.core.dom.IExtendedModifier; +import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.IVariableBinding; +import org.eclipse.jdt.core.dom.LambdaExpression; +import org.eclipse.jdt.core.dom.MethodReference; +import org.eclipse.jdt.core.dom.Modifier; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.ThrowStatement; +import org.eclipse.jdt.core.dom.TryStatement; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.UnionType; +import org.eclipse.jdt.core.dom.VariableDeclaration; +import org.eclipse.jdt.core.dom.VariableDeclarationExpression; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation; +import org.eclipse.jdt.core.dom.rewrite.ListRewrite; +import org.eclipse.jdt.core.refactoring.CompilationUnitChange; + +import org.eclipse.jdt.internal.core.manipulation.StubUtility; +import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving; +import org.eclipse.jdt.internal.core.manipulation.util.Strings; +import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; +import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.dom.CodeScopeBuilder; +import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; +import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder; +import org.eclipse.jdt.internal.corext.dom.Selection; +import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore; +import org.eclipse.jdt.internal.corext.refactoring.Checks; +import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; +import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; +import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil; + +import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessorUtil; + +/** + * Surround a set of statements with a try-with-resources block. + * + * Special case: + * + * URL url= file.toURL(); + * + * In this case the variable declaration statement gets convert into a + * declaration without initializer. So the body of the try/catch block + * only consists of new assignments. In this case we can't move the + * selected nodes (e.g. the declaration) into the try block. + */ +public class SurroundWithTryWithResourcesRefactoringCore extends Refactoring { + + public final String GROUP_EXC_TYPE= "exc_type"; //$NON-NLS-1$ + public final String GROUP_EXC_NAME= "exc_name"; //$NON-NLS-1$ + public final String GROUP_TRY_STATEMENT= "try_stmt"; //$NON-NLS-1$ + + private Selection fSelection; + private SurroundWithTryWithResourcesAnalyzer fAnalyzer; + private boolean fLeaveDirty; + + private ICompilationUnit fCUnit; + private CompilationUnit fRootNode; + private ASTRewrite fRewriter; + private ImportRewrite fImportRewrite; + private CodeScopeBuilder.Scope fScope; + private ASTNode[] fSelectedNodes; + private List fAutoClosableNodes; + + private LinkedProposalModelCore fLinkedProposalModel; + + protected SurroundWithTryWithResourcesRefactoringCore(ICompilationUnit cu, Selection selection) { + fCUnit= cu; + fSelection= selection; + fLeaveDirty= false; + } + + public static SurroundWithTryWithResourcesRefactoringCore create(ICompilationUnit cu, int offset, int length) { + return new SurroundWithTryWithResourcesRefactoringCore(cu, Selection.createFromStartLength(offset, length)); + } + + public static SurroundWithTryWithResourcesRefactoringCore create(ICompilationUnit cu, Selection selection) { + return new SurroundWithTryWithResourcesRefactoringCore(cu, selection); + } + + public LinkedProposalModelCore getLinkedProposalModelCore() { + return fLinkedProposalModel; + } + + public void setLeaveDirty(boolean leaveDirty) { + fLeaveDirty= leaveDirty; + } + + public boolean stopExecution() { + if (fAnalyzer == null) + return true; + ITypeBinding[] exceptions= fAnalyzer.getExceptions(fAnalyzer.getSelection()); + List autoClosableNodes= fAnalyzer.getCoveredAutoClosableNodes(); + return (exceptions == null || exceptions.length == 0) && (autoClosableNodes == null || autoClosableNodes.isEmpty()); + } + + /* non Java-doc + * @see IRefactoring#getName() + */ + @Override + public String getName() { + return RefactoringCoreMessages.SurroundWithTryWithResourcesRefactoring_name; + } + + public RefactoringStatus checkActivationBasics(CompilationUnit rootNode) throws CoreException { + RefactoringStatus result= new RefactoringStatus(); + fRootNode= rootNode; + + fAnalyzer= new SurroundWithTryWithResourcesAnalyzer(fCUnit, fSelection); + fRootNode.accept(fAnalyzer); + result.merge(fAnalyzer.getStatus()); + fAutoClosableNodes= fAnalyzer.getCoveredAutoClosableNodes(); + if (fAutoClosableNodes == null || fAutoClosableNodes.isEmpty()) { + result.merge(RefactoringStatus.createWarningStatus(RefactoringCoreMessages.SurroundWithTryWithResourcesRefactoring_notAutoclosable)); + } + return result; + } + + + /* + * @see Refactoring#checkActivation(IProgressMonitor) + */ + @Override + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { + CompilationUnit rootNode= new RefactoringASTParser(IASTSharedValues.SHARED_AST_LEVEL).parse(fCUnit, true, pm); + return checkActivationBasics(rootNode); + } + + /* + * @see Refactoring#checkInput(IProgressMonitor) + */ + @Override + public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException { + return Checks.validateModifiesFiles( + ResourceUtil.getFiles(new ICompilationUnit[]{fCUnit}), + getValidationContext(), pm); + } + + protected LinkedProposalModelCore createLinkedProposalModel() { + return new LinkedProposalModelCore(); + } + + /* non Java-doc + * @see IRefactoring#createChange(IProgressMonitor) + */ + @Override + public Change createChange(IProgressMonitor pm) throws CoreException { + final String NN= ""; //$NON-NLS-1$ + if (pm == null) pm= new NullProgressMonitor(); + pm.beginTask(NN, 2); + try { + final CompilationUnitChange result= new CompilationUnitChange(getName(), fCUnit); + if (fLeaveDirty) + result.setSaveMode(TextFileChange.LEAVE_DIRTY); + MultiTextEdit root= new MultiTextEdit(); + result.setEdit(root); + fRewriter= ASTRewrite.create(fAnalyzer.getEnclosingBodyDeclaration().getAST()); + fImportRewrite= StubUtility.createImportRewrite(fRootNode, true); + + fLinkedProposalModel= createLinkedProposalModel(); + + fScope= CodeScopeBuilder.perform(fAnalyzer.getEnclosingBodyDeclaration(), fSelection). + findScope(fSelection.getOffset(), fSelection.getLength()); + fScope.setCursor(fSelection.getOffset()); + + fSelectedNodes= fAnalyzer.getSelectedNodes(); + + createTryWithResourcesStatement(fCUnit.getBuffer(), fCUnit.findRecommendedLineSeparator()); + + if (fImportRewrite.hasRecordedChanges()) { + TextEdit edit= fImportRewrite.rewriteImports(null); + root.addChild(edit); + result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {edit} )); + } + TextEdit change= fRewriter.rewriteAST(); + root.addChild(change); + result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {change} )); + return result; + } finally { + pm.done(); + } + } + + private AST getAST() { + return fRootNode.getAST(); + } + + @SuppressWarnings("null") + private void createTryWithResourcesStatement(org.eclipse.jdt.core.IBuffer buffer, String lineDelimiter) throws CoreException { + List result= new ArrayList<>(1); + boolean modifyExistingTry= false; + TryStatement tryStatement= null; + ITypeBinding[] exceptions= fAnalyzer.getExceptions(fAnalyzer.getSelection()); + ImportRewriteContext context= new ContextSensitiveImportRewriteContext(fAnalyzer.getEnclosingBodyDeclaration(), fImportRewrite); + + TryStatement enclosingTry= (TryStatement)ASTResolving.findAncestor(fSelectedNodes[0], ASTNode.TRY_STATEMENT); + ListRewrite resourcesRewriter= null; + ListRewrite clausesRewriter= null; + ListRewrite statements= null; + if (enclosingTry == null || enclosingTry.getBody() == null || enclosingTry.getBody().statements().get(0) != fSelectedNodes[0]) { + tryStatement= getAST().newTryStatement(); + statements= fRewriter.getListRewrite(tryStatement.getBody(), Block.STATEMENTS_PROPERTY); + } else { + modifyExistingTry= true; + resourcesRewriter= fRewriter.getListRewrite(enclosingTry, TryStatement.RESOURCES2_PROPERTY); + clausesRewriter= fRewriter.getListRewrite(enclosingTry, TryStatement.CATCH_CLAUSES_PROPERTY); + } + + CatchClause catchClause= getAST().newCatchClause(); + SingleVariableDeclaration decl= getAST().newSingleVariableDeclaration(); + String varName= StubUtility.getExceptionVariableName(fCUnit.getJavaProject()); + String name= fScope.createName(varName, false); + decl.setName(getAST().newSimpleName(name)); + + + boolean selectedNodeRemoved= false; + ASTNode expressionStatement= null; + ASTNode replacementNode= null; + List nodesInRange= new ArrayList<>(); + + if (!modifyExistingTry) { + List variableDeclarations= getSpecialVariableDeclarationStatements(); + for (ASTNode node : fSelectedNodes) { + if (fAutoClosableNodes.contains(node)) { + continue; + } + if (node instanceof VariableDeclarationStatement && variableDeclarations.contains(node)) { + AST ast= getAST(); + VariableDeclarationStatement statement= (VariableDeclarationStatement)node; + // Create a copy and remove the initializer + VariableDeclarationStatement copy= (VariableDeclarationStatement)ASTNode.copySubtree(ast, statement); + List modifiers= copy.modifiers(); + for (Iterator iter= modifiers.iterator(); iter.hasNext();) { + IExtendedModifier modifier= iter.next(); + if (modifier.isModifier() && Modifier.isFinal(((Modifier)modifier).getKeyword().toFlagValue())) { + iter.remove(); + } + } + List fragments= copy.fragments(); + for (VariableDeclarationFragment fragment : fragments) { + fragment.setInitializer(null); + } + + // "var" type cannot have null initializer, so change to inferred type + if (ASTNodes.isVarType(statement, fRootNode)) { + ITypeBinding binding= statement.getType().resolveBinding(); + if (binding != null) { + Type varType= fImportRewrite.addImport(binding, getAST(), context, TypeLocation.LOCAL_VARIABLE); + copy.setType(varType); + } + } + + CompilationUnit root= (CompilationUnit)statement.getRoot(); + int extendedStart= root.getExtendedStartPosition(statement); + // we have a leading comment and the comment is covered by the selection + if (extendedStart != statement.getStartPosition() && extendedStart >= fSelection.getOffset()) { + String commentToken= buffer.getText(extendedStart, statement.getStartPosition() - extendedStart); + commentToken= Strings.trimTrailingTabsAndSpaces(commentToken); + Type type= statement.getType(); + String typeName= buffer.getText(type.getStartPosition(), type.getLength()); + copy.setType((Type)fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType())); + } + result.add(copy); + // convert the fragments into expression statements + fragments= statement.fragments(); + if (!fragments.isEmpty()) { + List newExpressionStatements= new ArrayList<>(); + for (VariableDeclarationFragment fragment : fragments) { + Expression initializer= fragment.getInitializer(); + if (initializer != null) { + Assignment assignment= ast.newAssignment(); + assignment.setLeftHandSide((Expression)fRewriter.createCopyTarget(fragment.getName())); + assignment.setRightHandSide((Expression)fRewriter.createCopyTarget(initializer)); + newExpressionStatements.add(ast.newExpressionStatement(assignment)); + } + } + if (!newExpressionStatements.isEmpty()) { + if (fSelectedNodes.length == 1) { + expressionStatement= fRewriter.createGroupNode(newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()])); + } else { + fRewriter.replace( + statement, + fRewriter.createGroupNode(newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()])), + null); + } + } else { + fRewriter.remove(statement, null); + selectedNodeRemoved= true; + } + } else { + fRewriter.remove(statement, null); + selectedNodeRemoved= true; + } + } + } + result.add(tryStatement); + if (result.size() == 1) { + replacementNode= result.get(0); + } else { + replacementNode= fRewriter.createGroupNode(result.toArray(new ASTNode[result.size()])); + } + + ASTNode node= fSelectedNodes[0]; + List coveredStatements= new ArrayList<>(); + for (ASTNode coveredNode : fSelectedNodes) { + Statement statement= ASTResolving.findParentStatement(coveredNode); + if (statement == null) { + continue; + } + if (!coveredStatements.contains(statement)) { + coveredStatements.add(statement); + } + } + + Selection nodesInRangeSelection= fAnalyzer.getSelection(); + if (!fAutoClosableNodes.isEmpty()) { + ASTNode parentBodyDeclaration= (node instanceof Block || node instanceof BodyDeclaration) ? + node : ASTNodes.getFirstAncestorOrNull(node, Block.class, BodyDeclaration.class); + int start= fAutoClosableNodes.get(0).getStartPosition(); + ASTNode lastSelectedNode= fSelectedNodes[fSelectedNodes.length - 1]; + int end= lastSelectedNode.getStartPosition() + lastSelectedNode.getLength(); + + for (ASTNode astNode : fAutoClosableNodes) { + int endPosition= findEndPosition(astNode); + end= Math.max(end, endPosition); + } + + // recursive loop to find all nodes affected by wrapping in try block + nodesInRange= findNodesInRange(parentBodyDeclaration, start, end); + int oldEnd= end; + int newEnd= end; + while (true) { + newEnd= oldEnd; + for (ASTNode astNode : nodesInRange) { + int endPosition= findEndPosition(astNode); + newEnd= Math.max(newEnd, endPosition); + } + if (newEnd > oldEnd) { + oldEnd= newEnd; + nodesInRange= findNodesInRange(parentBodyDeclaration, start, newEnd); + continue; + } + break; + } + if (nodesInRange.size() > 0) { + // must recalculate exceptions as additional lines are now in try statement + ASTNode lastNode= nodesInRange.get(nodesInRange.size() - 1); + nodesInRangeSelection= Selection.createFromStartEnd(start, lastNode.getStartPosition() + lastNode.getLength()); + exceptions= fAnalyzer.getExceptions(nodesInRangeSelection); + } + nodesInRange.removeAll(fAutoClosableNodes); + nodesInRange.removeAll(Arrays.asList(fSelectedNodes)); + } + } + + // add required resource statements + CompilationUnit cu= (CompilationUnit)fSelectedNodes[0].getRoot(); + AST ast= fSelectedNodes[0].getAST(); + Set resourceNameList= new HashSet<>(); + List allExceptions= new ArrayList<>(Arrays.asList(exceptions)); + for (ASTNode coveredNode : fAutoClosableNodes) { + ASTNode findAncestor= ASTResolving.findAncestor(coveredNode, ASTNode.VARIABLE_DECLARATION_STATEMENT); + if (findAncestor == null) { + findAncestor= ASTResolving.findAncestor(coveredNode, ASTNode.ASSIGNMENT); + } + if (findAncestor instanceof VariableDeclarationStatement) { + VariableDeclarationStatement vds= (VariableDeclarationStatement) findAncestor; + String commentToken= null; + int extendedStatementStart= cu.getExtendedStartPosition(vds); + if(vds.getStartPosition() > extendedStatementStart) { + commentToken= buffer.getText(extendedStatementStart, vds.getStartPosition() - extendedStatementStart); + } + Type type= vds.getType(); + ITypeBinding typeBinding= type.resolveBinding(); + if (typeBinding != null) { + IMethodBinding close= findAutocloseMethod(typeBinding); + if (close != null) { + for (ITypeBinding exceptionType : close.getExceptionTypes()) { + if (!allExceptions.contains(exceptionType)) { + allExceptions.add(exceptionType); + } + } + } + } + String typeName= buffer.getText(type.getStartPosition(), type.getLength()); + + for (Object object : vds.fragments()) { + VariableDeclarationFragment variableDeclarationFragment= (VariableDeclarationFragment) object; + VariableDeclarationFragment newVariableDeclarationFragment= ast.newVariableDeclarationFragment(); + SimpleName vdsName= variableDeclarationFragment.getName(); + + if(commentToken == null) { + int extendedStart= cu.getExtendedStartPosition(variableDeclarationFragment); + commentToken= buffer.getText(extendedStart, variableDeclarationFragment.getStartPosition() - extendedStart); + } + commentToken= Strings.trimTrailingTabsAndSpaces(commentToken); + commentToken += commentToken.isEmpty() ? "" : " "; //$NON-NLS-1$ //$NON-NLS-2$ + + newVariableDeclarationFragment.setName(ast.newSimpleName(vdsName.getIdentifier())); + Expression newExpression= null; + Expression initializer= variableDeclarationFragment.getInitializer(); + if (initializer == null) { + fRewriter.remove(coveredNode, null); + continue; + } else { + newExpression= (Expression) fRewriter.createMoveTarget(initializer); + } + resourceNameList.add(vdsName.getIdentifier()); + newVariableDeclarationFragment.setInitializer(newExpression); + VariableDeclarationExpression newVariableDeclarationExpression= ast.newVariableDeclarationExpression(newVariableDeclarationFragment); + newVariableDeclarationExpression.setType( + (Type) fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType())); + if (modifyExistingTry) { + if (enclosingTry.resources().isEmpty()) { + resourcesRewriter.insertFirst(newVariableDeclarationExpression, null); + } else { + resourcesRewriter.insertLast(newVariableDeclarationExpression, null); + } + } else { + tryStatement.resources().add(newVariableDeclarationExpression); + } + commentToken= null; + } +// String commentToken2= ""; //$NON-NLS-1$ +// int extendedStart= cu.getExtendedStartPosition(vds); +// int extendedLength= cu.getExtendedLength(vds); +// int endCommentLength= extendedLength - (vds.getStartPosition() - extendedStart) - vds.getLength(); +// if (endCommentLength > 0) { +// commentToken2= buffer.getText(vds.getStartPosition() + vds.getLength(), +// endCommentLength); +// commentToken2= Strings.trimLeadingTabsAndSpaces(commentToken2); +// } + } + } + + List mustRethrowList= new ArrayList<>(); + List catchExceptions= fAnalyzer.calculateCatchesAndRethrows(ASTNodes.filterSubtypes(allExceptions), mustRethrowList); + List filteredExceptions= ASTNodes.filterSubtypes(catchExceptions); + if (catchExceptions.size() > 0) { + LinkedProposalModelCore linkedProposalModel= new LinkedProposalModelCore(); + int i= 0; + if (!modifyExistingTry) { + for (ITypeBinding mustThrow : mustRethrowList) { + CatchClause newClause= ast.newCatchClause(); + SingleVariableDeclaration newDecl= ast.newSingleVariableDeclaration(); + newDecl.setName(ast.newSimpleName(name)); + Type importType= fImportRewrite.addImport(mustThrow, ast, context, TypeLocation.EXCEPTION); + newDecl.setType(importType); + newClause.setException(newDecl); + ThrowStatement newThrowStatement= ast.newThrowStatement(); + newThrowStatement.setExpression(ast.newSimpleName(name)); + linkedProposalModel.getPositionGroup(GROUP_EXC_NAME + i, true).addPosition(fRewriter.track(decl.getName()), false); + newClause.getBody().statements().add(newThrowStatement); + tryStatement.catchClauses().add(newClause); + ++i; + } + } + UnionType unionType= getAST().newUnionType(); + List types= unionType.types(); + for (ITypeBinding exception : filteredExceptions) { + Type type= fImportRewrite.addImport(exception, getAST(), context, TypeLocation.EXCEPTION); + types.add(type); + fLinkedProposalModel.getPositionGroup(GROUP_EXC_TYPE + i, true).addPosition(fRewriter.track(type), i == 0); + i++; + } + + decl.setType(unionType); + catchClause.setException(decl); + fLinkedProposalModel.getPositionGroup(GROUP_EXC_NAME + 0, true).addPosition(fRewriter.track(decl.getName()), false); + Statement st= getCatchBody("Exception", name, lineDelimiter); //$NON-NLS-1$ + if (st != null) { + catchClause.getBody().statements().add(st); + } + if (modifyExistingTry) { + clausesRewriter.insertLast(catchClause, null); + } else { + tryStatement.catchClauses().add(catchClause); + } + } + + + if (fSelectedNodes.length == 1 && fAutoClosableNodes.isEmpty()) { + ASTNode selectedNode= fSelectedNodes[0]; + + if (selectedNode instanceof MethodReference) { + MethodReference methodReference= (MethodReference) selectedNode; + IMethodBinding functionalMethod= QuickAssistProcessorUtil.getFunctionalMethodForMethodReference(methodReference); + // functionalMethod is non-null and non-generic. See ExceptionAnalyzer.handleMethodReference(MethodReference node). + Assert.isTrue(functionalMethod != null && !functionalMethod.isGenericMethod()); + LambdaExpression lambda= QuickAssistProcessorUtil.convertMethodRefernceToLambda(methodReference, functionalMethod, fRootNode, fRewriter, null, true); + ASTNode statementInBlock= (ASTNode) ((Block) lambda.getBody()).statements().get(0); + fRewriter.replace(statementInBlock, replacementNode, null); + statements.insertLast(statementInBlock, null); + return; + } + + LambdaExpression enclosingLambda= ASTResolving.findEnclosingLambdaExpression(selectedNode); + if (enclosingLambda != null && selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY && enclosingLambda.resolveMethodBinding() != null) { + QuickAssistProcessorUtil.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter); + Block blockBody= (Block) fRewriter.get(enclosingLambda, LambdaExpression.BODY_PROPERTY); + ASTNode statementInBlock= (ASTNode) blockBody.statements().get(0); + fRewriter.replace(statementInBlock, replacementNode, null); + statements.insertLast(statementInBlock, null); + return; + } + + if (expressionStatement != null) { + statements.insertLast(expressionStatement, null); + } else { + if (!selectedNodeRemoved) + statements.insertLast(fRewriter.createMoveTarget(selectedNode), null); + } + fRewriter.replace(selectedNode, replacementNode, null); + } else if (modifyExistingTry) { + ListRewrite source= fRewriter.getListRewrite(enclosingTry.getBody(), Block.STATEMENTS_PROPERTY); + for (ASTNode node : fAutoClosableNodes) { + source.remove(node, null); + } + } else { + ListRewrite source= fRewriter.getListRewrite( + fSelectedNodes[0].getParent(), + (ChildListPropertyDescriptor)fSelectedNodes[0].getLocationInParent()); + List nodes= new ArrayList<>(Arrays.asList(fSelectedNodes)); + if (!nodesInRange.isEmpty()) { + nodes.addAll(nodesInRange); + } + int index= fAutoClosableNodes.size(); + if (index < nodes.size()) { + ASTNode toMove= source.createMoveTarget(nodes.get(index), nodes.get(nodes.size() - 1), + index == 0 ? replacementNode : null, null); + statements.insertLast(toMove, null); + } + if (index > 0) { + source.replace(fAutoClosableNodes.get(0), replacementNode, null); + for (int i= 1; i < index; ++i) { + source.remove(fAutoClosableNodes.get(i), null); + } + } + } + + } + + public static IMethodBinding findAutocloseMethod(ITypeBinding type) { + while (type != null) { + IMethodBinding[] methods= type.getDeclaredMethods(); + for (IMethodBinding method : methods) { + if ("close".equals(method.getName()) && method.getParameterTypes().length == 0) { //$NON-NLS-1$ + return method; + } + } + type= type.getSuperclass(); + } + return null; + } + + private int findEndPosition(ASTNode node) { + int end= node.getStartPosition() + node.getLength(); + Map nodeSimpleNameBindings= fAnalyzer.getVariableStatementBinding(node); + List nodeNames= new ArrayList<>(nodeSimpleNameBindings.keySet()); + if (nodeNames.isEmpty()) { + return -1; + } + SimpleName nodeSimpleName= nodeNames.get(0); + SimpleName[] coveredNodeBindings= LinkedNodeFinder.findByNode(node.getRoot(), nodeSimpleName); + if (coveredNodeBindings.length == 0) { + return -1; + } + for (ASTNode astNode : coveredNodeBindings) { + end= Math.max(end, (astNode.getStartPosition() + astNode.getLength())); + } + return end; + } + + // find all nodes (statements) that are within the start/end positions + public static List findNodesInRange(ASTNode astNode, final int start, final int end) { + List nodesInRange= new ArrayList<>(); + astNode.accept(new ASTVisitor() { + int pre= start; + + @Override + public void preVisit(ASTNode preNode) { + pre= preNode.getStartPosition(); + super.preVisit(preNode); + } + + @Override + public void postVisit(ASTNode postNode) { + int post= postNode.getStartPosition() + postNode.getLength(); + if (pre >= start && post <= end) { + Statement statement= ASTResolving.findParentStatement(postNode); + while (statement != null && statement.getParent() != astNode) { + ASTNode parent= statement.getParent(); + if (parent == null) { + return; + } + statement= ASTResolving.findParentStatement(parent); + } + if (statement != null && !nodesInRange.contains(statement)) { + nodesInRange.add(statement); + } + } + super.postVisit(postNode); + } + }); + return nodesInRange; + } + + private List getSpecialVariableDeclarationStatements() { + List result= new ArrayList<>(3); + for (VariableDeclaration local : fAnalyzer.getAffectedLocals()) { + ASTNode parent= local.getParent(); + if (parent instanceof VariableDeclarationStatement && !result.contains(parent)) + result.add(parent); + } + return result; + } + + private Statement getCatchBody(String type, String name, String lineSeparator) throws CoreException { + String s= StubUtility.getCatchBodyContent(fCUnit, type, name, fSelectedNodes[0], lineSeparator); + if (s == null) { + return null; + } else { + return (Statement)fRewriter.createStringPlaceholder(s, ASTNode.RETURN_STATEMENT); + } + } +} diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ASTCreator.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ASTCreator.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ASTCreator.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ASTCreator.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompilationUnitRange.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompilationUnitRange.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompilationUnitRange.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompilationUnitRange.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompositeOrTypeConstraint.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompositeOrTypeConstraint.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompositeOrTypeConstraint.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/CompositeOrTypeConstraint.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCollector.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCollector.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCollector.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCollector.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCreator.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCreator.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCreator.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintCreator.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintOperator.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintOperator.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintOperator.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintOperator.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariable.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariable.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariable.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariable.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariableFactory.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariableFactory.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariableFactory.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ConstraintVariableFactory.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/DeclaringTypeVariable.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/DeclaringTypeVariable.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/DeclaringTypeVariable.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/DeclaringTypeVariable.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ExpressionVariable.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ExpressionVariable.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ExpressionVariable.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ExpressionVariable.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/FullConstraintCreator.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/FullConstraintCreator.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/FullConstraintCreator.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/FullConstraintCreator.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IConstraintVariableFactory.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IConstraintVariableFactory.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IConstraintVariableFactory.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IConstraintVariableFactory.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IContext.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IContext.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IContext.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/IContext.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraint.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraint.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraint.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraint.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraintFactory.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraintFactory.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraintFactory.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ITypeConstraintFactory.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/NullContext.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/NullContext.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/NullContext.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/NullContext.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ParameterTypeVariable.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ParameterTypeVariable.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ParameterTypeVariable.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ParameterTypeVariable.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/RawBindingVariable.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/RawBindingVariable.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/RawBindingVariable.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/RawBindingVariable.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ReturnTypeVariable.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ReturnTypeVariable.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ReturnTypeVariable.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/ReturnTypeVariable.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/SimpleTypeConstraint.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/SimpleTypeConstraint.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/SimpleTypeConstraint.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/SimpleTypeConstraint.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeConstraintFactory.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeConstraintFactory.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeConstraintFactory.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeConstraintFactory.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeVariable.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeVariable.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeVariable.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/TypeVariable.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArraySuperTypeSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArraySuperTypeSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArraySuperTypeSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArraySuperTypeSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArrayTypeSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArrayTypeSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArrayTypeSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/ArrayTypeSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EmptyTypeSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EmptyTypeSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EmptyTypeSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EmptyTypeSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EnumeratedTypeSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EnumeratedTypeSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EnumeratedTypeSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/EnumeratedTypeSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SingletonTypeSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SingletonTypeSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SingletonTypeSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SingletonTypeSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesOfSingleton.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesOfSingleton.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesOfSingleton.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesOfSingleton.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SubTypesSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesOfSingleton.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesOfSingleton.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesOfSingleton.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesOfSingleton.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/SuperTypesSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetEnvironment.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetEnvironment.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetEnvironment.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetEnvironment.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetIntersection.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetIntersection.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetIntersection.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetIntersection.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetUnion.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetUnion.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetUnion.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeSetUnion.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeUniverseSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeUniverseSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeUniverseSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/TypeUniverseSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayElementVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayElementVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayElementVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayElementVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayTypeVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayTypeVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayTypeVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ArrayTypeVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CastVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CastVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CastVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CastVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CollectionElementVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CollectionElementVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CollectionElementVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/CollectionElementVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ConstraintVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ConstraintVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ConstraintVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ConstraintVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ISourceConstraintVariable.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ISourceConstraintVariable.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ISourceConstraintVariable.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ISourceConstraintVariable.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraint2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraint2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraint2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraint2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraintVariable.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraintVariable.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraintVariable.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeConstraintVariable.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ITypeSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ImmutableTypeVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ImmutableTypeVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ImmutableTypeVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ImmutableTypeVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/IndependentTypeVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/IndependentTypeVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/IndependentTypeVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/IndependentTypeVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterTypeVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterTypeVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterTypeVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterTypeVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterizedTypeVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterizedTypeVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterizedTypeVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ParameterizedTypeVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ReturnTypeVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ReturnTypeVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ReturnTypeVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/ReturnTypeVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/SubTypeConstraint2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/SubTypeConstraint2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/SubTypeConstraint2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/SubTypeConstraint2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TTypes.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TTypes.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TTypes.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TTypes.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeEquivalenceSet.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeEquivalenceSet.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeEquivalenceSet.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeEquivalenceSet.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/TypeVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/VariableVariable2.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/VariableVariable2.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/VariableVariable2.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/VariableVariable2.java diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java similarity index 100% rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/JavaModelUtil.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/JavaModelUtil.java index a50255ad..06b25e5e 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/JavaModelUtil.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/JavaModelUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -80,7 +80,7 @@ public final class JavaModelUtil { */ public static final String VERSION_LATEST; static { - VERSION_LATEST= JavaCore.VERSION_16; // make sure it is not inlined + VERSION_LATEST= JavaCore.VERSION_19; // make sure it is not inlined } public static final int VALIDATE_EDIT_CHANGED_CONTENT= 10003; @@ -845,6 +845,18 @@ public static boolean is16OrHigher(String compliance) { return !isVersionLessThan(compliance, JavaCore.VERSION_16); } + public static boolean is17OrHigher(String compliance) { + return !isVersionLessThan(compliance, JavaCore.VERSION_17); + } + + public static boolean is18OrHigher(String compliance) { + return !isVersionLessThan(compliance, JavaCore.VERSION_18); + } + + public static boolean is19OrHigher(String compliance) { + return !isVersionLessThan(compliance, JavaCore.VERSION_19); + } + /** * Checks if the given project or workspace has source compliance 1.2 or greater. * @@ -974,6 +986,39 @@ public static boolean is16OrHigher(IJavaProject project) { return is16OrHigher(getSourceCompliance(project)); } + /** + * Checks if the given project or workspace has source compliance 17 or greater. + * + * @param project the project to test or null to test the workspace settings + * @return true if the given project or workspace has source compliance 17 or + * greater. + */ + public static boolean is17OrHigher(IJavaProject project) { + return is17OrHigher(getSourceCompliance(project)); + } + + /** + * Checks if the given project or workspace has source compliance 18 or greater. + * + * @param project the project to test or null to test the workspace settings + * @return true if the given project or workspace has source compliance 17 or + * greater. + */ + public static boolean is18OrHigher(IJavaProject project) { + return is18OrHigher(getSourceCompliance(project)); + } + + /** + * Checks if the given project or workspace has source compliance 19 or greater. + * + * @param project the project to test or null to test the workspace settings + * @return true if the given project or workspace has source compliance 17 or + * greater. + */ + public static boolean is19OrHigher(IJavaProject project) { + return is19OrHigher(getSourceCompliance(project)); + } + public static String getSourceCompliance(IJavaProject project) { return project != null ? project.getOption(JavaCore.COMPILER_SOURCE, true) : JavaCore.getOption(JavaCore.COMPILER_SOURCE); } @@ -1024,6 +1069,10 @@ public static String getCompilerCompliance(IVMInstall2 vMInstall, String default String version= vMInstall.getJavaVersion(); if (version == null) { return defaultCompliance; + } else if (version.startsWith(JavaCore.VERSION_18)) { + return JavaCore.VERSION_18; + } else if (version.startsWith(JavaCore.VERSION_17)) { + return JavaCore.VERSION_17; } else if (version.startsWith(JavaCore.VERSION_16)) { return JavaCore.VERSION_16; } else if (version.startsWith(JavaCore.VERSION_15)) { @@ -1068,7 +1117,13 @@ public static String getExecutionEnvironmentCompliance(IExecutionEnvironment exe // fallback: String desc= executionEnvironment.getId(); - if (desc.indexOf(JavaCore.VERSION_16) != -1) { + if (desc.indexOf(JavaCore.VERSION_19) != -1) { + return JavaCore.VERSION_19; + } else if (desc.indexOf(JavaCore.VERSION_18) != -1) { + return JavaCore.VERSION_18; + } else if (desc.indexOf(JavaCore.VERSION_17) != -1) { + return JavaCore.VERSION_17; + } else if (desc.indexOf(JavaCore.VERSION_16) != -1) { return JavaCore.VERSION_16; } else if (desc.indexOf(JavaCore.VERSION_15) != -1) { return JavaCore.VERSION_15; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/MethodOverrideTester.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/MethodOverrideTester.java index 00a53740..04ef60c3 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/MethodOverrideTester.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/MethodOverrideTester.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,12 +10,15 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Nikolay Metchev - [rename] https://bugs.eclipse.org/99622 *******************************************************************************/ package org.eclipse.jdt.internal.corext.util; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import org.eclipse.core.runtime.Assert; @@ -180,6 +183,28 @@ public IMethod findOverriddenMethodInHierarchy(IType type, IMethod overriding) t } return method; } + + /** + * Finds all overridden methods in a type and its super types. First the super class is examined and then the implemented interfaces. + * With generics it is possible that 2 methods in the same type are overidden at the same time. In that case all overrides are returned + * @param type The type to find methods in + * @param overriding The overriding method + * @return The overridden methods or an empty set if no method is overridden + * @throws JavaModelException if a problem occurs + */ + public Set findAllOverriddenMethodsInHierarchy(IType type, IMethod overriding) throws JavaModelException { + Set ans = findAllOverriddenMethodsInType(type, overriding); + IType superClass= fHierarchy.getSuperclass(type); + if (superClass != null) { + ans.addAll(findAllOverriddenMethodsInHierarchy(superClass, overriding)); + } + IType[] superInterfaces= fHierarchy.getSuperInterfaces(type); + for (int i= 0; i < superInterfaces.length; i++) { + ans.addAll(findAllOverriddenMethodsInHierarchy(superInterfaces[i], overriding)); + } + return ans; + } + /** * Finds an overridden method in a type. With generics it is possible that 2 methods in the same type are overridden at the same time. @@ -203,6 +228,33 @@ public IMethod findOverriddenMethodInType(IType overriddenType, IMethod overridi } return null; } + + /** + * Finds all overridden methods in a type. With generics it is possible that 2 methods in the same type are overridden at the same time. + * In that case all overridden methods found are returned. + * @param overriddenType The type to find methods in + * @param overriding The overriding method + * @return All overridden methods or an empty set if no method is overridden + * @throws JavaModelException if a problem occurs + */ + public Set findAllOverriddenMethodsInType(IType overriddenType, IMethod overriding) throws JavaModelException { + Set ans = new HashSet<>(); + int flags= overriding.getFlags(); + if (Flags.isPrivate(flags) || Flags.isStatic(flags) || overriding.isConstructor()) + return ans; + IMethod[] overriddenMethods= overriddenType.getMethods(); + for (int i= 0; i < overriddenMethods.length; i++) { + IMethod overridden= overriddenMethods[i]; + flags= overridden.getFlags(); + if (Flags.isPrivate(flags) || Flags.isStatic(flags) || overridden.isConstructor()) + continue; + if (isSubsignature(overriding, overridden)) { + ans.add(overridden); + } + } + return ans; + } + /** * Finds an overriding method in a type. @@ -549,4 +601,14 @@ private StringBuffer internalGetSubstitutedTypeName(String typeSig, IMember cont } } + /** + * Finds all overrides for the passed in method. + * With generics it is possible that 2 methods in the same type are overridden at the same time. In that case all overrides are returned + * @param overriding The overriding method + * @return The overridden methods or an empty set if no method is overridden + * @throws JavaModelException if a problem occurs + */ + public Set findAllOverridenMethods(IMethod overriding) throws JavaModelException { + return findAllOverriddenMethodsInHierarchy(overriding.getDeclaringType(), overriding); + } } diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/ui/fix/UseIteratorToForLoopCleanUpCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/ui/fix/UseIteratorToForLoopCleanUpCore.java new file mode 100644 index 00000000..a99d5b1b --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/ui/fix/UseIteratorToForLoopCleanUpCore.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - Initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.fix; + +import static org.eclipse.jdt.internal.corext.fix.CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_ONLY_IF_LOOP_VAR_USED; +import static org.eclipse.jdt.internal.corext.fix.CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED; +import static org.eclipse.jdt.internal.ui.fix.MultiFixMessages.Java50CleanUp_ConvertToEnhancedForLoop_description; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.manipulation.CleanUpContextCore; +import org.eclipse.jdt.core.manipulation.CleanUpRequirementsCore; +import org.eclipse.jdt.core.manipulation.ICleanUpFixCore; + +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation; +import org.eclipse.jdt.internal.corext.fix.UseIteratorToForLoopFixCore; +import org.eclipse.jdt.internal.corext.util.JavaModelUtil; + +public class UseIteratorToForLoopCleanUpCore extends AbstractCleanUpCore { + public UseIteratorToForLoopCleanUpCore(final Map options) { + super(options); + } + + public UseIteratorToForLoopCleanUpCore() { + } + + @Override + public CleanUpRequirementsCore getRequirementsCore() { + return new CleanUpRequirementsCore(requireAST(), false, false, null); + } + + public boolean requireAST() { + return isEnabled(CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + } + + @Override + public ICleanUpFixCore createFixCore(final CleanUpContextCore context) throws CoreException { + CompilationUnit compilationUnit= context.getAST(); + if (compilationUnit == null) { + return null; + } + EnumSet computeFixSet= computeFixSet(); + if (!isEnabled(CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED) || computeFixSet.isEmpty()) { + return null; + } + if (!JavaModelUtil.is1d8OrHigher(compilationUnit.getJavaElement().getJavaProject())) { + return null; + } + Set operations= new LinkedHashSet<>(); + Set nodesprocessed= new HashSet<>(); + computeFixSet.forEach(i -> i.findOperations(compilationUnit, operations, nodesprocessed, isEnabled(CONTROL_STATEMENTS_CONVERT_FOR_LOOP_ONLY_IF_LOOP_VAR_USED))); + if (operations.isEmpty()) { + return null; + } + return new CompilationUnitRewriteOperationsFixCore(Java50CleanUp_ConvertToEnhancedForLoop_description, compilationUnit, + operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[0])); + } + + @Override + public String[] getStepDescriptions() { + List result= new ArrayList<>(); + if (isEnabled(CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED)) { + result.add(Java50CleanUp_ConvertToEnhancedForLoop_description); + } + return result.toArray(new String[0]); + } + + @Override + public String getPreview() { + StringBuilder sb= new StringBuilder(); + EnumSet computeFixSet= computeFixSet(); + EnumSet.allOf(UseIteratorToForLoopFixCore.class).forEach(e -> sb.append(e.getPreview(computeFixSet.contains(e)))); + return sb.toString(); + } + + private EnumSet computeFixSet() { + EnumSet fixSet= EnumSet.noneOf(UseIteratorToForLoopFixCore.class); + + if (isEnabled(CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED)) { + fixSet= EnumSet.allOf(UseIteratorToForLoopFixCore.class); + } + return fixSet; + } +} diff --git a/org.eclipse.jdt.core.manipulation/pom.xml b/org.eclipse.jdt.core.manipulation/pom.xml index 94d979e4..1ab11bd4 100644 --- a/org.eclipse.jdt.core.manipulation/pom.xml +++ b/org.eclipse.jdt.core.manipulation/pom.xml @@ -1,6 +1,6 @@ - --add-modules ALL-SYSTEM --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens jdk.localedata/sun.util.resources.cldr.provider=ALL-UNNAMED --add-opens jdk.localedata/sun.util.resources.provider=ALL-UNNAMED --add-opens java.base/jdk.internal.module=ALL-UNNAMED --add-opens java.base/java.lang.module=ALL-UNNAMED --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED --add-opens java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/jdk.internal.math=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/jdk.internal.icu.impl=ALL-UNNAMED --add-opens java.base/jdk.internal.icu.text=ALL-UNNAMED --illegal-access=permit + --add-modules ALL-SYSTEM --add-opens jdk.localedata/sun.util.resources.cldr.provider=ALL-UNNAMED --add-opens jdk.localedata/sun.util.resources.provider=ALL-UNNAMED --add-opens java.base/com.sun.crypto.provider=ALL-UNNAMED --add-opens java.base/com.sun.security.ntlm=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.annotation=ALL-UNNAMED --add-opens java.base/java.lang.constant=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.lang.module=ALL-UNNAMED --add-opens java.base/java.lang.ref=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.lang.runtime=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.net.spi=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.nio.channels=ALL-UNNAMED --add-opens java.base/java.nio.channels.spi=ALL-UNNAMED --add-opens java.base/java.nio.charset=ALL-UNNAMED --add-opens java.base/java.nio.charset.spi=ALL-UNNAMED --add-opens java.base/java.nio.file=ALL-UNNAMED --add-opens java.base/java.nio.file.attribute=ALL-UNNAMED --add-opens java.base/java.nio.file.spi=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.security.cert=ALL-UNNAMED --add-opens java.base/java.security.interfaces=ALL-UNNAMED --add-opens java.base/java.security.spec=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.base/java.text.spi=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-opens java.base/java.time.chrono=ALL-UNNAMED --add-opens java.base/java.time.format=ALL-UNNAMED --add-opens java.base/java.time.temporal=ALL-UNNAMED --add-opens java.base/java.time.zone=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/java.util.concurrent.locks=ALL-UNNAMED --add-opens java.base/java.util.function=ALL-UNNAMED --add-opens java.base/java.util.jar=ALL-UNNAMED --add-opens java.base/java.util.random=ALL-UNNAMED --add-opens java.base/java.util.regex=ALL-UNNAMED --add-opens java.base/java.util.spi=ALL-UNNAMED --add-opens java.base/java.util.stream=ALL-UNNAMED --add-opens java.base/java.util.zip=ALL-UNNAMED --add-opens java.base/javax.crypto=ALL-UNNAMED --add-opens java.base/javax.crypto.interfaces=ALL-UNNAMED --add-opens java.base/javax.crypto.spec=ALL-UNNAMED --add-opens java.base/javax.net=ALL-UNNAMED --add-opens java.base/javax.net.ssl=ALL-UNNAMED --add-opens java.base/javax.security.auth=ALL-UNNAMED --add-opens java.base/javax.security.auth.callback=ALL-UNNAMED --add-opens java.base/javax.security.auth.login=ALL-UNNAMED --add-opens java.base/javax.security.auth.spi=ALL-UNNAMED --add-opens java.base/javax.security.auth.x500=ALL-UNNAMED --add-opens java.base/javax.security.cert=ALL-UNNAMED --add-opens java.base/jdk.internal=ALL-UNNAMED --add-opens java.base/jdk.internal.access=ALL-UNNAMED --add-opens java.base/jdk.internal.access.foreign=ALL-UNNAMED --add-opens java.base/jdk.internal.event=ALL-UNNAMED --add-opens java.base/jdk.internal.icu.impl=ALL-UNNAMED --add-opens java.base/jdk.internal.icu.impl.data.icudt67b=ALL-UNNAMED --add-opens java.base/jdk.internal.icu.lang=ALL-UNNAMED --add-opens java.base/jdk.internal.icu.text=ALL-UNNAMED --add-opens java.base/jdk.internal.icu.util=ALL-UNNAMED --add-opens java.base/jdk.internal.invoke=ALL-UNNAMED --add-opens java.base/jdk.internal.javac=ALL-UNNAMED --add-opens java.base/jdk.internal.jimage=ALL-UNNAMED --add-opens java.base/jdk.internal.jimage.decompressor=ALL-UNNAMED --add-opens java.base/jdk.internal.jmod=ALL-UNNAMED --add-opens java.base/jdk.internal.jrtfs=ALL-UNNAMED --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens java.base/jdk.internal.logger=ALL-UNNAMED --add-opens java.base/jdk.internal.math=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/jdk.internal.module=ALL-UNNAMED --add-opens java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED --add-opens java.base/jdk.internal.org.objectweb.asm.commons=ALL-UNNAMED --add-opens java.base/jdk.internal.org.objectweb.asm.signature=ALL-UNNAMED --add-opens java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED --add-opens java.base/jdk.internal.org.objectweb.asm.tree.analysis=ALL-UNNAMED --add-opens java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED --add-opens java.base/jdk.internal.org.xml.sax=ALL-UNNAMED --add-opens java.base/jdk.internal.org.xml.sax.helpers=ALL-UNNAMED --add-opens java.base/jdk.internal.perf=ALL-UNNAMED --add-opens java.base/jdk.internal.platform=ALL-UNNAMED --add-opens java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED --add-opens java.base/jdk.internal.util=ALL-UNNAMED --add-opens java.base/jdk.internal.util.jar=ALL-UNNAMED --add-opens java.base/jdk.internal.util.random=ALL-UNNAMED --add-opens java.base/jdk.internal.util.xml=ALL-UNNAMED --add-opens java.base/jdk.internal.util.xml.impl=ALL-UNNAMED --add-opens java.base/jdk.internal.vm=ALL-UNNAMED --add-opens java.base/jdk.internal.vm.annotation=ALL-UNNAMED --add-opens java.base/jdk.internal.vm.vector=ALL-UNNAMED --add-opens java.base/sun.invoke=ALL-UNNAMED --add-opens java.base/sun.invoke.empty=ALL-UNNAMED --add-opens java.base/sun.invoke.util=ALL-UNNAMED --add-opens java.base/sun.io=ALL-UNNAMED --add-opens java.base/sun.launcher=ALL-UNNAMED --add-opens java.base/sun.launcher.resources=ALL-UNNAMED --add-opens java.base/sun.net=ALL-UNNAMED --add-opens java.base/sun.net.dns=ALL-UNNAMED --add-opens java.base/sun.net.ext=ALL-UNNAMED --add-opens java.base/sun.net.ftp=ALL-UNNAMED --add-opens java.base/sun.net.ftp.impl=ALL-UNNAMED --add-opens java.base/sun.net.idn=ALL-UNNAMED --add-opens java.base/sun.net.sdp=ALL-UNNAMED --add-opens java.base/sun.net.smtp=ALL-UNNAMED --add-opens java.base/sun.net.spi=ALL-UNNAMED --add-opens java.base/sun.net.util=ALL-UNNAMED --add-opens java.base/sun.net.www=ALL-UNNAMED --add-opens java.base/sun.net.www.content.text=ALL-UNNAMED --add-opens java.base/sun.net.www.http=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.file=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.ftp=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.http=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.http.ntlm=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.https=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.jar=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.jmod=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.jrt=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.mailto=ALL-UNNAMED --add-opens java.base/sun.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.nio.cs=ALL-UNNAMED --add-opens java.base/sun.nio.fs=ALL-UNNAMED --add-opens java.base/sun.reflect.annotation=ALL-UNNAMED --add-opens java.base/sun.reflect.generics.factory=ALL-UNNAMED --add-opens java.base/sun.reflect.generics.parser=ALL-UNNAMED --add-opens java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED --add-opens java.base/sun.reflect.generics.repository=ALL-UNNAMED --add-opens java.base/sun.reflect.generics.scope=ALL-UNNAMED --add-opens java.base/sun.reflect.generics.tree=ALL-UNNAMED --add-opens java.base/sun.reflect.generics.visitor=ALL-UNNAMED --add-opens java.base/sun.reflect.misc=ALL-UNNAMED --add-opens java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/sun.security.internal.interfaces=ALL-UNNAMED --add-opens java.base/sun.security.internal.spec=ALL-UNNAMED --add-opens java.base/sun.security.jca=ALL-UNNAMED --add-opens java.base/sun.security.pkcs=ALL-UNNAMED --add-opens java.base/sun.security.pkcs10=ALL-UNNAMED --add-opens java.base/sun.security.pkcs12=ALL-UNNAMED --add-opens java.base/sun.security.provider=ALL-UNNAMED --add-opens java.base/sun.security.provider.certpath=ALL-UNNAMED --add-opens java.base/sun.security.provider.certpath.ssl=ALL-UNNAMED --add-opens java.base/sun.security.rsa=ALL-UNNAMED --add-opens java.base/sun.security.ssl=ALL-UNNAMED --add-opens java.base/sun.security.timestamp=ALL-UNNAMED --add-opens java.base/sun.security.tools=ALL-UNNAMED --add-opens java.base/sun.security.tools.keytool=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED --add-opens java.base/sun.security.util.math=ALL-UNNAMED --add-opens java.base/sun.security.util.math.intpoly=ALL-UNNAMED --add-opens java.base/sun.security.validator=ALL-UNNAMED --add-opens java.base/sun.security.x509=ALL-UNNAMED --add-opens java.base/sun.text=ALL-UNNAMED --add-opens java.base/sun.text.resources=ALL-UNNAMED --add-opens java.base/sun.text.resources.cldr=ALL-UNNAMED --add-opens java.base/sun.text.spi=ALL-UNNAMED --add-opens java.base/sun.util=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED --add-opens java.base/sun.util.cldr=ALL-UNNAMED --add-opens java.base/sun.util.locale=ALL-UNNAMED --add-opens java.base/sun.util.locale.provider=ALL-UNNAMED --add-opens java.base/sun.util.logging=ALL-UNNAMED --add-opens java.base/sun.util.resources=ALL-UNNAMED --add-opens java.base/sun.util.resources.cldr=ALL-UNNAMED --add-opens java.base/sun.util.spi=ALL-UNNAMED --add-opens java.xml/com.sun.java_cup.internal.runtime=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.bcel.internal=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.bcel.internal.classfile=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.bcel.internal.generic=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.bcel.internal.util=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.extensions=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.lib=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.res=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.templates=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.utils=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.util=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc.dom=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime.output=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc.util=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.dom=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.dom.events=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.dtd=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.dtd.models=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.dv=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.dv.dtd=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.dv.util=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.dv.xs=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.io=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.msg=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.validation=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.xpath=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.xpath.regex=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.xs=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.xs.identity=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.xs.models=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.xs.opti=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.impl.xs.util=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.jaxp=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.jaxp.datatype=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.jaxp.validation=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.parsers=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.utils=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.xinclude=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.xni=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.xni.grammars=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.xni.parser=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.xpointer=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.xs=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.xs.datatypes=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.dtm=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.dtm.ref=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.dtm.ref.dom2dtm=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.dtm.ref.sax2dtm=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.res=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.serialize=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.serializer=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.serializer.dom3=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.serializer.utils=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.utils=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xml.internal.utils.res=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.axes=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.compiler=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.functions=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.jaxp=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.objects=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.operations=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.patterns=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xpath.internal.res=ALL-UNNAMED --add-opens java.xml/com.sun.xml.internal.stream=ALL-UNNAMED --add-opens java.xml/com.sun.xml.internal.stream.dtd=ALL-UNNAMED --add-opens java.xml/com.sun.xml.internal.stream.dtd.nonvalidating=ALL-UNNAMED --add-opens java.xml/com.sun.xml.internal.stream.events=ALL-UNNAMED --add-opens java.xml/com.sun.xml.internal.stream.util=ALL-UNNAMED --add-opens java.xml/com.sun.xml.internal.stream.writers=ALL-UNNAMED --add-opens java.xml/javax.xml=ALL-UNNAMED --add-opens java.xml/javax.xml.catalog=ALL-UNNAMED --add-opens java.xml/javax.xml.datatype=ALL-UNNAMED --add-opens java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens java.xml/javax.xml.parsers=ALL-UNNAMED --add-opens java.xml/javax.xml.stream=ALL-UNNAMED --add-opens java.xml/javax.xml.stream.events=ALL-UNNAMED --add-opens java.xml/javax.xml.stream.util=ALL-UNNAMED --add-opens java.xml/javax.xml.transform=ALL-UNNAMED --add-opens java.xml/javax.xml.transform.dom=ALL-UNNAMED --add-opens java.xml/javax.xml.transform.sax=ALL-UNNAMED --add-opens java.xml/javax.xml.transform.stax=ALL-UNNAMED --add-opens java.xml/javax.xml.transform.stream=ALL-UNNAMED --add-opens java.xml/javax.xml.validation=ALL-UNNAMED --add-opens java.xml/javax.xml.xpath=ALL-UNNAMED --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens java.xml/org.w3c.dom=ALL-UNNAMED --add-opens java.xml/org.w3c.dom.bootstrap=ALL-UNNAMED --add-opens java.xml/org.w3c.dom.events=ALL-UNNAMED --add-opens java.xml/org.w3c.dom.ls=ALL-UNNAMED --add-opens java.xml/org.w3c.dom.ranges=ALL-UNNAMED --add-opens java.xml/org.w3c.dom.traversal=ALL-UNNAMED --add-opens java.xml/org.w3c.dom.views=ALL-UNNAMED --add-opens java.xml/org.xml.sax=ALL-UNNAMED --add-opens java.xml/org.xml.sax.ext=ALL-UNNAMED --add-opens java.xml/org.xml.sax.helpers=ALL-UNNAMED --add-opens java.desktop/com.sun.beans=ALL-UNNAMED --add-opens java.desktop/java.beans=ALL-UNNAMED --add-opens java.logging/java.util.logging=ALL-UNNAMED --add-opens java.management/com.sun.jmx.defaults=ALL-UNNAMED --add-opens java.management/com.sun.jmx.interceptor=ALL-UNNAMED --add-opens java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED --add-opens java.management/com.sun.jmx.remote.internal=ALL-UNNAMED --add-opens java.management/com.sun.jmx.remote.security=ALL-UNNAMED --add-opens java.management/com.sun.jmx.remote.util=ALL-UNNAMED --add-opens java.management/java.lang.management=ALL-UNNAMED --add-opens java.management/javax.management=ALL-UNNAMED --add-opens java.management/javax.management.loading=ALL-UNNAMED --add-opens java.management/javax.management.modelmbean=ALL-UNNAMED --add-opens java.management/javax.management.monitor=ALL-UNNAMED --add-opens java.management/javax.management.openmbean=ALL-UNNAMED --add-opens java.management/javax.management.relation=ALL-UNNAMED --add-opens java.management/javax.management.remote=ALL-UNNAMED --add-opens java.management/javax.management.timer=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED --add-opens java.management/sun.management.counter=ALL-UNNAMED --add-opens java.management/sun.management.counter.perf=ALL-UNNAMED --add-opens java.management/sun.management.spi=ALL-UNNAMED --add-opens jdk.management/com.sun.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED --illegal-access=permit @@ -39,7 +39,8 @@ true org/eclipse/jdt/ui/tests/AutomatedSuite.class - org/eclipse/jdt/ui/tests/LeakTestSuite.class + org/eclipse/jdt/internal/common/JUnit5TestSuite.class + diff --git a/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java b/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java index a5966fde..bb45ef0f 100644 --- a/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java +++ b/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java @@ -105,6 +105,7 @@ public class JavaProjectHelper { public static final IPath RT_STUBS14= new Path("testresources/rtstubs14.jar"); public static final IPath RT_STUBS15= new Path("testresources/rtstubs_15.jar"); public static final IPath RT_STUBS16= new Path("testresources/rtstubs_16.jar"); + public static final IPath RT_STUBS17= new Path("testresources/rtstubs_17.jar"); public static final IPath JUNIT_SRC_381= new Path("testresources/junit381-noUI-src.zip"); public static final String JUNIT_SRC_ENCODING= "ISO-8859-1"; @@ -314,7 +315,7 @@ public static void set15CompilerOptions(IJavaProject project, boolean enable_pre } /** - * Sets the compiler options to 15 for the given project. + * Sets the compiler options to 16 for the given project. * * @param project the java project * @param enable_preview_feature sets enable-preview compliance project option based on the @@ -330,6 +331,23 @@ public static void set16CompilerOptions(IJavaProject project, boolean enable_pre project.setOptions(options); } + /** + * Sets the compiler options to 17 for the given project. + * + * @param project the java project + * @param enable_preview_feature sets enable-preview compliance project option based on the + * value specified. + */ + public static void set17CompilerOptions(IJavaProject project, boolean enable_preview_feature) { + Map options= project.getOptions(false); + set17_CompilerOptions(options); + if (enable_preview_feature) { + options.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); + } + project.setOptions(options); + } + /** * Sets the compiler options to 1.8 for the given project. * @@ -455,6 +473,15 @@ public static void set16_CompilerOptions(Map options) { JavaCore.setComplianceOptions(JavaCore.VERSION_16, options); } + /** + * Sets the compiler options to 17. + * + * @param options the compiler options to configure + */ + public static void set17_CompilerOptions(Map options) { + JavaCore.setComplianceOptions(JavaCore.VERSION_17, options); + } + /** * Sets the compiler options to 1.8 * @@ -979,6 +1006,12 @@ public static IPackageFragmentRoot addRTJar_16(IJavaProject jproject, boolean en return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]); } + public static IPackageFragmentRoot addRTJar_17(IJavaProject jproject, boolean enable_preview_feature) throws CoreException { + IPath[] rtJarPath= findRtJar(RT_STUBS17); + set17CompilerOptions(jproject, enable_preview_feature); + return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]); + } + /** * Adds a variable entry with source attachment to a IJavaProject. * Can return null if variable can not be resolved. diff --git a/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/util/DisplayHelper.java b/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/util/DisplayHelper.java index a717a963..4175c35d 100644 --- a/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/util/DisplayHelper.java +++ b/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/util/DisplayHelper.java @@ -133,7 +133,7 @@ public boolean condition() { * @return if display.readAndDispatch returned * true at least once */ - private static boolean driveEventQueue(Display display) { + public static boolean driveEventQueue(Display display) { boolean events= false; while (display.readAndDispatch()) { events= true; diff --git a/org.eclipse.jdt.ui.tests/test.xml b/org.eclipse.jdt.ui.tests/test.xml index 1040e12c..9206c307 100644 --- a/org.eclipse.jdt.ui.tests/test.xml +++ b/org.eclipse.jdt.ui.tests/test.xml @@ -44,15 +44,320 @@ - + + + + + + - + diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/ExpectationTracer.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/ExpectationTracer.java new file mode 100644 index 00000000..42aa1fb3 --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/ExpectationTracer.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.common; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Stack; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.SimpleName; + +public class ExpectationTracer extends ConcurrentHashMap implements HelperVisitorProvider{ + + public Stack stack = new Stack<>(); + + /** + * + */ + private static final long serialVersionUID = 1L; + HelperVisitor hv; + + /** + * + */ + public ExpectationTracer() { + } + + @Override + public HelperVisitor getHelperVisitor() { + return hv; + } + + @Override + public void setHelperVisitor(HelperVisitor hv) { + this.hv=hv; + } + + private void writeObject(ObjectOutputStream stream) + throws IOException { + stream.defaultWriteObject(); + } + + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object o) { + return super.equals(o); + } +} diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/NodeFound.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/NodeFound.java new file mode 100644 index 00000000..54733fe5 --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/NodeFound.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2021 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer + *******************************************************************************/ +package org.eclipse.jdt.internal.common; + +public class NodeFound { + +} diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/VisitorTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/VisitorTest.java new file mode 100644 index 00000000..23bd0640 --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/internal/common/VisitorTest.java @@ -0,0 +1,625 @@ +/******************************************************************************* + * Copyright (c) 2021, 2022 Carsten Hammer. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Carsten Hammer - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.common; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BiPredicate; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.IBinding; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.eclipse.jdt.core.dom.WhileStatement; + +import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; + +public class VisitorTest { + + private static CompilationUnit result; + private static CompilationUnit result2; + + @BeforeAll + public static void init() { + ASTParser parser = ASTParser.newParser(AST.getJLSLatest()); + String code ="package test;\n" + +"import java.util.Collection;\n" + + "\n" + + "public class E {\n" + + " public void hui(Collection arr) {\n" + + " Collection coll = null;\n" + + " for (String var : arr) {\n" + + " coll.add(var);\n" + + " System.out.println(var);\n" + + " System.err.println(var);\n" + + " }\n" + + " System.out.println(arr);\n" + + " }\n" + + "}"; + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setEnvironment(new String[]{}, new String[]{}, null, true); + parser.setBindingsRecovery(true); + parser.setResolveBindings(true); + Map options = JavaCore.getOptions(); + JavaCore.setComplianceOptions(JavaCore.VERSION_11, options); + parser.setCompilerOptions(options); + parser.setUnitName("E"); + parser.setSource(code.toCharArray()); + result = (CompilationUnit) parser.createAST(null); + + + String code2="package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " Iterator it2 = strings2.iterator();\n" + + " while (it2.hasNext()) {\n" + + " String s2 = (String) it2.next();\n" + + " System.out.println(s2);\n" + + " }\n" + + " // OK\n" + + " System.out.println(it.next());\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + parser.setEnvironment(new String[]{}, new String[]{}, null, true); + parser.setBindingsRecovery(true); + parser.setResolveBindings(true); + parser.setUnitName("Test"); + parser.setSource(code2.toCharArray()); + result2 = (CompilationUnit) parser.createAST(null); +// System.out.println(result.toString()); + } + + private void astnodeprocessorend(ASTNode node, ReferenceHolder holder) { + String x = "End "+node.getNodeType() + " :" + node; + System.out.printf("%-40s %s%n",x,ASTNode.nodeClassForType(node.getNodeType())); + } + + private Boolean astnodeprocesser(ASTNode node, ReferenceHolder holder) { +// NodeFound nodeFound = holder.get(VisitorEnum.fromNodetype(node.getNodeType())); + String x = "Start "+node.getNodeType() + " :" + node; + System.out.printf("%-40s %s%n",x,ASTNode.nodeClassForType(node.getNodeType())); + return true; + } + + private boolean handleMethodInvocation(MethodInvocation assignment, ReferenceHolder holder) { + System.out.println(assignment); + return true; + } + + /** + * Here the method reference is referring to a method using the right parameter MethodInvocation instead of ASTNode + */ + @Test + public void simpleTest() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>()); + hv.addMethodInvocation(this::handleMethodInvocation); + hv.build(result); + } + + /** + * For methodinvocation there is a method that allows to specify the method name. + */ + @Test + public void simpleTest2() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>()); + hv.addMethodInvocation("add", this::handleMethodInvocation); + hv.build(result); + + +// Function multiply = this::extracted; +// BiFunction add = this::extracted2; +// +// BiFunction multiplyThenAdd = add.andThen(multiply); +// +// Integer result2 = multiplyThenAdd.apply(3, 3); +// System.out.println(result2); + } + +// private Integer extracted2(Integer value,Integer value2) { +// return value + value2; +// } +// +// private Integer extracted(Integer value) { +// return value * 2; +// } + + @Test + public void simpleTest2b() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>()); + BiPredicate> bs = this::handleMethodInvocation; + BiPredicate> after = (mi,mi2)->{ + return true; + }; + BiPredicate> bs2= bs.or(after); + hv.addMethodInvocation("add", bs2); + hv.build(result); + } + + @Test + public void simpleTest3() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>()); + VisitorEnum.stream().forEach(ve -> { + hv.add(ve, this::astnodeprocesser); + }); + VisitorEnum.stream().forEach(ve -> { + hv.addEnd(ve, this::astnodeprocessorend); + }); + hv.build(result); + } + + /** + * Use method reference, one for "visit" and another for "visitend" + */ + @Test + public void simpleTest3b() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>()); + VisitorEnum.stream().forEach(ve -> { + hv.add(ve, this::astnodeprocesser,this::astnodeprocessorend); + }); + hv.build(result2); + } + + /** + * Use method reference, you can use the method reference returning boolean needed for "visit" for "visitend" too. + * That way you need only one method. + */ + @Test + public void simpleTest3c() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>()); + VisitorEnum.stream().forEach(ve -> { + hv.add(ve, this::astnodeprocesser,this::astnodeprocesser); + }); + hv.build(result2); + } + + @Test + public void simpleTest3d() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder()); + VisitorEnum.stream().forEach(ve -> { + hv.add(ve, (node, holder) -> { + String x = "Start "+node.getNodeType() + " :" + node; + System.out.printf("%-40s %s%n",x,ASTNode.nodeClassForType(node.getNodeType())); + return true; + }); + }); + VisitorEnum.stream().forEach(ve -> { + hv.addEnd(ve, (node, holder) -> { + String x = "End "+node.getNodeType() + " :" + node; + System.out.printf("%-40s %s%n",x,ASTNode.nodeClassForType(node.getNodeType())); + }); + }); + hv.build(result); + } + + /** + * Show how to visit a collection of nodes + */ + @Test + public void simpleTest4() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>()); + EnumSet myset = EnumSet.of( + VisitorEnum.SingleVariableDeclaration, + VisitorEnum.VariableDeclarationExpression, + VisitorEnum.VariableDeclarationStatement, + VisitorEnum.VariableDeclarationFragment); + myset.forEach(ve -> { + hv.add(ve, this::astnodeprocesser,this::astnodeprocessorend); + }); + hv.build(result); + } + + @Test + public void simpleTest4b() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>()); + EnumSet myset = EnumSet.of( + VisitorEnum.SingleVariableDeclaration, + VisitorEnum.VariableDeclarationExpression, + VisitorEnum.VariableDeclarationStatement, + VisitorEnum.VariableDeclarationFragment); + myset.forEach(ve -> { + addVisitor(hv, ve); + }); + hv.build(result); + } + + private void addVisitor(HelperVisitor,String,NodeFound> hv, VisitorEnum ve) { + hv.add(ve, this::astnodeprocesser,this::astnodeprocessorend); + } + + @Test + public void simpleTest4c() { + EnumSet myset = EnumSet.of( + VisitorEnum.SingleVariableDeclaration, + VisitorEnum.VariableDeclarationExpression, + VisitorEnum.VariableDeclarationStatement, + VisitorEnum.VariableDeclarationFragment); + ReferenceHolder dataholder = new ReferenceHolder<>(); + BiPredicate> bs =(node,holder)->{ + System.out.printf("%-40s %s%n","Start "+node.getNodeType() + " :" + node,ASTNode.nodeClassForType(node.getNodeType())); + return false; + }; + BiConsumer> bc = (node,holder)->{ + System.out.printf("%-40s %s%n","End "+node.getNodeType() + " :" + node,ASTNode.nodeClassForType(node.getNodeType())); + }; + HelperVisitor.callVisitor(result, myset, dataholder,null, bs, bc); + } + + + + /** + * Show how to use the ReferenceHolder to access data while visiting the AST. + * Here: count nodes and list result + */ + @Test + public void simpleTest5() { + Set nodesprocessed = null; + ReferenceHolder dataholder = new ReferenceHolder<>(); + HelperVisitor,VisitorEnum,Integer> hv = new HelperVisitor<>(nodesprocessed, dataholder); + VisitorEnum.stream().forEach(ve -> { + hv.add(ve, (node, holder) -> { + holder.merge(VisitorEnum.fromNode(node), 1, Integer::sum); + return true; + }); + }); + VisitorEnum.stream().forEach(ve -> { + hv.addEnd(ve, (node, holder) -> { + holder.merge(VisitorEnum.fromNode(node), 1, Integer::sum); + }); + }); + hv.build(result); + for(VisitorEnum ve: dataholder.keySet()) { + System.out.println(dataholder.get(ve)+"\t"+ve.name()); + } + } + + /** + * Show how to use the ReferenceHolder to access data while visiting the AST. + * Here: count nodes and list result + * + * Simpler variant compared to the one above only making use of visitend + */ + @Test + public void simpleTest5b() { + ReferenceHolder dataholder = new ReferenceHolder<>(); + HelperVisitor.callVisitor(result, EnumSet.allOf(VisitorEnum.class), dataholder,null, this::countVisits); + + /** + * Presenting result + */ + dataholder.entrySet().stream().forEach(entry->{ + System.out.println(entry.getValue()+"\t"+entry.getKey().name()); + }); + } + + private void countVisits(ASTNode node, ReferenceHolder holder) { + holder.merge(VisitorEnum.fromNode(node), 1, Integer::sum); + } + + @Test + public void simpleTest5c() { + ReferenceHolder dataholder = new ReferenceHolder<>(); + HelperVisitor.callVisitor(result,EnumSet.of( + VisitorEnum.SingleVariableDeclaration, + VisitorEnum.VariableDeclarationExpression, + VisitorEnum.VariableDeclarationStatement, + VisitorEnum.VariableDeclarationFragment), dataholder,null, (node,holder)->{ + holder.put(node, node.getStartPosition()); + }); + + /** + * Presenting result + */ + dataholder.entrySet().stream().forEach(entry->{ + System.out.println(entry.getKey()+"\t"+entry.getValue()+"\t"+ASTNode.nodeClassForType(entry.getKey().getNodeType())); + }); + } + + @Test + public void simpleTest5d() { + ReferenceHolder> dataholder = new ReferenceHolder<>(); + HelperVisitor.callVisitor(result,EnumSet.of( + VisitorEnum.SingleVariableDeclaration, + VisitorEnum.VariableDeclarationExpression, + VisitorEnum.VariableDeclarationStatement, + VisitorEnum.VariableDeclarationFragment), dataholder,null, (node,holder)->{ + Map pernodemap = holder.computeIfAbsent(node, k -> new HashMap<>()); + switch(VisitorEnum.fromNode(node)) { + case SingleVariableDeclaration: + SingleVariableDeclaration svd=(SingleVariableDeclaration) node; + Expression svd_initializer = svd.getInitializer(); + pernodemap.put("init", svd_initializer); + break; + case VariableDeclarationExpression: +// VariableDeclarationExpression vde=(VariableDeclarationExpression) node; + ASTNodes.getTypedAncestor(node, Statement.class); + break; + case VariableDeclarationStatement: +// VariableDeclarationStatement vds=(VariableDeclarationStatement) node; + + break; + case VariableDeclarationFragment: + VariableDeclarationFragment vdf=(VariableDeclarationFragment) node; + Expression vdf_initializer = vdf.getInitializer(); + pernodemap.put("init", vdf_initializer); + break; + //$CASES-OMITTED$ + default: + break; + } + }); + + /** + * Presenting result + */ + dataholder.entrySet().stream().forEach(entry->{ + System.out.println(entry.getKey()+"\t"+ASTNode.nodeClassForType(entry.getKey().getNodeType())); + System.out.println("===>"+entry.getValue().get("init")); + System.out.println(); + }); + } + + @Test + public void simpleTest5e() { + ReferenceHolder> dataholder = new ReferenceHolder<>(); + HelperVisitor.callVariableDeclarationStatementVisitor(Iterator.class, result2, dataholder,null, (init_iterator,holder_a)->{ + List computeVarName = computeVarName(init_iterator); + HelperVisitor.callWhileStatementVisitor(init_iterator.getParent(), dataholder,null, (whilestatement,holder)->{ + String name = computeNextVarname(whilestatement); + if(computeVarName.get(0).equals(name)) { + HelperVisitor.callMethodInvocationVisitor("next", whilestatement.getBody() ,dataholder,null, (mi,holder2)->{ + Map pernodemap2 = holder2.computeIfAbsent(whilestatement, k -> new HashMap<>()); + Expression element2 = mi.getExpression(); + SimpleName sn= ASTNodes.as(element2, SimpleName.class); + if (sn !=null) { + String identifier = sn.getIdentifier(); + if(!name.equals(identifier)) + return true; + pernodemap2.put("init", init_iterator); + pernodemap2.put("while", whilestatement); + pernodemap2.put("next", mi); + pernodemap2.put("name", identifier); + return true; + // if(holder.containsKey(identifier)) { + // if (holder.getHelperVisitor().nodesprocessed.contains(hit.whilestatement)) { + // holder.remove(identifier); + // return true; + // } + } + return true; + }); + } + return true; + }); + return true; + }); + /** + * Presenting result + */ + System.out.println("#################"); + dataholder.entrySet().stream().forEach(entry->{ + System.out.println("============="); + System.out.println(entry.getKey()); + System.out.println("init ===>"+entry.getValue().get("init")); + System.out.println("while ===>"+entry.getValue().get("while")); + System.out.println("next ===>"+entry.getValue().get("next")); + System.out.println("name ===>"+entry.getValue().get("name")); + System.out.println(); + }); + } + + private static String computeNextVarname(WhileStatement whilestatement) { + String name = null; + Expression exp = whilestatement.getExpression(); +// Collection usedVarNames= getUsedVariableNames(whilestatement.getBody()); + if (exp instanceof MethodInvocation) { + MethodInvocation mi = (MethodInvocation) exp; + Expression expression = mi.getExpression(); + if (mi.getName().getIdentifier().equals("hasNext")) { //$NON-NLS-1$ +// ITypeBinding resolveTypeBinding = expression.resolveTypeBinding(); + SimpleName variable= ASTNodes.as(expression, SimpleName.class); + if (variable != null) { + IBinding resolveBinding = variable.resolveBinding(); + name = resolveBinding.getName(); + } + } + } + return name; + } + + private static List computeVarName(VariableDeclarationStatement node_a) { + List name = new ArrayList<>(); + VariableDeclarationFragment bli = (VariableDeclarationFragment) node_a.fragments().get(0); + name.add(bli.getName().getIdentifier()); + Expression exp = bli.getInitializer(); + if (exp instanceof MethodInvocation) { + MethodInvocation mi = (MethodInvocation) exp; + Expression element = mi.getExpression();{ + if (element instanceof SimpleName) { + SimpleName sn = (SimpleName) element; + if (mi.getName().toString().equals("iterator")) { //$NON-NLS-1$ + name.add(sn.getIdentifier()); + } + } + } + } + return name; + } + + /** + * Here we use fluent style to express visiting where the subsequent search is starting at the node the preceding search found. + * + * This sample finds the 3 nodes related to a while loop based on iterator for you. + * + * 1) VariableDeclarationStatement + * 2) "below 1)" all WhileStatement + * 3) "below 2)" all MethodInvocation + * + * "below" is not meant literally as there is a helper lambda expression that allows to navigate on the found node of + * the type searched for to another node as a start for the directly following fluent call. + * + * That means in this case by the lambda expression "s->s.getParent()" in the call to search for VariableDeclarationStatement + * the found node is not directly used as start node for the following call to search for WhileStatement. Instead the parent of this node + * is used. Otherwise it would not be possible to find related whilestatements. + * + * A similar trick is used in the next call to find all related MethodInvocations. As we are only interested in ".next()" calls in the + * while loop body we use the lambda expression "s -> ((WhileStatement)s).getBody()" to go on searching for ".next()". + */ + @Test + public void simpleTest5f() { + ReferenceHolder dataholder = new ReferenceHolder<>(); + ASTProcessor, String, Object> astp=new ASTProcessor<>(dataholder, null); + astp.callVariableDeclarationStatementVisitor(Iterator.class,(node,holder) -> { + /** + * This lambda expression is called for all VariableDeclarationStatement of type Iterator + */ + holder.put("init", node); + List computeVarName = computeVarName((VariableDeclarationStatement)node); + holder.put("initvarname", computeVarName.get(0)); + return true; + },s -> s.getParent()).callWhileStatementVisitor((node,holder) -> { + /** + * This lambda expression is called for all WhileStatements below the parent of each VariableDeclarationStatement + */ + holder.put("while", node); + String name = computeNextVarname((WhileStatement)node); + holder.put("whilevarname", name); + return true; + }, s -> ((WhileStatement)s).getBody()).callMethodInvocationVisitor("next",(node,holder) -> { + /** + * This lambda expression is called for all MethodInvocations "next()" in each Body of WhileStatements found above + */ + String name=(String) holder.get("initvarname"); + Expression element2 = ((MethodInvocation)node).getExpression(); + SimpleName sn= ASTNodes.as(element2, SimpleName.class); + if (sn !=null) { + String identifier = sn.getIdentifier(); + if(!name.equals(identifier)) + return true; + if(name.equals(holder.get("whilevarname"))) { + System.out.println("====================="); + System.out.println("iterator: "+holder.get("init").toString().trim()); + System.out.println("while: "+holder.get("while").toString().trim()); + System.out.println("next: "+node.toString().trim()); + } + } + return true; + }).build(result2); + } + + @Test + public void simpleTest5g() { + ReferenceHolder dataholder = new ReferenceHolder<>(); + ASTProcessor,String,Object> astp=new ASTProcessor<>(dataholder, null); + astp.callVariableDeclarationStatementVisitor(Iterator.class,(node,holder) -> { + holder.put("init", node); + List computeVarName = computeVarName((VariableDeclarationStatement)node); + holder.put("initvarname", computeVarName.get(0)); + System.out.println("init "+node.getNodeType() + " :" + node); + return true; + }).build(result2); + } + + /** + * This one is not really possible in "normal" visitors. Change visitors while visiting. + */ + @Test + public void modifyTest1() { + Set nodesprocessed = null; + HelperVisitor,String,NodeFound> hv = new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>()); + hv.addMethodInvocation("println",(node, holder) -> { + System.out.println("Start "+node.getNodeType() + " :" + node); + return true; + }); + hv.addMethodInvocation((node, holder) -> { + System.out.println("End "+node.getNodeType() + " :" + node); + holder.getHelperVisitor().removeVisitor(VisitorEnum.MethodInvocation); + }); + hv.build(result); + } + + @Test + public void modifyTest2() { + Set nodesprocessed = null; + ExpectationTracer dataholder = new ExpectationTracer(); + dataholder.stack.push(null); + HelperVisitor hv = new HelperVisitor<>(nodesprocessed, dataholder); + Set names = new HashSet<>(); + Set nodes = new HashSet<>(); + hv.addSingleVariableDeclaration((node, holder) -> { + names.add(node.getName()); + return true; + }); + hv.addVariableDeclarationFragment((node, holder) -> { + names.add(node.getName()); + return true; + }); + hv.addWhileStatement((node, holder) -> { + nodes.add(node); + return true; + }); + hv.addWhileStatement((node, holder) -> { + nodes.remove(node); + Collection usedVarNames= getUsedVariableNames(node.getBody()); + System.out.println(usedVarNames); + }); + hv.addMethodInvocation("next",(methodinvocationnode, myholder) -> { + String x = "Start "+methodinvocationnode.getNodeType() + " :" + methodinvocationnode; + System.out.printf("%-40s %s%n",x,ASTNode.nodeClassForType(methodinvocationnode.getNodeType())); + return true; + }); + hv.build(result2); + } + + Collection getUsedVariableNames(ASTNode node) { + CompilationUnit root= (CompilationUnit) node.getRoot(); + Collection res= (new ScopeAnalyzer(root)).getUsedVariableNames(node.getStartPosition(), node.getLength()); + return res; + } +} diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/JUnit4TestFinderTest16.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/JUnit4TestFinderTest16.java new file mode 100644 index 00000000..ab28aa75 --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/JUnit4TestFinderTest16.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2021 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.junit.tests; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.HashSet; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.eclipse.jdt.junit.JUnitCore; +import org.eclipse.jdt.testplugin.JavaProjectHelper; +import org.eclipse.jdt.testplugin.StringAsserts; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; + +import org.eclipse.jdt.internal.junit.launcher.ITestFinder; +import org.eclipse.jdt.internal.junit.launcher.ITestKind; +import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry; + +import org.eclipse.jdt.ui.tests.core.rules.Java16ProjectTestSetup; +import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; + + +public class JUnit4TestFinderTest16 { + + private IJavaProject fProject; + private IPackageFragmentRoot fRoot; + + @Rule + public ProjectTestSetup projectsetup= new Java16ProjectTestSetup(false); + + + @Before + public void setUp() throws Exception { + fProject= projectsetup.getProject(); + fProject.setRawClasspath(projectsetup.getDefaultClasspath(), null); + IClasspathEntry cpe= JavaCore.newContainerEntry(JUnitCore.JUNIT4_CONTAINER_PATH); + JavaProjectHelper.addToClasspath(fProject, cpe); + + fRoot= JavaProjectHelper.addSourceContainer(fProject, "src"); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testTestAnnotation_bug575762() throws Exception { + IPackageFragment p= fRoot.createPackageFragment("p", true, null); + StringBuilder buf= new StringBuilder(); + buf.append("package p;\n"); + buf.append("\n"); + buf.append("import org.junit.Test;\n"); + buf.append("\n"); + buf.append("public record Test1() {\n"); + buf.append(" @Test public void testFoo() {\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu1= p.createCompilationUnit("Test1.java", buf.toString(), true, null); + + IType[] types= cu1.getTypes(); + + IType validTest1= types[0]; + + assertTestFound(validTest1, new String[] { "p.Test1" }); + assertTestFound(validTest1.getCompilationUnit(), new String[] { "p.Test1" }); + + String[] validTests= { "p.Test1" }; + + assertTestFound(p, validTests); + assertTestFound(fRoot, validTests); + assertTestFound(fProject, validTests); + } + + private void assertTestFound(IJavaElement container, String[] expectedTypes) throws CoreException { + ITestKind testKind= TestKindRegistry.getContainerTestKind(container); + assertEquals(TestKindRegistry.JUNIT4_TEST_KIND_ID, testKind.getId()); + + ITestFinder finder= testKind.getFinder(); + + if (container instanceof IType) { + IType type= (IType) container; + boolean isTest= expectedTypes.length == 1 && type.getFullyQualifiedName('.').equals(expectedTypes[0]); + assertEquals(type.getFullyQualifiedName(), isTest, finder.isTest(type)); + } + + HashSet set= new HashSet<>(Arrays.asList(JUnitCore.findTestTypes(container, null))); + HashSet namesFound= new HashSet<>(); + for (IType curr : set) { + namesFound.add(curr.getFullyQualifiedName('.')); + } + String[] actuals= namesFound.toArray(new String[namesFound.size()]); + StringAsserts.assertEqualStringsIgnoreOrder(actuals, expectedTypes); + } + + +} diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/JUnitJUnitTests.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/JUnitJUnitTests.java index a87b4074..d1aef52d 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/JUnitJUnitTests.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/JUnitJUnitTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2020 IBM Corporation and others. + * Copyright (c) 2005, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -40,6 +40,7 @@ JUnit3TestFinderTest.class, JUnit4TestFinderTest.class, +JUnit4TestFinderTest16.class, TestSorting.class /** diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/TestTestSearchEngine.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/TestTestSearchEngine.java index c8e02f8e..7235dd57 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/TestTestSearchEngine.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/junit/tests/TestTestSearchEngine.java @@ -16,8 +16,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; + import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -68,10 +69,10 @@ public void testOnePackage() throws Exception { ICompilationUnit test1= createCompilationUnit(p, 1); ICompilationUnit test2= createCompilationUnit(p, 2); - IType[] result= findTests(p); - assertEqualTypes("Test case not found", new IType[] { + var result= findTests(p); + assertEqualTypes("Test case not found", List.of( test1.getType("Test1"), test2.getType("Test2") - }, result); + ), result); } @Test @@ -83,10 +84,10 @@ public void testTwoPackages() throws Exception { IPackageFragment q= fRoot.createPackageFragment("q", true, null); ICompilationUnit test3= createCompilationUnit(q, 3); - IType[] result= findTests(new IJavaElement[] {p, q}); - assertEqualTypes("Test case not found", new IType[] { + var result= findTests(new IJavaElement[] {p, q}); + assertEqualTypes("Test case not found", List.of( test1.getType("Test1"), test2.getType("Test2"), test3.getType("Test3") - }, result); + ), result); } @Test @@ -98,10 +99,10 @@ public void testTwoPackagesSearchingInOne() throws Exception { IPackageFragment q= fRoot.createPackageFragment("q", true, null); createCompilationUnit(q, 3); - IType[] result= findTests(p); - assertEqualTypes("Test case not found", new IType[] { + var result= findTests(p); + assertEqualTypes("Test case not found", List.of( test1.getType("Test1"), test2.getType("Test2") - }, result); + ), result); } @Test @@ -113,10 +114,10 @@ public void testPackageFragmentRoot() throws Exception { IPackageFragment q= fRoot.createPackageFragment("q", true, null); ICompilationUnit test3= createCompilationUnit(q, 3); - IType[] result= findTests(fRoot); - assertEqualTypes("Test case not found", new IType[] { + var result= findTests(fRoot); + assertEqualTypes("Test case not found", List.of( test1.getType("Test1"), test2.getType("Test2"), test3.getType("Test3") - }, result); + ), result); } @Test @@ -134,11 +135,11 @@ public void testTwoPackageFragmentRoots() throws Exception { ICompilationUnit test4= createCompilationUnit(r, 4); ICompilationUnit test5= createCompilationUnit(r, 5); - IType[] result= findTests(new IJavaElement[] {fRoot, root2}); - assertEqualTypes("Test case not found", new IType[] { + var result= findTests(new IJavaElement[] {fRoot, root2}); + assertEqualTypes("Test case not found", List.of( test1.getType("Test1"), test2.getType("Test2"), test3.getType("Test3"), test4.getType("Test4"), test5.getType("Test5") - }, result); + ), result); } @Test @@ -156,10 +157,10 @@ public void testTwoPackageFragmentRootsSearchingInOne() throws Exception { ICompilationUnit test4= createCompilationUnit(r, 4); ICompilationUnit test5= createCompilationUnit(r, 5); - IType[] result= findTests(root2); - assertEqualTypes("Test case not found", new IType[] { + var result= findTests(root2); + assertEqualTypes("Test case not found", List.of( test4.getType("Test4"), test5.getType("Test5") - }, result); + ), result); } @Test @@ -176,8 +177,8 @@ public void testTwoPackageFragmentRootsSearchingInOneNoSupertype() throws Except true, null); - IType[] result= findTests(root2); - assertEqualTypes("Test case not found", new IType[] { testSub.getType("TestSub") }, result); + var result= findTests(root2); + assertEqualTypes("Test case not found", List.of(testSub.getType("TestSub")), result); } @Test @@ -195,11 +196,11 @@ public void testProject() throws Exception { ICompilationUnit test4= createCompilationUnit(r, 4); ICompilationUnit test5= createCompilationUnit(r, 5); - IType[] result= findTests(fProject); - assertEqualTypes("Test case not found", new IType[] { + var result= findTests(fProject); + assertEqualTypes("Test case not found", List.of( test1.getType("Test1"), test2.getType("Test2"), test3.getType("Test3"), test4.getType("Test4"), test5.getType("Test5") - }, result); + ), result); } @Test @@ -210,27 +211,24 @@ public void testSubPackage() throws Exception { IPackageFragment q= fRoot.createPackageFragment("p.q", true, null); createCompilationUnit(q, 2); - IType[] result= findTests(p); - assertEqualTypes("Test case not found", new IType[] { - test1.getType("Test1") - }, result); + var result= findTests(p); + assertEqualTypes("Test case not found", List.of(test1.getType("Test1")), result); } - private IType[] findTests(IJavaElement element) throws InvocationTargetException, InterruptedException { + private List findTests(IJavaElement element) throws InvocationTargetException, InterruptedException { ITestKind testKind= TestKindRegistry.getContainerTestKind(fProject); - return TestSearchEngine.findTests(new BusyIndicatorRunnableContext(), element, testKind); + return new ArrayList<>(TestSearchEngine.findTests(new BusyIndicatorRunnableContext(), element, testKind)); } - private IType[] findTests(IJavaElement[] elements) throws InvocationTargetException, InterruptedException { + private List findTests(IJavaElement[] elements) throws InvocationTargetException, InterruptedException { HashSet res= new HashSet<>(); for (IJavaElement element : elements) { - IType[] types= findTests(element); - res.addAll(Arrays.asList(types)); + var types= findTests(element); + res.addAll(types); } - return res.toArray(new IType[res.size()]); + return new ArrayList<>(res); } - @Test public void testJUnit4NoSrc() throws Exception { //regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=151003 @@ -245,11 +243,10 @@ private ICompilationUnit createCompilationUnit(IPackageFragment pack, int number true, null); } - private void assertEqualTypes(String message, IType[] expected, IType[] actual) { - assertEquals("Wrong number of found tests", expected.length, actual.length); - List list= Arrays.asList(expected); - for (int i= 0; i < actual.length; i++) { - assertTrue(message + expected[i].getFullyQualifiedName(), list.contains(expected[i])); + private void assertEqualTypes(String message, List expected, List actual) { + assertEquals("Wrong number of found tests", expected.size(), actual.size()); + for (int i= 0; i < actual.size(); i++) { + assertTrue(message + expected.get(i).getFullyQualifiedName(), expected.contains(actual.get(i))); } } } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/AutomatedSuite.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/AutomatedSuite.java index e25ca69c..8c1c84cf 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/AutomatedSuite.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/AutomatedSuite.java @@ -41,6 +41,7 @@ import org.eclipse.jdt.ui.tests.wizardapi.ImporterTest; import org.eclipse.jdt.ui.tests.wizardapi.NewJavaProjectWizardTest; import org.eclipse.jdt.ui.tests.wizardapi.NewTypeWizardTest; +import org.eclipse.jdt.ui.tests.wizardapi.NewTypeWizardTest17; import org.eclipse.jdt.internal.ui.JavaPlugin; @@ -55,6 +56,7 @@ NewJavaProjectWizardTest.class, NewTypeWizardTest.class, + NewTypeWizardTest17.class, ImporterTest.class, PackageExplorerTests.class, diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/callhierarchy/CallHierarchyContentProviderTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/callhierarchy/CallHierarchyContentProviderTest.java index 9b60b84e..bc676a74 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/callhierarchy/CallHierarchyContentProviderTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/callhierarchy/CallHierarchyContentProviderTest.java @@ -23,11 +23,18 @@ import org.junit.Before; import org.junit.Test; -import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.testplugin.util.DisplayHelper; + +import org.eclipse.swt.widgets.Display; + +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.intro.IIntroManager; +import org.eclipse.ui.intro.IIntroPart; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy; import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; @@ -36,39 +43,43 @@ import org.eclipse.jdt.internal.ui.callhierarchy.CallHierarchyUI; import org.eclipse.jdt.internal.ui.callhierarchy.TreeRoot; -public class CallHierarchyContentProviderTest{ - private static final int DEFAULT_MAX_DEPTH= 10; +public class CallHierarchyContentProviderTest { + + private static final int DEFAULT_MAX_DEPTH = 10; private CallHierarchyTestHelper helper; private CallHierarchyContentProvider fProvider; + private int fOriginalMaxCallDepth; + @Before public void setUp() throws Exception { - helper= new CallHierarchyTestHelper(); - helper.setUp(); - - fProvider= new CallHierarchyContentProvider(null); - - CallHierarchyUI.getDefault().setMaxCallDepth(DEFAULT_MAX_DEPTH); + if (!welcomeClosed) { + closeIntro(PlatformUI.getWorkbench()); + } + helper= new CallHierarchyTestHelper(); + helper.setUp(); + fProvider= new CallHierarchyContentProvider(null); + + CallHierarchyUI callHierarchyUI= CallHierarchyUI.getDefault(); + fOriginalMaxCallDepth= callHierarchyUI.getMaxCallDepth(); + callHierarchyUI.setMaxCallDepth(DEFAULT_MAX_DEPTH); + DisplayHelper.driveEventQueue(Display.getDefault()); } @After public void tearDown() throws Exception { helper.tearDown(); helper= null; - - CallHierarchyUI.getDefault().setMaxCallDepth(DEFAULT_MAX_DEPTH); + CallHierarchyUI.getDefault().setMaxCallDepth(fOriginalMaxCallDepth); } - /** + /* * Tests getChildren and hasChildren on an "ordinary" callee tree. - * - * @throws JavaModelException - * @throws CoreException */ @Test - public void testGetChildrenOfCalleeRoot() throws JavaModelException, CoreException { + public void testGetChildrenOfCalleeRoot() throws Exception { helper.createSimpleClasses(); TreeRoot root= wrapCalleeRoot(helper.getMethod4()); @@ -98,14 +109,11 @@ public void testGetChildrenOfCalleeRoot() throws JavaModelException, CoreExcepti assertTrue("fourth level hasChildren", fProvider.hasChildren(fourthLevelMethodWrapper)); } - /** + /* * Tests getChildren and hasChildren on an "ordinary" callers tree. - * - * @throws JavaModelException - * @throws CoreException */ @Test - public void testGetChildrenOfCallerRoot() throws JavaModelException, CoreException { + public void testGetChildrenOfCallerRoot() throws Exception { helper.createSimpleClasses(); TreeRoot root= wrapCallerRoot(helper.getMethod1()); @@ -130,14 +138,11 @@ public void testGetChildrenOfCallerRoot() throws JavaModelException, CoreExcepti assertTrue("fourth level hasChildren", fProvider.hasChildren(thirdLevelChildren[0])); } - /** + /* * Tests getChildren and hasChildren on an callers tree which exceeds the max call depth. - * - * @throws JavaModelException - * @throws CoreException */ @Test - public void testGetChildrenOfCallerMaxDepth() throws JavaModelException, CoreException { + public void testGetChildrenOfCallerMaxDepth() throws Exception { helper.createSimpleClasses(); CallHierarchyUI.getDefault().setMaxCallDepth(2); @@ -164,14 +169,11 @@ public void testGetChildrenOfCallerMaxDepth() throws JavaModelException, CoreExc assertFalse("fourth level hasChildren", fProvider.hasChildren(thirdLevelChildren[0])); } - /** + /* * Tests getChildren and hasChildren on an callee tree which exceeds the max call depth. - * - * @throws JavaModelException - * @throws CoreException */ @Test - public void testGetChildrenOfCalleeMaxDepth() throws JavaModelException, CoreException { + public void testGetChildrenOfCalleeMaxDepth() throws Exception { helper.createSimpleClasses(); CallHierarchyUI.getDefault().setMaxCallDepth(2); @@ -203,14 +205,11 @@ public void testGetChildrenOfCalleeMaxDepth() throws JavaModelException, CoreExc assertFalse("fourth level hasChildren", fProvider.hasChildren(thirdLevelChildren[0])); } - /** + /* * Tests getChildren and hasChildren on an callers tree with recursion. - * - * @throws JavaModelException - * @throws CoreException */ @Test - public void testGetChildrenOfCalleeRecursive() throws JavaModelException, CoreException { + public void testGetChildrenOfCalleeRecursive() throws Exception { helper.createSimpleClasses(); TreeRoot root= wrapCalleeRoot(helper.getRecursiveMethod1()); @@ -232,14 +231,11 @@ public void testGetChildrenOfCalleeRecursive() throws JavaModelException, CoreEx assertFalse("third level hasChildren", fProvider.hasChildren(thirdLevelChildren[0])); } - /** + /* * Tests getChildren and hasChildren on an callees tree with recursion. - * - * @throws JavaModelException - * @throws CoreException */ @Test - public void testGetChildrenOfCallerRecursive() throws JavaModelException, CoreException { + public void testGetChildrenOfCallerRecursive() throws Exception { helper.createSimpleClasses(); TreeRoot root= wrapCallerRoot(helper.getRecursiveMethod1()); @@ -261,6 +257,23 @@ public void testGetChildrenOfCallerRecursive() throws JavaModelException, CoreEx assertFalse("third level hasChildren", fProvider.hasChildren(thirdLevelChildren[0])); } + @Test + public void testLambdaCallers() throws Exception { + helper.createClassWithLambdaCalls(); + TreeRoot root= wrapCallerRoot(helper.getMethod1()); + Object[] children= fProvider.getChildren(root); + helper.assertCalls(new IMember[] { helper.getMethod1() }, children); + assertTrue("root's hasChildren", fProvider.hasChildren(root)); + + Object[] secondLevelChildren= fProvider.getChildren(children[0]); + helper.assertCalls(new IMember[] { helper.getMethod2() }, secondLevelChildren); + + Object[] thirdLevelChildren= fProvider.getChildren(secondLevelChildren[0]); + + assertEquals( + "Wrong number of third level children", 6, thirdLevelChildren.length); + } + private void assertCalleeMethodWrapperChildren(Object[] children) { for (Object child : children) { assertTrue("Wrong class returned", child.getClass().getName().endsWith(".CalleeMethodWrapper")); @@ -281,4 +294,16 @@ private TreeRoot wrapCallerRoot(IMethod method) { return new TreeRoot(CallHierarchy.getDefault().getCallerRoots(new IMember[] { method })); } + private static boolean welcomeClosed; + private static void closeIntro(final IWorkbench wb) { + IWorkbenchWindow window= wb.getActiveWorkbenchWindow(); + if (window != null) { + IIntroManager im= wb.getIntroManager(); + IIntroPart intro= im.getIntro(); + if (intro != null) { + welcomeClosed= im.closeIntro(intro); + } + } + } + } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/callhierarchy/CallHierarchyTestHelper.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/callhierarchy/CallHierarchyTestHelper.java index 96d8839f..1156113d 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/callhierarchy/CallHierarchyTestHelper.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/callhierarchy/CallHierarchyTestHelper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.List; import org.junit.Assert; @@ -24,26 +25,43 @@ import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IncrementalProjectBuilder; + import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; +import org.eclipse.jdt.ui.tests.core.rules.Java17ProjectTestSetup; +import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; + +@SuppressWarnings("javadoc") public class CallHierarchyTestHelper { private static final String[] EMPTY= new String[0]; private IJavaProject fJavaProject1; private IJavaProject fJavaProject2; + private IJavaProject fJavaProject3; private IType fType1; private IType fType2; - private IPackageFragment fPack2; + private IType fTypeP; + private IType fFooImplAType; + private IType fFooImplBType; + private IType fFooType; + private IType fAbsType; + private IType fAbsI1Type; + private IType fAbsI2Type; private IPackageFragment fPack1; + private IPackageFragment fPack2; + private IPackageFragment fPack3; private IMethod fMethod1; private IMethod fMethod2; @@ -51,26 +69,47 @@ public class CallHierarchyTestHelper { private IMethod fMethod4; private IMethod fRecursiveMethod1; private IMethod fRecursiveMethod2; + private IMethod fCalleeMethod; + private IMethod fAbsCalleeMethod; + private IMethod fFooMethod; + private IMethod fFooImplMethod_A; + private IMethod fFooImplMethod_B; + private IMethod fAbsFooMethod; + private IMethod fAbsI1FooMethod; + private IMethod fAbsI2FooMethod; public void setUp() throws Exception { fJavaProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); fJavaProject2= JavaProjectHelper.createJavaProject("TestProject2", "bin"); + fJavaProject3= JavaProjectHelper.createJavaProject("TestProject3", "bin"); + assertBuildWithoutErrors(fJavaProject1); + assertBuildWithoutErrors(fJavaProject2); + assertBuildWithoutErrors(fJavaProject3); fType1= null; fType2= null; + fTypeP= null; + fFooImplAType= null; + fFooImplBType= null; + fAbsI1Type= null; + fAbsI2Type= null; + fAbsType= null; + fFooType= null; fPack1= null; fPack2= null; + fPack3= null; } public void tearDown() throws Exception { JavaProjectHelper.delete(fJavaProject1); JavaProjectHelper.delete(fJavaProject2); + JavaProjectHelper.delete(fJavaProject3); } /** * Creates two simple classes, A and B. Sets the instance fields fType1 and fType2. */ - public void createSimpleClasses() throws CoreException, JavaModelException { + public void createSimpleClasses() throws Exception { createPackages(); @@ -104,12 +143,15 @@ public void createSimpleClasses() throws CoreException, JavaModelException { null, true, null); + + assertBuildWithoutErrors(fJavaProject1); + assertBuildWithoutErrors(fJavaProject2); } /** * Creates two simple classes, A and its subclass B, where B calls A's implicit constructor explicitly. Sets the instance fields fType1 and fType2. */ - public void createImplicitConstructorClasses() throws CoreException, JavaModelException { + public void createImplicitConstructorClasses() throws Exception { createPackages(); ICompilationUnit cu1= fPack1.getCompilationUnit("A.java"); @@ -127,6 +169,7 @@ public void createImplicitConstructorClasses() throws CoreException, JavaModelEx null, true, null); + assertBuildWithoutErrors(fPack1); } /** @@ -146,6 +189,7 @@ public void createInnerClass() throws Exception { null, true, null); + assertBuildWithoutErrors(fPack1); } /** @@ -199,7 +243,7 @@ public void createAnonymousInnerClass() throws Exception { null, true, null); - + assertBuildWithoutErrors(fPack1); } /** @@ -225,9 +269,56 @@ public void createAnonymousInnerClassInsideMethod() throws Exception { null, true, null); - + assertBuildWithoutErrors(fPack1); } + /** + * Creates a class with various lambda function definitions and calls + */ + public void createClassWithLambdaCalls() throws Exception { + createPackages(); + + ICompilationUnit cu= fPack1.getCompilationUnit("Snippet.java"); + fType1= cu.createType("public class Snippet {\n" + + " static Function mapper1 = y -> transform(y);\n" + + " Function mapper2 = y -> transform(y);\n" + + "\n" + + " static {\n" + + " mapper1 = y -> transform(y);\n" + + " }\n" + + "\n" + + " public Snippet() {\n" + + " mapper2 = y -> transform(y);\n" + + " }\n" + + "\n" + + " public static void main(String[] args) {\n" + + " mapper1 = y -> transform(y);\n" + + " }\n" + + "\n" + + " Object[] funcCall() {\n" + + " return List.of(\"aaa\").stream().map(y -> transform(y)).toArray();\n" + + " }\n" + + "\n" + + " static String transform(String s) {\n" + + " x();\n" + + " return s.toUpperCase();\n" + + " }\n" + + " static String x() {" + + " return null;\n" + + "}\n" + + "}", + null, + true, + null); + cu.createImport("java.util.List", fType1, null); + cu.createImport("java.util.function.Function", fType1, null); + fMethod1= fType1.getMethod("x", EMPTY); + fMethod2= fType1.getMethod("transform", new String[] { "QString;" }); + Assert.assertNotNull(fMethod1); + Assert.assertNotNull(fMethod2); + assertBuildWithoutErrors(fPack1); + } + /** * Creates a class with a static initializer and sets the class attribute fType1. */ @@ -241,23 +332,203 @@ public void createStaticInitializerClass() throws Exception { null, true, null); + assertBuildWithoutErrors(fPack1); + } + + /** + * Creates a record class, OneRecord and sets the instance field fType1. + */ + public void createRecordClasses() throws Exception { + ProjectTestSetup projectsetup= new Java17ProjectTestSetup(false); + fJavaProject3.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJavaProject3, false); + + IPackageFragmentRoot fSourceFolder= JavaProjectHelper.addSourceContainer(fJavaProject3, "src"); + + String MODULE_INFO_FILE_CONTENT = "" + + "module test {\n" + + "}\n"; + + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", MODULE_INFO_FILE_CONTENT, false, null); + + fPack3= fSourceFolder.createPackageFragment("test", false, null); + + JavaProjectHelper.set16CompilerOptions(fJavaProject1, true); + + ICompilationUnit cu1= fPack3.getCompilationUnit("Outer.java"); + + fType1= + cu1.createType( + "public class Outer {\n" + + "record OneRecord(int number1, int number2) {\n" + + " OneRecord() { this(1, 2); }\n" + + "}\n " + + " public static void method1() {\n" + + " new OneRecord(3, 5);\n" + + " }\n" + + " public static void method2() {\n" + + " new OneRecord();\n" + + " }\n" + + " public static void method3() {\n" + + " method1();\n" + + " method2();\n" + + " }\n" + + "}\n", + null, + true, + null); + assertBuildWithoutErrors(fJavaProject3); + } + + public void createCalleeClasses() throws Exception { + createPackages(); + + ICompilationUnit cu3= fPack2.getCompilationUnit("P.java"); + fTypeP= + cu3.createType( + "public class P {\n" + + " private A handler;\n" + + " private Abs absHandler;\n" + + "\n" + + " public void callFoo() {\n" + + " handler.foo();\n" + + " }\n" + + " public void callAbsFoo() {\n" + + " absHandler.absFoo();\n" + + " }\n" + + "\n" + + "}", + null, + true, + null); + + ICompilationUnit cu4= fPack2.getCompilationUnit("A.java"); + fFooType= cu4.createType( + "public interface A {\n" + + " void foo();\n" + + "}\n" + , null, true, null); + + + ICompilationUnit cu5= fPack2.getCompilationUnit("AImpl.java"); + fFooImplAType= cu5.createType( + "public class AImpl implements A {\n" + + " public void foo() {\n" + + " System.out.println();\n" + + " }\n" + + "}\n" + , null, true, null); + + ICompilationUnit cu6= fPack2.getCompilationUnit("BImpl.java"); + fFooImplBType= cu6.createType( + "public class BImpl implements A {\n" + + " public void foo() {\n" + + " System.out.printf(\"\");\n" + + " }\n" + + "}\n" + , null, true, null); + + + ICompilationUnit cu7= fPack2.getCompilationUnit("Abs.java"); + fAbsType= cu7.createType( + "public abstract class Abs {\n" + + " abstract void absFoo();\n" + + "}\n" + , null, true, null); + + ICompilationUnit cu8= fPack2.getCompilationUnit("AbsI1.java"); + fAbsI1Type= cu8.createType( + "public class AbsI1 extends Abs {\n" + + " void absFoo() {}\n" + + "}\n" + , null, true, null); + + ICompilationUnit cu9= fPack2.getCompilationUnit("AbsI2.java"); + fAbsI2Type= cu9.createType( + "public class AbsI2 extends Abs {\n" + + " void absFoo() {}\n" + + "}\n" + , null, true, null); + + assertBuildWithoutErrors(fJavaProject1); + assertBuildWithoutErrors(fJavaProject2); + } /** * Creates two packages (pack1 and pack2) in different projects. Sets the * instance fields fPack1 and fPack2. */ - public void createPackages() throws CoreException, JavaModelException { - JavaProjectHelper.addRTJar(fJavaProject1); + public void createPackages() throws Exception { + JavaProjectHelper.addRTJar9(fJavaProject1); IPackageFragmentRoot root1= JavaProjectHelper.addSourceContainer(fJavaProject1, "src"); fPack1= root1.createPackageFragment("pack1", true, null); + assertBuildWithoutErrors(fPack1); - JavaProjectHelper.addRTJar(fJavaProject2); + JavaProjectHelper.addRTJar9(fJavaProject2); JavaProjectHelper.addRequiredProject(fJavaProject2, fJavaProject1); IPackageFragmentRoot root2= JavaProjectHelper.addSourceContainer(fJavaProject2, "src"); fPack2= root2.createPackageFragment("pack2", true, null); + assertBuildWithoutErrors(fPack2); + } + + /** + * Returns all error markers on given resource, recursively + */ + public List getErrorMarkers(IResource resource) throws CoreException { + IMarker[] markers = resource.findMarkers(null, true, IResource.DEPTH_INFINITE); + List errorMarkers = new ArrayList<>(); + for (IMarker marker : markers) { + if (marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO) == IMarker.SEVERITY_ERROR) { + errorMarkers.add(marker); + } + } + return errorMarkers; + } + + public static List convertMarkers(IMarker [] markers) throws Exception { + List result = new ArrayList<>(); + for (int i = 0; i < markers.length; i++) { + IMarker marker = markers[i]; + StringBuilder sb = new StringBuilder("Marker #"); + sb.append(i).append("["); + sb.append(marker.getAttribute("message", null)); + sb.append(" at line: ").append(marker.getAttribute("lineNumber", 0)); + sb.append("], "); + result.add(sb.toString()); + } + return result; + } + + /** + * Verifies that no error markers exist in the given resource. + *

    + * + * @param element + * The resource that is searched for error markers + */ + protected void assertBuildWithoutErrors(IJavaElement element) throws Exception { + IResource resource= element.getResource(); + Assert.assertNotNull("Given element has no resource: " + element, resource); + resource.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); + assertNoErrorMarkers(resource); + } + + /** + * Verifies that no error markers exist in the given resource. + *

    + * + * @param resource + * The resource that is searched for error markers + */ + protected void assertNoErrorMarkers(IResource resource) throws Exception { + List errorMarkers = getErrorMarkers(resource); + List messages = convertMarkers(errorMarkers.toArray(new IMarker[errorMarkers.size()])); + Assert.assertEquals("No error marker expected, but found markers with messages: " + messages.toString(), 0, + errorMarkers.size()); } /** @@ -323,7 +594,7 @@ public IPackageFragment getPackage2() { /** * @return */ - public IType getType1() { + public IType getType1() { return fType1; } @@ -334,6 +605,34 @@ public IType getType2() { return fType2; } + public IType getTypeP() { + return fTypeP; + } + + public IType getFooImplAType() { + return fFooImplAType; + } + + public IType getFooImplBType() { + return fFooImplBType; + } + + public IType getFooType() { + return fFooType; + } + + public IType getAbsType() { + return fAbsType; + } + + public IType getAbsI1Type() { + return fAbsI1Type; + } + + public IType getAbsI2Type() { + return fAbsI2Type; + } + public IMethod getMethod1() { if (fMethod1 == null) { fMethod1= getType1().getMethod("method1", EMPTY); @@ -375,4 +674,60 @@ public IMethod getRecursiveMethod2() { } return fRecursiveMethod2; } + + public IMethod getCalleeMethod() { + if (fCalleeMethod == null) { + fCalleeMethod= getTypeP().getMethod("callFoo", EMPTY); + } + return fCalleeMethod; + } + + public IMethod getAbsCalleeMethod() { + if (fAbsCalleeMethod == null) { + fAbsCalleeMethod= getTypeP().getMethod("callAbsFoo", EMPTY); + } + return fAbsCalleeMethod; + } + + public IMethod getFooImplMethod_A() { + if (fFooImplMethod_A == null) { + fFooImplMethod_A= getFooImplAType().getMethod("foo", EMPTY); + } + return fFooImplMethod_A; + } + + public IMethod getFooImplMethod_B() { + if (fFooImplMethod_B == null) { + fFooImplMethod_B= getFooImplBType().getMethod("foo", EMPTY); + } + return fFooImplMethod_B; + } + + public IMethod getFooMethod() { + if (fFooMethod == null) { + fFooMethod= getFooType().getMethod("foo", EMPTY); + } + return fFooMethod; + } + + public IMethod getAbsFooMethod() { + if (fAbsFooMethod == null) { + fAbsFooMethod= getAbsType().getMethod("absFoo", EMPTY); + } + return fAbsFooMethod; + } + + public IMethod getAbsI1FooMethod() { + if (fAbsI1FooMethod == null) { + fAbsI1FooMethod= getAbsI1Type().getMethod("absFoo", EMPTY); + } + return fAbsI1FooMethod; + } + + public IMethod getAbsI2FooMethod() { + if (fAbsI2FooMethod == null) { + fAbsI2FooMethod= getAbsI2Type().getMethod("absFoo", EMPTY); + } + return fAbsI2FooMethod; + } } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/AddImportTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/AddImportTest.java index 79bd7df2..bc137976 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/AddImportTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/AddImportTest.java @@ -496,6 +496,57 @@ public void testAddStaticImports2() throws Exception { assertEqualString(cu.getSource(), buf.toString()); } + @Test + public void testAddImportStaticForSubclassReference() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class T {\n"); + buf.append(" public static void foo() { };\n"); + buf.append("}\n"); + pack1.createCompilationUnit("T.java", buf.toString(), false, null); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class TSub extends T {\n"); + buf.append("}\n"); + pack1.createCompilationUnit("TSub.java", buf.toString(), false, null); + + IPackageFragment pack2= sourceFolder.createPackageFragment("test2", false, null); + buf= new StringBuilder(); + buf.append("package test2;\n"); + buf.append("\n"); + buf.append("import test1.TSub;\n"); + buf.append("public class S {\n"); + buf.append(" public S() {\n"); + buf.append(" TSub.foo();\n"); + buf.append(" TSub.foo();\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack2.createCompilationUnit("S.java", buf.toString(), false, null); + + int selOffset= buf.indexOf("foo"); + + AddImportsOperation op= new AddImportsOperation(cu, selOffset, 0, null, true); + op.run(null); + + StringBuilder expectation= new StringBuilder(); + expectation.append("package test2;\n"); + expectation.append("\n"); + expectation.append("import static test1.T.foo;\n"); + expectation.append("\n"); + expectation.append("import test1.TSub;\n"); + expectation.append("public class S {\n"); + expectation.append(" public S() {\n"); + expectation.append(" foo();\n"); + expectation.append(" TSub.foo();\n"); + expectation.append(" }\n"); + expectation.append("}\n"); + assertEqualString(cu.getSource(), expectation.toString()); + } + @Test public void testImportStructureWithSignatures() throws Exception { diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/BindingsHierarchyTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/BindingsHierarchyTest.java new file mode 100644 index 00000000..7396c0ec --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/BindingsHierarchyTest.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2022 Red Hat and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ui.tests.core; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.eclipse.jdt.testplugin.JavaProjectHelper; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.TypeDeclaration; + +import org.eclipse.jdt.internal.corext.dom.Bindings; +import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; + +import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; + +public class BindingsHierarchyTest { + @Rule + public ProjectTestSetup pts= new ProjectTestSetup(); + private IPackageFragment fPackage; + + @Before + public void setUp() throws CoreException { + IPackageFragmentRoot src= JavaProjectHelper.addSourceContainer(pts.getProject(), "src"); + fPackage= src.createPackageFragment("test1", false, new NullProgressMonitor()); + } + + @After + public void tearDown() throws Exception { + JavaProjectHelper.clear(pts.getProject(), pts.getDefaultClasspath()); + } + + @Test + public void testWalkSuperclassInterface() throws JavaModelException { + String source= "" + + "package test1\n" + + "interface I1 {\n" + + "\n" + + "}\n" + + "\n" + + "interface I2 {\n" + + "\n" + + "}\n" + + "\n" + + "class Test1 implements I1 {\n" + + "\n" + + "}\n" + + "\n" + + "class Test2 extends Test1 implements I2 {\n" + + "\n" + + "}"; + + CompilationUnit ast= createAST(fPackage.createCompilationUnit("Test1.java", source, false, new NullProgressMonitor())); + + TypeDeclaration typeDeclaration= (TypeDeclaration) ast.types().get(3); + ITypeBinding typeBinding= typeDeclaration.resolveBinding(); + + Set superTypeBindings= new HashSet<>(); + + Bindings.visitHierarchy(typeBinding, type -> { + superTypeBindings.add(type.getName()); + return true; + }); + + assertEquals(4, superTypeBindings.size()); + assertTrue(superTypeBindings.containsAll(Arrays.asList("Test1", "Object", "I1", "I2"))); + } + + private CompilationUnit createAST(ICompilationUnit compilationUnit) { + ASTParser parser= ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL); + parser.setSource(compilationUnit); + parser.setResolveBindings(true); + return (CompilationUnit) parser.createAST(null); + } +} + + + diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CallHierarchyTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CallHierarchyTest.java index dd8178bd..ef397d12 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CallHierarchyTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CallHierarchyTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -16,10 +16,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.List; import org.junit.After; import org.junit.Before; @@ -37,6 +40,8 @@ import org.eclipse.jdt.ui.tests.callhierarchy.CallHierarchyTestHelper; +import org.eclipse.jdt.internal.ui.JavaPlugin; + public class CallHierarchyTest { private static final String[] EMPTY= new String[0]; @@ -468,6 +473,60 @@ public void lineNumberCallees() throws Exception { assertEquals("Wrong line number", 12, recursiveMethod2Wrapper.getMethodCall().getFirstCallLocation().getLineNumber()); } + @Test + public void recordConstructorCallers() throws Exception { + helper.createRecordClasses(); + + checkCalls(helper.getType1().getType("OneRecord"), helper.getMethod1(), helper.getMethod2(), helper.getType1().getType("OneRecord").getMethod("OneRecord", EMPTY)); + checkCalls(helper.getType1().getType("OneRecord").getMethod("OneRecord", EMPTY), helper.getMethod2()); + } + + @Test + public void implementingCallees_onInterfaces() throws Exception { + JavaPlugin.getDefault().getPreferenceStore().setValue("PREF_USE_IMPLEMENTORS", true); + helper.createCalleeClasses(); + + IMethod method= helper.getCalleeMethod(); + + MethodWrapper wrapper= getSingleCalleeRoot(method); + + MethodWrapper[] firstLevel= wrapper.getCalls(new NullProgressMonitor()); + assertNotNull(firstLevel); + assertEquals(1, firstLevel.length); + helper.assertCalls(Arrays.asList(helper.getFooMethod()), firstLevel); + + MethodWrapper[] secondLevel= firstLevel[0].getCalls(new NullProgressMonitor()); + assertNotNull(secondLevel); + assertEquals(2, secondLevel.length); + helper.assertCalls(Arrays.asList(helper.getFooImplMethod_A(), helper.getFooImplMethod_B()), secondLevel); + } + + @Test + public void implementingCallees_onAbstractMethods() throws Exception { + JavaPlugin.getDefault().getPreferenceStore().setValue("PREF_USE_IMPLEMENTORS", true); + helper.createCalleeClasses(); + + IMethod method= helper.getAbsCalleeMethod(); + + MethodWrapper wrapper= getSingleCalleeRoot(method); + + MethodWrapper[] firstLevel= wrapper.getCalls(new NullProgressMonitor()); + assertNotNull(firstLevel); + assertEquals(1, firstLevel.length); + helper.assertCalls(Arrays.asList(helper.getAbsFooMethod()), firstLevel); + + MethodWrapper[] secondLevel= firstLevel[0].getCalls(new NullProgressMonitor()); + assertNotNull(secondLevel); + assertEquals(2, secondLevel.length); + helper.assertCalls(Arrays.asList(helper.getAbsI1FooMethod(), helper.getAbsI2FooMethod()), secondLevel); + } + + private void checkCalls(IMember memberToCheck, IMethod... expectedCallers) { + MethodWrapper[] methodWrappers = CallHierarchy.getDefault().getCallerRoots(new IMember[] { memberToCheck }); + MethodWrapper[] callers = methodWrappers[0].getCalls(new NullProgressMonitor()); + helper.assertCalls(List.of(expectedCallers), callers); + } + private void assertRecursive(MethodWrapper[] callResults, boolean shouldBeRecursive) { for (MethodWrapper callResult : callResults) { assertEquals("Wrong recursive value: " + callResult.getName(), shouldBeRecursive, callResult.isRecursive()); diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CoreTestSuite.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CoreTestSuite.java index d1c16293..4442d37c 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CoreTestSuite.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CoreTestSuite.java @@ -23,6 +23,7 @@ AddImportTest.class, SourceActionTests.class, ASTNodesInsertTest.class, +BindingsHierarchyTest.class, BindingsNameTest.class, CallHierarchyTest.class, ClassPathDetectorTest.class, diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/HierarchicalASTVisitorTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/HierarchicalASTVisitorTest.java index 00d3132c..ca3e4ffd 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/HierarchicalASTVisitorTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/HierarchicalASTVisitorTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -29,6 +29,8 @@ import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.AbstractTagElement; +import org.eclipse.jdt.core.dom.AbstractTextElement; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.jdt.core.dom.AnnotatableType; import org.eclipse.jdt.core.dom.Annotation; @@ -39,6 +41,7 @@ import org.eclipse.jdt.core.dom.ModuleDirective; import org.eclipse.jdt.core.dom.ModulePackageAccess; import org.eclipse.jdt.core.dom.Name; +import org.eclipse.jdt.core.dom.Pattern; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.VariableDeclaration; @@ -129,6 +132,42 @@ public void superEndVisit(AbstractTypeDeclaration node) { super.visit(node); } + @Override + public boolean visit(AbstractTagElement node) { + registerCall(AbstractTagElement.class); + return false; + } + @SuppressWarnings("unused") // called reflectively + public void superVisit(AbstractTagElement node) { + super.visit(node); + } + @Override + public void endVisit(AbstractTagElement node) { + registerCall(AbstractTagElement.class); + } + @SuppressWarnings("unused") // called reflectively + public void superEndVisit(AbstractTagElement node) { + super.visit(node); + } + + @Override + public boolean visit(AbstractTextElement node) { + registerCall(AbstractTextElement.class); + return false; + } + @SuppressWarnings("unused") // called reflectively + public void superVisit(AbstractTextElement node) { + super.visit(node); + } + @Override + public void endVisit(AbstractTextElement node) { + registerCall(AbstractTextElement.class); + } + @SuppressWarnings("unused") // called reflectively + public void superEndVisit(AbstractTextElement node) { + super.visit(node); + } + @Override public boolean visit(Comment node) { registerCall(Comment.class); @@ -255,6 +294,23 @@ public void superEndVisit(ModulePackageAccess node) { super.visit(node); } + @Override + public boolean visit(Pattern node) { + registerCall(Pattern.class); + return false; + } + @SuppressWarnings("unused") // called reflectively + public void superVisit(Pattern node) { + super.visit(node); + } + @Override + public void endVisit(Pattern node) { + registerCall(Pattern.class); + } + @SuppressWarnings("unused") // called reflectively + public void superEndVisit(Pattern node) { + super.visit(node); + } @Override public boolean visit(Statement node) { diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ImportOrganizeTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ImportOrganizeTest.java index 3f0acee3..dc364e28 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ImportOrganizeTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ImportOrganizeTest.java @@ -494,6 +494,42 @@ public void testReplaceImports() throws Exception { assertEqualString(cu.getSource(), buf.toString()); } + @Test + public void testRestoreExistingImports() throws Exception { + IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("import java.util.Properties;\n"); + buf.append("import java.io.File;\n"); + buf.append("import java.io.FileInputStream;\n"); + buf.append("\n"); + buf.append("public class C extends Vector {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("C.java", buf.toString(), false, null); + + + String[] order= new String[0]; + IChooseImportQuery query= createQuery("C", new String[] {}, new int[] {}); + + OrganizeImportsOperation op= createOperation(cu, order, 99, false, true, true, query, true); + op.run(null); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("\n"); + buf.append("import java.util.Properties;\n"); + buf.append("import java.util.Vector;\n"); + buf.append("import java.io.File;\n"); + buf.append("import java.io.FileInputStream;\n"); + buf.append("\n"); + buf.append("public class C extends Vector {\n"); + buf.append("}\n"); + assertEqualString(cu.getSource(), buf.toString()); + } + @Test public void testClearImportsNoPackage() throws Exception { IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); @@ -3626,6 +3662,11 @@ protected OrganizeImportsOperation createOperation(ICompilationUnit cu, String[] return new OrganizeImportsOperation(cu, null, ignoreLowerCaseNames, save, allowSyntaxErrors, chooseImportQuery); } + protected OrganizeImportsOperation createOperation(ICompilationUnit cu, String[] order, int threshold, boolean ignoreLowerCaseNames, boolean save, boolean allowSyntaxErrors, IChooseImportQuery chooseImportQuery, boolean restoreExistingImports) { + setOrganizeImportSettings(order, threshold, threshold, cu.getJavaProject()); + return new OrganizeImportsOperation(cu, null, ignoreLowerCaseNames, save, allowSyntaxErrors, chooseImportQuery, restoreExistingImports); + } + protected void setOrganizeImportSettings(String[] order, int threshold, int staticThreshold, IJavaProject project) { IEclipsePreferences scope= new ProjectScope(project.getProject()).getNode(JavaUI.ID_PLUGIN); if (order == null) { diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/TypeInfoTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/TypeInfoTest.java index c92bf7a8..5e0b677e 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/TypeInfoTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/TypeInfoTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -48,6 +48,8 @@ import org.eclipse.jdt.core.search.TypeNameMatch; import org.eclipse.jdt.core.search.TypeNameMatchRequestor; +import org.eclipse.jdt.internal.corext.util.TypeInfoFilter; + import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; public class TypeInfoTest { @@ -220,4 +222,82 @@ public void bug44772() throws Exception { assertNotNull(type2); assertNotEquals(type1, type2); } -} + + @Test + public void testSimplifySearchText() { + // simple filename: + assertEquals("MyType", TypeInfoFilter.simplifySearchText("MyType.java")); + // trim spaces (copied from gerrit): + assertEquals("MyType", TypeInfoFilter.simplifySearchText(" MyType.java ")); + // path filename: + assertEquals("Foo", TypeInfoFilter.simplifySearchText("/hello/Foo.java")); + // stacktraces from jvm: + assertEquals("Test", TypeInfoFilter.simplifySearchText("Test.main(Test.java:58)")); + assertEquals("org.eclipse.jdt.internal.ui.AbstractJavaElementLabelDecorator", TypeInfoFilter.simplifySearchText("at org.eclipse.jdt.internal.ui.AbstractJavaElementLabelDecorator.addListener(AbstractJavaElementLabelDecorator.java:62)")); + // stacktraces from eclipse: + assertEquals("Display", TypeInfoFilter.simplifySearchText("Display.getSystemFont() line: 2468")); + // qualified names from eclipse: + assertEquals("org.eclipse.swt.widgets.Display", TypeInfoFilter.simplifySearchText("org.eclipse.swt.widgets.Display.getSystemFont()")); + // copied from VisualVM: + assertEquals("org.eclipse.swt.internal.win32.OS.CallWindowProc", TypeInfoFilter.simplifySearchText("org.eclipse.swt.internal.win32.OS.CallWindowProc[native] ()")); + assertEquals("java.lang.Throwable", TypeInfoFilter.simplifySearchText(" at java.lang.Throwable.fillInStackTrace ()")); + assertEquals("java.io.FileOutputStream", TypeInfoFilter.simplifySearchText(" at java.io.FileOutputStream. ()")); + assertEquals("java.util.Map.Entry", TypeInfoFilter.simplifySearchText(" at java.util.Map$Entry.anything() (x.java:1)")); + assertEquals("*.Map.Entry", TypeInfoFilter.simplifySearchText("Map$Entry")); + assertEquals("org.eclipse.jdt.ui.tests.core.Main.Runner.Executor", TypeInfoFilter.simplifySearchText("org.eclipse.jdt.ui.tests.core.Main$Runner$Executor.exec(Main.java:10)")); + assertEquals("*.Main.Runner.Executor", TypeInfoFilter.simplifySearchText("Main$Runner$Executor.exec(Main.java:10)")); + assertEquals("java.io.FileOutputStream", TypeInfoFilter.simplifySearchText(" at java.io.FileOutputStream$1.close ()")); + assertEquals("org.eclipse.swt.internal.win32.OS", TypeInfoFilter.simplifySearchText(" at org.eclipse.swt.internal.win32.OS.WaitMessage(Native Method)")); + + // copied from Thread Dump: + assertEquals("jdk.internal.reflect.NativeMethodAccessorImpl", TypeInfoFilter.simplifySearchText(" at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@16.0.2/Native Method)")); + assertEquals("org.eclipse.ui.internal.Workbench", TypeInfoFilter.simplifySearchText(" at org.eclipse.ui.internal.Workbench$$Lambda$152/0x00000001002a1928.run(Unknown Source) ")); + // Lambdas: + assertEquals("org.eclipse.jface.viewers.TreeViewer", TypeInfoFilter.simplifySearchText("org.eclipse.jface.viewers.TreeViewer$$Lambda$1183.0x0000000101647440.run ()")); + assertEquals("org.eclipse.ui.internal.Workbench", TypeInfoFilter.simplifySearchText("org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644)")); + assertEquals("org.eclipse.debug.ui.DebugUITools", TypeInfoFilter.simplifySearchText(" at org.eclipse.debug.ui.DebugUITools.lambda$1(DebugUITools.java:630) ")); + + // keep "java"/"class" segment: + assertEquals("my.java.package.MyType", TypeInfoFilter.simplifySearchText(" my.java.package.MyType.java ")); + assertEquals("my.javas.package.Java", TypeInfoFilter.simplifySearchText("my.javas.package.Java.java")); + assertEquals("my.java.java.Java", TypeInfoFilter.simplifySearchText("my.java.java.Java")); + assertEquals("my.java.package.MyType", TypeInfoFilter.simplifySearchText(" my.java.package.MyType ")); + assertEquals("my.class.java.MyType", TypeInfoFilter.simplifySearchText(" my.class.java.MyType.java ")); + assertEquals("my.class.package.MyType", TypeInfoFilter.simplifySearchText(" my.class.package.MyType ")); + // class file: + assertEquals("MyType", TypeInfoFilter.simplifySearchText("/dev/mypackage/MyType.class")); + // convert inner types to qualified name: + assertEquals("java.lang.ref.ReferenceQueue.Lock", TypeInfoFilter.simplifySearchText(" at java.lang.ref.ReferenceQueue$Lock ")); + assertEquals("java.util.concurrent.ThreadPoolExecutor.Worker", TypeInfoFilter.simplifySearchText(" at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@16.0.2/ThreadPoolExecutor.java:630) ")); + assertEquals("*.DebugPlugin.EventDispatchJob",TypeInfoFilter.simplifySearchText("\"C:\\org.eclipse.debug.core\\bin\\org\\eclipse\\debug\\core\\DebugPlugin$EventDispatchJob.class\"")); + + + /** possible future features if useful: **/ +// // locks from thread dumps: +// assertEquals("sun.nio.ch.WindowsSelectorImpl", TypeInfoFilter.simplifySearchText(" - locked <0x0000000087428348> (a sun.nio.ch.WindowsSelectorImpl) ")); + // "- waiting to re-lock in wait() <0x00000007005919b0> (a java.lang.ref.ReferenceQueue$Lock)" + } + + @Test + public void testBug578547() { + IJavaElement[] elements= new IJavaElement[] { fJProject1 }; + IJavaSearchScope scope= SearchEngine.createJavaSearchScope(elements); + + TypeInfoFilter filter= new TypeInfoFilter("TestInner1.TestInner2", scope, 0, null); + assertEquals("TestInner2", filter.getNamePattern()); + assertEquals("*TestInner1*", filter.getPackagePattern()); + + filter= new TypeInfoFilter("TestInner1.TestInner2.TestInner3", scope, 0, null); + assertEquals("TestInner3", filter.getNamePattern()); + assertEquals("*TestInner1.TestInner2*", filter.getPackagePattern()); + + filter= new TypeInfoFilter("org.eclipse.jdt.IProblemInfo", scope, 0, null); + assertEquals("IProblemInfo", filter.getNamePattern()); + assertEquals("org*.eclipse*.jdt*", filter.getPackagePattern()); + + filter= new TypeInfoFilter("Test", scope, 0, null); + assertEquals("Test", filter.getNamePattern()); + assertEquals(null, filter.getPackagePattern()); + } + +} \ No newline at end of file diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/rules/Java17ProjectTestSetup.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/rules/Java17ProjectTestSetup.java new file mode 100644 index 00000000..714f6b1c --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/rules/Java17ProjectTestSetup.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2020 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * derived from corresponding file in org.eclipse.jdt.ui.tests.core + * instead extending TestSetup for junit4 ExternalResource is extended + * to allow use as junit "@Rule" + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ui.tests.core.rules; + +import org.eclipse.jdt.testplugin.JavaProjectHelper; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; + +import org.eclipse.jdt.core.IClasspathAttribute; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; + +import org.eclipse.jdt.internal.core.ClasspathEntry; + +public class Java17ProjectTestSetup extends ProjectTestSetup { + + public static final String PROJECT_NAME17= "TestSetupProject17"; + + private String projectName; + + private boolean enable_preview_feature; + + @Override + public IJavaProject getProject() { + IProject project= ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + return JavaCore.create(project); + } + + @Override + public IClasspathEntry[] getDefaultClasspath() throws CoreException { + IPath[] rtJarPath= JavaProjectHelper.findRtJar(JavaProjectHelper.RT_STUBS17); + IClasspathAttribute[] extraAttributes= { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, Boolean.TRUE.toString()) }; + return new IClasspathEntry[] { JavaCore.newLibraryEntry(rtJarPath[0], rtJarPath[1], rtJarPath[2], ClasspathEntry.NO_ACCESS_RULES, extraAttributes, true) }; + } + + public Java17ProjectTestSetup( boolean enable_preview_feature) { + this.enable_preview_feature= enable_preview_feature; + projectName= PROJECT_NAME17; + } + + public Java17ProjectTestSetup( String projectName, boolean enable_preview_feature) { + this.enable_preview_feature= enable_preview_feature; + this.projectName= projectName; + } + + @Override + protected boolean projectExists() { + return getProject().exists(); + } + + @Override + protected IJavaProject createAndInitializeProject() throws CoreException { + IJavaProject javaProject= JavaProjectHelper.createJavaProject(projectName, "bin"); + javaProject.setRawClasspath(getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(javaProject, enable_preview_feature); + return javaProject; + } + +} diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/rules/Java1d8ProjectTestSetup.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/rules/Java1d8ProjectTestSetup.java index 977df7c4..b0290553 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/rules/Java1d8ProjectTestSetup.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/rules/Java1d8ProjectTestSetup.java @@ -18,7 +18,6 @@ package org.eclipse.jdt.ui.tests.core.rules; import java.io.File; -import java.io.IOException; import org.osgi.framework.Bundle; @@ -40,9 +39,9 @@ public Java1d8ProjectTestSetup() { super("TestSetupProject1d8", JavaProjectHelper.RT_STUBS_18); } - public static String getJdtAnnotations20Path() throws IOException { + public static String getJdtAnnotations20Path() { Bundle[] annotationsBundles= JavaPlugin.getDefault().getBundles("org.eclipse.jdt.annotation", "2.0.0"); //$NON-NLS-1$ - File bundleFile= FileLocator.getBundleFile(annotationsBundles[0]); + File bundleFile= FileLocator.getBundleFileLocation(annotationsBundles[0]).get(); String path= bundleFile.getPath(); if (bundleFile.isDirectory()) { path= bundleFile.getPath() + "/bin"; diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/AddUnimplementedMethodsTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/AddUnimplementedMethodsTest1d8.java index 243124a3..15673528 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/AddUnimplementedMethodsTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/source/AddUnimplementedMethodsTest1d8.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2020 IBM Corporation and others. + * Copyright (c) 2015, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -90,6 +90,30 @@ public void testBug460521() throws Exception { checkMethods(new String[] { "hashCode", "equals", "clone", "toString", "finalize" }, methods); } + @Test + public void testBug478563() throws Exception { + StringBuilder buf= new StringBuilder(); + buf.append("import java.util.Optional;\n"); + buf.append("interface I {\n"); + buf.append(" public Optional foo();\n"); + buf.append("}\n"); + + fPackage.createCompilationUnit("I.java", buf.toString(), true, null); + + StringBuilder buf2= new StringBuilder(); + buf2.append("public class A implements I {\n"); + buf2.append("}\n"); + ICompilationUnit cu2= fPackage.createCompilationUnit("A.java", buf2.toString(), true, null); + + IType testClass= cu2.createType(buf2.toString(), null, true, null); + + testHelper(testClass, -1, true); + + IMethod[] methods= testClass.getMethods(); + checkMethods(new String[] { "foo", "hashCode", "equals", "clone", "toString", "finalize" }, methods); + assertTrue("Optional.empty method not found", cu2.getSource().contains("return Optional.empty();")); + } + private void testHelper(IType testClass, int insertionPos, boolean implementAllOverridable) throws JavaModelException, CoreException { RefactoringASTParser parser= new RefactoringASTParser(IASTSharedValues.SHARED_AST_LEVEL); CompilationUnit unit= parser.parse(testClass.getCompilationUnit(), true); diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/JavadocHoverTests.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/JavadocHoverTests.java index 24795bef..cbb229c3 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/JavadocHoverTests.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/JavadocHoverTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 GK Software SE and others. + * Copyright (c) 2020, 2022 GK Software SE and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,9 +10,12 @@ * * Contributors: * Stephan Herrmann - initial API and implementation + * Red Hat Inc. - add test for pre with code tag *******************************************************************************/ package org.eclipse.jdt.ui.tests.hover; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -32,6 +35,7 @@ import org.eclipse.jface.text.Region; import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.ISourceRange; @@ -115,4 +119,91 @@ public void testValueTag() throws Exception { assertTrue(actualHtmlContent, actualHtmlContent.contains("<script>")); } } + + @Test + public void testEnumWithAnonymousClass() throws Exception { + String myEnumSource = "package test;\n" + + "public enum MyEnum {\n" + + " ENUM1 {\n" + + " @Override\n" + + " public String get() {\n" + + " return \"ENUM1\";\n" + + " }\n" + + " };\n" + + " public abstract String get();\n" + + "}\n" + + ""; + ICompilationUnit myEnumCu= getWorkingCopy("/TestSetupProject/src/test/MyEnum.java", myEnumSource, null); + assertNotNull("MyEnum.java", myEnumCu); + + IType type= myEnumCu.getType("MyEnum"); + IField field = type.getField("ENUM1"); + IJavaElement[] elements= { field }; + ISourceRange range= ((ISourceReference) field).getNameRange(); + // Should not throw ClassCastException + JavadocHover.getHoverInfo(elements, myEnumCu, new Region(range.getOffset(), range.getLength()), null); + } + + @Test + public void testCodeTagWithPre() throws Exception { + String source= + "package p;\n" + + "public class TestClass {\n" + + "/**\n" + + " * Performs:\n" + + " *

    {@code\n" +
    +			    " *    for (String s : strings) {\n" +
    +			    " *        if (s.equals(value)) {\n" +
    +			    " *            return 0;\n" +
    +			    " *        }\n" +
    +			    " *        if (s.startsWith(value)) {\n" +
    +			    " *            return 1;\n" +
    +			    " *        }\n" +
    +			    " *    }\n" +
    +			    " *    return -1;\n" +
    +			    " * }
    \n" + + " */\n" + + "int check (String value, String[] strings) {\n" + + " for (String s : strings) {\n" + + " if (s.equals(value)) {\n" + + " return 0;\n" + + " }\n" + + " if (s.startsWith(value)) {\n" + + " return 1;\n" + + " }\n" + + " }\n" + + " return -1;\n" + + "}\n"; + ICompilationUnit cu= getWorkingCopy("/TestSetupProject/src/p/TestClass.java", source, null); + assertNotNull("TestClass.java", cu); + + IType type= cu.getType("TestClass"); + // check javadoc on each member: + for (IJavaElement member : type.getChildren()) { + IJavaElement[] elements= { member }; + ISourceRange range= ((ISourceReference) member).getNameRange(); + JavadocBrowserInformationControlInput hoverInfo= JavadocHover.getHoverInfo(elements, cu, new Region(range.getOffset(), range.getLength()), null); + String actualHtmlContent= hoverInfo.getHtml(); + + String expectedCodeSequence= "
    \n"
    +					+ "    for (String s : strings) {\n"
    +					+ "        if (s.equals(value)) {\n"
    +					+ "            return 0;\n"
    +					+ "        }\n"
    +					+ "        if (s.startsWith(value)) {\n"
    +					+ "            return 1;\n"
    +					+ "        }\n"
    +					+ "    }\n"
    +					+ "    return -1;\n"
    +					+ " 
    "; + + // value should be expanded: + int index= actualHtmlContent.indexOf("
    ");
    +			assertFalse(index == -1);
    +			String actualSnippet= actualHtmlContent.substring(index, index + expectedCodeSequence.length());
    +			assertEquals("sequence doesn't match", actualSnippet, expectedCodeSequence);
    +		}
    +	}
    +
     }
    +
    diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/PackageJavadocTests.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/PackageJavadocTests.java
    index 5470d1aa..28b24b80 100644
    --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/PackageJavadocTests.java
    +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/hover/PackageJavadocTests.java
    @@ -331,7 +331,7 @@ public void testFailToAccessAttachedJavadoc() throws Exception {
     		IClasspathAttribute attribute=
     				JavaCore.newClasspathAttribute(
     						IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME,
    -						"https://docs.oracle.com/javase/6/docs/apii/");
    +						"https://doc.oracle.com/javase/6/docs/apii/");
     		IClasspathEntry[] rawClasspath= fJProject1.getRawClasspath();
     		IClasspathEntry newEntry= JavaCore.newLibraryEntry(new Path(JavaTestPlugin.getDefault().getFileInPlugin(new Path("/testresources/rtstubs15.jar")).getAbsolutePath()), null, null, null,
     				new IClasspathAttribute[] { attribute }, false);
    diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests1.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests1.java
    index cc57bae1..1fe4b1de 100644
    --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests1.java
    +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests1.java
    @@ -30,6 +30,7 @@
     import org.eclipse.core.runtime.Path;
     
     import org.eclipse.core.resources.IFile;
    +import org.eclipse.core.resources.IFolder;
     import org.eclipse.core.resources.IResource;
     import org.eclipse.core.resources.IWorkspace;
     import org.eclipse.core.resources.IWorkspaceDescription;
    @@ -82,6 +83,7 @@ public class ContentProviderTests1 {
     	private IPackageFragment fPack5;
     	private IPackageFragment fPack6;
     	private IFile fDotClasspathFile;
    +	private IFolder dotSettings;
     	private IFile fDotProjectFile;
     	private ICompilationUnit fCUIMoney;
     	private ICompilationUnit fCUMoney;
    @@ -101,7 +103,7 @@ public class ContentProviderTests1 {
     	//---------Test for getChildren-------------------
     	@Test
     	public void testGetChildrenProjectWithSourceFolders() throws Exception {
    -		Object[] expectedChildren= new Object[]{fRoot1, fDotClasspathFile, fDotProjectFile};
    +		Object[] expectedChildren= new Object[]{fRoot1, fDotClasspathFile, dotSettings, fDotProjectFile};
     		Object[] actualChildren= fProvider.getChildren(fJProject2);
     		assertTrue("Wrong children found for project", compareArrays(actualChildren, expectedChildren));//$NON-NLS-1$
     	}
    @@ -347,10 +349,16 @@ public void setUp() throws Exception {
     					fDotClasspathFile= file;
     				else if (".project".equals(file.getName()))//$NON-NLS-1$
     					fDotProjectFile= file;
    +			} else if (object instanceof IFolder) {
    +				IFolder folder= (IFolder) object;
    +				if(".settings".equals(folder.getName())) {
    +					dotSettings= folder;
    +				}
     			}
     		}
     		assertNotNull(fDotClasspathFile);
     		assertNotNull(fDotProjectFile);
    +		assertNotNull(dotSettings);
     
     		// Set up project #1 : External Jar and zip file
     		IPackageFragmentRoot jdk= JavaProjectHelper.addVariableRTJar(fJProject1, "JRE_LIB_TEST", null, null);//$NON-NLS-1$
    diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests2.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests2.java
    index cd45fd4f..6eb87988 100644
    --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests2.java
    +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests2.java
    @@ -31,6 +31,7 @@
     import org.eclipse.core.runtime.Path;
     
     import org.eclipse.core.resources.IFile;
    +import org.eclipse.core.resources.IFolder;
     import org.eclipse.core.resources.IResource;
     import org.eclipse.core.resources.IWorkspace;
     import org.eclipse.core.resources.IWorkspaceDescription;
    @@ -84,6 +85,7 @@ public class ContentProviderTests2{
     	private IPackageFragment fY;
     	private IFile fFile1;
     	private IFile fFile2;
    +	private IFolder dotSettings;
     	private ICompilationUnit fCU1;
     	private ICompilationUnit fCU2;
     	private IClassFile fYClassFile;
    @@ -93,7 +95,7 @@ public class ContentProviderTests2{
     
     	@Test
     	public void testGetChildrenProject() throws Exception{
    -		Object[] expectedChildren= new Object[]{fPack1, fPack2, fPack3, fRoot1.getPackageFragment(""), fFile1, fFile2,fInternalRoot1,jdk}; //$NON-NLS-1$
    +		Object[] expectedChildren= new Object[]{fPack1, fPack2, fPack3, fRoot1.getPackageFragment(""), fFile1, fFile2, dotSettings, fInternalRoot1,jdk}; //$NON-NLS-1$
     		Object[] children= fProvider.getChildren(fJProject3);
     		assertTrue("Wrong children found for project", compareArrays(children, expectedChildren)); //$NON-NLS-1$
     	}
    @@ -213,10 +215,16 @@ public void setUp() throws Exception {
     					fFile1= file;
     				else if (".project".equals(file.getName())) //$NON-NLS-1$
     					fFile2= file;
    +			} else if (object instanceof IFolder) {
    +				IFolder folder= (IFolder) object;
    +				if(".settings".equals(folder.getName())) {
    +					dotSettings= folder;
    +				}
     			}
     		}
     		assertNotNull(fFile1);
     		assertNotNull(fFile2);
    +		assertNotNull(dotSettings);
     
     		//add rt.jar
     		jdk= JavaProjectHelper.addVariableRTJar(fJProject3, "JRE_LIB_TEST", null, null); //$NON-NLS-1$
    diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests3.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests3.java
    index 7e54ee28..eb2b94a0 100644
    --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests3.java
    +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests3.java
    @@ -32,6 +32,7 @@
     import org.eclipse.core.runtime.Path;
     
     import org.eclipse.core.resources.IFile;
    +import org.eclipse.core.resources.IFolder;
     import org.eclipse.core.resources.IResource;
     import org.eclipse.core.resources.IWorkspace;
     import org.eclipse.core.resources.IWorkspaceDescription;
    @@ -98,6 +99,7 @@ public class ContentProviderTests3{
     	private ICompilationUnit fCU3;
     	private IFile fFile1;
     	private IFile fFile2;
    +	private IFolder dotSettings;
     
     	private IWorkbenchPage page;
     	private IPackageFragmentRoot jdk;
    @@ -107,7 +109,7 @@ public class ContentProviderTests3{
     
     	@Test
     	public void testGetChildrenProjectWithSourceFolders() throws Exception{
    -		Object[] expectedChildren= new Object[]{fRoot1, fFile1, fFile2, jdk};
    +		Object[] expectedChildren= new Object[]{fRoot1, fFile1, fFile2, dotSettings, jdk};
     		Object[] children= fProvider.getChildren(fJProject2);
     		assertTrue("Wrong children found for project with folding", compareArrays(children, expectedChildren));//$NON-NLS-1$
     	}
    @@ -317,10 +319,16 @@ public void setUp() throws Exception {
     					fFile1= file;
     				else if (".project".equals(file.getName()))//$NON-NLS-1$
     					fFile2= file;
    +			} else if (object instanceof IFolder) {
    +				IFolder folder= (IFolder) object;
    +				if(".settings".equals(folder.getName())) {
    +					dotSettings= folder;
    +				}
     			}
     		}
     		assertNotNull(fFile1);
     		assertNotNull(fFile2);
    +		assertNotNull(dotSettings);
     
     		//set up project #1 : External Jar and zip file
     		jdk= JavaProjectHelper.addVariableRTJar(fJProject1, "JRE_LIB_TEST", null, null);//$NON-NLS-1$
    diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests4.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests4.java
    index 96e7a88c..5a5973df 100644
    --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests4.java
    +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests4.java
    @@ -31,6 +31,7 @@
     import org.eclipse.core.runtime.Path;
     
     import org.eclipse.core.resources.IFile;
    +import org.eclipse.core.resources.IFolder;
     import org.eclipse.core.resources.IResource;
     import org.eclipse.core.resources.IWorkspace;
     import org.eclipse.core.resources.IWorkspaceDescription;
    @@ -88,6 +89,7 @@ public class ContentProviderTests4{
     	private IPackageFragmentRoot jdk;
     	private IFile fFile1;
     	private IFile fFile2;
    +	private IFolder dotSettings;
     	private IClassFile fAClassFile;
     
     	private IWorkbenchPage page;
    @@ -97,7 +99,7 @@ public class ContentProviderTests4{
     
     	@Test
     	public void testGetChildrenProject() throws Exception{
    -		Object[] expectedChildren= new Object[]{fPack1, fPack2, fPack3, fDefaultPackage, fFile1, fFile2,fInternalRoot1,jdk};
    +		Object[] expectedChildren= new Object[]{fPack1, fPack2, fPack3, fDefaultPackage, fFile1, fFile2, dotSettings, fInternalRoot1,jdk};
     		Object[] children= fProvider.getChildren(fJProject3);
     		assertTrue("Wrong children found for project with folding", compareArrays(children, expectedChildren)); //$NON-NLS-1$
     	}
    @@ -222,10 +224,16 @@ public void setUp() throws Exception {
     					fFile1 = file;
     				else if (".project".equals(file.getName()))//$NON-NLS-1$
     					fFile2 = file;
    +			} else if (object instanceof IFolder) {
    +				IFolder folder= (IFolder) object;
    +				if(".settings".equals(folder.getName())) {
    +					dotSettings= folder;
    +				}
     			}
     		}
     		assertNotNull(fFile1);
     		assertNotNull(fFile2);
    +		assertNotNull(dotSettings);
     
     		//add rt.jar
     		jdk= JavaProjectHelper.addVariableRTJar(fJProject3, "JRE_LIB_TEST", null, null);//$NON-NLS-1$
    diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests5.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests5.java
    index 33579ea1..d98050ad 100644
    --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests5.java
    +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/packageview/ContentProviderTests5.java
    @@ -74,6 +74,7 @@ public class ContentProviderTests5{
     
     	private IJavaProject fJProject;
     	private IFile fDotClasspath;
    +	private IFolder dotSettings;
     	private IFile fDotProject;
     	private IPackageFragmentRoot jdk;
     
    @@ -98,10 +99,16 @@ public void setUp() throws Exception {
     					fDotClasspath = file;
     				else if (".project".equals(file.getName()))
     					fDotProject = file;
    +			} else if (object instanceof IFolder) {
    +				IFolder folder= (IFolder) object;
    +				if(".settings".equals(folder.getName())) {
    +					dotSettings= folder;
    +				}
     			}
     		}
     		assertNotNull(fDotClasspath);
     		assertNotNull(fDotProject);
    +		assertNotNull(dotSettings);
     
     		//add rt.jar
     		jdk= JavaProjectHelper.addVariableRTJar(fJProject, "JRE_LIB_TEST", null, null);
    @@ -182,7 +189,7 @@ public void testProjectSource1() throws Exception { //bug 35851, 66694
     		IPackageFragment zPackage= root.createPackageFragment("z", true, null);
     		ICompilationUnit Z= zPackage.createCompilationUnit("Z.java", "package z;public class Z{}", true, null);
     
    -		assertEqualElements(new Object[] {defaultPackage, exclInclPackage, xPackage, zPackage, jdk, ab, excl, y, fDotClasspath, fDotProject},
    +		assertEqualElements(new Object[] {defaultPackage, exclInclPackage, xPackage, zPackage, jdk, ab, excl, y, fDotClasspath, dotSettings, fDotProject},
     				fProvider.getChildren(fJProject));
     		assertEqualElements(new Object[0], fProvider.getChildren(defaultPackage));
     		assertEqualElements(new Object[] {In},	fProvider.getChildren(exclInclPackage));
    @@ -221,7 +228,7 @@ public void testNestedSource1() throws Exception { //bug 35851, 66694
     		ICompilationUnit b= defaultAbab.createCompilationUnit("B.java", "public class B {}", true, null);
     
     
    -		assertEqualElements(new Object[] {src, srcabab, jdk, fDotClasspath, fDotProject}, fProvider.getChildren(fJProject));
    +		assertEqualElements(new Object[] {src, srcabab, jdk, fDotClasspath, dotSettings, fDotProject}, fProvider.getChildren(fJProject));
     		assertEqualElements(new Object[] {defaultSrc, p, ab}, fProvider.getChildren(src));
     		assertEqualElements(new Object[] {}, fProvider.getChildren(defaultSrc));
     		assertEqualElements(new Object[] {file}, fProvider.getChildren(p));
    @@ -249,7 +256,7 @@ public void testInclExcl1() throws Exception { //bug 35851, 66694
     		IContainer b= d.getParent().getParent();
     		IContainer a= b.getParent();
     
    -		assertEqualElements(new Object[] {src, jdk, fDotClasspath, fDotProject}, fProvider.getChildren(fJProject));
    +		assertEqualElements(new Object[] {src, jdk, fDotClasspath, dotSettings, fDotProject}, fProvider.getChildren(fJProject));
     		assertEqualElements(new Object[] {abc, a}, fProvider.getChildren(src));
     		assertEqualElements(new Object[] {x, d}, fProvider.getChildren(abc));
     		assertEqualElements(new Object[] {dTxt}, fProvider.getChildren(d));
    diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AnnotateAssistTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AnnotateAssistTest1d8.java
    index 36e965f3..b76493cd 100644
    --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AnnotateAssistTest1d8.java
    +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AnnotateAssistTest1d8.java
    @@ -17,7 +17,10 @@
     import static org.junit.Assert.assertTrue;
     
     import java.io.ByteArrayInputStream;
    +import java.util.ArrayList;
    +import java.util.HashMap;
     import java.util.List;
    +import java.util.Map;
     
     import org.junit.After;
     import org.junit.Before;
    @@ -26,6 +29,8 @@
     
     import org.eclipse.jdt.testplugin.JavaProjectHelper;
     
    +import org.eclipse.core.runtime.CoreException;
    +import org.eclipse.core.runtime.IPath;
     import org.eclipse.core.runtime.Path;
     
     import org.eclipse.core.resources.IFile;
    @@ -34,12 +39,19 @@
     import org.eclipse.jface.text.IDocument;
     import org.eclipse.jface.text.contentassist.ICompletionProposal;
     
    +import org.eclipse.jdt.core.ClasspathContainerInitializer;
     import org.eclipse.jdt.core.IClasspathAttribute;
    +import org.eclipse.jdt.core.IClasspathContainer;
     import org.eclipse.jdt.core.IClasspathEntry;
    +import org.eclipse.jdt.core.IJavaProject;
     import org.eclipse.jdt.core.IType;
     import org.eclipse.jdt.core.JavaCore;
     
    +import org.eclipse.jdt.internal.core.ClasspathAttribute;
    +import org.eclipse.jdt.internal.core.ClasspathEntry;
    +
     import org.eclipse.jdt.ui.JavaUI;
    +import org.eclipse.jdt.ui.examples.MyClasspathContainerInitializer;
     import org.eclipse.jdt.ui.tests.core.rules.Java1d8ProjectTestSetup;
     import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;
     
    @@ -56,6 +68,86 @@ public class AnnotateAssistTest1d8 extends AbstractAnnotateAssistTests {
     
     	protected static final String ANNOTATION_PATH= "annots";
     
    +
    +	/**
    +	 * Initializer for a container that may provide customized content specified with source and external annotations.
    +	 * (Similar to org.eclipse.jdt.core.tests.model.ExternalAnnotations18Test.TestCustomContainerInitializer)
    +	 */
    +	static class TestCustomContainerInitializer extends ClasspathContainerInitializer {
    +
    +		List allEntries;
    +		Map sourceEntries;
    +		Map elementAnnotationPaths;
    +
    +		/**
    +		 * @param elementsWithSourcesAndAnnotationPaths each triplet of entries in this array defines one classpath entry:
    +		 * 
      + *
    • 1st string specifies the entry path, + *
    • 2nd string specifies source attachment + *
    • if 3nd string is "self" than the entry is "self-annotating". + * {@code null} is a legal value to signal "not self-annotating" + *
    + */ + public TestCustomContainerInitializer(String... elementsWithSourcesAndAnnotationPaths) { + this.allEntries = new ArrayList<>(); + this.sourceEntries = new HashMap<>(); + this.elementAnnotationPaths = new HashMap<>(); + for (int i = 0; i < elementsWithSourcesAndAnnotationPaths.length; i+=3) { + String entryPath = elementsWithSourcesAndAnnotationPaths[i]; + this.allEntries.add(entryPath); + this.sourceEntries.put(entryPath, elementsWithSourcesAndAnnotationPaths[i+1]); + String annotsPath = elementsWithSourcesAndAnnotationPaths[i+2]; + if ("self".equals(annotsPath)) + this.elementAnnotationPaths.put(entryPath, entryPath); + else if (annotsPath != null) + this.elementAnnotationPaths.put(entryPath, annotsPath); + } + } + + static class TestContainer implements IClasspathContainer { + IPath path; + IClasspathEntry[] entries; + TestContainer(IPath path, IClasspathEntry[] entries){ + this.path = path; + this.entries = entries; + } + @Override public IPath getPath() { return this.path; } + @Override public IClasspathEntry[] getClasspathEntries() { return this.entries; } + @Override public String getDescription() { return this.path.toString(); } + @Override public int getKind() { return 0; } + } + + @Override + public void initialize(IPath containerPath, IJavaProject project) throws CoreException { + List entries = new ArrayList<>(); + for (String entryPath : this.allEntries) { + String elementAnnotationPath = this.elementAnnotationPaths.get(entryPath); + + IClasspathAttribute[] extraAttributes; + if (elementAnnotationPath != null) + extraAttributes = externalAnnotationExtraAttributes(elementAnnotationPath); + else + extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES; + + String sourcePath= this.sourceEntries.get(entryPath); + IPath sourceAttachment = sourcePath != null ? new Path(sourcePath) : null; + entries.add(JavaCore.newLibraryEntry(new Path(entryPath), sourceAttachment, null, + ClasspathEntry.NO_ACCESS_RULES, extraAttributes, false/*not exported*/)); + } + JavaCore.setClasspathContainer( + containerPath, + new IJavaProject[]{ project }, + new IClasspathContainer[] { new TestContainer(containerPath, entries.toArray(IClasspathEntry[]::new)) }, + null); + } + } + + static IClasspathAttribute[] externalAnnotationExtraAttributes(String path) { + return new IClasspathAttribute[] { + new ClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, path) + }; + } + @Before public void setUp() throws Exception { fJProject1= projectSetup.getProject(); @@ -1255,4 +1347,91 @@ public void testAnnotateReturnInSourceFolder() throws Exception { } } + @Test + public void testAnnotationsInProjectReferencedViaContainer() throws Exception { + ClasspathContainerInitializer prev = MyClasspathContainerInitializer.initializerDelegate; + + // container providing an unannotated library and a dedicated annotation project in the workspace: + String eeaProjectName = "my.eeas"; + MyClasspathContainerInitializer.setInitializer(new TestCustomContainerInitializer( + "/TestSetupProject1d8/lib.jar", "/TestSetupProject1d8/lib.zip", null, + '/'+eeaProjectName, null, null)); + + IJavaProject eeaProject = null; + try { + // create the annotation project: + eeaProject = JavaProjectHelper.createJavaProject(eeaProjectName, ""); + + // create the library + String MY_MAP_PATH= "pack/age/MyMap"; + String[] pathAndContents= new String[] { + MY_MAP_PATH+".java", + "package pack.age;\n" + + "public interface MyMap {\n" + + " public V get(K key);\n" + + "}\n" + }; + createLibrary(fJProject1, "lib.jar", "lib.zip", pathAndContents, JavaCore.VERSION_1_8, null); + + // set the classpath: + IClasspathEntry[] rawClasspath= fJProject1.getRawClasspath(); + fJProject1.setRawClasspath(new IClasspathEntry[] { + rawClasspath[0], // assumed to be rtstubs.jar + JavaCore.newSourceEntry(fJProject1.getPath().append("src")), + JavaCore.newContainerEntry( + new Path(MyClasspathContainerInitializer.CONTAINER_NAME), null/*access rules*/, + externalAnnotationExtraAttributes(MyClasspathContainerInitializer.CONTAINER_NAME+"/my.eeas"), + false/*exported*/) + }, + null); + + // START of actual assist test: + IType type= fJProject1.findType(MY_MAP_PATH.replace('/', '.')); + JavaEditor javaEditor= (JavaEditor) JavaUI.openInEditor(type); + + try { + int offset= pathAndContents[1].indexOf("V get"); + + List list= collectAnnotateProposals(javaEditor, offset); + assertCorrectLabels(list); + assertNumberOfProposals(list, 2); + + ICompletionProposal proposal= findProposalByName("Annotate as '@NonNull V'", list); + String expectedInfo= + "
    get
    " + + "
    (TK;)TV;
    " + + "
    (TK;)T1V;
    " + // <= 1 + "
    "; + assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); + + proposal= findProposalByName("Annotate as '@Nullable V'", list); + expectedInfo= + "
    get
    " + + "
    (TK;)TV;
    " + + "
    (TK;)T0V;
    " + // <= 0 + "
    "; + assertEquals("expect detail", expectedInfo, proposal.getAdditionalProposalInfo()); + + IDocument document= javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput()); + proposal.apply(document); + + IFile annotationFile= eeaProject.getProject().getFile(new Path(MY_MAP_PATH + ".eea")); + assertTrue("Annotation file should have been created", annotationFile.exists()); + + String expectedContent= + "class pack/age/MyMap\n" + + "get\n" + + " (TK;)TV;\n" + + " (TK;)T0V;\n"; + checkContentOfFile("annotation file content", annotationFile, expectedContent); + } finally { + JavaPlugin.getActivePage().closeAllEditors(false); + } + } finally { + MyClasspathContainerInitializer.setInitializer(prev); + if (eeaProject != null && eeaProject.exists()) + eeaProject.getProject().delete(true, null); + } + } + } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest.java index 27ced635..f512d68e 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -19,6 +19,9 @@ *******************************************************************************/ package org.eclipse.jdt.ui.tests.quickfix; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; @@ -39,6 +42,11 @@ import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.ISourceViewer; + +import org.eclipse.ui.IEditorPart; + import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; @@ -50,12 +58,14 @@ import org.eclipse.jdt.internal.core.manipulation.StubUtility; import org.eclipse.jdt.internal.corext.fix.FixMessages; +import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jdt.ui.PreferenceConstants; import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal; import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; import org.eclipse.jdt.internal.ui.text.correction.AssistContext; import org.eclipse.jdt.internal.ui.text.correction.CorrectionMessages; import org.eclipse.jdt.internal.ui.text.correction.NewJUnitTestCaseProposal; @@ -6932,7 +6942,10 @@ public void testMakeFinal18() throws Exception { AssistContext context= getCorrectionContext(cu, offset, 1); List proposals= collectAssists(context, false); - assertNumberOfProposals(proposals, 1); + assertNumberOfProposals(proposals, 4); + assertProposalExists(proposals, Messages.format(CorrectionMessages.AddGetterSetter_creategetterssettersfortype_description, "E")); + assertProposalExists(proposals, Messages.format(CorrectionMessages.AddHashCodeEquals_createhashcodeequalsfortype_description, "E")); + assertProposalExists(proposals, Messages.format(CorrectionMessages.AddToString_createtostringfortype_description, "E")); assertProposalDoesNotExist(proposals, CHANGE_MODIFIER_TO_FINAL); } @@ -10311,7 +10324,6 @@ public void testCanConvertToStaticImportWhenClassContainsMethodInvocationWithout context= getCorrectionContext(cu, offset, selection.length()); proposals= collectAssists(context, false); - assertNumberOfProposals(proposals, 0); assertProposalDoesNotExist(proposals, "Convert to static import"); assertProposalDoesNotExist(proposals, "Convert to static import (replace all occurrences)"); } @@ -10414,7 +10426,6 @@ public void testDoesntOfferConvertToStaticImportForImportDeclarations() throws E ArrayList proposals= collectAssists(context, false); assertCorrectLabels(proposals); - assertNumberOfProposals(proposals, 1); assertProposalDoesNotExist(proposals, "Convert to static import"); assertProposalDoesNotExist(proposals, "Convert to static import (replace all occurrences)"); @@ -10424,11 +10435,78 @@ public void testDoesntOfferConvertToStaticImportForImportDeclarations() throws E proposals= collectAssists(context, false); assertCorrectLabels(proposals); - assertNumberOfProposals(proposals, 0); assertProposalDoesNotExist(proposals, "Convert to static import"); assertProposalDoesNotExist(proposals, "Convert to static import (replace all occurrences)"); } + @Test + public void testConvertToStaticImportFromReferenceToSubclass() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class T {\n"); + buf.append(" public static void foo() { };\n"); + buf.append("}\n"); + pack1.createCompilationUnit("T.java", buf.toString(), false, null); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class TSub extends T {\n"); + buf.append("}\n"); + pack1.createCompilationUnit("TSub.java", buf.toString(), false, null); + + + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + buf= new StringBuilder(); + buf.append("package test2;\n"); + buf.append("\n"); + buf.append("import test1.TSub;\n"); + buf.append("public class S {\n"); + buf.append(" public S() {\n"); + buf.append(" TSub.foo();\n"); + buf.append(" TSub.foo();\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack2.createCompilationUnit("S.java", buf.toString(), false, null); + + String selection= "foo"; + int offset= buf.toString().indexOf(selection); + AssistContext context= getCorrectionContext(cu, offset, selection.length()); + ArrayList proposals= collectAssists(context, false); + + assertProposalExists(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_static_import); + assertProposalExists(proposals, CorrectionMessages.QuickAssistProcessor_convert_to_static_import_replace_all); + assertCorrectLabels(proposals); + assertNumberOfProposals(proposals, 2); + + StringBuilder expectation= new StringBuilder(); + expectation.append("package test2;\n"); + expectation.append("\n"); + expectation.append("import static test1.T.foo;\n"); + expectation.append("\n"); + expectation.append("import test1.TSub;\n"); + expectation.append("public class S {\n"); + expectation.append(" public S() {\n"); + expectation.append(" foo();\n"); + expectation.append(" TSub.foo();\n"); + expectation.append(" }\n"); + expectation.append("}\n"); + String preview1= expectation.toString(); + + expectation= new StringBuilder(); + expectation.append("package test2;\n"); + expectation.append("\n"); + expectation.append("import static test1.T.foo;\n"); + expectation.append("public class S {\n"); + expectation.append(" public S() {\n"); + expectation.append(" foo();\n"); + expectation.append(" foo();\n"); + expectation.append(" }\n"); + expectation.append("}\n"); + String preview2= expectation.toString(); + assertExpectedExistInProposals(proposals, new String[] {preview1, preview2}); + } + @Test public void testCreateJUnitTestCase() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); @@ -10512,10 +10590,28 @@ public void testCreateNewImplementation() throws Exception { AssistContext context= getCorrectionContext(cu, offset, string.length()); List proposals= collectAssists(context, false); - assertNumberOfProposals(proposals, 2); + assertNumberOfProposals(proposals, 3); assertProposalExists(proposals, Messages.format(CorrectionMessages.QuickAssistProcessor_create_new_impl, "E.java")); } + @Test + public void testCreateNewInterfaceImplementation() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public interface E {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + String string= "E"; + int offset= buf.toString().indexOf(string); + AssistContext context= getCorrectionContext(cu, offset, string.length()); + List proposals= collectAssists(context, false); + + assertNumberOfProposals(proposals, 3); + assertProposalExists(proposals, Messages.format(CorrectionMessages.QuickAssistProcessor_create_new_interface_impl, "E.java")); + } + @Test public void testDoWhileRatherThanWhile1() throws Exception { @@ -10783,4 +10879,249 @@ public void testDoWhileRatherThanWhile5() throws Exception { assertExpectedExistInProposals(proposals, new String[] {expected1}); } + @Test + public void testAddStaticFavoritesImportBothMemberAndType() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class T {\n"); + buf.append(" public static void foo() { };\n"); + buf.append(" public static void bar() { };\n"); + buf.append("}\n"); + pack1.createCompilationUnit("T.java", buf.toString(), false, null); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import static test1.T.foo;"); + buf.append("public class E {\n"); + buf.append(" public void x() {\n"); + buf.append(" foo();\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + String string= "import"; + int offset= buf.toString().indexOf(string); + + IEditorPart part= JavaUI.openInEditor(cu); + JavaEditor javaEditor= (JavaEditor) part; + ISourceViewer viewer= javaEditor.getViewer(); + AssistContext context= new AssistContext(cu, viewer, offset, string.length()); + + IPreferenceStore store= PreferenceConstants.getPreferenceStore(); + String orig= store.getString(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS); + + try { + List proposals= collectAssists(context, false); + assertNumberOfProposals(proposals, 2); + assertProposalExists(proposals, Messages.format(CorrectionMessages.QuickAssistProcessor_modify_favorites, "test1.T.foo")); + assertProposalExists(proposals, Messages.format(CorrectionMessages.QuickAssistProcessor_modify_favorites, "test1.T.*")); + + assertFalse(orig.contains("test1.T")); + + IJavaCompletionProposal prop= proposals.get(0); + IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput()); + prop.apply(doc); + String newValue= store.getString(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS); + + assertTrue(newValue.contains("test1.T.foo")); + assertFalse(newValue.contains("test1.T.*")); + + prop= proposals.get(1); + prop.apply(context.getSourceViewer().getDocument()); + newValue= store.getString(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS); + + assertTrue(newValue.contains("test1.T.foo")); + assertTrue(newValue.contains("test1.T.*")); + } finally { + JavaPlugin.getActivePage().closeAllEditors(false); + store.setValue(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, orig); + } + } + + @Test + public void testAddStaticFavoritesMemberAlreadyImported() throws Exception { + IPreferenceStore store= PreferenceConstants.getPreferenceStore(); + store.setValue(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, "test1.T.foo"); + + String orig= store.getString(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS); + + try { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class T {\n"); + buf.append(" public static void foo() { };\n"); + buf.append(" public static void bar() { };\n"); + buf.append("}\n"); + pack1.createCompilationUnit("T.java", buf.toString(), false, null); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import static test1.T.foo;"); + buf.append("public class E {\n"); + buf.append(" public void x() {\n"); + buf.append(" foo();\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + IEditorPart part= JavaUI.openInEditor(cu); + JavaEditor javaEditor= (JavaEditor) part; + ISourceViewer viewer= javaEditor.getViewer(); + + String string= "import"; + int offset= buf.toString().indexOf(string); + AssistContext context= new AssistContext(cu, viewer, offset, string.length()); + List proposals= collectAssists(context, false); + + assertNumberOfProposals(proposals, 1); + assertProposalExists(proposals, Messages.format(CorrectionMessages.QuickAssistProcessor_modify_favorites, "test1.T.*")); + + assertFalse(orig.contains("test1.T.*")); + + IJavaCompletionProposal prop= proposals.get(0); + IDocument doc= JavaUI.getDocumentProvider().getDocument(part.getEditorInput()); + prop.apply(doc); + String newValue= store.getString(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS); + + assertTrue(newValue.contains("test1.T.*")); + } finally { + JavaPlugin.getActivePage().closeAllEditors(false); + store.setValue(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, orig); + } + } + + @Test + public void testAddStaticFavoritesNoNeedToImport() throws Exception { + IPreferenceStore store= PreferenceConstants.getPreferenceStore(); + store.setValue(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, "test1.T.*"); + try { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class T {\n"); + buf.append(" public static void foo() { };\n"); + buf.append(" public static void bar() { };\n"); + buf.append("}\n"); + pack1.createCompilationUnit("T.java", buf.toString(), false, null); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import static test1.T.foo;"); + buf.append("public class E {\n"); + buf.append(" public void x() {\n"); + buf.append(" foo();\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + String string= "import"; + int offset= buf.toString().indexOf(string); + AssistContext context= getCorrectionContext(cu, offset, string.length()); + List proposals= collectAssists(context, false); + + assertProposalDoesNotExist(proposals, Messages.format(CorrectionMessages.QuickAssistProcessor_modify_favorites, "test1.T.*")); + assertProposalDoesNotExist(proposals, Messages.format(CorrectionMessages.QuickAssistProcessor_modify_favorites, "test1.T.foo")); + } finally { + store.setToDefault(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS); + } + } + + @Test + public void testDoesntRemoveImportWhenClassReferenceIsPresent() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class T {\n"); + buf.append(" public static void foo() { };\n"); + buf.append("}\n"); + pack1.createCompilationUnit("T.java", buf.toString(), false, null); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + buf= new StringBuffer(); + buf.append("package test2;\n"); + buf.append("\n"); + buf.append("import test1.T;\n"); + buf.append("\n"); + buf.append("public class S {\n"); + buf.append(" public S() {\n"); + buf.append(" T.foo();\n"); + buf.append(" System.out.println(T.class);\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack2.createCompilationUnit("S.java", buf.toString(), false, null); + String selection= "foo"; + int offset= buf.toString().indexOf(selection); + AssistContext context= getCorrectionContext(cu, offset, selection.length()); + ArrayList proposals= collectAssists(context, false); + assertCorrectLabels(proposals); + assertNumberOfProposals(proposals, 2); + StringBuffer expectation= new StringBuffer(); + expectation.append("package test2;\n"); + expectation.append("\n"); + expectation.append("import static test1.T.foo;\n"); + expectation.append("\n"); + expectation.append("import test1.T;\n"); + expectation.append("\n"); + expectation.append("public class S {\n"); + expectation.append(" public S() {\n"); + expectation.append(" foo();\n"); + expectation.append(" System.out.println(T.class);\n"); + expectation.append(" }\n"); + expectation.append("}\n"); + assertProposalPreviewEquals(expectation.toString(), "Convert to static import", proposals); + assertProposalPreviewEquals(expectation.toString(), "Convert to static import (replace all occurrences)", proposals); + } + + @Test + public void testDoesntRemoveImportWithClassReferenceInSeparateClass() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuffer buf= new StringBuffer(); + buf.append("package test1;\n"); + buf.append("public class T {\n"); + buf.append(" public static void foo() { };\n"); + buf.append("}\n"); + pack1.createCompilationUnit("T.java", buf.toString(), false, null); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + buf= new StringBuffer(); + buf.append("package test2;\n"); + buf.append("\n"); + buf.append("import test1.T;\n"); + buf.append("\n"); + buf.append("public class S {\n"); + buf.append(" public S() {\n"); + buf.append(" T.foo();\n"); + buf.append(" }\n"); + buf.append("class C {\n"); + buf.append(" {\n"); + buf.append(" System.out.println(T.class);\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack2.createCompilationUnit("S.java", buf.toString(), false, null); + String selection= "foo"; + int offset= buf.toString().indexOf(selection); + AssistContext context= getCorrectionContext(cu, offset, selection.length()); + ArrayList proposals= collectAssists(context, false); + assertCorrectLabels(proposals); + assertNumberOfProposals(proposals, 2); + StringBuffer expectation= new StringBuffer(); + expectation.append("package test2;\n"); + expectation.append("\n"); + expectation.append("import static test1.T.foo;\n"); + expectation.append("\n"); + expectation.append("import test1.T;\n"); + expectation.append("\n"); + expectation.append("public class S {\n"); + expectation.append(" public S() {\n"); + expectation.append(" foo();\n"); + expectation.append(" }\n"); + expectation.append("class C {\n"); + expectation.append(" {\n"); + expectation.append(" System.out.println(T.class);\n"); + expectation.append(" }\n"); + expectation.append("}\n"); + assertProposalPreviewEquals(expectation.toString(), "Convert to static import", proposals); + assertProposalPreviewEquals(expectation.toString(), "Convert to static import (replace all occurrences)", proposals); + } + } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest15.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest15.java new file mode 100644 index 00000000..15b0cd08 --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest15.java @@ -0,0 +1,398 @@ +/******************************************************************************* + * Copyright (c) 2021 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + * Red Hat Inc. - modified to test Java 15 quick assists + *******************************************************************************/ +package org.eclipse.jdt.ui.tests.quickfix; + +import java.util.ArrayList; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.eclipse.jdt.testplugin.JavaProjectHelper; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; + +import org.eclipse.jdt.internal.corext.fix.FixMessages; + +import org.eclipse.jdt.ui.tests.core.rules.Java15ProjectTestSetup; +import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; +import org.eclipse.jdt.ui.text.java.IInvocationContext; +import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; + +public class AssistQuickFixTest15 extends QuickFixTest { + + @Rule + public ProjectTestSetup projectSetup = new Java15ProjectTestSetup(true); + + private IJavaProject fJProject1; + + private IPackageFragmentRoot fSourceFolder; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + if (fJProject1 != null) { + JavaProjectHelper.delete(fJProject1); + } + + } + + @Test + public void testConcatToTextBlock1() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null); + JavaProjectHelper.set15CompilerOptions(fJProject1, false); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + StringBuilder buf= new StringBuilder(); + buf.append("module test {\n"); + buf.append("}\n"); + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", buf.toString(), false, null); + + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \"\" +\n"); + buf.append(" \"public void foo() {\\n\" +\n"); + buf.append(" \" System.out.println(\\\"abc\\\");\\n\" +\n"); + buf.append(" \"}\\n\"; // comment 2\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null); + + int index= buf.indexOf("x"); + IInvocationContext ctx= getCorrectionContext(cu, index, 1); + assertNoErrors(ctx); + ArrayList proposals= collectAssists(ctx, false); + + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \"\"\"\n"); + buf.append(" \tpublic void foo() {\n"); + buf.append(" \t System.out.println(\"abc\");\n"); + buf.append(" \t}\n"); + buf.append(" \t\"\"\"; // comment 2\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected= buf.toString(); + + assertProposalExists(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg); + assertExpectedExistInProposals(proposals, new String[] { expected }); + } + + @Test + public void testConcatToTextBlock2() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null); + JavaProjectHelper.set15CompilerOptions(fJProject1, false); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + StringBuilder buf= new StringBuilder(); + buf.append("module test {\n"); + buf.append("}\n"); + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", buf.toString(), false, null); + + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \"\" +\n"); + buf.append(" \"public void foo() { \\n\" +\n"); + buf.append(" \" System.out.println(\\\"abc\\\");\\n\" +\n"); + buf.append(" \"}\\n\"; // comment 2\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null); + + int index= buf.indexOf("System"); + IInvocationContext ctx= getCorrectionContext(cu, index, 6); + assertNoErrors(ctx); + ArrayList proposals= collectAssists(ctx, false); + + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \"\"\"\n"); + buf.append(" \tpublic void foo() {\\s\n"); + buf.append(" \t System.out.println(\"abc\");\n"); + buf.append(" \t}\n"); + buf.append(" \t\"\"\"; // comment 2\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected= buf.toString(); + + assertProposalExists(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg); + assertExpectedExistInProposals(proposals, new String[] { expected }); + } + + @Test + public void testConcatToTextBlock3() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null); + JavaProjectHelper.set15CompilerOptions(fJProject1, false); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + StringBuilder buf= new StringBuilder(); + buf.append("module test {\n"); + buf.append("}\n"); + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", buf.toString(), false, null); + + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \"\" +\n"); + buf.append(" \"public void foo() { \\n\" +\n"); + buf.append(" \" System.out.println(\\\"\\\"\\\"abc\\\"\\\"\\\");\\n\" +\n"); + buf.append(" \"}\\n\"; // comment 2\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null); + + int index= buf.indexOf("System"); + IInvocationContext ctx= getCorrectionContext(cu, index, 6); + assertNoErrors(ctx); + ArrayList proposals= collectAssists(ctx, false); + + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \"\"\"\n"); + buf.append(" \tpublic void foo() {\\s\n"); + buf.append(" \t System.out.println(\\\"\"\"abc\\\"\"\");\n"); + buf.append(" \t}\n"); + buf.append(" \t\"\"\"; // comment 2\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected= buf.toString(); + + assertProposalExists(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg); + assertExpectedExistInProposals(proposals, new String[] { expected }); + } + + @Test + public void testConcatToTextBlock4() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null); + JavaProjectHelper.set15CompilerOptions(fJProject1, false); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + StringBuilder buf= new StringBuilder(); + buf.append("module test {\n"); + buf.append("}\n"); + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", buf.toString(), false, null); + + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \"\" +\n"); + buf.append(" \"abcdef\" +\n"); + buf.append(" \"ghijkl\\\"\\\"\\\"123\\\"\\\"\\\"\" +\n"); + buf.append(" \"mnop\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null); + + int index= buf.indexOf("abcdef"); + IInvocationContext ctx= getCorrectionContext(cu, index, 6); + assertNoErrors(ctx); + ArrayList proposals= collectAssists(ctx, false); + + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \"\"\"\n"); + buf.append(" \tabcdef\\\n"); + buf.append(" \tghijkl\\\"\"\"123\\\"\"\"\\\n"); + buf.append(" \tmnop\"\"\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected= buf.toString(); + + assertProposalExists(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg); + assertExpectedExistInProposals(proposals, new String[] { expected }); + } + + @Test + public void testNoConcatToTextBlock1() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null); + JavaProjectHelper.set15CompilerOptions(fJProject1, false); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + StringBuilder buf= new StringBuilder(); + buf.append("module test {\n"); + buf.append("}\n"); + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", buf.toString(), false, null); + + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \n"); + buf.append(" \"abcdef\" +\n"); + buf.append(" \"ghijkl\";\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null); + + int index= buf.indexOf("abcdef"); + IInvocationContext ctx= getCorrectionContext(cu, index, 6); + assertNoErrors(ctx); + ArrayList proposals= collectAssists(ctx, false); + + assertProposalDoesNotExist(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg); + } + + @Test + public void testNoConcatToTextBlock2() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null); + JavaProjectHelper.set15CompilerOptions(fJProject1, false); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + StringBuilder buf= new StringBuilder(); + buf.append("module test {\n"); + buf.append("}\n"); + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", buf.toString(), false, null); + + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \n"); + buf.append(" \"abcdef\" +\n"); + buf.append(" \"ghijkl\" +\n"); + buf.append(" String.valueOf(true);\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null); + + int index= buf.indexOf("abcdef"); + IInvocationContext ctx= getCorrectionContext(cu, index, 6); + assertNoErrors(ctx); + ArrayList proposals= collectAssists(ctx, false); + + assertProposalDoesNotExist(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg); + } + + @Test + public void testNoConcatToTextBlock3() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null); + JavaProjectHelper.set15CompilerOptions(fJProject1, false); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + StringBuilder buf= new StringBuilder(); + buf.append("module test {\n"); + buf.append("}\n"); + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", buf.toString(), false, null); + + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo() {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \n"); + buf.append(" \"abcdef\" +\n"); + buf.append(" \"ghijkl\" +\n"); + buf.append(" 3;\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null); + + int index= buf.indexOf("abcdef"); + IInvocationContext ctx= getCorrectionContext(cu, index, 6); + assertNoErrors(ctx); + ArrayList proposals= collectAssists(ctx, false); + + assertProposalDoesNotExist(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg); + } + + @Test + public void testNoConcatToTextBlock4() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null); + JavaProjectHelper.set15CompilerOptions(fJProject1, false); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + StringBuilder buf= new StringBuilder(); + buf.append("module test {\n"); + buf.append("}\n"); + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", buf.toString(), false, null); + + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + buf= new StringBuilder(); + buf.append("package test;\n"); + buf.append("public class Cls {\n"); + buf.append(" public void foo(String a) {\n"); + buf.append(" // comment 1\n"); + buf.append(" String x = \n"); + buf.append(" \"abcdef\" +\n"); + buf.append(" \"ghijkl\" +\n"); + buf.append(" a;\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null); + + int index= buf.indexOf("abcdef"); + IInvocationContext ctx= getCorrectionContext(cu, index, 6); + assertNoErrors(ctx); + ArrayList proposals= collectAssists(ctx, false); + + assertProposalDoesNotExist(proposals, FixMessages.StringConcatToTextBlockFix_convert_msg); + } + +} + diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest1d8.java index 2ab494ce..5e45be7a 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest1d8.java @@ -947,7 +947,7 @@ public void testConvertToLambda18() throws Exception { assertNoErrors(context); List proposals= collectAssists(context, false); - assertNumberOfProposals(proposals, 2); + assertNumberOfProposals(proposals, 3); assertCorrectLabels(proposals); buf= new StringBuilder(); @@ -2617,6 +2617,202 @@ public void testChangeLambdaBodyToExpression8() throws Exception { assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_change_lambda_body_to_expression); } + @Test + public void testExtractLambdaBodyToMethod1() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E {\n"); + buf.append(" public void foo1(int a) {\n"); + buf.append(" FI2 k = (e) -> {\n"); + buf.append(" int x = e + 3;\n"); + buf.append(" if (x > 3) {\n"); + buf.append(" return a;\n"); + buf.append(" }\n"); + buf.append(" return x;\n"); + buf.append(" };\n"); + buf.append(" k.foo(3);\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("@FunctionalInterface\n"); + buf.append("interface FI2 {\n"); + buf.append(" int foo(int x);\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("+"); + AssistContext context= getCorrectionContext(cu, offset, 0); + assertNoErrors(context); + List proposals= collectAssists(context, false); + assertCorrectLabels(proposals); + assertProposalDoesNotExist(proposals, CorrectionMessages.QuickAssistProcessor_extractmethod_description); + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E {\n"); + buf.append(" public void foo1(int a) {\n"); + buf.append(" FI2 k = (e) -> extracted(a, e);\n"); + buf.append(" k.foo(3);\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" private int extracted(int a, int e) {\n"); + buf.append(" int x = e + 3;\n"); + buf.append(" if (x > 3) {\n"); + buf.append(" return a;\n"); + buf.append(" }\n"); + buf.append(" return x;\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("@FunctionalInterface\n"); + buf.append("interface FI2 {\n"); + buf.append(" int foo(int x);\n"); + buf.append("}\n"); + + String expected1= buf.toString(); + + assertExpectedExistInProposals(proposals, new String[] { expected1 }); + } + + @Test + public void testExtractLambdaBodyToMethod2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E {\n"); + buf.append(" public void foo1(int a) {\n"); + buf.append(" FI2 k = (e) -> {\n"); + buf.append(" int x = e + 3;\n"); + buf.append(" if (x > 3) {\n"); + buf.append(" return a;\n"); + buf.append(" }\n"); + buf.append(" return x;\n"); + buf.append(" };\n"); + buf.append(" k.foo(3);\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("@FunctionalInterface\n"); + buf.append("interface FI2 {\n"); + buf.append(" int foo(int x);\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("e + 3"); + AssistContext context= getCorrectionContext(cu, offset, 5); + assertNoErrors(context); + List proposals= collectAssists(context, false); + assertCorrectLabels(proposals); + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E {\n"); + buf.append(" public void foo1(int a) {\n"); + buf.append(" FI2 k = (e) -> extracted(a, e);\n"); + buf.append(" k.foo(3);\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" private int extracted(int a, int e) {\n"); + buf.append(" int x = e + 3;\n"); + buf.append(" if (x > 3) {\n"); + buf.append(" return a;\n"); + buf.append(" }\n"); + buf.append(" return x;\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("@FunctionalInterface\n"); + buf.append("interface FI2 {\n"); + buf.append(" int foo(int x);\n"); + buf.append("}\n"); + + String expected1= buf.toString(); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E {\n"); + buf.append(" public void foo1(int a) {\n"); + buf.append(" FI2 k = (e) -> {\n"); + buf.append(" int x = extracted(e);\n"); + buf.append(" if (x > 3) {\n"); + buf.append(" return a;\n"); + buf.append(" }\n"); + buf.append(" return x;\n"); + buf.append(" };\n"); + buf.append(" k.foo(3);\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" private int extracted(int e) {\n"); + buf.append(" return e + 3;\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("@FunctionalInterface\n"); + buf.append("interface FI2 {\n"); + buf.append(" int foo(int x);\n"); + buf.append("}\n"); + + String expected2= buf.toString(); + assertExpectedExistInProposals(proposals, new String[] { expected1, expected2 }); + } + + @Test + public void testExtractLambdaBodyToMethod3() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E {\n"); + buf.append(" public void foo1(int a) {\n"); + buf.append(" FI2 k = (e) -> {\n"); + buf.append(" int x = e + 3;\n"); + buf.append(" System.out.println(\"help\");\n"); + buf.append(" if (x > 3) {\n"); + buf.append(" return a;\n"); + buf.append(" }\n"); + buf.append(" return x;\n"); + buf.append(" };\n"); + buf.append(" k.foo(3);\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("@FunctionalInterface\n"); + buf.append("interface FI2 {\n"); + buf.append(" int foo(int x);\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + int offset= buf.toString().indexOf("elp"); + AssistContext context= getCorrectionContext(cu, offset, 5); + assertNoErrors(context); + List proposals= collectAssists(context, false); + assertCorrectLabels(proposals); + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E {\n"); + buf.append(" public void foo1(int a) {\n"); + buf.append(" FI2 k = (e) -> extracted(a, e);\n"); + buf.append(" k.foo(3);\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" private int extracted(int a, int e) {\n"); + buf.append(" int x = e + 3;\n"); + buf.append(" System.out.println(\"help\");\n"); + buf.append(" if (x > 3) {\n"); + buf.append(" return a;\n"); + buf.append(" }\n"); + buf.append(" return x;\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("@FunctionalInterface\n"); + buf.append("interface FI2 {\n"); + buf.append(" int foo(int x);\n"); + buf.append("}\n"); + + String expected1= buf.toString(); + + assertExpectedExistInProposals(proposals, new String[] { expected1 }); + } + @Test public void testBug433754() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); @@ -4477,7 +4673,7 @@ public void testConvertLambdaToMethodReference3() throws Exception { context= getCorrectionContext(cu, offset, 0); assertNoErrors(context); proposals= collectAssists(context, false); - assertNumberOfProposals(proposals, 1); + assertNumberOfProposals(proposals, 2); assertCorrectLabels(proposals); buf= new StringBuilder(); buf.append("package test1;\n"); @@ -5573,7 +5769,7 @@ public void testSurroundWithTryWithResource_01() throws Exception { assertNumberOfProposals(proposals, 4); assertCorrectLabels(proposals); - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + CUCorrectionProposal proposal= (CUCorrectionProposal) findProposalByName("Surround with try-with-resources", proposals); String preview1= getPreviewContent(proposal); StringBuilder buf= new StringBuilder(); @@ -5606,7 +5802,7 @@ public void testSurroundWithTryWithResource_01() throws Exception { assertNumberOfProposals(proposals, 4); assertCorrectLabels(proposals); - proposal= (CUCorrectionProposal) proposals.get(0); + proposal= (CUCorrectionProposal) findProposalByName("Surround with try-with-resources", proposals); String preview2= getPreviewContent(proposal); buf= new StringBuilder(); @@ -5671,7 +5867,7 @@ public void testSurroundWithTryWithResource_02() throws Exception { assertNumberOfProposals(proposals, 4); assertCorrectLabels(proposals); - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + CUCorrectionProposal proposal= (CUCorrectionProposal) findProposalByName("Surround with try-with-resources", proposals); String preview1= getPreviewContent(proposal); StringBuilder buf= new StringBuilder(); @@ -5712,7 +5908,7 @@ public void testSurroundWithTryWithResource_02() throws Exception { assertNumberOfProposals(proposals, 4); assertCorrectLabels(proposals); - proposal= (CUCorrectionProposal) proposals.get(0); + proposal= (CUCorrectionProposal) findProposalByName("Surround with try-with-resources", proposals); String preview2= getPreviewContent(proposal); buf= new StringBuilder(); @@ -5787,7 +5983,7 @@ public void testSurroundWithTryWithResource_03() throws Exception { assertCorrectLabels(proposals); - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + CUCorrectionProposal proposal= (CUCorrectionProposal) findProposalByName("Surround with try-with-resources", proposals); String preview1= getPreviewContent(proposal); StringBuilder buf= new StringBuilder(); @@ -5856,7 +6052,7 @@ public void testSurroundWithTryWithResource_04() throws Exception { assertCorrectLabels(proposals); - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + CUCorrectionProposal proposal= (CUCorrectionProposal) findProposalByName("Surround with try-with-resources", proposals); String preview1= getPreviewContent(proposal); StringBuilder buf= new StringBuilder(); @@ -5890,6 +6086,64 @@ public void testSurroundWithTryWithResource_04() throws Exception { assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 }); assertCorrectLabels(proposals); } + + @Test + public void testSurroundWithTryWithResource_05() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null); + StringBuilder bufOrg= new StringBuilder(); + bufOrg.append("package p;\n"); + bufOrg.append("\n"); + bufOrg.append("import java.io.File;\n" + + "import java.util.stream.Stream;\n" + + "\n" + + "public class X {\n" + + " public static void main(String[] args) throws Exception {\n" + + " try {\n" + + " try {\n" + + " Stream stream = Stream.of(new File(\"\"));\n" + + " System.out.println(stream);\n" + + " } catch (Exception e) {\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " }\n" + + "}"); + + ICompilationUnit cu= pack1.createCompilationUnit("X.java", bufOrg.toString(), false, null); + + int cursor = bufOrg.toString().indexOf("Stream"); + AssistContext context= getCorrectionContext(cu, cursor + 1, 0); + List proposals= collectAssists(context, false); + + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) findProposalByName("Surround with try-with-resources", proposals); + String preview1= getPreviewContent(proposal); + + StringBuilder buf= new StringBuilder(); + buf.append("package p;\n"); + buf.append("\n"); + buf.append("import java.io.File;\n" + + "import java.util.stream.Stream;\n" + + "\n" + + "public class X {\n" + + " public static void main(String[] args) throws Exception {\n" + + " try {\n" + + " try (Stream stream = Stream.of(new File(\"\"))) {\n" + + " System.out.println(stream);\n" + + " } catch (Exception e) {\n" + + " }\n" + + " } catch (Exception e) {\n" + + " }\n" + + " }\n" + + "}"); + String expected1= buf.toString(); + + assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 }); + assertCorrectLabels(proposals); + } + + @Test public void testWrapInOptional_01() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null); diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpStressTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpStressTest.java index 3dbbbd11..2d608c92 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpStressTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpStressTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -309,7 +309,7 @@ private void addAllCUs(IJavaElement[] children, List result) throw buf.append(" * Extract the class name from a String in VA/Java style\n"); buf.append(" */\n"); buf.append(" public String extractClassName(final String className) {\n"); - buf.append(" if (className.startsWith(\"Default package for\")) {\n"); + buf.append(" if (className.startsWith(\"Default package for\")) { // $NON-NLS-1$\n"); buf.append(" return className.substring(className.lastIndexOf(\".\") + 1); //$NON-NLS-1$\n"); buf.append(" }\n"); buf.append(" return className;\n"); @@ -1797,7 +1797,7 @@ private void addAllCUs(IJavaElement[] children, List result) throw buf.append(" if (key.startsWith(\"excluded.\")) { //$NON-NLS-1$\n"); buf.append(" String path = p.getProperty(key);\n"); buf.append(" path = path.trim();\n"); - buf.append(" if (path.endsWith(\"*\")) {\n"); + buf.append(" if (path.endsWith(\"*\")) { //$NON-NLS-1$\n"); buf.append(" path = path.substring(0, path.length() - 1);\n"); buf.append(" }\n"); buf.append(" if (path.length() > 0) {\n"); @@ -2439,7 +2439,10 @@ private void addAllCUs(IJavaElement[] children, List result) throw buf.append(" Assert.failNotEquals(message, new Double(expected),\n"); buf.append(" new Double(actual));\n"); buf.append(" }\n"); - buf.append(" } else if (!(Math.abs(expected - actual) <= delta)) {\n"); + buf.append(" } else if (!(Math.abs(expected - actual) <= delta)) { // Because\n"); + buf.append(" // comparison with\n"); + buf.append(" // NaN always\n"); + buf.append(" // returns false\n"); buf.append(" Assert.failNotEquals(message, new Double(expected),\n"); buf.append(" new Double(actual));\n"); buf.append(" }\n"); @@ -2698,7 +2701,7 @@ private void addAllCUs(IJavaElement[] children, List result) throw buf.append(" final String s = classFileName.substring(0,\n"); buf.append(" classFileName.length() - ClassPathTestCollector.SUFFIX_LENGTH);\n"); buf.append(" final String s2 = s.replace(File.separatorChar, '.');\n"); - buf.append(" if (s2.startsWith(\".\")) {\n"); + buf.append(" if (s2.startsWith(\".\")) { //$NON-NLS-1$\n"); buf.append(" return s2.substring(1);\n"); buf.append(" }\n"); buf.append(" return s2;\n"); @@ -3081,19 +3084,19 @@ private void addAllCUs(IJavaElement[] children, List result) throw buf.append(" boolean wait = false;\n"); buf.append("\n"); buf.append(" for (int i = 0; i < args.length; i++) {\n"); - buf.append(" if (args[i].equals(\"-wait\")) {\n"); + buf.append(" if (args[i].equals(\"-wait\")) { //$NON-NLS-1$\n"); buf.append(" wait = true;\n"); - buf.append(" } else if (args[i].equals(\"-c\")) {\n"); + buf.append(" } else if (args[i].equals(\"-c\")) { //$NON-NLS-1$\n"); buf.append(" testCase = this.extractClassName(args[++i]);\n"); - buf.append(" } else if (args[i].equals(\"-v\")) {\n"); + buf.append(" } else if (args[i].equals(\"-v\")) { //$NON-NLS-1$\n"); buf.append(" System.err.println(\"JUnit \" + Version.id() //$NON-NLS-1$\n"); buf.append(" + \" by Kent Beck and Erich Gamma\"); //$NON-NLS-1$\n"); - buf.append(" } else {\n"); + buf.append(" } else { // $NON-NLS-1$\n"); buf.append(" testCase = args[i];\n"); buf.append(" }\n"); buf.append(" }\n"); buf.append("\n"); - buf.append(" if (testCase.equals(\"\")) {\n"); + buf.append(" if (testCase.equals(\"\")) { // $NON-NLS-1$\n"); buf.append(" throw new Exception(\n"); buf.append(" \"Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class\"); //$NON-NLS-1$\n"); buf.append(" }\n"); diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java index d0c732c4..d73cfe77 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -77,6 +77,7 @@ import org.eclipse.jdt.internal.ui.fix.Java50CleanUp; import org.eclipse.jdt.internal.ui.fix.MultiFixMessages; import org.eclipse.jdt.internal.ui.fix.PlainReplacementCleanUpCore; +import org.eclipse.jdt.internal.ui.fix.PrimitiveRatherThanWrapperCleanUpCore; import org.eclipse.jdt.internal.ui.fix.RedundantModifiersCleanUp; import org.eclipse.jdt.internal.ui.fix.UnimplementedCodeCleanUp; import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation; @@ -863,6 +864,238 @@ public void testUnusedCode11() throws Exception { assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1, cu2}, new String[] {expected1, expected2}, null); } + @Test + public void testUnusedCode12() throws Exception { + // don't clean up parameters in public methods + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "public class E1 {\n" + + " public void bla() {\n" + + " foo(83);\n" + + " }\n" // + + " private void foo(int zoz) {\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + String expected1= "" // + + "package test1;\n" // + + "public class E1 {\n" + + " public void bla() {\n" + + " foo();\n" + + " }\n" // + + " private void foo() {\n" // + + " }\n" // + + "}\n"; + + sample= "" // + + "package test1;\n" + + "class E3 {\n" + + " protected void foo(int subu, Object[] gork) {\n" + + " System.out.println(gork.length + subu);\n" + + " }\n" + + "}\n" // + + "public class E2 extends E3 {\n" + + " public void bla() {\n" + + " foo(null, 83, null);\n" + + " }\n" // + + " private void foo(String bubu, int zoz, Object... gork) {\n" // + + " System.out.println(gork.length + bubu.length());\n" + + " }\n" // + + "}\n"; + ICompilationUnit cu2= pack1.createCompilationUnit("E2.java", sample, false, null); + + String expected2= "" // + + "package test1;\n" // + + "class E3 {\n" + + " protected void foo(int subu, Object[] gork) {\n" + + " System.out.println(gork.length + subu);\n" + + " }\n" + + "}\n" // + + "public class E2 extends E3 {\n" + + " public void bla() {\n" + + " foo1(null, null);\n" + + " }\n" // + + " private void foo1(String bubu, Object... gork) {\n" // + + " System.out.println(gork.length + bubu.length());\n" + + " }\n" // + + "}\n"; + + + sample = "" + + "package test1;\n" + + "\n" + + "public class E4 {\n" + + " \n" + + " private void foo(int one, K kay, int two, T tee) {\n" + + " System.out.println(one + two);\n" + + " }\n" + + "}\n"; + ICompilationUnit cu3= pack1.createCompilationUnit("E4.java", sample, false, null); + + String expected3= "" + + "package test1;\n" + + "\n" + + "public class E4 {\n" + + " \n" + + " private void foo(int one, int two) {\n" + + " System.out.println(one + two);\n" + + " }\n" + + "}\n"; + + enable(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS); + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1, cu2, cu3}, new String[] {expected1, expected2, expected3}, null); + } + + @Test + public void testUnusedCodeBug578906_1() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "import java.util.Iterator;\n" // + + "import java.util.List;\n" // + + "public class E1 {\n" // + + " public void foo(List resultHints, List results) {\n" // + + " Iterator it = results.iterator();\n" // + + " for (int j = resultHints.size();it.hasNext();j++) {\n" // + + " }\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES); + + sample= "" // + + "package test1;\n" // + + "import java.util.Iterator;\n" // + + "import java.util.List;\n" // + + "public class E1 {\n" // + + " public void foo(List resultHints, List results) {\n" // + + " Iterator it = results.iterator();\n" // + + " for (resultHints.size();it.hasNext();) {\n" // + + " }\n" // + + " }\n" // + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}, null); + } + + @Test + public void testUnusedCodeBug578906_2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "import java.util.Iterator;\n" // + + "import java.util.List;\n" // + + "public class E1 {\n" // + + " public void foo(List resultHints, List results) {\n" // + + " Iterator it = results.iterator();\n" // + + " for (int j = resultHints.size() + resultHints.hashCode();it.hasNext();j++) {\n" // + + " }\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES); + + sample= "" // + + "package test1;\n" // + + "import java.util.Iterator;\n" // + + "import java.util.List;\n" // + + "public class E1 {\n" // + + " public void foo(List resultHints, List results) {\n" // + + " Iterator it = results.iterator();\n" // + + " for (resultHints.size(), resultHints.hashCode();it.hasNext();) {\n" // + + " }\n" // + + " }\n" // + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}, null); + } + + + @Test + public void testUnusedCodeBug578169() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "public class E1 {\n" // + + " static class Point {\n" // + + " int x, y;\n" // + + " public int getX() {\n" // + + " return x;\n" // + + " }\n" // + + " }\n" // + + "\n" // + + " static class Rect {\n" // + + " Point loc;\n" // + + " int w, h;\n" // + + " public Point getLoc() {\n" // + + " return loc;\n" // + + " }\n" // + + " }\n" // + + "\n" // + + " Rect getRect() {\n" // + + " return new Rect();\n" // + + " }\n" // + + "\n" // + + " void test() {\n" // + + " int x;\n" // + + " int y;\n" // + + " int z;\n" // + + " int k = getRect().loc.getX();\n" // + + " x = getRect().getLoc().x;\n" // + + " y = getRect().loc.y;\n" // + + " System.out.println(y);\n" // + + " z = getRect().loc.x;\n" // + + " k = getRect().loc.getX();\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES); + + sample= "" // + + "package test1;\n" // + + "public class E1 {\n" // + + " static class Point {\n" // + + " int x, y;\n" // + + " public int getX() {\n" // + + " return x;\n" // + + " }\n" // + + " }\n" // + + "\n" // + + " static class Rect {\n" // + + " Point loc;\n" // + + " int w, h;\n" // + + " public Point getLoc() {\n" // + + " return loc;\n" // + + " }\n" // + + " }\n" // + + "\n" // + + " Rect getRect() {\n" // + + " return new Rect();\n" // + + " }\n" // + + "\n" // + + " void test() {\n" // + + " int y;\n" // + + " getRect().loc.getX();\n" // + + " getRect().getLoc();\n" // + + " y = getRect().loc.y;\n" // + + " System.out.println(y);\n" // + + " getRect();\n" // + + " getRect().loc.getX();\n" // + + " }\n" // + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}, null); + } + @Test public void testUnusedCodeBug123766() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); @@ -995,6 +1228,37 @@ public void testUnusedCodeBug189394() throws Exception { assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); } + @Test + public void testUnusedCodeBug578911() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public void foo(Integer o1, Integer o2) {\n" // + + " o1 = (Integer)o1;\n" // + + " o2 = (((Integer)o2));\n" // + + " o1 = (Integer)o2;\n" // + + " }\n" // + + "}\n"; + + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.REMOVE_UNNECESSARY_CASTS); + + sample= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public void foo(Integer o1, Integer o2) {\n" // + + " o1 = o2;\n" // + + " }\n" // + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); + } + @Test public void testUnusedCodeBug335173_1() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); @@ -3394,6 +3658,36 @@ public void testCodeStyleBug154787() throws Exception { assertRefactoringHasNoChange(new ICompilationUnit[] {cu1}); } + @Test + public void testCodeStyleBug579044() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "class E1 {public static String FOO = \"FOO\";}\n"; + pack1.createCompilationUnit("E1.java", sample, false, null); + + sample= "" // + + "package test1;\n" // + + "public class E2 extends E1 {}\n"; + pack1.createCompilationUnit("E2.java", sample, false, null); + + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + sample= "" // + + "package test2;\n" // + + "import test1.E2;\n" // + + "public class E3 {\n" // + + " public String foo() {\n" // + + " return E2.FOO;\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack2.createCompilationUnit("E3.java", sample, false, null); + + enable(CleanUpConstants.MEMBER_ACCESSES_STATIC_QUALIFY_WITH_DECLARING_CLASS); + enable(CleanUpConstants.MEMBER_ACCESSES_STATIC_QUALIFY_WITH_DECLARING_CLASS_SUBTYPE_ACCESS); + + assertRefactoringHasNoChange(new ICompilationUnit[] {cu1}); + } + @Test public void testCodeStyleBug189398() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); @@ -4866,6 +5160,17 @@ public void testValueOfRatherThanInstantiation() throws Exception { + " Float f3 = new Float(dObject);\n" // + " }\n" // + "\n" // + + " public static void parsedByStringAutoboxedToPrimitive() {\n" // + + " // Keep this comment\n" // + + " byte by = new Byte(\"42\");\n" // + + " boolean bo = new Boolean(\"true\");\n" // + + " double d = new Double(\"42\");\n" // + + " float f = new Float(\"42\");\n" // + + " long l = new Long(\"42\");\n" // + + " short s = new Short(\"42\");\n" // + + " int i = new Integer(\"42\");\n" // + + " }\n" // + + "\n" // + " public static void removeUnnecessaryObjectCreation() {\n" // + " // Keep this comment\n" // + " new Byte(\"0\").byteValue();\n" // @@ -4957,6 +5262,17 @@ public void testValueOfRatherThanInstantiation() throws Exception { + " Float f3 = dObject.floatValue();\n" // + " }\n" // + "\n" // + + " public static void parsedByStringAutoboxedToPrimitive() {\n" // + + " // Keep this comment\n" // + + " byte by = Byte.valueOf(\"42\");\n" // + + " boolean bo = Boolean.valueOf(\"true\");\n" // + + " double d = Double.valueOf(\"42\");\n" // + + " float f = Float.valueOf(\"42\");\n" // + + " long l = Long.valueOf(\"42\");\n" // + + " short s = Short.valueOf(\"42\");\n" // + + " int i = Integer.valueOf(\"42\");\n" // + + " }\n" // + + "\n" // + " public static void removeUnnecessaryObjectCreation() {\n" // + " // Keep this comment\n" // + " Byte.valueOf(\"0\").byteValue();\n" // @@ -5020,6 +5336,8 @@ public void testValueOfRatherThanInstantiation() throws Exception { MultiFixMessages.ValueOfRatherThanInstantiationCleanup_description_valueof))); } + + @Test public void testDoNotUseValueOfRatherThanInstantiation() throws Exception { IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); @@ -5040,6 +5358,40 @@ public void testDoNotUseValueOfRatherThanInstantiation() throws Exception { assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); } + @Test + public void testValueOfRatherThanInstantiationBug578917() throws Exception { + // Given + IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); + String given= "" // + + "package test1;\n" + + "\n" // + + "public class E {\n" + + " public static void replaceWrapperConstructorsWithValueOf() {\n" + + " double k= 33;\n" + + " Float f= new Float(((k= (4 * 3f / 72d))))" + + " }\n" + + "}\n"; + + String expected= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public static void replaceWrapperConstructorsWithValueOf() {\n" + + " double k= 33;\n" + + " Float f= Float.valueOf((float) (k= (4 * 3f / 72d)))" // + + " }\n" // + + "}\n"; + + // When + ICompilationUnit cu= pack.createCompilationUnit("E.java", given, false, null); + enable(CleanUpConstants.VALUEOF_RATHER_THAN_INSTANTIATION); + + // Then + assertNotEquals("The class must be changed", given, expected); + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(MultiFixMessages.ValueOfRatherThanInstantiationCleanup_description_float_with_float_value))); + } + @Test public void testPrimitiveComparison() throws Exception { // Given @@ -6420,14 +6772,14 @@ public void testPrimitiveCharRatherThanWrapper() throws Exception { + " public void replaceReassignedWrapper() {\n" // + " // Keep this comment\n" // + " Character reassignedCharacter = Character.MIN_VALUE;\n" // - + " reassignedCharacter = 123;\n" // + + " reassignedCharacter = 'a';\n" // + " }\n" // + "\n" // + " public void replaceMultiReassignedWrapper() {\n" // + " // Keep this comment\n" // + " Character multiReassignedCharacter = Character.MIN_VALUE;\n" // - + " multiReassignedCharacter = 123;\n" // - + " multiReassignedCharacter = 456;\n" // + + " multiReassignedCharacter = 'a';\n" // + + " multiReassignedCharacter = 'b';\n" // + " }\n" // + "\n" // + " public void replaceAssignedWrapper() {\n" // @@ -6636,14 +6988,14 @@ public void testPrimitiveCharRatherThanWrapper() throws Exception { + " public void replaceReassignedWrapper() {\n" // + " // Keep this comment\n" // + " char reassignedCharacter = Character.MIN_VALUE;\n" // - + " reassignedCharacter = 123;\n" // + + " reassignedCharacter = 'a';\n" // + " }\n" // + "\n" // + " public void replaceMultiReassignedWrapper() {\n" // + " // Keep this comment\n" // + " char multiReassignedCharacter = Character.MIN_VALUE;\n" // - + " multiReassignedCharacter = 123;\n" // - + " multiReassignedCharacter = 456;\n" // + + " multiReassignedCharacter = 'a';\n" // + + " multiReassignedCharacter = 'b';\n" // + " }\n" // + "\n" // + " public void replaceAssignedWrapper() {\n" // @@ -10242,6 +10594,42 @@ public void testDoNotUsePrimitiveDoubleRatherThanWrapper() throws Exception { assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); } + @Test + public void testPrimitiveRatherThanWrapperPreview() throws Exception { + String previewHeader= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public void preview(int i) {\n"; + String previewFooter= "" // + + " }\n" // + + "}\n"; + AbstractCleanUpCore cleanUp= new PrimitiveRatherThanWrapperCleanUpCore() { + @Override + protected boolean isEnabled(String key) { + return false; + } + }; + String given= previewHeader + cleanUp.getPreview() + previewFooter; + cleanUp= new PrimitiveRatherThanWrapperCleanUpCore() { + @Override + protected boolean isEnabled(String key) { + return true; + } + }; + String expected= previewHeader + cleanUp.getPreview() + previewFooter; + + // When + IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); + ICompilationUnit cu= pack.createCompilationUnit("E.java", given, false, null); + enable(CleanUpConstants.PRIMITIVE_RATHER_THAN_WRAPPER); + + // Then + assertNotEquals("The class must be changed", given, expected); + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(MultiFixMessages.PrimitiveRatherThanWrapperCleanUp_description))); + } + @Test public void testEvaluateNullable() throws Exception { IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); @@ -10962,51 +11350,120 @@ public void testOperandFactorization() throws Exception { + "import java.util.List;\n" // + "\n" // + "public class E {\n" // - + " private static int staticField = 0;\n" // + + " public void replaceDuplicateConditionsWithPrimitiveTypes(boolean repeatedBoolean, boolean thenExpression, boolean elseExpression) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = repeatedBoolean && thenExpression || repeatedBoolean && elseExpression;\n" // + + " boolean newBoolean2 = repeatedBoolean && !thenExpression || repeatedBoolean && elseExpression;\n" // + + " boolean newBoolean3 = repeatedBoolean && thenExpression || repeatedBoolean && !elseExpression;\n" // + + " boolean newBoolean4 = repeatedBoolean && !thenExpression || repeatedBoolean && !elseExpression;\n" // + + " boolean newBoolean5 = !repeatedBoolean && thenExpression || !repeatedBoolean && elseExpression;\n" // + + " boolean newBoolean6 = !repeatedBoolean && !thenExpression || !repeatedBoolean && elseExpression;\n" // + + " boolean newBoolean7 = !repeatedBoolean && thenExpression || !repeatedBoolean && !elseExpression;\n" // + + " boolean newBoolean8 = !repeatedBoolean && !thenExpression || !repeatedBoolean && !elseExpression;\n" // + + " }\n" // + + "\n" // + + " public void replaceDuplicateConditionsWithPermutedExpressions(boolean repeatedExpression, boolean thenExpression, boolean elseExpression) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = repeatedExpression && thenExpression || elseExpression && repeatedExpression;\n" // + + " boolean newBoolean2 = repeatedExpression && !thenExpression || elseExpression && repeatedExpression;\n" // + + " boolean newBoolean3 = repeatedExpression && thenExpression || !elseExpression && repeatedExpression;\n" // + + " boolean newBoolean4 = repeatedExpression && !thenExpression || !elseExpression && repeatedExpression;\n" // + + " boolean newBoolean5 = !repeatedExpression && thenExpression || elseExpression && !repeatedExpression;\n" // + + " boolean newBoolean6 = !repeatedExpression && !thenExpression || elseExpression && !repeatedExpression;\n" // + + " boolean newBoolean7 = !repeatedExpression && thenExpression || !elseExpression && !repeatedExpression;\n" // + + " boolean newBoolean8 = !repeatedExpression && !thenExpression || !elseExpression && !repeatedExpression;\n" // + + "\n" // + + " newBoolean1 = thenExpression && repeatedExpression || repeatedExpression && elseExpression;\n" // + + " newBoolean2 = !thenExpression && repeatedExpression || repeatedExpression && elseExpression;\n" // + + " newBoolean3 = thenExpression && repeatedExpression || repeatedExpression && !elseExpression;\n" // + + " newBoolean4 = !thenExpression && repeatedExpression || repeatedExpression && !elseExpression;\n" // + + " newBoolean5 = !repeatedExpression && thenExpression || !repeatedExpression && elseExpression;\n" // + + " newBoolean6 = !repeatedExpression && !thenExpression || !repeatedExpression && elseExpression;\n" // + + " newBoolean7 = !repeatedExpression && thenExpression || !repeatedExpression && !elseExpression;\n" // + + " newBoolean8 = !repeatedExpression && !thenExpression || !repeatedExpression && !elseExpression;\n" // + + " }\n" // + "\n" // - + " public void replaceDuplicateConditionsWithPrimitiveTypes(boolean repeatedBoolean, boolean isValid, boolean isActive) {\n" // + + " public void replaceDuplicateConditionsOnConditionalAndExpression(boolean repeatedBoolean, boolean thenExpression, boolean elseExpression) {\n" // + " // Keep this comment\n" // - + " boolean newBoolean1 = repeatedBoolean && isValid || repeatedBoolean && isActive;\n" // - + " boolean newBoolean2 = repeatedBoolean && !isValid || repeatedBoolean && isActive;\n" // - + " boolean newBoolean3 = repeatedBoolean && isValid || repeatedBoolean && !isActive;\n" // - + " boolean newBoolean4 = repeatedBoolean && !isValid || repeatedBoolean && !isActive;\n" // - + " boolean newBoolean5 = !repeatedBoolean && isValid || !repeatedBoolean && isActive;\n" // - + " boolean newBoolean6 = !repeatedBoolean && !isValid || !repeatedBoolean && isActive;\n" // - + " boolean newBoolean7 = !repeatedBoolean && isValid || !repeatedBoolean && !isActive;\n" // - + " boolean newBoolean8 = !repeatedBoolean && !isValid || !repeatedBoolean && !isActive;\n" // + + " boolean newBoolean1 = (repeatedBoolean || thenExpression) && (repeatedBoolean || elseExpression);\n" // + + " boolean newBoolean2 = (repeatedBoolean || !thenExpression) && (repeatedBoolean || elseExpression);\n" // + + " boolean newBoolean3 = (repeatedBoolean || thenExpression) && (repeatedBoolean || !elseExpression);\n" // + + " boolean newBoolean4 = (repeatedBoolean || !thenExpression) && (repeatedBoolean || !elseExpression);\n" // + + " boolean newBoolean5 = (!repeatedBoolean || thenExpression) && (!repeatedBoolean || elseExpression);\n" // + + " boolean newBoolean6 = (!repeatedBoolean || !thenExpression) && (!repeatedBoolean || elseExpression);\n" // + + " boolean newBoolean7 = (!repeatedBoolean || thenExpression) && (!repeatedBoolean || !elseExpression);\n" // + + " boolean newBoolean8 = (!repeatedBoolean || !thenExpression) && (!repeatedBoolean || !elseExpression);\n" // + + " }\n" // + + "\n" // + + " public void replaceDuplicateConditionsWithEagerOperator(boolean repeatedBoolean, boolean thenExpression, boolean elseExpression) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = repeatedBoolean & thenExpression | repeatedBoolean & elseExpression;\n" // + + " boolean newBoolean2 = repeatedBoolean & !thenExpression | repeatedBoolean & elseExpression;\n" // + + " boolean newBoolean3 = repeatedBoolean & thenExpression | repeatedBoolean & !elseExpression;\n" // + + " boolean newBoolean4 = repeatedBoolean & !thenExpression | repeatedBoolean & !elseExpression;\n" // + + " boolean newBoolean5 = !repeatedBoolean & thenExpression | !repeatedBoolean & elseExpression;\n" // + + " boolean newBoolean6 = !repeatedBoolean & !thenExpression | !repeatedBoolean & elseExpression;\n" // + + " boolean newBoolean7 = !repeatedBoolean & thenExpression | !repeatedBoolean & !elseExpression;\n" // + + " boolean newBoolean8 = !repeatedBoolean & !thenExpression | !repeatedBoolean & !elseExpression;\n" // + + " }\n" // + + "\n" // + + " public void replaceDuplicateConditionsOnEagerAndExpression(boolean repeatedBoolean, boolean thenExpression, boolean elseExpression) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = (repeatedBoolean | thenExpression) & (repeatedBoolean | elseExpression);\n" // + + " boolean newBoolean2 = (repeatedBoolean | !thenExpression) & (repeatedBoolean | elseExpression);\n" // + + " boolean newBoolean3 = (repeatedBoolean | thenExpression) & (repeatedBoolean | !elseExpression);\n" // + + " boolean newBoolean4 = (repeatedBoolean | !thenExpression) & (repeatedBoolean | !elseExpression);\n" // + + " boolean newBoolean5 = (!repeatedBoolean | thenExpression) & (!repeatedBoolean | elseExpression);\n" // + + " boolean newBoolean6 = (!repeatedBoolean | !thenExpression) & (!repeatedBoolean | elseExpression);\n" // + + " boolean newBoolean7 = (!repeatedBoolean | thenExpression) & (!repeatedBoolean | !elseExpression);\n" // + + " boolean newBoolean8 = (!repeatedBoolean | !thenExpression) & (!repeatedBoolean | !elseExpression);\n" // + + " }\n" // + + "\n" // + + " public boolean replaceDuplicateConditionsWithWrapperAtTheStart(boolean factor, Boolean thenExpression, boolean elseExpression) {\n" // + + " return thenExpression && factor || factor && elseExpression;\n" // + + " }\n" // + + "\n" // + + " public boolean replaceDuplicateConditionsWithWrapperAtTheEnd(boolean factor, boolean thenExpression, Boolean elseExpression) {\n" // + + " return thenExpression & factor | factor & elseExpression;\n" // + + " }\n" // + + "\n" // + + " public void replaceDuplicateConditionsWithActiveExpressionAtFirstPosition(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = (!(i3 == i4++) && (i1 == i2)) || ((i1 == i2) && (i5 == i6));\n" // + + " boolean newBoolean2 = (!(i3 == ++i4) && (i1 == i2)) || ((i1 == i2) && (i5 == i6));\n" // + + " boolean newBoolean3 = (!(i3 == i4--) && (i1 == i2)) || ((i1 == i2) && (i5 == i6));\n" // + + " boolean newBoolean4 = (!(i3 == --i4) && (i1 == i2)) || ((i1 == i2) && (i5 == i6));\n" // + + "\n" // + + " boolean newBoolean5 = ((i3 == i4++) && (i1 == i2)) || ((i1 == i2) && !(i5 == i6));\n" // + + " boolean newBoolean6 = ((i3 == ++i4) && (i1 == i2)) || ((i1 == i2) && !(i5 == i6));\n" // + + " boolean newBoolean7 = ((i3 == i4--) && (i1 == i2)) || ((i1 == i2) && !(i5 == i6));\n" // + + " boolean newBoolean8 = ((i3 == --i4) && (i1 == i2)) || ((i1 == i2) && !(i5 == i6));\n" // + " }\n" // + "\n" // - + " public void replaceDuplicateConditionsWithEagerOperator(boolean repeatedBoolean, boolean isValid, boolean isEnable) {\n" // + + " public void replaceDuplicateConditionsOnEagerActiveExpression(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // + " // Keep this comment\n" // - + " boolean newBoolean1 = repeatedBoolean & isValid | repeatedBoolean & isEnable;\n" // - + " boolean newBoolean2 = repeatedBoolean & !isValid | repeatedBoolean & isEnable;\n" // - + " boolean newBoolean3 = repeatedBoolean & isValid | repeatedBoolean & !isEnable;\n" // - + " boolean newBoolean4 = repeatedBoolean & !isValid | repeatedBoolean & !isEnable;\n" // - + " boolean newBoolean5 = !repeatedBoolean & isValid | !repeatedBoolean & isEnable;\n" // - + " boolean newBoolean6 = !repeatedBoolean & !isValid | !repeatedBoolean & isEnable;\n" // - + " boolean newBoolean7 = !repeatedBoolean & isValid | !repeatedBoolean & !isEnable;\n" // - + " boolean newBoolean8 = !repeatedBoolean & !isValid | !repeatedBoolean & !isEnable;\n" // + + " boolean newBoolean1 = ((i1 == i2) & !(i3 == i4)) | ((i1 == i2) & (i5 == i6++));\n" // + + " boolean newBoolean2 = ((i1 == i2) & !(i3 == i4)) | ((i1 == i2) & (i5 == ++i6));\n" // + + " boolean newBoolean3 = ((i1 == i2) & !(i3 == i4)) | ((i1 == i2) & (i5 == i6--));\n" // + + " boolean newBoolean4 = ((i1 == i2) & !(i3 == i4)) | ((i1 == i2) & (i5 == --i6));\n" // + + "\n" // + + " boolean newBoolean5 = ((i1 == i2) & (i3 == i4)) | ((i1 == i2) & !(i5 == i6++));\n" // + + " boolean newBoolean6 = ((i1 == i2) & (i3 == i4)) | ((i1 == i2) & !(i5 == ++i6));\n" // + + " boolean newBoolean7 = ((i1 == i2) & (i3 == i4)) | ((i1 == i2) & !(i5 == i6--));\n" // + + " boolean newBoolean8 = ((i1 == i2) & (i3 == i4)) | ((i1 == i2) & !(i5 == --i6));\n" // + " }\n" // + "\n" // - + " public void replaceDuplicateConditionsWithPermutedBooleans(boolean repeatedBoolean, boolean isValid, boolean isActive) {\n" // + + " public void moveDuplicateExpressionOnTheLeftWithFinalEagerActiveExpression(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // + " // Keep this comment\n" // - + " boolean newBoolean1 = repeatedBoolean && isValid || isActive && repeatedBoolean;\n" // - + " boolean newBoolean2 = repeatedBoolean && !isValid || isActive && repeatedBoolean;\n" // - + " boolean newBoolean3 = repeatedBoolean && isValid || !isActive && repeatedBoolean;\n" // - + " boolean newBoolean4 = repeatedBoolean && !isValid || !isActive && repeatedBoolean;\n" // - + " boolean newBoolean5 = !repeatedBoolean && isValid || isActive && !repeatedBoolean;\n" // - + " boolean newBoolean6 = !repeatedBoolean && !isValid || isActive && !repeatedBoolean;\n" // - + " boolean newBoolean7 = !repeatedBoolean && isValid || !isActive && !repeatedBoolean;\n" // - + " boolean newBoolean8 = !repeatedBoolean && !isValid || !isActive && !repeatedBoolean;\n" // + + " boolean newBoolean1 = (!(i3 == i4) & (i1 == i2)) | ((i1 == i2) & (i5 == i6++));\n" // + + " boolean newBoolean2 = (!(i3 == i4) & (i1 == i2)) | ((i1 == i2) & (i5 == ++i6));\n" // + + " boolean newBoolean3 = (!(i3 == i4) & (i1 == i2)) | ((i1 == i2) & (i5 == i6--));\n" // + + " boolean newBoolean4 = (!(i3 == i4) & (i1 == i2)) | ((i1 == i2) & (i5 == --i6));\n" // + "\n" // - + " newBoolean1 = isValid && repeatedBoolean || repeatedBoolean && isActive;\n" // - + " newBoolean2 = !isValid && repeatedBoolean || repeatedBoolean && isActive;\n" // - + " newBoolean3 = isValid && repeatedBoolean || repeatedBoolean && !isActive;\n" // - + " newBoolean4 = !isValid && repeatedBoolean || repeatedBoolean && !isActive;\n" // - + " newBoolean5 = !repeatedBoolean && isValid || !repeatedBoolean && isActive;\n" // - + " newBoolean6 = !repeatedBoolean && !isValid || !repeatedBoolean && isActive;\n" // - + " newBoolean7 = !repeatedBoolean && isValid || !repeatedBoolean && !isActive;\n" // - + " newBoolean8 = !repeatedBoolean && !isValid || !repeatedBoolean && !isActive;\n" // + + " boolean newBoolean5 = ((i3 == i4) & (i1 == i2)) | ((i1 == i2) & !(i5 == i6++));\n" // + + " boolean newBoolean6 = ((i3 == i4) & (i1 == i2)) | ((i1 == i2) & !(i5 == ++i6));\n" // + + " boolean newBoolean7 = ((i3 == i4) & (i1 == i2)) | ((i1 == i2) & !(i5 == i6--));\n" // + + " boolean newBoolean8 = ((i3 == i4) & (i1 == i2)) | ((i1 == i2) & !(i5 == --i6));\n" // + " }\n" // + "\n" // + " public void replaceDuplicateConditionsWithExpressions(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // @@ -11034,51 +11491,120 @@ public void testOperandFactorization() throws Exception { + "import java.util.List;\n" // + "\n" // + "public class E {\n" // - + " private static int staticField = 0;\n" // + + " public void replaceDuplicateConditionsWithPrimitiveTypes(boolean repeatedBoolean, boolean thenExpression, boolean elseExpression) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = (repeatedBoolean && (thenExpression || elseExpression));\n" // + + " boolean newBoolean2 = (repeatedBoolean && (!thenExpression || elseExpression));\n" // + + " boolean newBoolean3 = (repeatedBoolean && (thenExpression || !elseExpression));\n" // + + " boolean newBoolean4 = (repeatedBoolean && (!thenExpression || !elseExpression));\n" // + + " boolean newBoolean5 = (!repeatedBoolean && (thenExpression || elseExpression));\n" // + + " boolean newBoolean6 = (!repeatedBoolean && (!thenExpression || elseExpression));\n" // + + " boolean newBoolean7 = (!repeatedBoolean && (thenExpression || !elseExpression));\n" // + + " boolean newBoolean8 = (!repeatedBoolean && (!thenExpression || !elseExpression));\n" // + + " }\n" // + + "\n" // + + " public void replaceDuplicateConditionsWithPermutedExpressions(boolean repeatedExpression, boolean thenExpression, boolean elseExpression) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = ((thenExpression || elseExpression) && repeatedExpression);\n" // + + " boolean newBoolean2 = ((!thenExpression || elseExpression) && repeatedExpression);\n" // + + " boolean newBoolean3 = ((thenExpression || !elseExpression) && repeatedExpression);\n" // + + " boolean newBoolean4 = ((!thenExpression || !elseExpression) && repeatedExpression);\n" // + + " boolean newBoolean5 = ((thenExpression || elseExpression) && !repeatedExpression);\n" // + + " boolean newBoolean6 = ((!thenExpression || elseExpression) && !repeatedExpression);\n" // + + " boolean newBoolean7 = ((thenExpression || !elseExpression) && !repeatedExpression);\n" // + + " boolean newBoolean8 = ((!thenExpression || !elseExpression) && !repeatedExpression);\n" // + + "\n" // + + " newBoolean1 = (repeatedExpression && (thenExpression || elseExpression));\n" // + + " newBoolean2 = (repeatedExpression && (!thenExpression || elseExpression));\n" // + + " newBoolean3 = (repeatedExpression && (thenExpression || !elseExpression));\n" // + + " newBoolean4 = (repeatedExpression && (!thenExpression || !elseExpression));\n" // + + " newBoolean5 = (!repeatedExpression && (thenExpression || elseExpression));\n" // + + " newBoolean6 = (!repeatedExpression && (!thenExpression || elseExpression));\n" // + + " newBoolean7 = (!repeatedExpression && (thenExpression || !elseExpression));\n" // + + " newBoolean8 = (!repeatedExpression && (!thenExpression || !elseExpression));\n" // + + " }\n" // + + "\n" // + + " public void replaceDuplicateConditionsOnConditionalAndExpression(boolean repeatedBoolean, boolean thenExpression, boolean elseExpression) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = (repeatedBoolean || (thenExpression && elseExpression));\n" // + + " boolean newBoolean2 = (repeatedBoolean || (!thenExpression && elseExpression));\n" // + + " boolean newBoolean3 = (repeatedBoolean || (thenExpression && !elseExpression));\n" // + + " boolean newBoolean4 = (repeatedBoolean || (!thenExpression && !elseExpression));\n" // + + " boolean newBoolean5 = (!repeatedBoolean || (thenExpression && elseExpression));\n" // + + " boolean newBoolean6 = (!repeatedBoolean || (!thenExpression && elseExpression));\n" // + + " boolean newBoolean7 = (!repeatedBoolean || (thenExpression && !elseExpression));\n" // + + " boolean newBoolean8 = (!repeatedBoolean || (!thenExpression && !elseExpression));\n" // + + " }\n" // + + "\n" // + + " public void replaceDuplicateConditionsWithEagerOperator(boolean repeatedBoolean, boolean thenExpression, boolean elseExpression) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = (repeatedBoolean & (thenExpression | elseExpression));\n" // + + " boolean newBoolean2 = (repeatedBoolean & (!thenExpression | elseExpression));\n" // + + " boolean newBoolean3 = (repeatedBoolean & (thenExpression | !elseExpression));\n" // + + " boolean newBoolean4 = (repeatedBoolean & (!thenExpression | !elseExpression));\n" // + + " boolean newBoolean5 = (!repeatedBoolean & (thenExpression | elseExpression));\n" // + + " boolean newBoolean6 = (!repeatedBoolean & (!thenExpression | elseExpression));\n" // + + " boolean newBoolean7 = (!repeatedBoolean & (thenExpression | !elseExpression));\n" // + + " boolean newBoolean8 = (!repeatedBoolean & (!thenExpression | !elseExpression));\n" // + + " }\n" // + "\n" // - + " public void replaceDuplicateConditionsWithPrimitiveTypes(boolean repeatedBoolean, boolean isValid, boolean isActive) {\n" // + + " public void replaceDuplicateConditionsOnEagerAndExpression(boolean repeatedBoolean, boolean thenExpression, boolean elseExpression) {\n" // + " // Keep this comment\n" // - + " boolean newBoolean1 = (repeatedBoolean && (isValid || isActive));\n" // - + " boolean newBoolean2 = (repeatedBoolean && (!isValid || isActive));\n" // - + " boolean newBoolean3 = (repeatedBoolean && (isValid || !isActive));\n" // - + " boolean newBoolean4 = (repeatedBoolean && (!isValid || !isActive));\n" // - + " boolean newBoolean5 = (!repeatedBoolean && (isValid || isActive));\n" // - + " boolean newBoolean6 = (!repeatedBoolean && (!isValid || isActive));\n" // - + " boolean newBoolean7 = (!repeatedBoolean && (isValid || !isActive));\n" // - + " boolean newBoolean8 = (!repeatedBoolean && (!isValid || !isActive));\n" // + + " boolean newBoolean1 = (repeatedBoolean | (thenExpression & elseExpression));\n" // + + " boolean newBoolean2 = (repeatedBoolean | (!thenExpression & elseExpression));\n" // + + " boolean newBoolean3 = (repeatedBoolean | (thenExpression & !elseExpression));\n" // + + " boolean newBoolean4 = (repeatedBoolean | (!thenExpression & !elseExpression));\n" // + + " boolean newBoolean5 = (!repeatedBoolean | (thenExpression & elseExpression));\n" // + + " boolean newBoolean6 = (!repeatedBoolean | (!thenExpression & elseExpression));\n" // + + " boolean newBoolean7 = (!repeatedBoolean | (thenExpression & !elseExpression));\n" // + + " boolean newBoolean8 = (!repeatedBoolean | (!thenExpression & !elseExpression));\n" // + " }\n" // + "\n" // - + " public void replaceDuplicateConditionsWithEagerOperator(boolean repeatedBoolean, boolean isValid, boolean isEnable) {\n" // + + " public boolean replaceDuplicateConditionsWithWrapperAtTheStart(boolean factor, Boolean thenExpression, boolean elseExpression) {\n" // + + " return ((thenExpression || elseExpression) && factor);\n" // + + " }\n" // + + "\n" // + + " public boolean replaceDuplicateConditionsWithWrapperAtTheEnd(boolean factor, boolean thenExpression, Boolean elseExpression) {\n" // + + " return (factor & (thenExpression | elseExpression));\n" // + + " }\n" // + + "\n" // + + " public void replaceDuplicateConditionsWithActiveExpressionAtFirstPosition(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // + + " // Keep this comment\n" // + + " boolean newBoolean1 = ((!(i3 == i4++) || (i5 == i6)) && (i1 == i2));\n" // + + " boolean newBoolean2 = ((!(i3 == ++i4) || (i5 == i6)) && (i1 == i2));\n" // + + " boolean newBoolean3 = ((!(i3 == i4--) || (i5 == i6)) && (i1 == i2));\n" // + + " boolean newBoolean4 = ((!(i3 == --i4) || (i5 == i6)) && (i1 == i2));\n" // + + "\n" // + + " boolean newBoolean5 = (((i3 == i4++) || !(i5 == i6)) && (i1 == i2));\n" // + + " boolean newBoolean6 = (((i3 == ++i4) || !(i5 == i6)) && (i1 == i2));\n" // + + " boolean newBoolean7 = (((i3 == i4--) || !(i5 == i6)) && (i1 == i2));\n" // + + " boolean newBoolean8 = (((i3 == --i4) || !(i5 == i6)) && (i1 == i2));\n" // + + " }\n" // + + "\n" // + + " public void replaceDuplicateConditionsOnEagerActiveExpression(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // + " // Keep this comment\n" // - + " boolean newBoolean1 = (repeatedBoolean & (isValid | isEnable));\n" // - + " boolean newBoolean2 = (repeatedBoolean & (!isValid | isEnable));\n" // - + " boolean newBoolean3 = (repeatedBoolean & (isValid | !isEnable));\n" // - + " boolean newBoolean4 = (repeatedBoolean & (!isValid | !isEnable));\n" // - + " boolean newBoolean5 = (!repeatedBoolean & (isValid | isEnable));\n" // - + " boolean newBoolean6 = (!repeatedBoolean & (!isValid | isEnable));\n" // - + " boolean newBoolean7 = (!repeatedBoolean & (isValid | !isEnable));\n" // - + " boolean newBoolean8 = (!repeatedBoolean & (!isValid | !isEnable));\n" // + + " boolean newBoolean1 = ((i1 == i2) & (!(i3 == i4) | (i5 == i6++)));\n" // + + " boolean newBoolean2 = ((i1 == i2) & (!(i3 == i4) | (i5 == ++i6)));\n" // + + " boolean newBoolean3 = ((i1 == i2) & (!(i3 == i4) | (i5 == i6--)));\n" // + + " boolean newBoolean4 = ((i1 == i2) & (!(i3 == i4) | (i5 == --i6)));\n" // + + "\n" // + + " boolean newBoolean5 = ((i1 == i2) & ((i3 == i4) | !(i5 == i6++)));\n" // + + " boolean newBoolean6 = ((i1 == i2) & ((i3 == i4) | !(i5 == ++i6)));\n" // + + " boolean newBoolean7 = ((i1 == i2) & ((i3 == i4) | !(i5 == i6--)));\n" // + + " boolean newBoolean8 = ((i1 == i2) & ((i3 == i4) | !(i5 == --i6)));\n" // + " }\n" // + "\n" // - + " public void replaceDuplicateConditionsWithPermutedBooleans(boolean repeatedBoolean, boolean isValid, boolean isActive) {\n" // + + " public void moveDuplicateExpressionOnTheLeftWithFinalEagerActiveExpression(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // + " // Keep this comment\n" // - + " boolean newBoolean1 = (repeatedBoolean && (isValid || isActive));\n" // - + " boolean newBoolean2 = (repeatedBoolean && (!isValid || isActive));\n" // - + " boolean newBoolean3 = (repeatedBoolean && (isValid || !isActive));\n" // - + " boolean newBoolean4 = (repeatedBoolean && (!isValid || !isActive));\n" // - + " boolean newBoolean5 = (!repeatedBoolean && (isValid || isActive));\n" // - + " boolean newBoolean6 = (!repeatedBoolean && (!isValid || isActive));\n" // - + " boolean newBoolean7 = (!repeatedBoolean && (isValid || !isActive));\n" // - + " boolean newBoolean8 = (!repeatedBoolean && (!isValid || !isActive));\n" // + + " boolean newBoolean1 = ((i1 == i2) & (!(i3 == i4) | (i5 == i6++)));\n" // + + " boolean newBoolean2 = ((i1 == i2) & (!(i3 == i4) | (i5 == ++i6)));\n" // + + " boolean newBoolean3 = ((i1 == i2) & (!(i3 == i4) | (i5 == i6--)));\n" // + + " boolean newBoolean4 = ((i1 == i2) & (!(i3 == i4) | (i5 == --i6)));\n" // + "\n" // - + " newBoolean1 = (repeatedBoolean && (isValid || isActive));\n" // - + " newBoolean2 = (repeatedBoolean && (!isValid || isActive));\n" // - + " newBoolean3 = (repeatedBoolean && (isValid || !isActive));\n" // - + " newBoolean4 = (repeatedBoolean && (!isValid || !isActive));\n" // - + " newBoolean5 = (!repeatedBoolean && (isValid || isActive));\n" // - + " newBoolean6 = (!repeatedBoolean && (!isValid || isActive));\n" // - + " newBoolean7 = (!repeatedBoolean && (isValid || !isActive));\n" // - + " newBoolean8 = (!repeatedBoolean && (!isValid || !isActive));\n" // + + " boolean newBoolean5 = ((i1 == i2) & ((i3 == i4) | !(i5 == i6++)));\n" // + + " boolean newBoolean6 = ((i1 == i2) & ((i3 == i4) | !(i5 == ++i6)));\n" // + + " boolean newBoolean7 = ((i1 == i2) & ((i3 == i4) | !(i5 == i6--)));\n" // + + " boolean newBoolean8 = ((i1 == i2) & ((i3 == i4) | !(i5 == --i6)));\n" // + " }\n" // + "\n" // + " public void replaceDuplicateConditionsWithExpressions(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // @@ -11113,15 +11639,15 @@ public void testDoNotUseOperandFactorization() throws Exception { + "public class E {\n" // + " private static int staticField = 0;\n" // + "\n" // - + " public boolean doNoRefactorFailingCode(boolean b1, boolean[] b2, boolean b3) {\n" // - + " return b2[-1] && b1 || b3 && b1;\n" // + + " public boolean doNoRefactorFailingCode(boolean factor, boolean thenExpression, boolean[] elseCrashingExpression) {\n" // + + " return thenExpression && factor || elseCrashingExpression[-1] && factor;\n" // + " }\n" // + "\n" // - + " public boolean doNoReplaceDuplicateConditionsWithOtherCondition(boolean b1, boolean b2, boolean b3, boolean b4) {\n" // - + " return b1 && b2 || b1 && b3 && b4;\n" // + + " public boolean doNotRefactorWithOtherCondition(boolean factor, boolean thenExpression, boolean elseExpression, boolean extendedOperand) {\n" // + + " return factor && thenExpression || factor && elseExpression && extendedOperand;\n" // + " }\n" // + "\n" // - + " public void doNoReplaceDuplicateConditionsWithOtherOperandBefore(boolean b1, boolean b2, boolean b3, boolean unrelevantCondition) {\n" // + + " public void doNotRefactorWithOtherOperandBefore(boolean b1, boolean b2, boolean b3, boolean unrelevantCondition) {\n" // + " boolean newBoolean1 = unrelevantCondition || (b1 && b2) || (!b1 && b3);\n" // + " boolean newBoolean2 = unrelevantCondition || (b1 && !b2) || (b3 && !b1);\n" // + " boolean newBoolean3 = unrelevantCondition || (b1 && b2) || (!b3 && !b1);\n" // @@ -11132,7 +11658,7 @@ public void testDoNotUseOperandFactorization() throws Exception { + " boolean newBoolean8 = unrelevantCondition || (!b1 && !b2) || (!b3 && b1);\n" // + " }\n" // + "\n" // - + " public void doNoReplaceDuplicateConditionsWithOtherOperandAfter(boolean b1, boolean b2, boolean b3, boolean unrelevantCondition) {\n" // + + " public void doNotRefactorWithOtherOperandAfter(boolean b1, boolean b2, boolean b3, boolean unrelevantCondition) {\n" // + " boolean newBoolean1 = (b1 && b2) || (!b1 && b3) || unrelevantCondition;\n" // + " boolean newBoolean2 = (b1 && !b2) || (b3 && !b1) || unrelevantCondition;\n" // + " boolean newBoolean3 = (b1 && b2) || (!b3 && !b1) || unrelevantCondition;\n" // @@ -11143,18 +11669,26 @@ public void testDoNotUseOperandFactorization() throws Exception { + " boolean newBoolean8 = (!b1 && !b2) || (!b3 && b1) || unrelevantCondition;\n" // + " }\n" // + "\n" // - + " public boolean doNoReplaceDuplicateConditionsWithWrappers(Boolean b1, Boolean b2, Boolean b3) {\n" // - + " return b1 && b2 || b1 && b3;\n" // + + " public boolean doNotRefactorWithWrapperFactor(Boolean factor, boolean thenExpression, boolean elseExpression) {\n" // + + " return factor & thenExpression | factor & elseExpression;\n" // + " }\n" // + "\n" // - + " public void doNotReplaceDuplicateConditionsWithMethods(List myList) {\n" // + + " public boolean doNotRefactorWithWrapperInTheMiddle(boolean factor, Boolean thenExpression, boolean elseExpression) {\n" // + + " return factor & thenExpression | factor & elseExpression;\n" // + + " }\n" // + + "\n" // + + " public boolean doNotRefactorWithLazyWrapperAtTheEnd(boolean factor, boolean thenExpression, Boolean elseExpression) {\n" // + + " return thenExpression && factor || factor && elseExpression;\n" // + + " }\n" // + + "\n" // + + " public void doNotRefactorWithMethods(List myList) {\n" // + " boolean newBoolean1 = myList.remove(\"lorem\") && !myList.remove(\"foo\") || myList.remove(\"lorem\")\n" // + " && myList.remove(\"ipsum\");\n" // + " boolean newBoolean2 = myList.remove(\"lorem\") && myList.remove(\"bar\") || myList.remove(\"lorem\")\n" // + " && !myList.remove(\"ipsum\");\n" // + " }\n" // + "\n" // - + " public void doNotReplaceDuplicateConditionsWithIncrements(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // + + " public void doNotRefactorWithIncrements(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // + " boolean newBoolean1 = (i1 == i2) && !(i3 == i4++) || (i1 == i2) && (i5 == i6++);\n" // + " boolean newBoolean2 = (i1 == i2) && !(i3 == ++i4) || (i1 == i2) && (i5 == ++i6);\n" // + " boolean newBoolean3 = (i1 == i2) && !(i3 == i4--) || (i1 == i2) && (i5 == i6--);\n" // @@ -11166,7 +11700,31 @@ public void testDoNotUseOperandFactorization() throws Exception { + " boolean newBoolean8 = (i1 == i2) && (i3 == --i4) || (i1 == i2) && !(i5 == --i6);\n" // + " }\n" // + "\n" // - + " public void doNotReplaceDuplicateConditionsWithAssignments(int i1, int i2, boolean b1, boolean b2, boolean b3) {\n" // + + " public void doNotReplaceActiveDuplicateConditions(int i1, int i2, int i3, int i4, int i5, int i6) {\n" // + + " boolean newBoolean1 = (i1 == i2++) & !(i3 == i4) | (i1 == i2++) & (i5 == i6);\n" // + + " boolean newBoolean2 = (i1 == ++i2) & !(i3 == i4) | (i1 == ++i2) & (i5 == i6);\n" // + + " boolean newBoolean3 = (i1 == i2--) & !(i3 == i4) | (i1 == i2--) & (i5 == i6);\n" // + + " boolean newBoolean4 = (i1 == --i2) & !(i3 == i4) | (i1 == --i2) & (i5 == i6);\n" // + + "\n" // + + " boolean newBoolean5 = (i1 == i2++) & (i3 == i4) || (i1 == i2++) & !(i5 == i6);\n" // + + " boolean newBoolean6 = (i1 == ++i2) & (i3 == i4) || (i1 == ++i2) & !(i5 == i6);\n" // + + " boolean newBoolean7 = (i1 == i2--) & (i3 == i4) || (i1 == i2--) & !(i5 == i6);\n" // + + " boolean newBoolean8 = (i1 == --i2) & (i3 == i4) || (i1 == --i2) & !(i5 == i6);\n" // + + " }\n" // + + "\n" // + + " public boolean doNotRefactorWithSideEffectDueToThenExpression(int i1, int i2, int i3, int i4, int i5) {\n" // + + " return ((i1 == i2) & (i3 == i2++)) | ((i1 == i2) & (i5 == i4));\n" // + + " }\n" // + + "\n" // + + " public boolean doNotRefactorWithSideEffectDueToElseExpression(int i1, int i2, int i3, int i4, int i5) {\n" // + + " return ((i1 == i2) & (i3 == i4)) | ((i5 == i2++) & (i1 == i2));\n" // + + " }\n" // + + "\n" // + + " public boolean doNotRefactorWithSideEffectDueToElseExpressionToo(int i1, int i2, int i3, int i4, int i5) {\n" // + + " return ((i3 == i4) & (i1 == i2)) | ((i5 == i2++) & (i1 == i2));\n" // + + " }\n" // + + "\n" // + + " public void doNotRefactorWithAssignments(int i1, int i2, boolean b1, boolean b2, boolean b3) {\n" // + " boolean newBoolean1 = (i1 == i2) && !(b1 = b2) || (i1 == i2) && (b1 = b3);\n" // + " boolean newBoolean2 = (i1 == i2) && (b1 = b2) || (i1 == i2) && !(b1 = b3);\n" // + " }\n" // @@ -11177,7 +11735,7 @@ public void testDoNotUseOperandFactorization() throws Exception { + " }\n" // + " }\n" // + "\n" // - + " public void doNotReplaceDuplicateConditionsWithInstanciations(Boolean b1) {\n" // + + " public void doNotRefactorWithInstantiation(boolean b1) {\n" // + " boolean newBoolean1 = b1 && !(new SideEffect() instanceof SideEffect)\n" // + " || b1 && new SideEffect() instanceof Object;\n" // + " boolean newBoolean2 = b1 && new SideEffect() instanceof SideEffect\n" // @@ -11477,6 +12035,7 @@ public void testStrictlyEqualOrDifferent() throws Exception { + " boolean newBoolean2 = (i1 == i2) && (i3 <= i4) || !(i1 == i2) && !(i4 >= i3);\n" // + " boolean newBoolean3 = (i1 == i2) && (i3 != i4) || (i2 != i1) && (i3 == i4);\n" // + " boolean newBoolean4 = (i1 == i2) && (i3 < i4) || (i1 != i2) && (i4 <= i3);\n" // + + " boolean newBoolean5 = (i1 == i2 && i3 != i4) || (i2 != i1 && i3 == i4);\n" // + " }\n" // + "\n" // + " public void replaceDuplicateConditionsWithFields() {\n" // @@ -11545,6 +12104,7 @@ public void testStrictlyEqualOrDifferent() throws Exception { + " boolean newBoolean2 = (i1 == i2) == (i3 <= i4);\n" // + " boolean newBoolean3 = (i1 == i2) == (i3 != i4);\n" // + " boolean newBoolean4 = (i1 == i2) == (i3 < i4);\n" // + + " boolean newBoolean5 = (i1 == i2) == (i3 != i4);\n" // + " }\n" // + "\n" // + " public void replaceDuplicateConditionsWithFields() {\n" // @@ -16853,13 +17413,14 @@ public void testOverriddenAssignment() throws Exception { + " public boolean removeUselessInitialization() {\n" // + " // Keep this comment\n" // + " boolean reassignedVar = true;\n" // - + " reassignedVar = \"\\n\".equals(File.pathSeparator);\n" // + + " reassignedVar = \"\\n\".equals(File.pathSeparator);//$NON-NLS-1\n" // + " return reassignedVar;\n" // + " }\n" // + "\n" // + " public long removeInitForLong() {\n" // + " // Keep this comment\n" // + " long reassignedVar = 0;\n" // + + " System.out.println();\n" // + " reassignedVar = System.currentTimeMillis();\n" // + " return reassignedVar;\n" // + " }\n" // @@ -16867,6 +17428,7 @@ public void testOverriddenAssignment() throws Exception { + " public String removeInitForString() {\n" // + " // Keep this comment\n" // + " String reassignedVar = \"\";\n" // + + " System.out.println();\n" // + " reassignedVar = File.pathSeparator;\n" // + " return reassignedVar;\n" // + " }\n" // @@ -16877,10 +17439,58 @@ public void testOverriddenAssignment() throws Exception { + " reassignedPassiveVar = \"\\n\".equals(File.pathSeparator);\n" // + " return reassignedPassiveVar;\n" // + " }\n" // + + "\n" // + + " public long moveDeclOnlyIfEnabled() {\n" // + + " // comment 1\n" // + + " long time = 0;\n" // + + " // comment 2\n" // + + " String separator = \"\";\n" // + + " separator = System.lineSeparator();\n" // + + " // comment 3\n" // + + " time = System.currentTimeMillis();\n" // + + " return time;\n" // + + " }\n" // + + "\n" // + + " public void complexMoves(String str) {\n" // + + " // t is a String\n" // + + " String t = null;\n" // + + " // s is a String\n" // + + " String s = null;\n" // + + " // No move for multiple declarations\n" // + + " String v = \"ppp\", w = \"qqq\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " // No move for multiple statements on line\n" // + + " String k = \"rrr\"; String l = \"sss\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " int j = 7;\n" // + + " // this comment will get lost\n" // + + " s = /* abc */ \"def\" + //$NON-NLS-1$\n" // + + " \"xyz\" +\n" // + + " \"ghi\"; //$NON-NLS-1$\n" // + + " j = 4 +\n" // + + " // some comment\n" // + + " 5 +\n" // + + " 6;\n" // + + " t = /* abc */ \"pqr\"; //$NON-NLS-1$\n" // + + " w = \"aaa\"; //$NON-NLS-1$\n" // + + " k = \"ttt\"; //$NON-NLS-1$\n" // + + " l = \"uuu\"; //$NON-NLS-1$\n" // + + " // No move when parent statement other than block is on same line\n" // + + " if (\"TRUE\".equals(str)) { var x= \"bar\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " x = v;\n" // + + " System.out.println(x);\n" // + + " }\n" // + + " System.out.println(j);\n" // + + " System.out.println(k);\n" // + + " System.out.println(l);\n" // + + " System.out.println(s);\n" // + + " System.out.println(t);\n" // + + " System.out.println(w);\n" // + + " }\n" // + "}\n"; ICompilationUnit cu= pack.createCompilationUnit("E.java", input, false, null); enable(CleanUpConstants.OVERRIDDEN_ASSIGNMENT); + disable(CleanUpConstants.OVERRIDDEN_ASSIGNMENT_MOVE_DECL); + disable(CleanUpConstants.REMOVE_REDUNDANT_SEMICOLONS); String output= "" // + "package test1;\n" // @@ -16890,30 +17500,359 @@ public void testOverriddenAssignment() throws Exception { + "public class E {\n" // + " public boolean removeUselessInitialization() {\n" // + " // Keep this comment\n" // - + " boolean reassignedVar;\n" // - + " reassignedVar = \"\\n\".equals(File.pathSeparator);\n" // + + " boolean reassignedVar = \"\\n\".equals(File.pathSeparator);//$NON-NLS-1\n" // + " return reassignedVar;\n" // + " }\n" // + "\n" // + " public long removeInitForLong() {\n" // + " // Keep this comment\n" // + " long reassignedVar;\n" // + + " System.out.println();\n" // + + " reassignedVar = System.currentTimeMillis();\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "\n" // + + " public String removeInitForString() {\n" // + + " // Keep this comment\n" // + + " String reassignedVar = File.pathSeparator;\n" // + + " System.out.println();\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "\n" // + + " public boolean removePassiveInitialization(int i) {\n" // + + " // Keep this comment\n" // + + " boolean reassignedPassiveVar = \"\\n\".equals(File.pathSeparator);\n" // + + " return reassignedPassiveVar;\n" // + + " }\n" // + + "\n" // + + " public long moveDeclOnlyIfEnabled() {\n" // + + " // comment 1\n" // + + " long time;\n" // + + " // comment 2\n" // + + " String separator = System.lineSeparator();\n" // + + " // comment 3\n" // + + " time = System.currentTimeMillis();\n" // + + " return time;\n" // + + " }\n" // + + "\n" // + + " public void complexMoves(String str) {\n" // + + " // t is a String\n" // + + " String t = /* abc */ \"pqr\"; //$NON-NLS-1$\n" // + + " // s is a String\n" // + + " String s = /* abc */ \"def\" + //$NON-NLS-1$\n" // + + " \"xyz\" +\n" // + + " \"ghi\"; //$NON-NLS-1$\n" // + + " // No move for multiple declarations\n" // + + " String v = \"ppp\", w = \"qqq\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " // No move for multiple statements on line\n" // + + " String k = \"rrr\"; String l = \"sss\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " int j = 4 +\n" // + + " \t // some comment\n" // + + " \t 5 +\n" // + + " \t 6;\n" // + + " w = \"aaa\"; //$NON-NLS-1$\n" // + + " k = \"ttt\"; //$NON-NLS-1$\n" // + + " l = \"uuu\"; //$NON-NLS-1$\n" // + + " // No move when parent statement other than block is on same line\n" // + + " if (\"TRUE\".equals(str)) { var x= \"bar\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " x = v;\n" // + + " System.out.println(x);\n" // + + " }\n" // + + " System.out.println(j);\n" // + + " System.out.println(k);\n" // + + " System.out.println(l);\n" // + + " System.out.println(s);\n" // + + " System.out.println(t);\n" // + + " System.out.println(w);\n" // + + " }\n" // + + "}\n"; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { output }, + new HashSet<>(Arrays.asList(MultiFixMessages.OverriddenAssignmentCleanUp_description))); + + input= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class F {\n" // + + " public boolean removeUselessInitialization() {\n" // + + " // Keep this comment\n" // + + " boolean reassignedVar = true;\n" // + + " reassignedVar = \"\\n\".equals(File.pathSeparator);//$NON-NLS-1\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "\n" // + + " public long removeInitForLong() {\n" // + + " // This comment will be lost\n" // + + " long reassignedVar = 0;\n" // + + " System.out.println();\n" // + + " // Keep this comment\n" // + " reassignedVar = System.currentTimeMillis();\n" // + " return reassignedVar;\n" // + " }\n" // + "\n" // - + " public String removeInitForString() {\n" // - + " // Keep this comment\n" // - + " String reassignedVar;\n" // - + " reassignedVar = File.pathSeparator;\n" // - + " return reassignedVar;\n" // + + " public String removeInitForString() {\n" // + + " // Keep this comment\n" // + + " String reassignedVar = \"\";\n" // + + " System.out.println();\n" // + + " reassignedVar = File.pathSeparator;\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "\n" // + + " public boolean removePassiveInitialization(int i) {\n" // + + " // Keep this comment\n" // + + " boolean reassignedPassiveVar = i > 0;\n" // + + " reassignedPassiveVar = \"\\n\".equals(File.pathSeparator);\n" // + + " return reassignedPassiveVar;\n" // + + " }\n" // + + "\n" // + + " public long moveDeclOnlyIfEnabled() {\n" // + + " // comment 1\n" // + + " long time = 0;\n" // + + " // comment 2\n" // + + " String separator = \"\";\n" // + + " separator = System.lineSeparator();\n" // + + " System.out.println(separator);\n" // + + " // comment 3\n" // + + " time = System.currentTimeMillis();\n" // + + " return time;\n" // + + " }\n" // + + "\n" // + + " public void complexMoves(String str) {\n" // + + " // t is a String\n" // + + " String t = null;\n" // + + " // s is a String\n" // + + " String s = null;\n" // + + " // No move for multiple declarations\n" // + + " String v = \"ppp\", w = \"qqq\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " // No move for multiple statements on line\n" // + + " String k = \"rrr\"; String l = \"sss\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " int j = 7;\n" // + + " // this comment will get lost\n" // + + " s = /* abc */ \"def\" + //$NON-NLS-1$\n" // + + " \"xyz\" +\n" // + + " \"ghi\"; //$NON-NLS-1$\n" // + + " j = 4 +\n" // + + " // some comment\n" // + + " 5 +\n" // + + " 6;\n" // + + " t = /* abc */ \"pqr\"; //$NON-NLS-1$\n" // + + " w = \"aaa\"; //$NON-NLS-1$\n" // + + " k = \"ttt\"; //$NON-NLS-1$\n" // + + " l = \"uuu\"; //$NON-NLS-1$\n" // + + " // No move when parent statement other than block is on same line\n" // + + " if (\"TRUE\".equals(str)) { var x= \"bar\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " x = v;\n" // + + " System.out.println(x);\n" // + + " }\n" // + + " System.out.println(j);\n" // + + " System.out.println(k);\n" // + + " System.out.println(l);\n" // + + " System.out.println(s);\n" // + + " System.out.println(t);\n" // + + " System.out.println(w);\n" // + + " }\n" // + + "}\n"; + cu= pack.createCompilationUnit("F.java", input, false, null); + + enable(CleanUpConstants.OVERRIDDEN_ASSIGNMENT_MOVE_DECL); + enable(CleanUpConstants.REMOVE_REDUNDANT_SEMICOLONS); + + output= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class F {\n" // + + " public boolean removeUselessInitialization() {\n" // + + " // Keep this comment\n" // + + " boolean reassignedVar = \"\\n\".equals(File.pathSeparator);//$NON-NLS-1\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "\n" // + + " public long removeInitForLong() {\n" // + + " System.out.println();\n" // + + " // Keep this comment\n" // + + " long reassignedVar = System.currentTimeMillis();\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "\n" // + + " public String removeInitForString() {\n" // + + " // Keep this comment\n" // + + " String reassignedVar = File.pathSeparator;\n" // + + " System.out.println();\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "\n" // + + " public boolean removePassiveInitialization(int i) {\n" // + + " // Keep this comment\n" // + + " boolean reassignedPassiveVar = \"\\n\".equals(File.pathSeparator);\n" // + + " return reassignedPassiveVar;\n" // + + " }\n" // + + "\n" // + + " public long moveDeclOnlyIfEnabled() {\n" // + + " \n" // + + " // comment 2\n" // + + " String separator = System.lineSeparator();\n" // + + " System.out.println(separator);\n" // + + " // comment 3\n" // + + " long time = System.currentTimeMillis();\n" // + + " return time;\n" // + + " }\n" // + + "\n" // + + " public void complexMoves(String str) {\n" // + + " // t is a String\n" // + + " String t = /* abc */ \"pqr\"; //$NON-NLS-1$\n" // + + " // s is a String\n" // + + " String s = /* abc */ \"def\" + //$NON-NLS-1$\n" // + + " \"xyz\" +\n" // + + " \"ghi\"; //$NON-NLS-1$\n" // + + " // No move for multiple declarations\n" // + + " String v = \"ppp\", w = \"qqq\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " // No move for multiple statements on line\n" // + + " String k = \"rrr\"; String l = \"sss\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " int j = 4 +\n" // + + " \t // some comment\n" // + + " \t 5 +\n" // + + " \t 6;\n" // + + " w = \"aaa\"; //$NON-NLS-1$\n" // + + " k = \"ttt\"; //$NON-NLS-1$\n" // + + " l = \"uuu\"; //$NON-NLS-1$\n" // + + " // No move when parent statement other than block is on same line\n" // + + " if (\"TRUE\".equals(str)) { var x= \"bar\"; //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " x = v;\n" // + + " System.out.println(x);\n" // + + " }\n" // + + " System.out.println(j);\n" // + + " System.out.println(k);\n" // + + " System.out.println(l);\n" // + + " System.out.println(s);\n" // + + " System.out.println(t);\n" // + + " System.out.println(w);\n" // + + " }\n" // + + "}\n"; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { output }, + new HashSet<>(Arrays.asList(MultiFixMessages.OverriddenAssignmentCleanUp_description))); + } + + @Test + public void testDoNotMoveAssignment() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); + String input= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E1 {\n" // + + " public boolean dontMoveForNestedReassignement() {\n" // + + " boolean reassignedVar= true;\n" // + + " if (System.lineSeparator()) {\n" // + + " reassignedVar = false;\n" // + + " }\n" // + + " reassignedVar = \"\\n\".equals(File.pathSeparator);\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("E1.java", input, false, null); + + enable(CleanUpConstants.OVERRIDDEN_ASSIGNMENT); + enable(CleanUpConstants.OVERRIDDEN_ASSIGNMENT_MOVE_DECL); + disable(CleanUpConstants.REMOVE_REDUNDANT_SEMICOLONS); + + String output= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E1 {\n" // + + " public boolean dontMoveForNestedReassignement() {\n" // + + " boolean reassignedVar;\n" // + + " if (System.lineSeparator()) {\n" // + + " reassignedVar = false;\n" // + + " }\n" // + + " reassignedVar = \"\\n\".equals(File.pathSeparator);\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "}\n"; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { output }, + new HashSet<>(Arrays.asList(MultiFixMessages.OverriddenAssignmentCleanUp_description))); + + input= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E2 {\n" // + + " public boolean dontMoveForUndefinedVarst() {\n" // + + " boolean reassignedVar= true;\n" // + + " String pathSep= File.pathSeparator;\n" // + + " reassignedVar = \"\\n\".equals(pathSep);\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "}\n"; + cu= pack.createCompilationUnit("E2.java", input, false, null); + + enable(CleanUpConstants.OVERRIDDEN_ASSIGNMENT); + disable(CleanUpConstants.OVERRIDDEN_ASSIGNMENT_MOVE_DECL); + disable(CleanUpConstants.REMOVE_REDUNDANT_SEMICOLONS); + + output= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E2 {\n" // + + " public boolean dontMoveForUndefinedVarst() {\n" // + + " boolean reassignedVar;\n" // + + " String pathSep= File.pathSeparator;\n" // + + " reassignedVar = \"\\n\".equals(pathSep);\n" // + + " return reassignedVar;\n" // + + " }\n" // + + "}\n"; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { output }, + new HashSet<>(Arrays.asList(MultiFixMessages.OverriddenAssignmentCleanUp_description))); + } + + @Test + public void testDontMoveUpOverriddenAssignment() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); + String input= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public boolean dontMoveUpIfUsingUndefined() {\n" // + + " int totalHeight = 0;\n" //; + + " int innerHeight = 0;\n" // + + " int topMargin= 0;\n" // + + " int bottomMargin = 0;\n" // + + " totalHeight = topMargin + innerHeight + bottomMargin;\n" // + + " return true;\n" // + " }\n" // + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("E.java", input, false, null); + + enable(CleanUpConstants.OVERRIDDEN_ASSIGNMENT); + disable(CleanUpConstants.OVERRIDDEN_ASSIGNMENT_MOVE_DECL); + + String output= "" // + + "package test1;\n" // + "\n" // - + " public boolean removePassiveInitialization(int i) {\n" // - + " // Keep this comment\n" // - + " boolean reassignedPassiveVar;\n" // - + " reassignedPassiveVar = \"\\n\".equals(File.pathSeparator);\n" // - + " return reassignedPassiveVar;\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public boolean dontMoveUpIfUsingUndefined() {\n" // + + " int totalHeight;\n" //; + + " int innerHeight = 0;\n" // + + " int topMargin= 0;\n" // + + " int bottomMargin = 0;\n" // + + " totalHeight = topMargin + innerHeight + bottomMargin;\n" // + + " return true;\n" // + " }\n" // + "}\n"; @@ -17737,6 +18676,17 @@ public void testReduceIndentation() throws Exception { + " return -1;\n" // + " }\n" // + "\n" // + + " public int reduceWithUnbrackettedThenAndParent(boolean isValid, boolean isActive) {\n" // + + " if (isValid)\n" // + + " if (isActive)\n" // + + " return 0; // This kind of comment is correctly handled\n" // + + " else {\n" // + + " System.out.println(\"Valid and active\");\n" // + + " }\n" // + + "\n" // + + " return -1;\n" // + + " }\n" // + + "\n" // + " public int refactorElseInSwitch(int discriminant, boolean isVisible) {\n" // + " switch (discriminant) {\n" // + " case 0:\n" // @@ -17883,6 +18833,16 @@ public void testReduceIndentation() throws Exception { + " } else {\n" // + " }\n" // + " }\n" // + + "\n" // + + " public void refactorNegativeCondition(Date date) {\n" // + + " // Keep this comment\n" // + + " if (!(date != null)) {\n" // + + " System.out.println(\"null args: we should not be here\");\n" // + + " } else {\n" // + + " return;\n" // + + " }\n" // + + " return;\n" // + + " }\n" // + "}\n"; String expected= "" // @@ -18044,6 +19004,16 @@ public void testReduceIndentation() throws Exception { + " return -1;\n" // + " }\n" // + "\n" // + + " public int reduceWithUnbrackettedThenAndParent(boolean isValid, boolean isActive) {\n" // + + " if (isValid) {\n" // + + " if (isActive)\n" // + + " return 0; // This kind of comment is correctly handled\n" // + + " System.out.println(\"Valid and active\");\n" // + + " }\n" // + + "\n" // + + " return -1;\n" // + + " }\n" // + + "\n" // + " public int refactorElseInSwitch(int discriminant, boolean isVisible) {\n" // + " switch (discriminant) {\n" // + " case 0:\n" // @@ -18180,6 +19150,15 @@ public void testReduceIndentation() throws Exception { + " return;\n" // + " }\n" // + " }\n" // + + "\n" // + + " public void refactorNegativeCondition(Date date) {\n" // + + " // Keep this comment\n" // + + " if (date != null) {\n" // + + " return;\n" // + + " }\n" // + + " System.out.println(\"null args: we should not be here\");\n" // + + " return;\n" // + + " }\n" // + "}\n"; // When @@ -18244,6 +19223,16 @@ public void testDoNotReduceIndentation() throws Exception { + "\n" // + " return i;\n" // + " }\n" // + + "\n" // + + " public int doNotRefactorWithUnbrackettedNodeAndParent(boolean isValid, boolean isActive) {\n" // + + " if (isValid)\n" // + + " if (isActive) {\n" // + + " System.out.println(\"Valid and active\");\n" // + + " } else\n" // + + " return 0; // This kind of comment is badly handled\n" // + + "\n" // + + " return -1;\n" // + + " }\n" // + "}\n"; ICompilationUnit cu= pack.createCompilationUnit("E.java", sample, false, null); @@ -18391,6 +19380,58 @@ public void testAddParentheses02() throws Exception { assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); } + @Test + public void testAddParenthesesBug578081() throws Exception { + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "public class E {\n" // + + " void foo(int i) {\n" // + + " if (i == 0 || i == 1 /* i is 0 or 1 */) // if comment\n" // + + " /* additional if comment */\n" + + " System.out.println(i);\n" // + + " \n" // + + " while (i > 0 && i < 10 /* i gt 0 and lt 10 */) // while comment\n" // + + " /* additional while comment */\n" + + " System.out.println(1);\n" // + + " \n" // + + " boolean b= i != -1 && i > 10 && i < 100 || i > 20;\n" // + + " \n" // + + " do ; while (i > 5 && b || i < 100 && i > 90);\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_USE_BLOCKS); + enable(CleanUpConstants.CONTROL_STATEMENTS_USE_BLOCKS_ALWAYS); + + sample= "" // + + "package test1;\n" // + + "public class E {\n" // + + " void foo(int i) {\n" // + + " if (i == 0 || i == 1 /* i is 0 or 1 */) { // if comment\n" // + + " \t/* additional if comment */\n" + + " \tSystem.out.println(i);\n" // + + " }\n" // + + " \n" // + + " while (i > 0 && i < 10 /* i gt 0 and lt 10 */) { // while comment\n" // + + " \t/* additional while comment */\n" + + " \tSystem.out.println(1);\n" // + + " }\n" // + + " \n" // + + " boolean b= i != -1 && i > 10 && i < 100 || i > 20;\n" // + + " \n" // + + " do {\n" // + + " ;\n" // + + " } while (i > 5 && b || i < 100 && i > 90);\n" // + + " }\n" // + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu1}, new String[] {expected1}, null); + } + @Test public void testRemoveParentheses01() throws Exception { @@ -21105,7 +22146,24 @@ public void testStaticInnerClass() throws Exception { + "import java.util.jar.Attributes.Name;\n" // + "import java.util.List;\n" // + "\n" // - + "public class E {\n" // + + "public final class E {\n" // + + " public RefactorThisInnerClass keepInnerInstanciation() {\n" // + + " return new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public RefactorThisInnerClass rewriteInnerInstanciation() {\n" // + + " return this.new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public RefactorThisInnerClass rewriteQualifiedInnerInstanciation() {\n" // + + " return test1.E.this.new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public static RefactorThisInnerClass rewriteInnerInstanciationOnTopLevelObject() {\n" // + + " E object = new E();\n" // + + " return object.new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + " public class RefactorThisInnerClass {\n" // + " int i;\n" // + "\n" // @@ -21307,7 +22365,24 @@ public void testStaticInnerClass() throws Exception { + "import java.util.jar.Attributes.Name;\n" // + "import java.util.List;\n" // + "\n" // - + "public class E {\n" // + + "public final class E {\n" // + + " public RefactorThisInnerClass keepInnerInstanciation() {\n" // + + " return new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public RefactorThisInnerClass rewriteInnerInstanciation() {\n" // + + " return new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public RefactorThisInnerClass rewriteQualifiedInnerInstanciation() {\n" // + + " return new test1.E.RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public static RefactorThisInnerClass rewriteInnerInstanciationOnTopLevelObject() {\n" // + + " E object = new E();\n" // + + " return new test1.E.RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + " public static class RefactorThisInnerClass {\n" // + " int i;\n" // + "\n" // @@ -21508,6 +22583,118 @@ public void testStaticInnerClass() throws Exception { new HashSet<>(Arrays.asList(MultiFixMessages.StaticInnerClassCleanUp_description))); } + @Test + public void testStaticInnerClassOnGenricTopLevelClass() throws Exception { + // Given + IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); + String given= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public RefactorThisInnerClass rewriteInnerInstanciationOnTopLevelObject(E parameterizedObject) {\n" // + + " return parameterizedObject.new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " private class RefactorThisInnerClass {\n" // + + " int i;\n" // + + "\n" // + + " public boolean anotherMethod() {\n" // + + " return true;\n" // + + " }\n" // + + " }\n" // + + "}\n"; + + String expected= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public RefactorThisInnerClass rewriteInnerInstanciationOnTopLevelObject(E parameterizedObject) {\n" // + + " return new test1.E.RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " private static class RefactorThisInnerClass {\n" // + + " int i;\n" // + + "\n" // + + " public boolean anotherMethod() {\n" // + + " return true;\n" // + + " }\n" // + + " }\n" // + + "}\n"; + + // When + ICompilationUnit cu= pack.createCompilationUnit("E.java", given, false, null); + enable(CleanUpConstants.STATIC_INNER_CLASS); + + // Then + assertNotEquals("The class must be changed", given, expected); + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(MultiFixMessages.StaticInnerClassCleanUp_description))); + } + + @Test + public void testStaticInnerClassOnPrivateInnerClass() throws Exception { + // Given + IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); + String given= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public RefactorThisInnerClass keepInnerInstanciation() {\n" // + + " return new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public RefactorThisInnerClass rewriteInnerInstanciation() {\n" // + + " return this.new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public RefactorThisInnerClass rewriteQualifiedInnerInstanciation() {\n" // + + " return test1.E.this.new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " private class RefactorThisInnerClass {\n" // + + " int i;\n" // + + "\n" // + + " public boolean anotherMethod() {\n" // + + " return true;\n" // + + " }\n" // + + " }\n" // + + "}\n"; + + String expected= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public RefactorThisInnerClass keepInnerInstanciation() {\n" // + + " return new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public RefactorThisInnerClass rewriteInnerInstanciation() {\n" // + + " return new RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " public RefactorThisInnerClass rewriteQualifiedInnerInstanciation() {\n" // + + " return new test1.E.RefactorThisInnerClass();\n" // + + " }\n" // + + "\n" // + + " private static class RefactorThisInnerClass {\n" // + + " int i;\n" // + + "\n" // + + " public boolean anotherMethod() {\n" // + + " return true;\n" // + + " }\n" // + + " }\n" // + + "}\n"; + + // When + ICompilationUnit cu= pack.createCompilationUnit("E.java", given, false, null); + enable(CleanUpConstants.STATIC_INNER_CLASS); + + // Then + assertNotEquals("The class must be changed", given, expected); + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(MultiFixMessages.StaticInnerClassCleanUp_description))); + } + @Test public void testDoNotUseStaticInnerClass() throws Exception { IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); @@ -21517,7 +22704,7 @@ public void testDoNotUseStaticInnerClass() throws Exception { + "import java.sql.DriverPropertyInfo;\n" // + "import org.junit.jupiter.api.Nested;\n" // + "\n" // - + "public class E {\n" // + + "public final class E {\n" // + " public interface DoNotRefactorInnerInterface {\n" // + " boolean anotherMethod();\n" // + " }\n" // @@ -21636,6 +22823,26 @@ public void testDoNotUseStaticInnerClass() throws Exception { assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); } + @Test + public void testDoNotUseStaticInnerClassOnNotFinalTopLevelClass() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public class DoNotRefactorInnerInheritableClass {\n" // + + " boolean anotherMethod() {\n" // + + " return true;\n" // + + " }\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.STATIC_INNER_CLASS); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + @Test public void testDoNotUseStaticInnerClassOnInterface() throws Exception { IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); @@ -27242,6 +28449,20 @@ public void testConstantsForSystemProperty() throws Exception { + " System.out.println(\"out:\"+lsp); //$NON-NLS-1$\n" // + " Boolean value = Boolean.parseBoolean(System.getProperty(\"arbitrarykey\")); //$NON-NLS-1$\n" // + " System.out.println(\"out:\"+value); //$NON-NLS-1$\n" // + + " Boolean value2 = Boolean.parseBoolean(System.getProperty(\"arbitrarykey\",\"false\")); //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " System.out.println(\"out:\"+value2); //$NON-NLS-1$\n" // + + " Integer intvalue = Integer.parseInt(System.getProperty(\"arbitrarykey\")); //$NON-NLS-1$\n" // + + " System.out.println(\"out:\"+intvalue); //$NON-NLS-1$\n" // + + " Integer intvalue2 = Integer.parseInt(System.getProperty(\"arbitrarykey\",\"0\")); //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " System.out.println(\"out:\"+intvalue2); //$NON-NLS-1$\n" // + + " Integer intvalue3 = Integer.parseInt(System.getProperty(\"arbitrarykey\",\"15\")); //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " System.out.println(\"out:\"+intvalue3); //$NON-NLS-1$\n" // + + " Long longvalue = Long.parseLong(System.getProperty(\"arbitrarykey\")); //$NON-NLS-1$\n" // + + " System.out.println(\"out:\"+longvalue); //$NON-NLS-1$\n" // + + " Long longvalue2 = Long.parseLong(System.getProperty(\"arbitrarykey\",\"0\")); //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " System.out.println(\"out:\"+longvalue2); //$NON-NLS-1$\n" // + + " Long longvalue3 = Long.parseLong(System.getProperty(\"arbitrarykey\",\"15\")); //$NON-NLS-1$ //$NON-NLS-2$\n" // + + " System.out.println(\"out:\"+longvalue3); //$NON-NLS-1$\n" // + " }\n" // + "}\n"; @@ -27265,6 +28486,20 @@ public void testConstantsForSystemProperty() throws Exception { + " System.out.println(\"out:\"+lsp); //$NON-NLS-1$\n" // + " Boolean value = Boolean.getBoolean(\"arbitrarykey\"); //$NON-NLS-1$\n" // + " System.out.println(\"out:\"+value); //$NON-NLS-1$\n" // + + " Boolean value2 = Boolean.getBoolean(\"arbitrarykey\"); //$NON-NLS-1$\n" // + + " System.out.println(\"out:\"+value2); //$NON-NLS-1$\n" // + + " Integer intvalue = Integer.getInteger(\"arbitrarykey\"); //$NON-NLS-1$\n" // + + " System.out.println(\"out:\"+intvalue); //$NON-NLS-1$\n" // + + " Integer intvalue2 = Integer.getInteger(\"arbitrarykey\"); //$NON-NLS-1$\n" // + + " System.out.println(\"out:\"+intvalue2); //$NON-NLS-1$\n" // + + " Integer intvalue3 = Integer.getInteger(\"arbitrarykey\", 15); //$NON-NLS-1$\n" // + + " System.out.println(\"out:\"+intvalue3); //$NON-NLS-1$\n" // + + " Long longvalue = Long.getLong(\"arbitrarykey\"); //$NON-NLS-1$\n" // + + " System.out.println(\"out:\"+longvalue); //$NON-NLS-1$\n" // + + " Long longvalue2 = Long.getLong(\"arbitrarykey\"); //$NON-NLS-1$\n" // + + " System.out.println(\"out:\"+longvalue2); //$NON-NLS-1$\n" // + + " Long longvalue3 = Long.getLong(\"arbitrarykey\", 15); //$NON-NLS-1$\n" // + + " System.out.println(\"out:\"+longvalue3); //$NON-NLS-1$\n" // + " }\n" // + "}\n"; @@ -27275,7 +28510,7 @@ public void testConstantsForSystemProperty() throws Exception { enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_PATH_SEPARATOR); enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_LINE_SEPARATOR); enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_FILE_ENCODING); - enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOOLEAN); + enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOXED); // Then assertNotEquals("The class must be changed", given, expected); @@ -27284,7 +28519,9 @@ public void testConstantsForSystemProperty() throws Exception { Messages.format(ConstantsCleanUp_description,UpdateProperty.PATH_SEPARATOR.toString()), Messages.format(ConstantsCleanUp_description,UpdateProperty.LINE_SEPARATOR.toString()), Messages.format(ConstantsCleanUp_description,UpdateProperty.FILE_ENCODING.toString()), - Messages.format(ConstantsCleanUp_description,UpdateProperty.BOOLEAN_PROPERTY.toString())))); + Messages.format(ConstantsCleanUp_description,UpdateProperty.BOOLEAN_PROPERTY.toString()), + Messages.format(ConstantsCleanUp_description,UpdateProperty.INTEGER_PROPERTY.toString()), + Messages.format(ConstantsCleanUp_description,UpdateProperty.LONG_PROPERTY.toString())))); } @Test @@ -27336,7 +28573,7 @@ public void testConstantsForSystemProperty_NLS() throws Exception { enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_PATH_SEPARATOR); enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_LINE_SEPARATOR); enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_FILE_ENCODING); - enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOOLEAN); + enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOXED); // Then assertNotEquals("The class must be changed", given, expected); @@ -27371,7 +28608,7 @@ public void testConstantsForSystemProperty_donttouch() throws Exception { enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_PATH_SEPARATOR); enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_LINE_SEPARATOR); enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_FILE_ENCODING); - enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOOLEAN); + enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOXED); // Then assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); @@ -27656,4 +28893,55 @@ public void testBug491087() throws Exception { Messages.format(FixMessages.CodeStyleFix_QualifyWithThis_description, new Object[] {"field", "this"}) }))); } + + @Test + public void testRemoveParenthesesBug438266_1() throws Exception { + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" + + "package test1;\n" // + + "public class E {\n" + + " public static void main(String[] args) {\n" + + " Integer b = (Integer) (-1);\n" + + " System.out.println(b);\n" + + " }\n" + + "}"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.EXPRESSIONS_USE_PARENTHESES); + enable(CleanUpConstants.EXPRESSIONS_USE_PARENTHESES_NEVER); + + String expected= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected }, null); + } + + @Test + public void testRemoveParenthesesBug438266_2() throws Exception { + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" + + "package test1;\n" // + + "public class E {\n" + + " public static void main(String[] args) {\n" + + " Integer b = (int) (-1);\n" + + " System.out.println(b);\n" + + " }\n" + + "}"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.EXPRESSIONS_USE_PARENTHESES); + enable(CleanUpConstants.EXPRESSIONS_USE_PARENTHESES_NEVER); + + String expected= "" + + "package test1;\n" // + + "public class E {\n" + + " public static void main(String[] args) {\n" + + " Integer b = (int) -1;\n" + + " System.out.println(b);\n" + + " }\n" + + "}"; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected }, null); + } } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest10.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest10.java index 482f6b33..07dbe452 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest10.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest10.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2021 Fabrice TIERCELIN and others. + * Copyright (c) 2020, 2022 Fabrice TIERCELIN and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * Fabrice TIERCELIN - initial API and implementation + * Christian Femers - Bug 579471 *******************************************************************************/ package org.eclipse.jdt.ui.tests.quickfix; @@ -712,4 +713,27 @@ public void testDoNotUseLocalVariableTypeForArrayInitialization() throws Excepti assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); } + + @Test + public void testDoNotUseCurlyBracesOnlyArrayInitializationForVar() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public void foo() {\n" // + + " var a = new String[0];\n" // + + " var b = new String[][]{ {\"a\", \"b\", \"c\"}, {\"d\", \"e\", \"f\"} };\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + /* + * As Array initialization requires and explicit target type, the code above must not change + * even if we activate the "Create array with curly if possible" cleanup. + */ + enable(CleanUpConstants.ARRAY_WITH_CURLY); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest12.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest12.java index 45ad9382..86a861b4 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest12.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest12.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 Red Hat Inc. and others. + * Copyright (c) 2020, 2022 Red Hat Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -453,6 +453,23 @@ public void testSwitch() throws Exception { + " return 155;\n" // + " }\n" // + "\n" // + + " public void replaceWhenVariableTypesConflict(int i1) {\n" // + + " int i = 0;\n" // + + " if (i1 == 0) {\n" // + + " int integer1 = 0;\n" // + + " i = integer1;\n" // + + " } else if (i1 == 2) {\n" // + + " char integer1 = 'a';\n" // + + " i = integer1;\n" // + + " } else if (i1 == 3) {\n" // + + " char c = 'a';\n" // + + " i = c;\n" // + + " } else {\n" // + + " char c = 'b';\n" // + + " i = c;\n" // + + " }\n" // + + " }\n" // + + "\n" // + " public int replaceMeltCases(int i1) {\n" // + " // Keep this comment\n" // + " if (i1 == 0) {\n" // @@ -760,7 +777,7 @@ public void testSwitch() throws Exception { + " case 0 :\n" // + " j = 0;\n" // + " break;\n" // - + " case 1 :\n" // + + " case 1 : {\n" // + " j = 10;\n" // + " short k = 0;\n" // + " do {\n" // @@ -770,6 +787,7 @@ public void testSwitch() throws Exception { + " k++;\n" // + " } while (k < j);\n" // + " break;\n" // + + " }\n" // + " case 2 :\n" // + " j = 20;\n" // + " for (short l = 0; l < j; l++) {\n" // @@ -778,7 +796,7 @@ public void testSwitch() throws Exception { + " }\n" // + " }\n" // + " break;\n" // - + " case 3 :\n" // + + " case 3 : {\n" // + " j = 25;\n" // + " j = 30;\n" // + " short m = 0;\n" // @@ -789,6 +807,7 @@ public void testSwitch() throws Exception { + " m++;\n" // + " }\n" // + " break;\n" // + + " }\n" // + " case 4 :\n" // + " j = 40;\n" // + " for (short o : new short[] { 1, 2, 3 }) {\n" // @@ -816,18 +835,21 @@ public void testSwitch() throws Exception { + " public void replaceIfWhenNoVariableNameConflictExists(int i1) {\n" // + " int i = 0;\n" // + " switch (i1) {\n" // - + " case 0 :\n" // + + " case 0 : {\n" // + " int newVariable1 = 0;\n" // + " i = newVariable1;\n" // + " break;\n" // - + " case 1 :\n" // + + " }\n" // + + " case 1 : {\n" // + " int newVariable2 = 10;\n" // + " i = newVariable2;\n" // + " break;\n" // - + " case 2 :\n" // + + " }\n" // + + " case 2 : {\n" // + " char newVariable3 = 'a';\n" // + " i = newVariable3;\n" // + " break;\n" // + + " }\n" // + " default :\n" // + " break;\n" // + " }\n" // @@ -842,14 +864,16 @@ public void testSwitch() throws Exception { + " i = integer1;\n" // + " }\n" // + " break;\n" // - + " case 1 :\n" // + + " case 1 : {\n" // + " int integer1 = 10;\n" // + " i = integer1;\n" // + " break;\n" // - + " case 2 :\n" // + + " }\n" // + + " case 2 : {\n" // + " int i2 = 20;\n" // + " i = i2;\n" // + " break;\n" // + + " }\n" // + " default :\n" // + " break;\n" // + " }\n" // @@ -978,6 +1002,32 @@ public void testSwitch() throws Exception { + " return 155;\n" // + " }\n" // + "\n" // + + " public void replaceWhenVariableTypesConflict(int i1) {\n" // + + " int i = 0;\n" // + + " switch (i1) {\n" // + + " case 0 : {\n" // + + " int integer1 = 0;\n" // + + " i = integer1;\n" // + + " break;\n" // + + " }\n" // + + " case 2 : {\n" // + + " char integer1 = 'a';\n" // + + " i = integer1;\n" // + + " break;\n" // + + " }\n" // + + " case 3 : {\n" // + + " char c = 'a';\n" // + + " i = c;\n" // + + " break;\n" // + + " }\n" // + + " default : {\n" // + + " char c = 'b';\n" // + + " i = c;\n" // + + " break;\n" // + + " }\n" // + + " }\n" // + + " }\n" // + + "\n" // + " public int replaceMeltCases(int i1) {\n" // + " // Keep this comment\n" // + " switch (i1) {\n" // @@ -1051,34 +1101,6 @@ public void testDoNotUseSwitch() throws Exception { + " }\n" // + " }\n" // + "\n" // - + " public void doNotReplaceWhenVariableNameConflicts(int number) {\n" // - + " int i = 0;\n" // - + " if (number == 0) {\n" // - + " int integer1 = 0;\n" // - + " i = integer1;\n" // - + " } else if (number == 1) {\n" // - + " int integer1 = 10;\n" // - + " i = integer1;\n" // - + " } else if (number == 2) {\n" // - + " int i2 = 20;\n" // - + " i = i2;\n" // - + " }\n" // - + " }\n" // - + "\n" // - + " public void doNotReplaceWhenVariableTypesConflict(int i1) {\n" // - + " int i = 0;\n" // - + " if (i1 == 0) {\n" // - + " int integer1 = 0;\n" // - + " i = integer1;\n" // - + " } else if (i1 == 2) {\n" // - + " char integer1 = 'a';\n" // - + " i = integer1;\n" // - + " } else if (i1 == 3) {\n" // - + " char c = 'a';\n" // - + " i = c;\n" // - + " }\n" // - + " }\n" // - + "\n" // + " public void doNotReplaceIfWithoutElseIf(int i1) {\n" // + " int i = 0;\n" // + " if (i1 == 0) {\n" // diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest14.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest14.java index 910ade92..9f78d99a 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest14.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest14.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2021 Red Hat Inc. and others. + * Copyright (c) 2020, 2022 Red Hat Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -259,6 +259,7 @@ public void testConvertToSwitchExpressionEnumsNoDefault() throws Exception { assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); } + @Test public void testConvertToSwitchExpressionBug574824() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); @@ -309,6 +310,387 @@ public void testConvertToSwitchExpressionBug574824() throws Exception { assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); } + @Test + public void testConvertToSwitchExpressionBug578130() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public void foo(String[] args) throws Exception {\n" // + + " boolean isWhiteSpace;\n" // + + " switch (args[0].charAt(0)) {\n" // + + " case 10: /* \\ u000a: LINE FEED */\n" // + + " case 12: /* \\ u000c: FORM FEED */\n" // + + " case 13: /* \\ u000d: CARRIAGE RETURN */\n" // + + " case 32: /* \\ u0020: SPACE */\n" // + + " case 9: /* \\ u0009: HORIZONTAL TABULATION */\n" // + + " isWhiteSpace = true; /* comment x */\n" // + + " break;\n" // + + " case 0:\n" // + + " throw new Exception(\"invalid char\"); //$NON-NLS-1$\n" // + + " case 95:\n" // + + " {\n" // + + " System.out.println(\"here\"); //$NON-NLS-1$\n" // + + " isWhiteSpace = false;\n" // + + " }\n" // + + " break;\n" // + + " default:\n" // + + " isWhiteSpace = false;\n" // + + " }\n" // + + " System.out.println(isWhiteSpace);\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS); + + sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public void foo(String[] args) throws Exception {\n" // + + " boolean isWhiteSpace = switch (args[0].charAt(0)) {\n" // + + " case 10: /* \\ u000a: LINE FEED */\n" // + + " case 12: /* \\ u000c: FORM FEED */\n" // + + " case 13: /* \\ u000d: CARRIAGE RETURN */\n" // + + " case 32: /* \\ u0020: SPACE */\n" // + + " case 9: /* \\ u0009: HORIZONTAL TABULATION */\n" // + + " yield true; /* comment x */\n" // + + " case 0:\n" // + + " throw new Exception(\"invalid char\"); //$NON-NLS-1$\n" // + + " case 95: {\n" // + + " System.out.println(\"here\"); //$NON-NLS-1$\n" // + + " yield false;\n" // + + " }\n" // + + " default:\n" // + + " yield false;\n" // + + " };\n" // + + " System.out.println(isWhiteSpace);\n" // + + " }\n" // + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); + } + + @Test + public void testConvertToSwitchExpressionBug578129_1() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public void foo(String[] args) throws Exception {\n" // + + " boolean isWhiteSpace;\n" // + + " switch (args[0].charAt(0)) {\n" // + + " case 10:\n" // + + " case 12:\n" // + + " case 13:\n" // + + " case 32:\n" // + + " case 9:\n" // + + " isWhiteSpace = true; /* comment x */\n" // + + " break;\n" // + + " case 0:\n" // + + " throw new Exception(\"invalid char\"); //$NON-NLS-1$\n" // + + " case 95:\n" // + + " default:\n" // + + " isWhiteSpace = false;\n" // + + " }\n" // + + " System.out.println(isWhiteSpace);\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS); + + sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public void foo(String[] args) throws Exception {\n" // + + " boolean isWhiteSpace = switch (args[0].charAt(0)) {\n" // + + " case 10, 12, 13, 32, 9 -> true; /* comment x */\n" // + + " case 0 -> throw new Exception(\"invalid char\"); //$NON-NLS-1$\n" // + + " case 95 -> false;\n" // + + " default -> false;\n" // + + " };\n" // + + " System.out.println(isWhiteSpace);\n" // + + " }\n" // + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); + } + + @Test + public void testConvertToSwitchExpressionBug578129_2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public void foo(String[] args) throws Exception {\n" // + + " boolean isWhiteSpace;\n" // + + " switch (args[0].charAt(0)) {\n" // + + " case 10:\n" // + + " case 12:\n" // + + " case 13:\n" // + + " case 32:\n" // + + " case 9:\n" // + + " // comment 1\n" + + " isWhiteSpace = true; /* comment x */\n" // + + " break;\n" // + + " case 0:\n" // + + " throw new Exception(\"invalid char\"); //$NON-NLS-1$\n" // + + " case 95:\n" // + + " default: {\n" // + + " System.out.println(\"non-whitespace\");\n" // + + " isWhiteSpace = false;\n" // + + " }\n" // + + " }\n" // + + " System.out.println(isWhiteSpace);\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS); + + sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public void foo(String[] args) throws Exception {\n" // + + " boolean isWhiteSpace = switch (args[0].charAt(0)) {\n" // + + " case 10, 12, 13, 32, 9 -> /* comment 1 */ true; /* comment x */\n" // + + " case 0 -> throw new Exception(\"invalid char\"); //$NON-NLS-1$\n" // + + " case 95 -> {\n" // + + " System.out.println(\"non-whitespace\");\n" // + + " yield false;\n" // + + " }\n" // + + " default -> {\n" // + + " System.out.println(\"non-whitespace\");\n" // + + " yield false;\n" // + + " }\n" // + + " };\n" // + + " System.out.println(isWhiteSpace);\n" // + + " }\n" // + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); + } + + @Test + public void testConvertToReturnSwitchExpressionIssue104_1() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public enum InnerEnum {\n" + + " A, B, C, D;\n" + + " }\n" + + " public int foo(InnerEnum k) {\n" + + " switch (k) {\n" + + " case A:\n" + + " case B:\n" + + " /* comment 1 */\n" + + " return 6; /* abc */\n" + + " case C: {\n" + + " System.out.println(\"x\"); //$NON-NLS-1$\n" + + " /* comment 2 */\n" + + " return 8; /* def */\n" + + " }\n" + + " case D:\n" + + " // comment 3\n" + + " return 9;\n" + + " default:\n" + + " throw new NullPointerException();\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS); + + sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public enum InnerEnum {\n" + + " A, B, C, D;\n" + + " }\n" + + " public int foo(InnerEnum k) {\n" + + " return switch (k) {\n" + + " case A, B -> /* comment 1 */ 6; /* abc */\n" + + " case C -> {\n" + + " System.out.println(\"x\"); //$NON-NLS-1$\n" + + " /* comment 2 */\n" + + " yield 8; /* def */\n" + + " }\n" + + " case D -> /* comment 3 */ 9;\n" + + " default -> throw new NullPointerException();\n" + + " };\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); + } + + @Test + public void testConvertToReturnSwitchExpressionIssue104_2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public enum InnerEnum {\n" + + " A, B, C, D;\n" + + " }\n" + + " public int foo(InnerEnum k) {\n" + + " switch (k) {\n" + + " case A:\n" + + " case B:\n" + + " /* comment 1 */\n" + + " return 6; /* abc */\n" + + " case C:\n" + + " System.out.println(\"x\"); //$NON-NLS-1$\n" + + " /* comment 2 */\n" + + " return 8; /* def */\n" + + " case D:\n" + + " return 9;\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS); + + sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public enum InnerEnum {\n" + + " A, B, C, D;\n" + + " }\n" + + " public int foo(InnerEnum k) {\n" + + " return switch (k) {\n" + + " case A, B -> /* comment 1 */ 6; /* abc */\n" + + " case C -> {\n" + + " System.out.println(\"x\"); //$NON-NLS-1$\n" + + " /* comment 2 */\n" + + " yield 8; /* def */\n" + + " }\n" + + " case D -> 9;\n" + + " };\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); + } + + @Test + public void testDoNotConvertToReturnSwitchExpressionIssue104_1() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public enum InnerEnum {\n" + + " A, B, C, D;\n" + + " }\n" + + " public int foo(InnerEnum k) {\n" + + " switch (k) {\n" + + " case A:\n" + + " System.out.println(\"a\");\n" + + " case B:\n" + + " /* comment 1 */\n" + + " return 6; /* abc */\n" + + " case C: {\n" + + " System.out.println(\"x\"); //$NON-NLS-1$\n" + + " /* comment 2 */\n" + + " return 8; /* def */\n" + + " }\n" + + " case D:\n" + + " return 9;\n" + + " default:\n" + + " throw new NullPointerException();\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } + + @Test + public void testDoNotConvertToReturnSwitchExpressionIssue104_2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "import java.io.File;\n" // + + "\n" // + + "public class E {\n" // + + " public enum InnerEnum {\n" + + " A, B, C, D;\n" + + " }\n" + + " public int foo(InnerEnum k, int x) {\n" + + " switch (k) {\n" + + " case A:\n" + + " System.out.println(\"a\");\n" + + " case B:\n" + + " /* comment 1 */\n" + + " if (x > 3)\n" + + " return 6; /* abc */\n" + + " else\n" + + " return 10;\n" + + " case C: {\n" + + " System.out.println(\"x\"); //$NON-NLS-1$\n" + + " /* comment 2 */\n" + + " return 8; /* def */\n" + + " }\n" + + " case D:\n" + + " return 9;\n" + + " default:\n" + + " throw new NullPointerException();\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } + @Test public void testDoNotConvertToSwitchExpressionNoBreak() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); @@ -532,4 +914,39 @@ public void testDoNotConvertToSwitchExpressionReturn() throws Exception { assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); } + @Test + public void testDoNotConvertToSwitchExpressionBug578128() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "public class E1 {\n" // + + " public static void main(String[] args) {\n" // + + " boolean rulesOK = true;\n" // + + " switch (args[0].charAt(0)) {\n" // + + " case '+':\n" // + + " args[0] = \"+\";\n" // + + " break;\n" // + + " case '~':\n" // + + " args[0] = \"~\";\n" // + + " break;\n" // + + " case '-':\n" // + + " args[0] = \"-\";\n" // + + " break;\n" // + + " case '?':\n" // + + " args[0] = \"?\";\n" // + + " break;\n" // + + " default:\n" // + + " rulesOK = false;\n" // + + " }\n" // + + " System.out.println(rulesOK);\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } + } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest15.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest15.java new file mode 100644 index 00000000..a8bed29d --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest15.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2021 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ui.tests.quickfix; + +import org.junit.Rule; +import org.junit.Test; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; + +import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; + +import org.eclipse.jdt.ui.tests.core.rules.Java15ProjectTestSetup; +import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; + +/** + * Tests the cleanup features related to Java 16. + */ +public class CleanUpTest15 extends CleanUpTestCase { + @Rule + public ProjectTestSetup projectSetup= new Java15ProjectTestSetup(false); + + @Override + protected IJavaProject getProject() { + return projectSetup.getProject(); + } + + @Override + protected IClasspathEntry[] getDefaultClasspath() throws CoreException { + return projectSetup.getDefaultClasspath(); + } + + @Test + public void testConcatToTextBlock() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public void testSimple() {\n" + + " // comment 1\n" // + + " String x = \"\" +\n" // + + " \"public void foo() {\\n\" +\n" // + + " \" System.out.println(\\\"abc\\\");\\n\" +\n" // + + " \"}\\n\"; // comment 2\n" // + + " }\n" // + + "\n" // + + " public void testTrailingSpacesAndInnerNewlines() {\n" + + " String x = \"\" +\n" // + + " \"public \\nvoid foo() { \\n\" +\n" // + + " \" System.out.println\\\\(\\\"abc\\\");\\n\" +\n" // + + " \"}\\n\";\n" // + + " }\n" // + + "\n" // + + " public void testLineContinuationAndTripleQuotes() {\n" // + + " String x = \"\" +\n" // + + " \"abcdef\" +\n" // + + " \"ghijkl\\\"\\\"\\\"\\\"123\\\"\\\"\\\"\" +\n" // + + " \"mnop\\\\\";\n" // + + " }\n" // + + "}\n"; + + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.STRINGCONCAT_TO_TEXTBLOCK); + + String expected1= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public void testSimple() {\n" // + + " // comment 1\n" // + + " String x = \"\"\"\n" // + + " \tpublic void foo() {\n" // + + " \t System.out.println(\"abc\");\n" // + + " \t}\n" // + + " \t\"\"\"; // comment 2\n" // + + " }\n" // + + "\n" // + + " public void testTrailingSpacesAndInnerNewlines() {\n" // + + " String x = \"\"\"\n" // + + " \tpublic\\s\n" + + " \tvoid foo() {\\s\\s\n" // + + " \t System.out.println\\\\(\"abc\");\n" // + + " \t}\n" // + + " \t\"\"\";\n" // + + " }\n" // + + "\n" // + + " public void testLineContinuationAndTripleQuotes() {\n" // + + " String x = \"\"\"\n" // + + " \tabcdef\\\n" // + + " \tghijkl\\\"\"\"\\\"123\\\"\"\"\\\n" // + + " \tmnop\\\\\"\"\";\n" // + + " }\n" // + + "}\n"; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); + } + + @Test + public void testNoConcatToTextBlock() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "\n" // + + "public class E {\n" // + + " public void testNotThreeStrings() {\n" // + + " String x = \n" // + + " \"abcdef\" +\n" // + + " \"ghijkl\";" // + + " }\n" // + + "\n" // + + " public void testNotAllLiterals() {\n" // + + " String x = \"\" +\n" // + + " \"abcdef\" +\n" // + + " \"ghijkl\" +\n" // + + " String.valueOf(true)\n;" + + " }\n" // + + "\n" // + + " public void testNotAllLiterals2(String a) {\n" // + + " String x = \"\" +\n" // + + " \"abcdef\" +\n" // + + " \"ghijkl\" +\n" // + + " a\n;" + + " }\n" // + + "\n" // + + " public void testNotAllStrings() {\n" // + + " String x = \"\" +\n" // + + " \"abcdef\" +\n" // + + " \"ghijkl\" +\n" // + + " 3;\n;" + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null); + + enable(CleanUpConstants.STRINGCONCAT_TO_TEXTBLOCK); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } + +} diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java index 6f64edb6..a887787e 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java @@ -630,4 +630,32 @@ public void testChangeStringBufferToStringBuilderAll() throws Exception { assertRefactoringResultAsExpected(new ICompilationUnit[] { cu0, cu1 }, new String[] { expected0, expected1 }, null); } + @Test + public void testDoNotRemoveParenthesesFromPatternInstanceof() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + + String sample= "" // + + "package test1;\n" // + + "\n" // + + "public class TestParenthesesRemoval {\n" // + + " public static void doNotChangeParenthesesForInstanceof(Object o) {\n" // + + " if (!(o instanceof String)) {\n" // + + " System.out.println(\"not a String\");\n" // + + " }\n" // + + " }\n" // + + " public static void doNotChangeParenthesesForPatternInstanceof(Object o) {\n" // + + " if (!(o instanceof String s)) {\n" // + + " System.out.println(\"not a String\");\n" // + + " } else {\n" // + + " System.out.println(\"String length is \" + s.length());\n" // + + " }\n" // + + " }\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("TestParenthesesRemoval.java", sample, false, null); + + enable(CleanUpConstants.EXPRESSIONS_USE_PARENTHESES_NEVER); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } + } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java index f944e5b6..fe181781 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2021 IBM Corporation and others. + * Copyright (c) 2019, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -13,6 +13,7 @@ *******************************************************************************/ package org.eclipse.jdt.ui.tests.quickfix; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.fail; @@ -20,24 +21,44 @@ import java.io.StringWriter; import java.util.Arrays; import java.util.HashSet; +import java.util.Hashtable; import org.junit.Rule; import org.junit.Test; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IncrementalProjectBuilder; + +import org.eclipse.ui.IEditorInput; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.refactoring.CompilationUnitChange; +import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; import org.eclipse.jdt.internal.corext.fix.FixMessages; +import org.eclipse.jdt.ui.cleanup.CleanUpOptions; +import org.eclipse.jdt.ui.cleanup.ICleanUpFix; import org.eclipse.jdt.ui.tests.core.rules.Java1d5ProjectTestSetup; import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; +import org.eclipse.jdt.ui.text.java.IProblemLocation; +import org.eclipse.jdt.internal.ui.fix.IMultiFix; +import org.eclipse.jdt.internal.ui.fix.Java50CleanUp; import org.eclipse.jdt.internal.ui.fix.MultiFixMessages; +import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; +import org.eclipse.jdt.internal.ui.text.correction.CorrectionMarkerResolutionGenerator; /** * Tests the cleanup features related to Java 5 (i.e. Tiger). @@ -1229,6 +1250,123 @@ public void testJava50ForBug560431_2() throws Exception { } @Test + public void testJava50ForLoopBug578910() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "import java.util.Iterator;\n" // + + "import java.util.Map;\n" // + + "\n" // + + "public class E1 {\n" // + + "\n" // + + " public void foo(Map extensionMap) {\n" // + + " for (Iterator iterator = extensionMap.keySet().iterator(); iterator.hasNext();) {\n" // + + " try {\n" // + + " String expression = iterator.next();\n" // + + " System.out.println(expression);\n" // + + " } catch (Exception e) {\n" // + + " }\n" // + + " }\n" // + + " int j = 7;\n" // + + " for (Iterator iterator = extensionMap.keySet().iterator(); iterator.hasNext();) {\n" // + + " do {\n" // + + " String expression = iterator.next();\n" // + + " System.out.println(expression);\n" // + + " } while (j-- > 0);\n" // + + " }\n" // + + " for (Iterator iterator = extensionMap.keySet().iterator(); iterator.hasNext();) {\n" // + + " String expression = null;\n" // + + " if (extensionMap != null) {\n" // + + " expression = iterator.next();\n" // + + " }\n" // + + " System.out.println(expression);\n" // + + " }\n" // + + " }\n" // + + "}"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test1;\n" // + + "import java.util.Map;\n" // + + "\n" // + + "public class E1 {\n" // + + "\n" // + + " public void foo(Map extensionMap) {\n" // + + " for (String expression : extensionMap.keySet()) {\n" // + + " try {\n" // + + " System.out.println(expression);\n" // + + " } catch (Exception e) {\n" // + + " }\n" // + + " }\n" // + + " int j = 7;\n" // + + " for (String expression : extensionMap.keySet()) {\n" // + + " do {\n" // + + " System.out.println(expression);\n" // + + " } while (j-- > 0);\n" // + + " }\n" // + + " for (String expression : extensionMap.keySet()) {\n" // + + " if (extensionMap != null) {\n" // + + " }\n" // + + " System.out.println(expression);\n" // + + " }\n" // + + " }\n" // + + "}"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); + } + + @Test + public void testJava50ForLoopIssue109() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "import java.util.List;\n" // + + "import java.util.ArrayList;\n" // + + "public class E1 {\n" // + + " public void foo() {\n" // + + " List list1 = new ArrayList();\n" // + + " for (int i = 0; i < list1.size(); i++) {\n" // + + " String s1 = list1.get(i);\n" // + + " String s2 = list1.get(i);\n" // + + " System.out.println(s1 + \",\" + s2); //$NON-NLS-1\n" // + + " }\n" // + + " for (int i = 0; i < list1.size(); i++) {\n" // + + " System.out.println(list1.get(i));\n" // + + " System.out.println(list1.get(i));\n" // + + " }\n" // + + " }\n" // + + "}\n"; + + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test1;\n" // + + "import java.util.List;\n" // + + "import java.util.ArrayList;\n" // + + "public class E1 {\n" // + + " public void foo() {\n" // + + " List list1 = new ArrayList();\n" // + + " for (String s1 : list1) {\n" // + + " String s2 = s1;\n" // + + " System.out.println(s1 + \",\" + s2); //$NON-NLS-1\n" // + + " }\n" // + + " for (String element : list1) {\n" // + + " System.out.println(element);\n" // + + " System.out.println(element);\n" // + + " }\n" // + + " }\n" // + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); + } + + @Test public void testBug550726() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= "" // @@ -2343,12 +2481,30 @@ public void testAutoboxing() throws Exception { } @Test - public void testDoNotUseAutoboxingOnString() throws Exception { + public void testDoNotUseAutoboxing() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= "" // + "package test1;\n" // + "\n" // + + "import java.util.List;\n" // + + "\n" // + "public class E1 {\n" // + + " public static int dummyMethod(Byte byObject) {\n" // + + " return 1;\n" // + + " }\n" // + + "\n" // + + " public static int dummyMethod(byte byPrimitive) {\n" // + + " return 2;\n" // + + " }\n" // + + "\n" // + + " public static void doNotCleanupOnConflictingMethod(byte byPrimitive) {\n" // + + " dummyMethod(Byte.valueOf(byPrimitive));\n" // + + " }\n" // + + "\n" // + + " public static void doNotCleanupOnOverloadedMethod(List integers, int notAnIndex) {\n" // + + " integers.remove(Integer.valueOf(notAnIndex));\n" // + + " }\n" // + + "\n" // + " public static void doNotUseAutoboxingOnString() {\n" // + " Integer i = Integer.valueOf(\"1\");\n" // + " Long l = Long.valueOf(\"1\");\n" // @@ -2612,6 +2768,22 @@ public void testDoNotUseUnboxing() throws Exception { + "package test1;\n" // + "\n" // + "public class E1 {\n" // + + " public static int dummyMethod(Byte byObject) {\n" // + + " return 1;\n" // + + " }\n" // + + "\n" // + + " public static int dummyMethod(byte byPrimitive) {\n" // + + " return 2;\n" // + + " }\n" // + + "\n" // + + " public static void doNotCleanupOnConflictingMethod(Byte byObject) {\n" // + + " dummyMethod(byObject.byteValue());\n" // + + " }\n" // + + "\n" // + + " public static void doNotCleanupOnOverloadedMethod(StringBuilder builder, Character optimizedObject) {\n" // + + " builder.append(optimizedObject.charValue());\n" // + + " }\n" // + + "\n" // + " public static void doNotUseUnboxingOnNarrowingType(Character cObject, Byte byObject,\n" // + " Integer iObject, Short sObject, Float fObject) {\n" // + " int c = cObject.charValue();\n" // @@ -2621,6 +2793,16 @@ public void testDoNotUseUnboxing() throws Exception { + " double f = fObject.floatValue();\n" // + " }\n" // + "\n" // + + " public static void doNotUseUnboxingOnCastCalls(Character cObject, Byte byObject,\n" // + + " Integer iObject, Short sObject, Float fObject, Object unknown) {\n" // + + " int c = (int)cObject.charValue();\n" // + + " int by = (int)byObject.byteValue();\n" // + + " long i = (long)iObject.intValue();\n" // + + " int s = (int)sObject.shortValue();\n" // + + " double f = (double)fObject.floatValue();\n" // + + " byte b = (byte)((Integer)unknown).intValue();\n" // + + " }\n" // + + "\n" // + " public static void doNotUseUnboxingWhenTypesDontMatch(Byte byObject,\n" // + " Integer iObject, Short sObject, Long lObject, Float fObject, Double dObject) {\n" // + " short by = byObject.shortValue();\n" // @@ -4085,4 +4267,67 @@ public void testConvertStringBufferToStringBuilderAll() throws Exception { new HashSet<>(Arrays.asList(MultiFixMessages.StringBufferToStringBuilderCleanUp_description))); } + @Test + public void testOverrideMultiFix() throws Exception { + Hashtable opts= JavaCore.getOptions(); + opts.put(JavaCore.COMPILER_PB_MISSING_OVERRIDE_ANNOTATION, JavaCore.ERROR); + JavaCore.setOptions(opts); + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" // + + "public class E1 extends MyAbstract {\n" // + + " public void run() {};\n" // + + " public int compareTo(String o) { return -1; };\n" // + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + sample= "" // + + "package test1;\n" // + + "public abstract class MyAbstract {\n" // + + " public void run();\n" // + + " public int compareTo(String o);\n" // + + "}"; + pack1.createCompilationUnit("MyAbstract.java", sample, false, null); + + cu1.getJavaProject().getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); + + sample= "" // + + "package test1;\n" // + + "public class E1 extends MyAbstract {\n" // + + " @Override\n" // + + " public void run() {};\n" // + + " @Override\n" // + + " public int compareTo(String o) { return -1; };\n" // + + "}\n"; + String expected1= sample; + + // Two error markers due to missing override annotations + IMarker[] markers= cu1.getResource().findMarkers(null, true, IResource.DEPTH_INFINITE); + assertEquals(2, markers.length); + + IEditorInput input= EditorUtility.getEditorInput(cu1); + IProblemLocation location1= CorrectionMarkerResolutionGenerator.findProblemLocation(input, markers[0]); + IProblemLocation location2= CorrectionMarkerResolutionGenerator.findProblemLocation(input, markers[1]); + + CleanUpOptions cleanUpOptions= new CleanUpOptions(); + cleanUpOptions.setOption(CleanUpConstants.ADD_MISSING_ANNOTATIONS, CleanUpOptions.TRUE); + cleanUpOptions.setOption(CleanUpConstants.ADD_MISSING_ANNOTATIONS_OVERRIDE, CleanUpOptions.TRUE); + cleanUpOptions.setOption(CleanUpConstants.ADD_MISSING_ANNOTATIONS_OVERRIDE_FOR_INTERFACE_METHOD_IMPLEMENTATION, CleanUpOptions.TRUE); + + Java50CleanUp cleanUp = new Java50CleanUp(); + cleanUp.setOptions(cleanUpOptions); + + ASTParser parser= ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL); + parser.setResolveBindings(true); + parser.setProject(getProject()); + parser.setSource(cu1); + CompilationUnit ast= (CompilationUnit)parser.createAST(null); + + ICleanUpFix cleanUpFix= cleanUp.createFix(new IMultiFix.MultiFixContext(cu1, ast, new IProblemLocation[] {location1, location2})); + CompilationUnitChange change= cleanUpFix.createChange(new NullProgressMonitor()); + change.perform(new NullProgressMonitor()); + assertEquals(expected1, cu1.getBuffer().getContents()); + + } + } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d6.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d6.java index cd52e4af..f4f1f55a 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d6.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d6.java @@ -260,7 +260,8 @@ public void testConstantsForSystemProperty() throws Exception { enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_PATH_SEPARATOR); enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_LINE_SEPARATOR); enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_FILE_ENCODING); - enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOOLEAN); + enable(CleanUpConstants.CONSTANTS_FOR_SYSTEM_PROPERTY_BOXED); + // Then assertNotEquals("The class must be changed", given, expected); assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, @@ -268,7 +269,9 @@ public void testConstantsForSystemProperty() throws Exception { Messages.format(ConstantsCleanUp_description,UpdateProperty.PATH_SEPARATOR.toString()), Messages.format(ConstantsCleanUp_description,UpdateProperty.LINE_SEPARATOR.toString()), Messages.format(ConstantsCleanUp_description,UpdateProperty.FILE_ENCODING.toString()), - Messages.format(ConstantsCleanUp_description,UpdateProperty.BOOLEAN_PROPERTY.toString())))); + Messages.format(ConstantsCleanUp_description,UpdateProperty.BOOLEAN_PROPERTY.toString()), + Messages.format(ConstantsCleanUp_description,UpdateProperty.INTEGER_PROPERTY.toString()), + Messages.format(ConstantsCleanUp_description,UpdateProperty.LONG_PROPERTY.toString())))); } } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d7.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d7.java index e490cea2..d7ae0fc0 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d7.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d7.java @@ -1180,4 +1180,39 @@ public void testJava50ForLoop563267() throws Exception { assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); } + + @Test + public void testInstanceVarToLocal() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" + + "package test1;\n" + + "\n" + + "public class Bar {\n" + + " private transient int zoz=38, fubu;\n" + + " \n" + + " public void baz() {\n" + + " zoz = 37;\n" + + " System.out.println(zoz);\n" + + " }\n" + + "}\n"; + + ICompilationUnit cu1= pack1.createCompilationUnit("Bar.java", sample, false, null); + + enable(CleanUpConstants.SINGLE_USED_FIELD); + + + String expected= "" + + "package test1;\n" + + "\n" + + "public class Bar {\n" + + " private transient int fubu;\n" + + " \n" + + " public void baz() {\n" + + " int zoz = 37;\n" + + " System.out.println(zoz);\n" + + " }\n" + + "}\n"; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected }, null); + } } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d8.java index e97a897e..9678b876 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d8.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2021 IBM Corporation and others. + * Copyright (c) 2020, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -18,6 +18,7 @@ import java.util.Arrays; import java.util.HashSet; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; @@ -762,6 +763,123 @@ public void testConvertToLambdaConflictingNames() throws Exception { assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, null); } + @Test + public void testConvertToLambdaNoRenameLocals() throws CoreException { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String original= "" + + "package test;\n" + + "\n" + + "interface FI {\n" + + " void doIt(String p);\n" + + "}\n" + + "public class C1 {\n" + + " public void foo() {\n" + + " FI fi= new FI() {\n" + + " @Override\n" + + " public void doIt(String e) {\n" + + " if (e != null) {\n" + + " int i= 0;\n" + + " System.out.println(i);\n" + + " } else {\n" + + " int i= 0;\n" + + " System.out.println(i);\n" + + " }\n" + + " }\n" + + " };\n" + + " }\n" + + "}\n"; + + String fixed= "" + + "package test;\n" + + "\n" + + "interface FI {\n" + + " void doIt(String p);\n" + + "}\n" + + "public class C1 {\n" + + " public void foo() {\n" + + " FI fi= e -> {\n" + + " if (e != null) {\n" + + " int i= 0;\n" + + " System.out.println(i);\n" + + " } else {\n" + + " int i= 0;\n" + + " System.out.println(i);\n" + + " }\n" + + " };\n" + + " }\n" + + "}\n"; + + enable(CleanUpConstants.CONVERT_FUNCTIONAL_INTERFACES); + enable(CleanUpConstants.USE_LAMBDA); + ICompilationUnit cu= pack.createCompilationUnit("C1.java", original, false, null); + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { fixed }, null); + } + + @Test + public void testConvertToLambdaWithRenameLocals() throws CoreException { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String original= "" + + "package test1;\n" + + "interface FI {\n" + + " void doIt(String p);\n" + + "}\n" + + "public class C1 {\n" + + " public void foo() {\n" + + " int i= 33;\n" + + " FI fi = new FI() {\n" + + " @Override\n" + + " public void doIt(String e) {\n" + + " FI fi = new FI() {\n" + + " @Override\n" + + " public void doIt(String e) {\n" + + " int i1= 37;\n" + + " if (e != null) {\n" + + " int i = 0;\n" + + " System.out.println(i);\n" + + " } else {\n" + + " int i = 0;\n" + + " System.out.println(i);\n" + + " }\n" + + " }\n" + + " };\n" + + " }\n" + + " };\n" + + " }\n" + + "}\n"; + + + String fixed= "" + + "package test1;\n" + + "interface FI {\n" + + " void doIt(String p);\n" + + "}\n" + + "public class C1 {\n" + + " public void foo() {\n" + + " int i= 33;\n" + + " FI fi = e -> {\n" + + " FI fi1 = e1 -> {\n" + + " int i1= 37;\n" + + " if (e1 != null) {\n" + + " int i2 = 0;\n" + + " System.out.println(i2);\n" + + " } else {\n" + + " int i3 = 0;\n" + + " System.out.println(i3);\n" + + " }\n" + + " };\n" + + " };\n" + + " }\n" + + "}\n"; + + enable(CleanUpConstants.CONVERT_FUNCTIONAL_INTERFACES); + enable(CleanUpConstants.USE_LAMBDA); + ICompilationUnit cu= pack.createCompilationUnit("C1.java", original, false, null); + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { fixed }, null); + + } + @Test public void testConvertToLambdaWithMethodAnnotations() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); @@ -1473,6 +1591,80 @@ public void testDoNotSimplifyLambdaExpression() throws Exception { assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); } + @Test + public void testBug579393() throws Exception { + // Given + IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); + String given= "" // + + "import java.util.stream.Stream;\n" // + + "\n" // + + "public class E {\n" // + + " public static void main(String[] args) {\n" // + + " new A() {\n" // + + " };\n" // + + " get();\n" // + + " System.out.println(\"done\");\n" // + + " }\n" // + + "\n" // + + " public static A get(B... sources) {\n" // + + " return Stream.of(sources)\n" // + + " .map(B::getT)\n" // + + " .filter(x -> x.exists_testOpen())\n" // + + " .findFirst()\n" // + + " .orElse(null);\n" // + + " }\n" // + + "\n" // + + " public interface B extends A {\n" // + + " T getT();\n" // + + " }\n" // + + "\n" // + + " public interface A {\n" // + + " default boolean exists_testOpen() {\n" // + + " return true;\n" // + + " }\n" // + + " }\n" // + + "}\n"; + + String expected= "" // + + "import java.util.stream.Stream;\n" // + + "\n" // + + "public class E {\n" // + + " public static void main(String[] args) {\n" // + + " new A() {\n" // + + " };\n" // + + " get();\n" // + + " System.out.println(\"done\");\n" // + + " }\n" // + + "\n" // + + " public static A get(B... sources) {\n" // + + " return Stream.of(sources)\n" // + + " .map(B::getT)\n" // + + " .filter(A::exists_testOpen)\n" // + + " .findFirst()\n" // + + " .orElse(null);\n" // + + " }\n" // + + "\n" // + + " public interface B extends A {\n" // + + " T getT();\n" // + + " }\n" // + + "\n" // + + " public interface A {\n" // + + " default boolean exists_testOpen() {\n" // + + " return true;\n" // + + " }\n" // + + " }\n" // + + "}\n"; + + // When + ICompilationUnit cu= pack.createCompilationUnit("E.java", given, false, null); + enable(CleanUpConstants.SIMPLIFY_LAMBDA_EXPRESSION_AND_METHOD_REF); + + // Then + assertNotEquals("The class must be changed", given, expected); + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(MultiFixMessages.LambdaExpressionAndMethodRefCleanUp_description))); + } + @Test public void testConvertToLambdaWithRecursion() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); @@ -2435,6 +2627,74 @@ public void testJoin() throws Exception { + " return concatenation.toString();\n" // + " }\n" // + "\n" // + + " public String refactorConcatenationWithCharVariable(String[] titles, char delimiter) {\n" // + + " boolean isFirst = true;\n" // + + " StringBuilder concatenation = new StringBuilder();\n" // + + "\n" // + + " // Keep this comment\n" // + + " for (String title : titles) {\n" // + + " if (isFirst) {\n" // + + " isFirst = false;\n" // + + " } else {\n" // + + " concatenation.append(delimiter);\n" // + + " }\n" // + + " concatenation.append(title);\n" // + + " }\n" // + + "\n" // + + " return concatenation.toString();\n" // + + " }\n" // + + "\n" // + + " public String refactorConcatenationWithCharacterWrapper(String[] titles, Character delimiter) {\n" // + + " boolean isFirst = true;\n" // + + " StringBuilder concatenation = new StringBuilder();\n" // + + "\n" // + + " // Keep this comment\n" // + + " for (String title : titles) {\n" // + + " if (isFirst) {\n" // + + " isFirst = false;\n" // + + " } else {\n" // + + " concatenation.append(delimiter);\n" // + + " }\n" // + + " concatenation.append(title);\n" // + + " }\n" // + + "\n" // + + " return concatenation.toString();\n" // + + " }\n" // + + "\n" // + + " public String refactorConcatenationWithEscapedChar(String[] titles) {\n" // + + " boolean isFirst = true;\n" // + + " StringBuilder concatenation = new StringBuilder();\n" // + + "\n" // + + " // Keep this comment\n" // + + " for (String title : titles) {\n" // + + " if (isFirst) {\n" // + + " isFirst = false;\n" // + + " } else {\n" // + + " concatenation.append('\\n');\n" // + + " }\n" // + + " concatenation.append(title);\n" // + + " }\n" // + + "\n" // + + " return concatenation.toString();\n" // + + " }\n" // + + "\n" // + + " public String refactorConcatenationWithInt(String[] titles) {\n" // + + " boolean isFirst = true;\n" // + + " StringBuilder concatenation = new StringBuilder();\n" // + + "\n" // + + " // Keep this comment\n" // + + " for (String title : titles) {\n" // + + " if (isFirst) {\n" // + + " isFirst = false;\n" // + + " } else {\n" // + + " concatenation.append(123);\n" // + + " }\n" // + + " concatenation.append(title);\n" // + + " }\n" // + + "\n" // + + " return concatenation.toString();\n" // + + " }\n" // + + "\n" // + " public String refactorConcatenationWithHardCodedDelimiter(String[] texts) {\n" // + " boolean isFirst = true;\n" // + " StringBuilder concatenation = new StringBuilder();\n" // @@ -2871,7 +3131,43 @@ public void testJoin() throws Exception { + " \n" // + "\n" // + " // Keep this comment\n" // - + " String concatenation = String.join(String.valueOf(','), titles);\n" // + + " String concatenation = String.join(\",\", titles);\n" // + + "\n" // + + " return concatenation;\n" // + + " }\n" // + + "\n" // + + " public String refactorConcatenationWithCharVariable(String[] titles, char delimiter) {\n" // + + " \n" // + + "\n" // + + " // Keep this comment\n" // + + " String concatenation = String.join(String.valueOf(delimiter), titles);\n" // + + "\n" // + + " return concatenation;\n" // + + " }\n" // + + "\n" // + + " public String refactorConcatenationWithCharacterWrapper(String[] titles, Character delimiter) {\n" // + + " \n" // + + "\n" // + + " // Keep this comment\n" // + + " String concatenation = String.join(String.valueOf(delimiter), titles);\n" // + + "\n" // + + " return concatenation;\n" // + + " }\n" // + + "\n" // + + " public String refactorConcatenationWithEscapedChar(String[] titles) {\n" // + + " \n" // + + "\n" // + + " // Keep this comment\n" // + + " String concatenation = String.join(\"\\n\", titles);\n" // + + "\n" // + + " return concatenation;\n" // + + " }\n" // + + "\n" // + + " public String refactorConcatenationWithInt(String[] titles) {\n" // + + " \n" // + + "\n" // + + " // Keep this comment\n" // + + " String concatenation = String.join(String.valueOf(123), titles);\n" // + "\n" // + " return concatenation;\n" // + " }\n" // @@ -3789,4 +4085,1117 @@ public void testChangeStringBufferToStringBuilderAll() throws Exception { new HashSet<>(Arrays.asList(MultiFixMessages.StringBufferToStringBuilderCleanUp_description))); } + @Test + public void testWhile() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Collections.reverse(strings);\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " // OK\n" + + " System.err.println(s);\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Collections.reverse(strings);\n" + + " for (String s : strings) {\n" + + " System.out.println(s);\n" + + " // OK\n" + + " System.err.println(s);\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileNested() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " Iterator it2 = strings2.iterator();\n" + + " while (it2.hasNext()) {\n" + + " String s2 = (String) it2.next();\n" + + " System.out.println(s2);\n" + + " }\n" + + " // OK\n" + + " System.err.println(s);\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " for (String s : strings) {\n" + + " for (String s2 : strings2) {\n" + + " System.out.println(s2);\n" + + " }\n" + + " // OK\n" + + " System.err.println(s);\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileNested2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " Iterator it2 = strings2.iterator();\n" + + " while (it2.hasNext()) {\n" + + " String s2 = (String) it2.next();\n" + + " System.out.println(s2);\n" + + " }\n" + + " // OK\n" + + " System.out.println(it.next());\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " for (String string : strings) {\n" + + " for (String s2 : strings2) {\n" + + " System.out.println(s2);\n" + + " }\n" + + " // OK\n" + + " System.out.println(string);\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileNested3() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " it.next();\n" + + " Iterator it2 = strings2.iterator();\n" + + " while (it2.hasNext()) {\n" + + " String s2 = (String) it2.next();\n" + + " System.out.println(s2);\n" + + " }\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " for (String string : strings) {\n" + + " for (String s2 : strings2) {\n" + + " System.out.println(s2);\n" + + " }\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileNested4() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " it.next();\n" + + " Iterator it2 = strings2.iterator();\n" + + " while (it2.hasNext()) {\n" + + " String s2 = (String) it2.next();\n" + + " System.out.println(s2);\n" + + " }\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_ONLY_IF_LOOP_VAR_USED); + + sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " it.next();\n" + + " for (String s2 : strings2) {\n" + + " System.out.println(s2);\n" + + " }\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileNested5() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String)it.next();\n" + + " Iterator it2 = strings2.iterator();\n" + + " while (it2.hasNext()) {\n" + + " String s2 = (String) it2.next();\n" + + " System.out.println(s2);\n" + + " }\n" + + " // end line comment\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_ONLY_IF_LOOP_VAR_USED); + + sample= "" // + + "package test1;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings,List strings2) {\n" + + " Collections.reverse(strings);\n" + + " for (String s : strings) {\n" + + " for (String s2 : strings2) {\n" + + " System.out.println(s2);\n" + + " }\n" + + " // end line comment\n" + + " }\n" + + " System.out.println();\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileGenericSubtype() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List> lists) {\n" + + " Iterator it = lists.iterator();\n" + + " while (it.hasNext()) {\n" + + " List list = (List) it.next();\n" + + " System.out.println(list);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List> lists) {\n" + + " for (List list : lists) {\n" + + " System.out.println(list);\n" + + " }\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + /** + * https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/109 + * + * @throws CoreException + */ + @Test + public void testWhileIssue109_EntrySet() throws CoreException { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "import java.util.Map.Entry;\n" + + "public class Test {\n" + + " void m() {\n" + + " Map map = Map.of(\"Hello\", new Object());\n" + + " Iterator> iterator = map.entrySet().iterator();\n" + + " while (iterator.hasNext()) {\n" + + " Entry entry = iterator.next();\n" + + " System.out.println(entry);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + String expected= "" // + + "package test;\n" + + "import java.util.*;\n" + + "import java.util.Map.Entry;\n" + + "public class Test {\n" + + " void m() {\n" + + " Map map = Map.of(\"Hello\", new Object());\n" + + " for (Entry entry : map.entrySet()) {\n" + + " System.out.println(entry);\n" + + " }\n" + + " }\n" + + "}\n"; + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + /** + * https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/109 + * + * @throws CoreException + */ + @Test + public void testWhileIssue109_EntrySet_2() throws CoreException { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "import java.util.Map.Entry;\n" + + "public class Test {\n" + + " void m(Map, Object> map) {\n" + + " Iterator, Object>> iterator = map.entrySet().iterator();\n" + + " while (iterator.hasNext()) {\n" + + " Entry, Object> entry = iterator.next();\n" + + " System.out.println(entry);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + String expected= "" // + + "package test;\n" + + "import java.util.*;\n" + + "import java.util.Map.Entry;\n" + + "public class Test {\n" + + " void m(Map, Object> map) {\n" + + " for (Entry, Object> entry : map.entrySet()) {\n" + + " System.out.println(entry);\n" + + " }\n" + + " }\n" + + "}\n"; + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + /** + * https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/109 + * + * @throws CoreException + */ + @Test + public void testWhileIssue109_EntrySet_3() throws CoreException { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "import java.util.Map.Entry;\n" + + "public class Test {\n" + + " void m(Map[], Date[]> map) {\n" + + " Iterator[], Date[]>> iterator = map.entrySet().iterator();\n" // + + " while (iterator.hasNext()) {\n" // + + " Entry[], Date[]> entry = iterator.next();\n" // + + " System.out.println(entry);\n" // + + " }\n" // + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + String expected= "" // + + "package test;\n" + + "import java.util.*;\n" + + "import java.util.Map.Entry;\n" + + "public class Test {\n" + + " void m(Map[], Date[]> map) {\n" + + " for (Entry[], Date[]> entry : map.entrySet()) {\n" // + + " System.out.println(entry);\n" // + + " }\n" // + + " }\n" + + "}\n"; + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + /** + * https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/120 + * + * @throws CoreException + */ + @Test + public void testWhileIssue120_CollectionTypeResolution() throws CoreException { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " private static List m(Map> map) {\n" + + " List results = new ArrayList<>();\n" + + " Iterator> iterator = map.values().iterator();\n" + + " while (iterator.hasNext()) {\n" + + " results.addAll(iterator.next());\n" + + " }\n" + + " return results;\n" + + " }" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + String expected= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " private static List m(Map> map) {\n" + + " List results = new ArrayList<>();\n" + + " for (List element : map.values()) {\n" + + " results.addAll(element);\n" + + " }\n" + + " return results;\n" + + " }" + + "}\n"; + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + /** + * https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/190 + * + * @throws CoreException + */ + @Test + public void testWhileIssue190_MultipleWhileLoops() throws CoreException { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " Iterator it2 = strings.iterator();\n" + + " while (it2.hasNext()) {\n" + + " String s = (String) it2.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + String expected= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " for (String s : strings) {\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " for (String s : strings) {\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileSelf() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test extends ArrayList {\n" + + " void m() {\n" + + " Iterator it = iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test extends ArrayList {\n" + + " void m() {\n" + + " for (String s : this) {\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileIteratorAssigned() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test extends ArrayList {\n" + + " void m(ArrayList strings) {\n" + + " Iterator it;\n" + + " it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test extends ArrayList {\n" + + " void m(ArrayList strings) {\n" + + " for (String s : strings) {\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileNoSelf() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m() {\n" + + " Iterator it = factory().iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + " private ArrayList factory() {\n" + + " return new ArrayList();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m() {\n" + + " for (String s : factory()) {\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + " private ArrayList factory() {\n" + + " return new ArrayList();\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileWithNonRawSuperclass() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(MyList strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + " static class MyList extends ArrayList {}\n" + + "}\n"; + ICompilationUnit cu1= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(MyList strings) {\n" + + " for (String s : strings) {\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + " static class MyList extends ArrayList {}\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileWithRawIterator() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " for (String s : strings) {\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testWhileSubtype() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List bundles) {\n" + + " Iterator it = bundles.iterator();\n" + + " while (it.hasNext()) {\n" + + " ResourceBundle bundle = (ResourceBundle) it.next();\n" + + " System.out.println(bundle);\n" + + " System.err.println(bundle);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List bundles) {\n" + + " for (ResourceBundle bundle : bundles) {\n" + + " System.out.println(bundle);\n" + + " System.err.println(bundle);\n" + + " }\n" + + " }\n" + + "}\n"; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 }, + new HashSet<>(Arrays.asList(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description))); + } + + @Test + public void testDoNotWhileBigChangeNeeded() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List nodes) {\n" + + " Iterator fragments= null;\n" + + " if (nodes != null) {\n" + + " fragments= nodes.iterator();\n" + + " }\n" + + " if (fragments != null) {\n" + + " while (fragments.hasNext()) {\n" + + " System.out.println(fragments.next());\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu1= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } + + @Test + public void testDoNotWhileUsedSpecially() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " if (s.isEmpty()) {\n" + + " it.remove();\n" + + " } else {\n" + + " System.out.println(s);\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + + @Ignore("Either check exactly the data type (eg CopyOnWriteArrayList allows modifications)" + + " or stay away from refactoring when deletions/additions happen." + + "btw simple for loop to enhanced for loop should do the same.") + @Test + public void testDoNotConcurrentModificationException() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " List strings=new ArrayList<>();\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " }\n" + + " }\n" + + " void outside(int x) {\n" + + " strings.remove(x);\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + + @Test + public void testDoNotWhileUsedSpecially2() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " String startvalue = (String) it.next();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + + @Test + public void testDoNotWhileWithIndirectIterator() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m() {\n" + + " Iterator it = getIterator();\n" + + " String startvalue = (String) it.next();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " }\n" + + " }\n" + + " List strings= new ArrayList();\n" + + " public Iterator getIterator() {\n" + + " return strings.iterator();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + + @Test + public void testDoNotWhileWithIndirectIterator2() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " public static class MyIterator implements Iterator {\n" + + " List strings= new ArrayList<>();\n" + + " Iterator iterator;\n" + + " public MyIterator() {\n" + + " iterator= strings.iterator();\n" + + " }\n" + + " @Override\n" + + " public boolean hasNext() {\n" + + " return iterator.hasNext();\n" + + " }\n" + + " @Override\n" + + " public String next() {\n" + + " return iterator.next();\n" + + " }\n" + + " @Override\n" + + " public void remove() {\n" + + " iterator.remove();\n" + + " }\n" + + " }\n" + + " void m() {\n" + + " Iterator it = new MyIterator();\n" + + " String startvalue = (String) it.next();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " }\n" + + " }\n" + + " List strings= new ArrayList<>();\n" + + " public Iterator getIterator() {\n" + + " return strings.iterator();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + + @Test + public void testDoNotWhileWithDoubleNext() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " String s2 = (String) it.next();\n" + + " System.out.println(s + s2);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + + @Test + public void testDoNotWhileRaw() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + + @Test + public void testDoNotWhileWrongType() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + + @Test + public void testDoNotWhileIssue190_1() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + + } + + @Test + public void testDoNotWhileIssue190_2() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + + } + + @Test + public void testDoNotWhileNotIterable() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(MyList strings) {\n" + + " Iterator it = strings.iterator();\n" + + " while (it.hasNext()) {\n" + + " String s = (String) it.next();\n" + + " System.out.println(s);\n" + + " System.err.println(s);\n" + + " }\n" + + " }\n" + + " interface MyList {\n" + + " Iterator iterator();\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } + + @Test + public void testDoNotWhileNotSubtype() throws Exception { + IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null); + String sample= "" // + + "package test;\n" + + "import java.util.*;\n" + + "public class Test {\n" + + " void m(List bundles) {\n" + + " Iterator it = bundles.iterator();\n" + + " while (it.hasNext()) {\n" + + " PropertyResourceBundle bundle = (PropertyResourceBundle) it.next();\n" + + " System.out.println(bundle);\n" + + " System.err.println(bundle);\n" + + " }\n" + + " }\n" + + "}\n"; + ICompilationUnit cu= pack.createCompilationUnit("Test.java", sample, false, null); + + enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu }); + } } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTestCaseSuite.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTestCaseSuite.java index dc268a11..657ae7ed 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTestCaseSuite.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTestCaseSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 IBM Corporation and others. + * Copyright (c) 2020, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -31,6 +31,7 @@ CleanUpTest11.class, CleanUpTest12.class, CleanUpTest14.class, + CleanUpTest15.class, CleanUpTest16.class, CleanUpAnnotationTest.class, SaveParticipantTest.class, diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java index 9f48f971..e747ee46 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -1423,7 +1423,6 @@ public void testUncaughtExceptionRemoveMoreSpecific() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); buf.append("import java.io.IOException;\n"); - buf.append("import java.net.SocketException;\n"); buf.append("public class E {\n"); buf.append(" public void goo() throws IOException {\n"); buf.append(" return;\n"); @@ -6391,6 +6390,39 @@ public void testUnnecessaryCastBug335173_2() throws Exception { assertEqualString(preview, buf.toString()); } + @Test + public void testUnnecessaryCastBug578911() throws Exception { + Hashtable hashtable= JavaCore.getOptions(); + hashtable.put(JavaCore.COMPILER_PB_UNNECESSARY_TYPE_CHECK, JavaCore.ERROR); + JavaCore.setOptions(hashtable); + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo(Integer n) {\n"); + buf.append(" n = (Integer)n;\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0); + String preview= getPreviewContent(proposal); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public void foo(Integer n) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEqualString(preview, buf.toString()); + } + @Test public void testSuperfluousSemicolon() throws Exception { Hashtable hashtable= JavaCore.getOptions(); @@ -6809,7 +6841,7 @@ public void testUnnecessaryThrownException1() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); - buf.append("import java.io.IOException;\n"); + buf.append("\n"); buf.append("public class E {\n"); buf.append(" public void foo(String b) {\n"); buf.append(" if (b != null) {\n"); @@ -6870,7 +6902,6 @@ public void testUnnecessaryThrownException2() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); buf.append("import java.io.IOException;\n"); - buf.append("import java.text.ParseException;\n"); buf.append("public class E {\n"); buf.append(" /**\n"); buf.append(" * @throws IOException\n"); @@ -6940,7 +6971,6 @@ public void testUnnecessaryThrownException3() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); buf.append("import java.io.IOException;\n"); - buf.append("import java.text.ParseException;\n"); buf.append("public class E {\n"); buf.append(" /**\n"); buf.append(" * @param i\n"); @@ -6955,6 +6985,86 @@ public void testUnnecessaryThrownException3() throws Exception { assertEqualString(preview, buf.toString()); } + @Test + public void testUnnecessaryThrownException4() throws Exception { + Hashtable hashtable= JavaCore.getOptions(); + hashtable.put(JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION, JavaCore.ERROR); + JavaCore.setOptions(hashtable); + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import java.io.IOException;\n"); + buf.append("import java.text.ParseException;\n"); + buf.append("public class E {\n"); + buf.append(" /**\n"); + buf.append(" * @throws IOException\n"); + buf.append(" */\n"); + buf.append(" public E(int i) throws IOException, ParseException {\n"); + buf.append(" if (i == 0) {\n"); + buf.append(" throw new IOException();\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append(" public void foo(int i) throws ParseException {\n"); + buf.append(" if (i == 0) {\n"); + buf.append(" throw new ParseException(null, 4);\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertNumberOfProposals(proposals, 3); + assertCorrectLabels(proposals); + + String[] expected= new String[2]; + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import java.io.IOException;\n"); + buf.append("import java.text.ParseException;\n"); + buf.append("public class E {\n"); + buf.append(" /**\n"); + buf.append(" * @throws IOException\n"); + buf.append(" */\n"); + buf.append(" public E(int i) throws IOException {\n"); + buf.append(" if (i == 0) {\n"); + buf.append(" throw new IOException();\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append(" public void foo(int i) throws ParseException {\n"); + buf.append(" if (i == 0) {\n"); + buf.append(" throw new ParseException(null, 4);\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append("}\n"); + expected[0]= buf.toString(); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import java.io.IOException;\n"); + buf.append("import java.text.ParseException;\n"); + buf.append("public class E {\n"); + buf.append(" /**\n"); + buf.append(" * @throws IOException\n"); + buf.append(" * @throws ParseException \n"); + buf.append(" */\n"); + buf.append(" public E(int i) throws IOException, ParseException {\n"); + buf.append(" if (i == 0) {\n"); + buf.append(" throw new IOException();\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append(" public void foo(int i) throws ParseException {\n"); + buf.append(" if (i == 0) {\n"); + buf.append(" throw new ParseException(null, 4);\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append("}\n"); + expected[1]= buf.toString(); + + assertExpectedExistInProposals(proposals, expected); + } @Test public void testUnqualifiedFieldAccess1() throws Exception { diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest1d8.java index 498ce034..7412975d 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest1d8.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2020 IBM Corporation and others. + * Copyright (c) 2014, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -1216,6 +1216,204 @@ public void testOverrideDefaultMethod_multiLevel() throws Exception { assertExpectedExistInProposals(proposals, expected); } + @Test + public void testCreateMethodInSuperTypeQuickFix1() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(int... i) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(int... i) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("\n"); + buf.append(" void foo(int... i);\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + + @Test + public void testCreateMethodInSuperTypeQuickFix2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(int[]... i) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(int[]... i) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("\n"); + buf.append(" void foo(int[]... i);\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + + @Test + public void testCreateMethodInSuperTypeQuickFix3() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(double d, int[]... i) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(double d, int[]... i) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("\n"); + buf.append(" void foo(double d, int[]... i);\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + + @Test + public void testCreateMethodInSuperTypeQuickFix4() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(T t) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(T t) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("\n"); + buf.append(" void foo(T t);\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + + @Test + public void testCreateMethodInSuperTypeQuickFix5() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(T... t) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(T... t) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("\n"); + buf.append(" void foo(T... t);\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + + @Test + public void testCreateMethodInSuperTypeQuickFix6() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(T[]... t) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("class E implements I {\n"); + buf.append(" @Override\n"); + buf.append(" void foo(T[]... t) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("interface I {\n"); + buf.append("\n"); + buf.append(" void foo(T[]... t);\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + @Test public void testOverrideDefaultMethod_noParam() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/ModifierCorrectionsQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/ModifierCorrectionsQuickFixTest.java index c146d2f5..1e072294 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/ModifierCorrectionsQuickFixTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/ModifierCorrectionsQuickFixTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -1269,7 +1269,7 @@ public void testMethodRequiresBody() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); - buf.append("public class E {\n"); + buf.append("public abstract class E {\n"); buf.append(" public abstract void foo();\n"); buf.append("}\n"); String expected2= buf.toString(); @@ -1310,7 +1310,7 @@ public void testMethodRequiresBody2() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); - buf.append("public class E {\n"); + buf.append("public abstract class E {\n"); buf.append(" public abstract int foo();\n"); buf.append("}\n"); String expected2= buf.toString(); @@ -1318,6 +1318,52 @@ public void testMethodRequiresBody2() throws Exception { assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 }); } + @Test + public void testMethodRequiresBody3() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static class E1 {\n"); + buf.append(" public int foo();\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview1= getPreviewContent(proposal); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static class E1 {\n"); + buf.append(" public int foo() {\n"); + buf.append(" return 0;\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected1= buf.toString(); + + proposal= (CUCorrectionProposal) proposals.get(1); + String preview2= getPreviewContent(proposal); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static abstract class E1 {\n"); + buf.append(" public abstract int foo();\n"); + buf.append(" }\n"); + buf.append("}\n"); + String expected2= buf.toString(); + + assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 }); + } + @Test public void testNeedToEmulateMethodAccess() throws Exception { Hashtable hashtable= JavaCore.getOptions(); diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsCleanUpTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsCleanUpTest1d8.java index 60396bc7..fa62377c 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsCleanUpTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsCleanUpTest1d8.java @@ -78,7 +78,7 @@ public void setUp() throws Exception { if (this.ANNOTATION_JAR_PATH == null) { String version= "[2.0.0,3.0.0)"; // tests run at 1.8, need the "new" null annotations Bundle[] bundles= Platform.getBundles("org.eclipse.jdt.annotation", version); - File bundleFile= FileLocator.getBundleFile(bundles[0]); + File bundleFile= FileLocator.getBundleFileLocation(bundles[0]).get(); if (bundleFile.isDirectory()) this.ANNOTATION_JAR_PATH= bundleFile.getPath() + "/bin"; else diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest.java index d9031626..ca02c4e3 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest.java @@ -113,7 +113,7 @@ public void setUp() throws Exception { if (ANNOTATION_JAR_PATH == null) { String version= "[1.1.0,2.0.0)"; // tests run at 1.5, need the "old" null annotations Bundle[] bundles= Platform.getBundles("org.eclipse.jdt.annotation", version); - File bundleFile= FileLocator.getBundleFile(bundles[0]); + File bundleFile= FileLocator.getBundleFileLocation(bundles[0]).get(); if (bundleFile.isDirectory()) ANNOTATION_JAR_PATH= bundleFile.getPath() + "/bin"; else diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest1d8.java index e661b273..11018813 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest1d8.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2020 GK Software AG and others. + * Copyright (c) 2017, 2022 GK Software AG and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -57,6 +57,7 @@ import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal; import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.text.correction.AssistContext; /** * Those tests are made to run on Java Spider 1.8 . @@ -101,7 +102,7 @@ public void setUp() throws Exception { if (this.ANNOTATION_JAR_PATH == null) { String version= "[2.0.0,3.0.0)"; // tests run at 1.8, need the "new" null annotations Bundle[] bundles= Platform.getBundles("org.eclipse.jdt.annotation", version); - File bundleFile= FileLocator.getBundleFile(bundles[0]); + File bundleFile= FileLocator.getBundleFileLocation(bundles[0]).get(); if (bundleFile.isDirectory()) this.ANNOTATION_JAR_PATH= bundleFile.getPath() + "/bin"; else @@ -1208,6 +1209,39 @@ public void testBug513209d() throws Exception { assertEqualString(preview, buf.toString()); } @Test + public void testBug562891() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import org.eclipse.jdt.annotation.*;\n"); + buf.append("@NonNullByDefault\n"); + buf.append("public class A {\n"); + buf.append(" private @Nullable String foo;\n"); + buf.append("}\n"); + ICompilationUnit cu = pack1.createCompilationUnit("A.java", buf.toString(), false, null); + AssistContext context= new AssistContext(cu, buf.toString().indexOf("foo"), 0); + ArrayList proposals= collectAssists(context, false); + + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import org.eclipse.jdt.annotation.*;\n"); + buf.append("@NonNullByDefault\n"); + buf.append("public class A {\n"); + buf.append(" private @Nullable String foo;\n"); + buf.append("\n"); + buf.append(" public @Nullable String getFoo() {\n"); + buf.append(" return foo;\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" public void setFoo(@Nullable String foo) {\n"); + buf.append(" this.foo = foo;\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] {buf.toString()}); + } + @Test public void testBug525424() throws Exception { Hashtable options= JavaCore.getOptions(); try { diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest1d8Mix.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest1d8Mix.java index 7ad1db41..96802bac 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest1d8Mix.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/NullAnnotationsQuickFixTest1d8Mix.java @@ -96,7 +96,7 @@ public void setUp() throws Exception { if (ANNOTATION_JAR_PATH == null) { String version= "[1.1.0,2.0.0)"; // tests run at 1.8, but still use "old" null annotations Bundle[] bundles= Platform.getBundles("org.eclipse.jdt.annotation", version); - File bundleFile= FileLocator.getBundleFile(bundles[0]); + File bundleFile= FileLocator.getBundleFileLocation(bundles[0]).get(); if (bundleFile.isDirectory()) ANNOTATION_JAR_PATH= bundleFile.getPath() + "/bin"; else diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest.java index 360f14ee..c05e2ecd 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest.java @@ -353,6 +353,20 @@ protected static final ArrayList collectAssists(IInvoca return proposals; } + protected static final ArrayList collectAssistsWithProblems(IInvocationContext context) throws CoreException { + ArrayList proposals= new ArrayList<>(); + IProblem[] problems= context.getASTRoot().getProblems(); + IProblemLocation firstProblemLocation= new ProblemLocation(problems[0]); + IStatus status= JavaCorrectionProcessor.collectAssists(context, new IProblemLocation[] { firstProblemLocation }, proposals); + assertStatusOk(status); + + if (!proposals.isEmpty()) { + assertTrue("should be marked as 'has assist'", JavaCorrectionProcessor.hasAssists(context)); + } + + return proposals; + } + private static boolean isFiltered(Object curr, Class[] filteredTypes) { for (Class filteredType : filteredTypes) { if (filteredType.isInstance(curr)) { diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest17.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest17.java new file mode 100644 index 00000000..b4257684 --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest17.java @@ -0,0 +1,675 @@ +/******************************************************************************* + * Copyright (c) 2019, 2022 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ui.tests.quickfix; + +import java.util.ArrayList; + +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; + +import org.eclipse.jdt.testplugin.JavaProjectHelper; + +import org.eclipse.core.internal.expressions.Messages; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.dom.CompilationUnit; + +import org.eclipse.jdt.ui.tests.core.rules.Java17ProjectTestSetup; +import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; +import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; +import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal; + +import org.eclipse.jdt.internal.ui.text.correction.CorrectionMessages; + +public class QuickFixTest17 extends QuickFixTest { + + @Rule + public ProjectTestSetup projectsetup= new Java17ProjectTestSetup(false); + + private IJavaProject fJProject1; + + private IPackageFragmentRoot fSourceFolder; + + @After + public void tearDown() throws Exception { + if (fJProject1 != null) { + JavaProjectHelper.delete(fJProject1); + } + } + + @Test + public void testAddSealedMissingClassModifierProposal() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square {}\n" + + "\n" + + "class Square extends Shape {}\n"; + ICompilationUnit cu= pack1.createCompilationUnit("Shape.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 3); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview1= getPreviewContent(proposal); + + String expected1= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square {}\n" + + "\n" + + "final class Square extends Shape {}\n"; + + proposal= (CUCorrectionProposal) proposals.get(1); + String preview2= getPreviewContent(proposal); + + String expected2= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square {}\n" + + "\n" + + "non-sealed class Square extends Shape {}\n"; + + proposal= (CUCorrectionProposal) proposals.get(2); + String preview3= getPreviewContent(proposal); + + String expected3= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square {}\n" + + "\n" + + "sealed class Square extends Shape {}\n"; + + assertEqualStringsIgnoreOrder(new String[] { preview1, preview2, preview3 }, new String[] { expected1, expected2, expected3 }); + + } + + @Test + public void testAddSealedMissingInterfaceModifierProposal() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed interface Shape permits Square {}\n" + + "\n" + + "interface Square extends Shape {}\n"; + ICompilationUnit cu= pack1.createCompilationUnit("Shape.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview1= getPreviewContent(proposal); + + String expected1= "" + + "package test;\n" + + "\n" + + "public sealed interface Shape permits Square {}\n" + + "\n" + + "sealed interface Square extends Shape {}\n"; + + proposal= (CUCorrectionProposal) proposals.get(1); + String preview2= getPreviewContent(proposal); + + String expected2= "" + + "package test;\n" + + "\n" + + "public sealed interface Shape permits Square {}\n" + + "\n" + + "non-sealed interface Square extends Shape {}\n"; + + assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 }); + + } + + @Test + public void testAddSealedAsDirectSuperTypeProposal1() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square {\n" + + "}\n"; + pack1.createCompilationUnit("Shape.java", test, false, null); + + test= "" + + "package test;\n" + + "\n" + + "public non-sealed class Square extends Shape {\n" + + "}\n"; + pack1.createCompilationUnit("Square.java", test, false, null); + + test= "" + + "package test;\n" + + "\n" + + "public non-sealed class Circle extends Shape {\n" + + "}\n"; + ICompilationUnit cu2= pack1.createCompilationUnit("Circle.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu2); + ArrayList proposals= collectCorrections(cu2, astRoot, 1); + assertNumberOfProposals(proposals, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview= getPreviewContent(proposal); + + String expected= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square, Circle {\n" + + "}\n"; + + assertEqualString(preview, expected); + } + + @Test + public void testAddSealedAsDirectSuperTypeProposal2() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed interface Shape permits Square {\n" + + "}\n"; + pack1.createCompilationUnit("Shape.java", test, false, null); + + test= "" + + "package test;\n" + + "\n" + + "public non-sealed class Square implements Shape {\n" + + "}\n"; + pack1.createCompilationUnit("Square.java", test, false, null); + + test= "" + + "package test;\n" + + "\n" + + "public non-sealed class Circle implements Shape {\n" + + "}\n"; + ICompilationUnit cu2= pack1.createCompilationUnit("Circle.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu2); + ArrayList proposals= collectCorrections(cu2, astRoot, 1); + assertNumberOfProposals(proposals, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview= getPreviewContent(proposal); + + String expected= "" + + "package test;\n" + + "\n" + + "public sealed interface Shape permits Square, Circle {\n" + + "}\n"; + + assertEqualString(preview, expected); + } + + @Test + public void testAddSealedAsDirectSuperTypeProposal3() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed interface Shape permits Square {\n" + + "}\n"; + pack1.createCompilationUnit("Shape.java", test, false, null); + + test= "" + + "package test;\n" + + "\n" + + "public non-sealed class Square implements Shape {\n" + + "}\n"; + pack1.createCompilationUnit("Square.java", test, false, null); + + test= "" + + "package test;\n" + + "\n" + + "public non-sealed interface Circle extends Shape {\n" + + "}\n"; + ICompilationUnit cu2= pack1.createCompilationUnit("Circle.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu2); + ArrayList proposals= collectCorrections(cu2, astRoot, 1); + assertNumberOfProposals(proposals, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview= getPreviewContent(proposal); + + String expected= "" + + "package test;\n" + + "\n" + + "public sealed interface Shape permits Square, Circle {\n" + + "}\n"; + + assertEqualString(preview, expected); + } + + @Test + public void testAddSealedAsDirectSuperTypeProposal4() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit("module-info.java", MODULE_INFO_FILE_CONTENT, false, null); + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed interface Shape permits Square {\n" + + "}\n"; + pack1.createCompilationUnit("Shape.java", test, false, null); + + test= "" + + "package test;\n" + + "\n" + + "public non-sealed class Square implements Shape {\n" + + "}\n"; + pack1.createCompilationUnit("Square.java", test, false, null); + + + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + + test= "" + + "package test2;\n" + + "\n" + + "import test.Shape;\n" + + "\n" + + "public non-sealed interface Circle extends Shape {\n" + + "}\n"; + ICompilationUnit cu2= pack2.createCompilationUnit("Circle.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu2); + ArrayList proposals= collectCorrections(cu2, astRoot, 1); + assertNumberOfProposals(proposals, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview= getPreviewContent(proposal); + + String expected= "" + + "package test;\n" + + "\n" + + "import test2.Circle;\n" + + "\n" + + "public sealed interface Shape permits Square, Circle {\n" + + "}\n"; + + assertEqualString(preview, expected); + } + + @Test + public void testAddSealedAsDirectSuperInterface1() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits Circle {\\n" + + "\n" + + "}\n" + + "\n" + + "class Circle {\n" + + " \n" + + "}\n"; + ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 2); + assertNumberOfProposals(proposals, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview1= getPreviewContent(proposal); + + String expected1= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits Circle {\\n" + + "\n" + + "}\n" + + "\n" + + "class Circle implements IShape {\n" + + " \n" + + "}\n"; + + assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 }); + } + + @Test + public void testAddSealedAsDirectSuperInterface2() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits IRectangle {\\n" + + "\n" + + "}\n" + + "\n" + + "interface IRectangle {\n" + + " \n" + + "}\n"; + ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 2); + assertNumberOfProposals(proposals, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview1= getPreviewContent(proposal); + + String expected1= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits IRectangle {\\n" + + "\n" + + "}\n" + + "\n" + + "interface IRectangle extends IShape {\n" + + " \n" + + "}\n"; + + assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 }); + } + + @Test + public void testAddSealedAsDirectSuperInterface3() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "import java.lang.annotation.IncompleteAnnotationException;\n" + + "\n" + + "public sealed interface IShape permits IncompleteAnnotationException {\\n" + + "\n" + + "}\n"; + ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 3); + assertNumberOfProposals(proposals, 0); + } + + @Test + public void testAddSealedAsDirectSuperInterface4() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + + IPackageFragment defaultPkg= fSourceFolder.createPackageFragment("", false, null); + defaultPkg.createCompilationUnit("module-info.java", MODULE_INFO_FILE_CONTENT, false, null); + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String test= "" + + "package test1;\n" + + "\n" + + "import test2.IRectangle;\n" + + "\n" + + "public sealed interface IShape permits IRectangle {\n" + + "}\n"; + ICompilationUnit cu1= pack1.createCompilationUnit("IShape.java", test, false, null); + + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + test= "" + + "package test2;\n" + + "\n" + + "public interface IRectangle {\n" + + "}\n"; + pack2.createCompilationUnit("IRectangle.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu1); + ArrayList proposals= collectCorrections(cu1, astRoot, 1); + assertNumberOfProposals(proposals, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview= getPreviewContent(proposal); + + String expected= "" + + "package test2;\n" + + "\n" + + "import test1.IShape;\n" + + "\n" + + "public interface IRectangle extends IShape {\n" + + "}\n"; + assertEqualString(preview, expected); + } + + @Test + public void testAddSealedAsDirectSuperClass1() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Circle {\\n" + + "\n" + + "}\n" + + "\n" + + "class Circle extends AssertionError {\n" + + " \n" + + "}\n"; + ICompilationUnit cu= pack1.createCompilationUnit("Shape.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 3); + assertNumberOfProposals(proposals, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + String preview1= getPreviewContent(proposal); + + String expected1= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Circle {\\n" + + "\n" + + "}\n" + + "\n" + + "class Circle extends Shape {\n" + + " \n" + + "}\n"; + + assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 }); + } + + @Test + public void testAddRecordAsSubType() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits Circle, Square {\\n" + + "\n" + + "}\n" + + "\n" + + "class Circle implements IShape {\n" + + " \n" + + "}\n"; + ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null); + String expectedProposal= Messages.format(CorrectionMessages.NewCUCompletionUsingWizardProposal_createrecord_description, "Square"); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 3); + assertProposalExists(proposals, expectedProposal); + } + + @Test + public void testDoNotAddRecordAsSubType() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Circle, Square {\\n" + + "\n" + + "}\n" + + "\n" + + "class Circle extends Shape {\n" + + " \n" + + "}\n"; + ICompilationUnit cu= pack1.createCompilationUnit("Shape.java", test, false, null); + String expectedProposal= Messages.format(CorrectionMessages.NewCUCompletionUsingWizardProposal_createrecord_description, "Square"); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 3); + assertProposalDoesNotExist(proposals, expectedProposal); + } + + @Test + public void testCreatePermittedNewSubType1() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed class Shape {\n" + + "\n" + + "}\n" + + "\n"; + ICompilationUnit cu= pack1.createCompilationUnit("Shape.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + String expectedProposal1= CorrectionMessages.NewCUCompletionUsingWizardProposal_createnewinnerclass_description; + String expectedProposal2= Messages.format(CorrectionMessages.NewCUCompletionUsingWizardProposal_createnewclass_inpackage_description, "test"); + assertProposalExists(proposals, expectedProposal1); + assertProposalExists(proposals, expectedProposal2); + } + + @Test + public void testCreatePermittedNewSubType2() throws Exception { + fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); + fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); + JavaProjectHelper.set17CompilerOptions(fJProject1, false); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); + + String test= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape {\n" + + "\n" + + "}\n" + + "\n"; + ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 6); + assertCorrectLabels(proposals); + String expectedProposal1= CorrectionMessages.NewCUCompletionUsingWizardProposal_createnewinnerclass_description; + String expectedProposal2= Messages.format(CorrectionMessages.NewCUCompletionUsingWizardProposal_createnewclass_inpackage_description, "test"); + String expectedProposal3= CorrectionMessages.NewCUCompletionUsingWizardProposal_createnewinnerrecord_description; + String expectedProposal4= Messages.format(CorrectionMessages.NewCUCompletionUsingWizardProposal_createnewrecord_inpackage_description, "test"); + String expectedProposal5= CorrectionMessages.NewCUCompletionUsingWizardProposal_createnewinnerinterface_description; + String expectedProposal6= Messages.format(CorrectionMessages.NewCUCompletionUsingWizardProposal_createnewinterface_inpackage_description, "test"); + + assertProposalExists(proposals, expectedProposal1); + assertProposalExists(proposals, expectedProposal2); + assertProposalExists(proposals, expectedProposal3); + assertProposalExists(proposals, expectedProposal4); + assertProposalExists(proposals, expectedProposal5); + assertProposalExists(proposals, expectedProposal6); + } + +} diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest1d8.java index 17e8a995..e95b1014 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest1d8.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2020 IBM Corporation and others. + * Copyright (c) 2013, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -40,6 +40,7 @@ import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.core.manipulation.CodeTemplateContextType; import org.eclipse.jdt.internal.core.manipulation.StubUtility; @@ -51,6 +52,7 @@ import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.text.correction.AssistContext; +import org.eclipse.jdt.internal.ui.text.correction.CorrectionMessages; /** * Those tests are made to run on Java Spider 1.8 . @@ -71,7 +73,6 @@ public void setUp() throws Exception { options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE, JavaCore.DO_NOT_INSERT); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ANNOTATIONS_ON_LOCAL_VARIABLE, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_NO_SPLIT)); - JavaCore.setOptions(options); IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); @@ -2374,4 +2375,147 @@ public void testBug496103_createParam() throws Exception { assertExpectedExistInProposals(proposals, new String[] {expected}); } + // bug 576502 : try-with-resources quick fix should be offered for resource leaks + @Test + public void testBug576502_potentiallyUnclosedCloseable() throws Exception { + Hashtable options = JavaCore.getOptions(); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); + JavaCore.setOptions(options); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test1", false, null); + + + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import java.io.File;\n"); + buf.append("import java.io.FileReader;\n"); + buf.append("import java.io.IOException;\n"); + buf.append("class E {\n"); + buf.append(" public void foo() throws IOException {\n"); + buf.append(" final File file = new File(\"somefile\");\n"); + buf.append(" FileReader fileReader = new FileReader(file);\n"); + buf.append(" char[] in = new char[50];\n"); + buf.append(" fileReader.read(in);\n"); + buf.append(" new Runnable() {\n"); + buf.append(" public void run() { \n"); + buf.append(" try {\n"); + buf.append(" fileReader.close();\n"); + buf.append(" } catch (IOException ex) { /* nop */ }\n"); + buf.append(" }}.run();\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append(""); + + + ICompilationUnit cu= pack2.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import java.io.File;\n"); + buf.append("import java.io.FileReader;\n"); + buf.append("import java.io.IOException;\n"); + buf.append("class E {\n"); + buf.append(" public void foo() throws IOException {\n"); + buf.append(" final File file = new File(\"somefile\");\n"); + buf.append(" try (FileReader fileReader = new FileReader(file)) {\n"); + buf.append(" char[] in = new char[50];\n"); + buf.append(" fileReader.read(in);\n"); + buf.append(" new Runnable() {\n"); + buf.append(" public void run() { \n"); + buf.append(" try {\n"); + buf.append(" fileReader.close();\n"); + buf.append(" } catch (IOException ex) { /* nop */ }\n"); + buf.append(" }}.run();\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append(""); + String expected= buf.toString(); + + assertExpectedExistInProposals(proposals, new String[] {expected}); + } + + // bug 576502 : try-with-resources quick fix should be offered for resource leaks + @Test + public void testBug576502_unclosedCloseable() throws Exception { + Hashtable options = JavaCore.getOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + JavaCore.setOptions(options); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test1", false, null); + + + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import java.io.File;\n"); + buf.append("import java.io.FileReader;\n"); + buf.append("import java.io.IOException;\n"); + buf.append("class E {\n"); + buf.append(" public void foo(boolean f1, boolean f2) throws IOException {\n"); + buf.append(" File file = new File(\"somefile\");\n"); + buf.append(" if (f1) {\n"); + buf.append(" FileReader fileReader = new FileReader(file); // err: not closed\n"); + buf.append(" char[] in = new char[50];\n"); + buf.append(" fileReader.read(in);\n"); + buf.append(" while (true) {\n"); + buf.append(" FileReader loopReader = new FileReader(file); // don't warn, properly closed\n"); + buf.append(" loopReader.close();\n"); + buf.append(" break;\n"); + buf.append(" }\n"); + buf.append(" } else {\n"); + buf.append(" FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n"); + buf.append(" if (f2)\n"); + buf.append(" fileReader.close();\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append(""); + + + ICompilationUnit cu= pack2.createCompilationUnit("E.java", buf.toString(), false, null); + String str= "fileReader"; + AssistContext context= getCorrectionContext(cu, buf.toString().indexOf(str), 0); + + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("import java.io.File;\n"); + buf.append("import java.io.FileReader;\n"); + buf.append("import java.io.IOException;\n"); + buf.append("class E {\n"); + buf.append(" public void foo(boolean f1, boolean f2) throws IOException {\n"); + buf.append(" File file = new File(\"somefile\");\n"); + buf.append(" if (f1) {\n"); + buf.append(" try (FileReader fileReader = new FileReader(file)) {\n"); + buf.append(" char[] in = new char[50];\n"); + buf.append(" fileReader.read(in);\n"); + buf.append(" }\n"); + buf.append(" while (true) {\n"); + buf.append(" FileReader loopReader = new FileReader(file); // don't warn, properly closed\n"); + buf.append(" loopReader.close();\n"); + buf.append(" break;\n"); + buf.append(" }\n"); + buf.append(" } else {\n"); + buf.append(" FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n"); + buf.append(" if (f2)\n"); + buf.append(" fileReader.close();\n"); + buf.append(" }\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append(""); + String expected= buf.toString(); + + // bug 576701 - ensure we don't duplicate try-with-resources as assist as well + assertExpectedExistInProposals(proposals, new String[] {expected}); + + List assists= collectAssistsWithProblems(context); + assertProposalDoesNotExist(assists, CorrectionMessages.QuickAssistProcessor_convert_to_try_with_resource); + } + } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestPreview.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestPreview.java index 10e00d8b..02b64cad 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestPreview.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestPreview.java @@ -13,35 +13,24 @@ *******************************************************************************/ package org.eclipse.jdt.ui.tests.quickfix; -import java.util.ArrayList; -import java.util.Map; - import org.junit.After; import org.junit.Rule; -import org.junit.Test; import org.eclipse.jdt.testplugin.JavaProjectHelper; -import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IPackageFragment; -import org.eclipse.jdt.core.IPackageFragmentRoot; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.ui.tests.core.rules.Java16ProjectTestSetup; import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; -import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; -import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal; public class QuickFixTestPreview extends QuickFixTest { - @Rule - public ProjectTestSetup projectsetup = new Java16ProjectTestSetup(true); + @Rule + public ProjectTestSetup projectsetup= new Java16ProjectTestSetup(true); - private IJavaProject fJProject1; + private IJavaProject fJProject1; - private IPackageFragmentRoot fSourceFolder; +// private IPackageFragmentRoot fSourceFolder; @After public void tearDown() throws Exception { @@ -50,549 +39,4 @@ public void tearDown() throws Exception { } } - @Test - public void testAddSealedMissingClassModifierProposal() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test= "" + - "package test;\n" + - "\n" + - "public sealed class Shape permits Square {}\n" + - "\n" + - "class Square extends Shape {}\n"; - ICompilationUnit cu= pack1.createCompilationUnit("Shape.java",test, false, null); - - CompilationUnit astRoot= getASTRoot(cu); - ArrayList proposals= collectCorrections(cu, astRoot, 1); - assertNumberOfProposals(proposals, 3); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview1= getPreviewContent(proposal); - - String expected1= "" + - "package test;\n" + - "\n" + - "public sealed class Shape permits Square {}\n" + - "\n" + - "final class Square extends Shape {}\n"; - - proposal= (CUCorrectionProposal) proposals.get(1); - String preview2= getPreviewContent(proposal); - - String expected2= "" + - "package test;\n" + - "\n" + - "public sealed class Shape permits Square {}\n" + - "\n" + - "non-sealed class Square extends Shape {}\n"; - - proposal= (CUCorrectionProposal) proposals.get(2); - String preview3= getPreviewContent(proposal); - - String expected3= "" + - "package test;\n" + - "\n" + - "public sealed class Shape permits Square {}\n" + - "\n" + - "sealed class Square extends Shape {}\n"; - - assertEqualStringsIgnoreOrder(new String[] { preview1, preview2, preview3 }, new String[] { expected1, expected2, expected3 }); - - } - - @Test - public void testAddSealedMissingInterfaceModifierProposal() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test = "" + - "package test;\n" + - "\n" + - "public sealed interface Shape permits Square {}\n" + - "\n" + - "interface Square extends Shape {}\n"; - ICompilationUnit cu= pack1.createCompilationUnit("Shape.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu); - ArrayList proposals= collectCorrections(cu, astRoot, 1); - assertNumberOfProposals(proposals, 2); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview1= getPreviewContent(proposal); - - String expected1= "" + - "package test;\n" + - "\n" + - "public sealed interface Shape permits Square {}\n" + - "\n" + - "sealed interface Square extends Shape {}\n"; - - proposal= (CUCorrectionProposal) proposals.get(1); - String preview2= getPreviewContent(proposal); - - String expected2= "" + - "package test;\n" + - "\n" + - "public sealed interface Shape permits Square {}\n" + - "\n" + - "non-sealed interface Square extends Shape {}\n"; - - assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 }); - - } - - @Test - public void testAddSealedAsDirectSuperTypeProposal1() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test= "" + - "package test;\n" + - "\n" + - "public sealed class Shape permits Square {\n" + - "}\n"; - pack1.createCompilationUnit("Shape.java", test, false, null); - - test= "" + - "package test;\n" + - "\n" + - "public non-sealed class Square extends Shape {\n" + - "}\n"; - pack1.createCompilationUnit("Square.java", test, false, null); - - test= "" + - "package test;\n" + - "\n" + - "public non-sealed class Circle extends Shape {\n" + - "}\n"; - ICompilationUnit cu2= pack1.createCompilationUnit("Circle.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu2); - ArrayList proposals= collectCorrections(cu2, astRoot, 1); - assertNumberOfProposals(proposals, 1); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview= getPreviewContent(proposal); - - String expected= "" + - "package test;\n" + - "\n" + - "public sealed class Shape permits Square, Circle {\n" + - "}\n"; - - assertEqualString(preview, expected); - } - - @Test - public void testAddSealedAsDirectSuperTypeProposal2() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test= "" + - "package test;\n" + - "\n" + - "public sealed interface Shape permits Square {\n" + - "}\n"; - pack1.createCompilationUnit("Shape.java", test, false, null); - - test= "" + - "package test;\n" + - "\n" + - "public non-sealed class Square implements Shape {\n" + - "}\n"; - pack1.createCompilationUnit("Square.java", test, false, null); - - test= "" + - "package test;\n" + - "\n" + - "public non-sealed class Circle implements Shape {\n" + - "}\n"; - ICompilationUnit cu2= pack1.createCompilationUnit("Circle.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu2); - ArrayList proposals= collectCorrections(cu2, astRoot, 1); - assertNumberOfProposals(proposals, 1); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview= getPreviewContent(proposal); - - String expected= "" + - "package test;\n" + - "\n" + - "public sealed interface Shape permits Square, Circle {\n" + - "}\n"; - - assertEqualString(preview, expected); - } - - @Test - public void testAddSealedAsDirectSuperTypeProposal3() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test= "" + - "package test;\n" + - "\n" + - "public sealed interface Shape permits Square {\n" + - "}\n"; - pack1.createCompilationUnit("Shape.java", test, false, null); - - test= "" + - "package test;\n" + - "\n" + - "public non-sealed class Square implements Shape {\n" + - "}\n"; - pack1.createCompilationUnit("Square.java", test, false, null); - - test= "" + - "package test;\n" + - "\n" + - "public non-sealed interface Circle extends Shape {\n" + - "}\n"; - ICompilationUnit cu2= pack1.createCompilationUnit("Circle.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu2); - ArrayList proposals= collectCorrections(cu2, astRoot, 1); - assertNumberOfProposals(proposals, 1); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview= getPreviewContent(proposal); - - String expected= "" + - "package test;\n" + - "\n" + - "public sealed interface Shape permits Square, Circle {\n" + - "}\n"; - - assertEqualString(preview, expected); - } - - @Test - public void testAddSealedAsDirectSuperTypeProposal4() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - - IPackageFragment def= fSourceFolder.createPackageFragment("", false, null); - def.createCompilationUnit("module-info.java", MODULE_INFO_FILE_CONTENT, false, null); - - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test= "" + - "package test;\n" + - "\n" + - "public sealed interface Shape permits Square {\n" + - "}\n"; - pack1.createCompilationUnit("Shape.java", test, false, null); - - test= "" + - "package test;\n" + - "\n" + - "public non-sealed class Square implements Shape {\n" + - "}\n"; - pack1.createCompilationUnit("Square.java", test, false, null); - - - IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); - - test= "" + - "package test2;\n" + - "\n" + - "import test.Shape;\n" + - "\n" + - "public non-sealed interface Circle extends Shape {\n" + - "}\n"; - ICompilationUnit cu2= pack2.createCompilationUnit("Circle.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu2); - ArrayList proposals= collectCorrections(cu2, astRoot, 1); - assertNumberOfProposals(proposals, 1); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview= getPreviewContent(proposal); - - String expected= "" + - "package test;\n" + - "\n" + - "import test2.Circle;\n" + - "\n" + - "public sealed interface Shape permits Square, Circle {\n" + - "}\n"; - - assertEqualString(preview, expected); - } - - @Test - public void testAddSealedAsDirectSuperInterface1() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test= "" + - "package test;\n" + - "\n" + - "public sealed interface IShape permits Circle {\\n" + - "\n" + - "}\n" + - "\n" + - "class Circle {\n" + - " \n" + - "}\n"; - ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu); - ArrayList proposals= collectCorrections(cu, astRoot, 2); - assertNumberOfProposals(proposals, 1); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview1= getPreviewContent(proposal); - - String expected1= "" + - "package test;\n" + - "\n" + - "public sealed interface IShape permits Circle {\\n" + - "\n" + - "}\n" + - "\n" + - "class Circle implements IShape {\n" + - " \n" + - "}\n"; - - assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 }); - } - - @Test - public void testAddSealedAsDirectSuperInterface2() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test= "" + - "package test;\n" + - "\n" + - "public sealed interface IShape permits IRectangle {\\n" + - "\n" + - "}\n" + - "\n" + - "interface IRectangle {\n" + - " \n" + - "}\n"; - ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu); - ArrayList proposals= collectCorrections(cu, astRoot, 2); - assertNumberOfProposals(proposals, 1); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview1= getPreviewContent(proposal); - - String expected1= "" + - "package test;\n" + - "\n" + - "public sealed interface IShape permits IRectangle {\\n" + - "\n" + - "}\n" + - "\n" + - "interface IRectangle extends IShape {\n" + - " \n" + - "}\n"; - - assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 }); - } - - @Test - public void testAddSealedAsDirectSuperInterface3() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test= "" + - "package test;\n" + - "\n" + - "import java.lang.annotation.IncompleteAnnotationException;\n" + - "\n" + - "public sealed interface IShape permits IncompleteAnnotationException {\\n" + - "\n" + - "}\n"; - ICompilationUnit cu= pack1.createCompilationUnit("IShape.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu); - ArrayList proposals= collectCorrections(cu, astRoot, 3); - assertNumberOfProposals(proposals, 0); - } - - @Test - public void testAddSealedAsDirectSuperInterface4() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - - IPackageFragment defaultPkg= fSourceFolder.createPackageFragment("", false, null); - defaultPkg.createCompilationUnit("module-info.java", MODULE_INFO_FILE_CONTENT, false, null); - - IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); - String test= "" + - "package test1;\n" + - "\n" + - "import test2.IRectangle;\n" + - "\n" + - "public sealed interface IShape permits IRectangle {\n" + - "}\n"; - ICompilationUnit cu1= pack1.createCompilationUnit("IShape.java", test, false, null); - - IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); - test= "" + - "package test2;\n" + - "\n" + - "public interface IRectangle {\n" + - "}\n"; - pack2.createCompilationUnit("IRectangle.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu1); - ArrayList proposals= collectCorrections(cu1, astRoot, 1); - assertNumberOfProposals(proposals, 1); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview= getPreviewContent(proposal); - - String expected= "" + - "package test2;\n" + - "\n" + - "import test1.IShape;\n" + - "\n" + - "public interface IRectangle extends IShape {\n" + - "}\n"; - assertEqualString(preview, expected); - } - - @Test - public void testAddSealedAsDirectSuperClass1() throws Exception { - fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin"); - fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null); - JavaProjectHelper.set16CompilerOptions(fJProject1, true); - - Map options= fJProject1.getOptions(false); - options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE); - fJProject1.setOptions(options); - - fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); - IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); - - String test= "" + - "package test;\n" + - "\n" + - "public sealed class Shape permits Circle {\\n" + - "\n" + - "}\n" + - "\n" + - "class Circle extends AssertionError {\n" + - " \n" + - "}\n"; - ICompilationUnit cu= pack1.createCompilationUnit("Shape.java", test, false, null); - - CompilationUnit astRoot= getASTRoot(cu); - ArrayList proposals= collectCorrections(cu, astRoot, 3); - assertNumberOfProposals(proposals, 1); - assertCorrectLabels(proposals); - - CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); - String preview1= getPreviewContent(proposal); - - String expected1= "" + - "package test;\n" + - "\n" + - "public sealed class Shape permits Circle {\\n" + - "\n" + - "}\n" + - "\n" + - "class Circle extends Shape {\n" + - " \n" + - "}\n"; - - assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 }); - } - } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestSuite.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestSuite.java index d27cd626..152e33bc 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestSuite.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTestSuite.java @@ -23,13 +23,14 @@ QuickFixTest1d8.class, QuickFixTest14.class, QuickFixTest15.class, - QuickFixTestPreview.class, + QuickFixTest17.class, SerialVersionQuickFixTest.class, UtilitiesTest.class, UnresolvedTypesQuickFixTest.class, UnresolvedVariablesQuickFixTest.class, UnresolvedMethodsQuickFixTest.class, UnresolvedMethodsQuickFixTest1d8.class, + UnresolvedMethodsQuickFixTest16.class, ReturnTypeQuickFixTest.class, LocalCorrectionsQuickFixTest.class, LocalCorrectionsQuickFixTest1d7.class, @@ -43,7 +44,10 @@ AssistQuickFixTest.class, AssistQuickFixTest1d7.class, AssistQuickFixTest1d8.class, + AssistQuickFixTest10.class, AssistQuickFixTest12.class, + AssistQuickFixTest14.class, + AssistQuickFixTest15.class, ChangeNonStaticToStaticTest.class, MarkerResolutionTest.class, JavadocQuickFixTest.class, diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/TypeMismatchQuickFixTests.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/TypeMismatchQuickFixTests.java index cb021c00..f2e2fa00 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/TypeMismatchQuickFixTests.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/TypeMismatchQuickFixTests.java @@ -1692,7 +1692,7 @@ public void testMismatchingExceptions1() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); - buf.append("import java.io.IOException;\n"); + buf.append("\n"); buf.append("public class E implements IBase {\n"); buf.append(" public String[] getValues() {\n"); buf.append(" return null;\n"); @@ -1752,7 +1752,6 @@ public void testMismatchingExceptions2() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); buf.append("import java.io.EOFException;\n"); - buf.append("import java.text.ParseException;\n"); buf.append("public class E extends Base {\n"); buf.append(" public String[] getValues() throws EOFException {\n"); buf.append(" return null;\n"); @@ -1834,7 +1833,6 @@ public void testMismatchingExceptions3() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); buf.append("import java.io.EOFException;\n"); - buf.append("import java.text.ParseException;\n"); buf.append("public class E extends Base {\n"); buf.append(" /**\n"); buf.append(" * @param i The parameter\n"); @@ -1894,7 +1892,7 @@ public void testMismatchingExceptionsOnGeneric() throws Exception { buf= new StringBuilder(); buf.append("package test1;\n"); - buf.append("import java.io.IOException;\n"); + buf.append("\n"); buf.append("public class E implements IBase {\n"); buf.append(" public String[] getValues() {\n"); buf.append(" return null;\n"); diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedMethodsQuickFixTest16.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedMethodsQuickFixTest16.java new file mode 100644 index 00000000..e9440669 --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedMethodsQuickFixTest16.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2022 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ui.tests.quickfix; + +import java.util.ArrayList; +import java.util.Hashtable; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.eclipse.jdt.testplugin.JavaProjectHelper; +import org.eclipse.jdt.testplugin.TestOptions; + +import org.eclipse.jface.preference.IPreferenceStore; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; + +import org.eclipse.jdt.internal.core.manipulation.CodeTemplateContextType; +import org.eclipse.jdt.internal.core.manipulation.StubUtility; + +import org.eclipse.jdt.ui.PreferenceConstants; +import org.eclipse.jdt.ui.tests.core.rules.Java16ProjectTestSetup; +import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; +import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; +import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal; + +import org.eclipse.jdt.internal.ui.JavaPlugin; + +public class UnresolvedMethodsQuickFixTest16 extends QuickFixTest { + + @Rule + public ProjectTestSetup projectSetup = new Java16ProjectTestSetup(false); + + private IJavaProject fJProject1; + private IPackageFragmentRoot fSourceFolder; + + @Before + public void setUp() throws Exception { + Hashtable options= TestOptions.getDefaultOptions(); + options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE); + options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4"); + options.put(JavaCore.COMPILER_PB_NO_EFFECT_ASSIGNMENT, JavaCore.IGNORE); + options.put(JavaCore.CODEASSIST_FIELD_PREFIXES, "f"); + options.put(JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES, "fg"); + JavaCore.setOptions(options); + + IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); + store.setValue(PreferenceConstants.CODEGEN_ADD_COMMENTS, false); + + fJProject1= projectSetup.getProject(); + + StubUtility.setCodeTemplate(CodeTemplateContextType.CATCHBLOCK_ID, "", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.CONSTRUCTORSTUB_ID, "", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.METHODSTUB_ID, "", null); + + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + } + + @After + public void tearDown() throws Exception { + JavaProjectHelper.clear(fJProject1, projectSetup.getDefaultClasspath()); + } + + /* + * Test that compiler-generated methods like toString() are not added when + * invoking "Add unimplemented methods". + */ + @Test + public void testMethodInRecord() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("interface Snippet {\n"); + buf.append(" String name();\n"); + buf.append("}\n\n"); + buf.append("public record XX(String bla) implements Snippet {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("XX.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 1); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("interface Snippet {\n"); + buf.append(" String name();\n"); + buf.append("}\n\n"); + buf.append("public record XX(String bla) implements Snippet {\n"); + buf.append("\n"); + buf.append(" @Override\n"); + buf.append(" public String name() {\n"); + buf.append(" return null;\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEqualStringsIgnoreOrder(new String[] { getPreviewContent(proposal) }, new String[] { buf.toString() }); + } + +} diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedMethodsQuickFixTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedMethodsQuickFixTest1d8.java index 193227aa..f1b3ba2a 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedMethodsQuickFixTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedMethodsQuickFixTest1d8.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2020 IBM Corporation and others. + * Copyright (c) 2014, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -401,6 +401,159 @@ public void testCreateMethodQuickFix7() throws Exception { buf.append("}\n"); assertEqualStringsIgnoreOrder(new String[] { getPreviewContent(proposal) }, new String[] { buf.toString() }); } + + @Test + public void testCreateMethodIssue322_1() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static void test(T a) {\n"); + buf.append(" test(a, a); // error here\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 3); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static void test(T a) {\n"); + buf.append(" test(a, a); // error here\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" private static void test(T a, T a2) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + + @Test + public void testCreateMethodIssue322_2() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static void test(T a, U b) {\n"); + buf.append(" test(a);\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 3); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static void test(T a, U b) {\n"); + buf.append(" test(a);\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" private static void test(T a) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + + @Test + public void testCreateMethodIssue322_3() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static void test(T a, U b) {\n"); + buf.append(" test(a);\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 3); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static void test(T a, U b) {\n"); + buf.append(" test(a);\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" private static void test(T a) {\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + + @Test + public void testCreateMethodIssue322_4() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static U test(T a, U b) {\n"); + buf.append(" return test(a);\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 3); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static U test(T a, U b) {\n"); + buf.append(" return test(a);\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" private static U test(T a) {\n"); + buf.append(" return null;\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + + @Test + public void testCreateMethodIssue322_5() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static U test(T a) {\n"); + buf.append(" return test(a, a);\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 3); + assertCorrectLabels(proposals); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("public class E {\n"); + buf.append(" public static U test(T a) {\n"); + buf.append(" return test(a, a);\n"); + buf.append(" }\n"); + buf.append("\n"); + buf.append(" private static U test(T a, T a2) {\n"); + buf.append(" return null;\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertExpectedExistInProposals(proposals, new String[] { buf.toString() }); + } + @Test public void testBug514213_avoidRedundantNonNullWhenCreatingMissingMethodForOverride() throws Exception { Hashtable options= JavaCore.getOptions(); @@ -659,4 +812,57 @@ public void testBug528876() throws Exception { } } + /* + * Test that a default method that is overridden with an abstract method is + * added when invoking "Add unimplemented methods" + */ + @Test + public void testOverrideDefaultMethod() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + StringBuilder buf= new StringBuilder(); + + buf.append("package test1;\n"); + buf.append("interface I1 {\n"); + buf.append(" default int gogo() {\n"); + buf.append(" return 24;\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface I2 extends I1 {\n"); + buf.append(" int gogo();\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("public class XX implements I1, I2 {\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("XX.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1); + assertNumberOfProposals(proposals, 2); + assertCorrectLabels(proposals); + + CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0); + + buf= new StringBuilder(); + buf.append("package test1;\n"); + buf.append("interface I1 {\n"); + buf.append(" default int gogo() {\n"); + buf.append(" return 24;\n"); + buf.append(" }\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("interface I2 extends I1 {\n"); + buf.append(" int gogo();\n"); + buf.append("}\n"); + buf.append("\n"); + buf.append("public class XX implements I1, I2 {\n"); + buf.append("\n"); + buf.append(" @Override\n"); + buf.append(" public int gogo() {\n"); + buf.append(" return 0;\n"); + buf.append(" }\n"); + buf.append("}\n"); + assertEqualStringsIgnoreOrder(new String[] { getPreviewContent(proposal) }, new String[] { buf.toString() }); + } + } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedTypesQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedTypesQuickFixTest.java index 3eaa299c..3740b9e7 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedTypesQuickFixTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedTypesQuickFixTest.java @@ -1642,4 +1642,35 @@ public void testBug530193() throws Exception { ArrayList proposals= collectCorrections(cu1, astRoot, 2, 1); assertFalse(proposals.stream().anyMatch(p -> "Import 'Tests' (pt)".equals(p.getDisplayString()))); } + + @Test + public void testBug321464() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("pack", false, null); + StringBuilder buf= new StringBuilder(); + buf.append("package pack;\n"); + buf.append("\n"); + buf.append("class E {\n"); + buf.append(" public static class StaticInner {\n"); + buf.append(" }\n"); + buf.append("}\n"); + ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1, 0); + + assertCorrectLabels(proposals); + + String[] expected= new String[1]; + buf= new StringBuilder(); + buf.append("package pack;\n"); + buf.append("\n"); + buf.append("class E {\n"); + buf.append(" public static class StaticInner {\n"); + buf.append(" }\n"); + buf.append("}\n"); + expected[0]= buf.toString(); + + assertExpectedExistInProposals(proposals, expected); + } + } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest.java index 09223d73..712421bb 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest.java @@ -17,6 +17,8 @@ package org.eclipse.jdt.ui.tests.wizardapi; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Hashtable; @@ -31,6 +33,8 @@ import org.eclipse.jdt.testplugin.StringAsserts; import org.eclipse.jdt.testplugin.TestOptions; +import org.eclipse.core.runtime.IStatus; + import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.StructuredSelection; @@ -43,10 +47,16 @@ import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.jdt.internal.core.manipulation.CodeTemplateContextType; import org.eclipse.jdt.internal.core.manipulation.StubUtility; +import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving; +import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; +import org.eclipse.jdt.internal.corext.util.Messages; import org.eclipse.jdt.ui.PreferenceConstants; import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; @@ -58,6 +68,7 @@ import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; +import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; /** * @@ -797,4 +808,48 @@ public void testAttemptCreateExistingClass() throws Exception String actual= wizardPage.getCreatedType().getCompilationUnit().getElementName(); assertEquals("Foo3.java", actual); } + + @Test + public void testAddFinalSuperClassError1() throws Exception { + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String test= "" + + "package test1;\n" + + "\n" + + "public final class A{\n" + + "}\n"; + ICompilationUnit superClsUnit= pack1.createCompilationUnit("A.java", test, false, null); + ITypeBinding superCls= getTypeBinding(superClsUnit); + + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(pack1, true); + wizardPage.setTypeName("E", true); + wizardPage.setSuperClass(superCls, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfaces(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + String sclassName= wizardPage.getSuperClass(); + String expected= Messages.format(NewWizardMessages.NewTypeWizardPage_error_InvalidFinalSuperClass, BasicElementLabels.getJavaElementName(sclassName)); + + IStatus status= wizardPage.getSuperClassStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(expected.equals(status.getMessage())); + } + + private static ITypeBinding getTypeBinding(ICompilationUnit cu) { + CompilationUnit compUnit= ASTResolving.createQuickFixAST(cu, null); + ITypeBinding tBinding= null; + if (compUnit != null) { + Object typeDecl= compUnit.types().get(0); + if (typeDecl instanceof AbstractTypeDeclaration) { + tBinding= ((AbstractTypeDeclaration) typeDecl).resolveBinding(); + } + } + return tBinding; + } } diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest17.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest17.java new file mode 100644 index 00000000..513ab78b --- /dev/null +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest17.java @@ -0,0 +1,1424 @@ +/******************************************************************************* + * Copyright (c) 2021 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.jdt.ui.tests.wizardapi; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.eclipse.jdt.testplugin.JavaProjectHelper; +import org.eclipse.jdt.testplugin.StringAsserts; +import org.eclipse.jdt.testplugin.TestOptions; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; + +import org.eclipse.jface.preference.IPreferenceStore; + +import org.eclipse.jdt.core.Flags; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; + +import org.eclipse.jdt.internal.core.manipulation.CodeTemplateContextType; +import org.eclipse.jdt.internal.core.manipulation.StubUtility; +import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving; +import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; +import org.eclipse.jdt.internal.corext.util.Messages; + +import org.eclipse.jdt.ui.PreferenceConstants; +import org.eclipse.jdt.ui.tests.core.rules.Java17ProjectTestSetup; +import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup; +import org.eclipse.jdt.ui.tests.quickfix.QuickFixTest14; +import org.eclipse.jdt.ui.wizards.NewClassWizardPage; +import org.eclipse.jdt.ui.wizards.NewInterfaceWizardPage; +import org.eclipse.jdt.ui.wizards.NewRecordWizardPage; + +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; + +/** + * + */ +public class NewTypeWizardTest17 { + private IJavaProject fJProject1, fJProject2; + + private IJavaProject fJProjectM1, fJProjectM2; + + private IPackageFragmentRoot fSourceFolder, fMSourceFolder; + + private IPackageFragment fpack1, fMpack1; + + private ICompilationUnit fSealedSuperCls, fSealedSuperInterface, fMSealedSuperCls, fMSealedSuperInterface; + + private ITypeBinding fSealedClsBinding, fSealedInterfaceBinding, fMSealedClsBinding, fMSealedInterfaceBinding; + + @Rule + public ProjectTestSetup projectSetup= new Java17ProjectTestSetup(false); + + @Rule + public ProjectTestSetup projectSetup2= new Java17ProjectTestSetup(Java17ProjectTestSetup.PROJECT_NAME17 + "_2", false); + + @Rule + public ProjectTestSetup projectMSetup= new Java17ProjectTestSetup(Java17ProjectTestSetup.PROJECT_NAME17 + "_M", false); + + @Rule + public ProjectTestSetup projectMSetup2= new Java17ProjectTestSetup(Java17ProjectTestSetup.PROJECT_NAME17 + "_M_2", false); + + @Before + public void setUp() throws Exception { + Hashtable options= TestOptions.getDefaultOptions(); + options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE); + options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4"); + JavaCore.setOptions(options); + + IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); + store.setValue(PreferenceConstants.CODEGEN_ADD_COMMENTS, false); + store.setValue(PreferenceConstants.CODEGEN_USE_OVERRIDE_ANNOTATION, true); + + String newFileTemplate= "${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}"; + StubUtility.setCodeTemplate(CodeTemplateContextType.NEWTYPE_ID, newFileTemplate, null); + StubUtility.setCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID, "/**\n * Type\n */", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, "/**\n * File\n */", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.CONSTRUCTORCOMMENT_ID, "/**\n * Constructor\n */", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.METHODCOMMENT_ID, "/**\n * Method\n */", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.OVERRIDECOMMENT_ID, "/**\n * Overridden\n */", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.METHODSTUB_ID, "${body_statement}", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.CONSTRUCTORSTUB_ID, "${body_statement}", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.CLASSBODY_ID, "/* class body */\n", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.INTERFACEBODY_ID, "/* interface body */\n", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.ENUMBODY_ID, "/* enum body */\n", null); + StubUtility.setCodeTemplate(CodeTemplateContextType.ANNOTATIONBODY_ID, "/* annotation body */\n", null); + + } + + private void initNonModularProject() throws Exception { + fJProject1= projectSetup.getProject(); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + fpack1= fSourceFolder.createPackageFragment("test1", false, null); + String test= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square {\n" + + "}\n"; + fSealedSuperCls= fpack1.createCompilationUnit("Shape.java", test, false, null); + test= "" + + "package test;\n" + + "\n" + + "public non-sealed class Square extends Shape {\n" + + "}\n"; + fpack1.createCompilationUnit("Square.java", test, false, null); + fSealedClsBinding= getTypeBinding(fSealedSuperCls); + test= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits ISquare {\n" + + "}\n"; + fSealedSuperInterface= fpack1.createCompilationUnit("IShape.java", test, false, null); + test= "" + + "package test;\n" + + "\n" + + "public non-sealed interface ISquare extends IShape {\n" + + "}\n"; + fpack1.createCompilationUnit("ISquare.java", test, false, null); + fSealedInterfaceBinding= getTypeBinding(fSealedSuperInterface); + } + + private void initModularProject() throws Exception { + // Init Modular Projects(); + fJProjectM1= projectMSetup.getProject(); + fMSourceFolder= JavaProjectHelper.addSourceContainer(fJProjectM1, "src"); + fMpack1= fMSourceFolder.createPackageFragment("test1", false, null); + String test= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square {\n" + + "}\n"; + fMSealedSuperCls= fMpack1.createCompilationUnit("Shape.java", test, false, null); + test= "" + + "package test;\n" + + "\n" + + "public non-sealed class Square extends Shape {\n" + + "}\n"; + fMpack1.createCompilationUnit("Square.java", test, false, null); + fMSealedClsBinding= getTypeBinding(fMSealedSuperCls); + test= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits ISquare {\n" + + "}\n"; + fMSealedSuperInterface= fMpack1.createCompilationUnit("IShape.java", test, false, null); + test= "" + + "package test;\n" + + "\n" + + "public non-sealed interface ISquare extends IShape {\n" + + "}\n"; + fMpack1.createCompilationUnit("ISquare.java", test, false, null); + fMSealedInterfaceBinding= getTypeBinding(fMSealedSuperInterface); + } + + private void initSecondProject() throws Exception { + fJProject2= projectSetup2.getProject(); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject2, "src"); + fpack1= fSourceFolder.createPackageFragment("test3", false, null); + IPath path= fJProject1.getPath(); + IClasspathEntry dep= JavaCore.newContainerEntry(path); + IClasspathEntry[] old= fJProject2.getRawClasspath(); + IClasspathEntry[] newPath= new IClasspathEntry[old.length + 1]; + System.arraycopy(old, 0, newPath, 0, old.length); + newPath[old.length]= dep; + fJProject2.setRawClasspath(newPath, null); + } + + private void createModuleInfo() throws Exception { + String test= "" + + "\n" + + "\n" + + "module modTest1 {\n" + + " exports test1;\n" + + "}\n"; + IPackageFragment def= fMSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit(QuickFixTest14.MODULE_INFO_FILE, test, false, null); + } + + private void initSecondModularProject() throws Exception { + createModuleInfo(); + fJProjectM2= projectMSetup2.getProject(); + fMSourceFolder= JavaProjectHelper.addSourceContainer(fJProjectM2, "src"); + fMpack1= fMSourceFolder.createPackageFragment("test3", false, null); + String test= "" + + "\n" + + "\n" + + "module modTest2 {\n" + + " requires modTest2;\n" + + "}\n"; + IPackageFragment def= fMSourceFolder.createPackageFragment("", false, null); + def.createCompilationUnit(QuickFixTest14.MODULE_INFO_FILE, test, false, null); + IPath path= fJProjectM1.getPath(); + IClasspathEntry dep= JavaCore.newContainerEntry(path); + IClasspathEntry[] old= fJProjectM2.getRawClasspath(); + IClasspathEntry[] newPath= new IClasspathEntry[old.length + 1]; + System.arraycopy(old, 0, newPath, 0, old.length); + newPath[old.length]= dep; + fJProjectM2.setRawClasspath(newPath, null); + } + + @After + public void tearDown() throws Exception { + if (fJProject1 != null) + JavaProjectHelper.clear(fJProject1, projectSetup.getDefaultClasspath()); + if (fJProjectM1 != null) + JavaProjectHelper.clear(fJProjectM1, projectMSetup.getDefaultClasspath()); + if (fJProject2 != null) + JavaProjectHelper.clear(fJProject2, projectSetup.getDefaultClasspath()); + if (fJProjectM2 != null) + JavaProjectHelper.clear(fJProjectM2, projectSetup.getDefaultClasspath()); + } + + + // --------------------------------- + // Testing in a non-modular project + // --------------------------------- + + // Throw error if the sealed super class is in different package to the new class + @Test + public void testNonModularCreateClassError1() throws Exception { + initNonModularProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + wizardPage.setSuperClass(fSealedClsBinding, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperClassStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_class_SealedSuperClassInDifferentPackage.equals(status.getMessage())); + } + + // Throw error if the sealed super interface is in different package to the new class + @Test + public void testNonModularCreateClassError2() throws Exception { + initNonModularProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_class_SealedSuperInterfaceInDifferentPackage.equals(status.getMessage())); + } + + // Throw error if the sealed super interface is in different package to the new interface + @Test + public void testNonModularCreateInterfaceError1() throws Exception { + initNonModularProject(); + NewInterfaceWizardPage wizardPage= new NewInterfaceWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("IE", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_interface_SealedSuperInterfaceInDifferentPackage.equals(status.getMessage())); + } + + // Successfully Create non-sealed class which has sealed super class + @Test + public void testNonModularCreateClassSuccess1() throws Exception { + initNonModularProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + wizardPage.setSuperClass(fSealedClsBinding, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperClassStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedClass_extend_superclass_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccNonSealed, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test1;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public non-sealed class E extends Shape {\n" + + " /* class body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fSealedSuperCls.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square, E {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // Successfully Create non-sealed class which has sealed super interface + @Test + public void testNonModularCreateClassSuccess2() throws Exception { + initNonModularProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedClass_implement_superinterface_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccNonSealed, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test1;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public non-sealed class E implements IShape {\n" + + " /* class body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fSealedSuperInterface.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits ISquare, E {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // Successfully Create final class which has sealed super class + @Test + public void testNonModularCreateClassSuccess3() throws Exception { + initNonModularProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + wizardPage.setSuperClass(fSealedClsBinding, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperClassStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedClass_extend_superclass_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccFinal, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test1;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public final class E extends Shape {\n" + + " /* class body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fSealedSuperCls.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "public sealed class Shape permits Square, E {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // Successfully Create final class which has sealed super interface + @Test + public void testNonModularCreateClassSuccess4() throws Exception { + initNonModularProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedClass_implement_superinterface_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccFinal, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test1;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public final class E implements IShape {\n" + + " /* class body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fSealedSuperInterface.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits ISquare, E {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // Successfully Create non-sealed interface which has sealed super interface + @Test + public void testNonModularCreateInterfaceSuccess1() throws Exception { + initNonModularProject(); + NewInterfaceWizardPage wizardPage= new NewInterfaceWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("IE", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedInterface_extend_superinterface_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccNonSealed, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test1;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public non-sealed interface IE extends IShape {\n" + + " /* interface body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fSealedSuperInterface.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "public sealed interface IShape permits ISquare, IE {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // ----------------------------------------- + // Testing in dependent non-modular projects + // ----------------------------------------- + + // Throw error if the sealed super class is in different project to the new class + @Test + public void testNonModularDependantCreateClassError1() throws Exception { + initNonModularProject(); + initSecondProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + wizardPage.setSuperClass(fSealedClsBinding, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperClassStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_class_SealedSuperClassInDifferentProject.equals(status.getMessage())); + } + + // Throw error if the sealed super interface is in different project to the new class + @Test + public void testNonModularDependantCreateClassError2() throws Exception { + initNonModularProject(); + initSecondProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_class_SealedSuperInterfaceInDifferentProject.equals(status.getMessage())); + } + + // Throw error if the sealed super interface is in different project to the new interface + @Test + public void testNonModularDependantCreateInterfaceError1() throws Exception { + initNonModularProject(); + initSecondProject(); + NewInterfaceWizardPage wizardPage= new NewInterfaceWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("IE", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_interface_SealedSuperInterfaceInDifferentProject.equals(status.getMessage())); + } + + + // ----------------------------- + // Testing in a modular projects + // ----------------------------- + + // Successfully Create non-sealed class which has sealed super class in a + // different package in a modular project + @Test + public void testModularCreateClassSuccess1() throws Exception { + initModularProject(); + createModuleInfo(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fMSourceFolder, true); + IPackageFragment pack2= fMSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + wizardPage.setSuperClass(fMSealedClsBinding, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperClassStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedClass_extend_superclass_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccNonSealed, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test2;\n" + + "\n" + + "import test1.Shape;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public non-sealed class E extends Shape {\n" + + " /* class body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fMSealedSuperCls.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "import test2.E;\n" + + "\n" + + "public sealed class Shape permits Square, E {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // Successfully Create non-sealed class which has sealed super interface in a + // different package in a modular project + @Test + public void testModularCreateClassSuccess2() throws Exception { + initModularProject(); + createModuleInfo(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fMSourceFolder, true); + IPackageFragment pack2= fMSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fMSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedClass_implement_superinterface_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccNonSealed, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test2;\n" + + "\n" + + "import test1.IShape;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public non-sealed class E implements IShape {\n" + + " /* class body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fMSealedSuperInterface.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "import test2.E;\n" + + "\n" + + "public sealed interface IShape permits ISquare, E {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // Successfully Create final class which has sealed super class in a + // different package in a modular project + @Test + public void testModularCreateClassSuccess3() throws Exception { + initModularProject(); + createModuleInfo(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fMSourceFolder, true); + IPackageFragment pack2= fMSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + wizardPage.setSuperClass(fMSealedClsBinding, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperClassStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedClass_extend_superclass_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccFinal, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test2;\n" + + "\n" + + "import test1.Shape;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public final class E extends Shape {\n" + + " /* class body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fMSealedSuperCls.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "import test2.E;\n" + + "\n" + + "public sealed class Shape permits Square, E {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // Successfully Create final class which has sealed super interface in a + // different package in a modular project + @Test + public void testModularCreateClassSuccess4() throws Exception { + initModularProject(); + createModuleInfo(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fMSourceFolder, true); + IPackageFragment pack2= fMSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fMSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedClass_implement_superinterface_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccFinal, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test2;\n" + + "\n" + + "import test1.IShape;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public final class E implements IShape {\n" + + " /* class body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fMSealedSuperInterface.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "import test2.E;\n" + + "\n" + + "public sealed interface IShape permits ISquare, E {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // Successfully Create non-sealed interface which has sealed super interface in a + // different package in a modular project + @Test + public void testModularCreateInterfaceSuccess1() throws Exception { + initModularProject(); + createModuleInfo(); + NewInterfaceWizardPage wizardPage= new NewInterfaceWizardPage(); + wizardPage.setPackageFragmentRoot(fMSourceFolder, true); + IPackageFragment pack2= fMSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("IE", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fMSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_SealedFinalNonSealedInterface_extend_superinterface_notSelected_message.equals(status.getMessage())); + int modifiers= wizardPage.getModifiers(); + wizardPage.setModifiers(modifiers | Flags.AccNonSealed, true); + status= wizardPage.getSealedModifierStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.OK); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test2;\n" + + "\n" + + "import test1.IShape;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public non-sealed interface IE extends IShape {\n" + + " /* interface body */\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + + actual= fMSealedSuperInterface.getSource(); + + expected= "" + + "package test;\n" + + "\n" + + "import test2.IE;\n" + + "\n" + + "public sealed interface IShape permits ISquare, IE {\n" + + "}\n"; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + // ------------------------------------- + // Testing in dependent modular projects + // ------------------------------------- + + // Throw error if the sealed super class is in different module to the new class + @Test + public void testModularDependentCreateClassError1() throws Exception { + initModularProject(); + initSecondModularProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fMSourceFolder, true); + IPackageFragment pack2= fMSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + wizardPage.setSuperClass(fMSealedClsBinding, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperClassStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_class_SealedSuperClassInDifferentModule.equals(status.getMessage())); + } + + // Throw error if the sealed super interface is in different module to the new class + @Test + public void testModularDependentCreateClassError2() throws Exception { + initModularProject(); + initSecondModularProject(); + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fMSourceFolder, true); + IPackageFragment pack2= fMSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fMSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_class_SealedSuperInterfaceInDifferentModule.equals(status.getMessage())); + } + + // Throw error if the sealed super interface is in different module to the new interface + @Test + public void testModularDependentCreateInterfaceError1() throws Exception { + initModularProject(); + initSecondModularProject(); + NewInterfaceWizardPage wizardPage= new NewInterfaceWizardPage(); + wizardPage.setPackageFragmentRoot(fMSourceFolder, true); + IPackageFragment pack2= fMSourceFolder.createPackageFragment("test2", false, null); + wizardPage.setPackageFragment(pack2, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("IE", true); + + List interfaces= new ArrayList<>(); + interfaces.add(fMSealedInterfaceBinding); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + IStatus status= wizardPage.getSealedSuperInterfaceStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(NewWizardMessages.NewTypeWizardPage_error_interface_SealedSuperInterfaceInDifferentModule.equals(status.getMessage())); + } + + @Test + public void testAddRecordSuperClassError1() throws Exception { + fJProject1= projectSetup.getProject(); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + fpack1= fSourceFolder.createPackageFragment("test1", false, null); + String test= "" + + "package test;\n" + + "\n" + + "public record Rec1(int x){\n" + + "}\n"; + ICompilationUnit superClsUnit= fpack1.createCompilationUnit("Rec1.java", test, false, null); + ITypeBinding superCls= getTypeBinding(superClsUnit); + + NewClassWizardPage wizardPage= new NewClassWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("E", true); + + wizardPage.setSuperClass(superCls, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setMethodStubSelection(false, false, false, true); + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + String sclassName= wizardPage.getSuperClass(); + String expected= Messages.format(NewWizardMessages.NewTypeWizardPage_error_InvalidSuperClassRecord, BasicElementLabels.getJavaElementName(sclassName)); + + IStatus status= wizardPage.getSuperClassStatus(); + assertNotNull(status); + assertTrue(status.getSeverity() == IStatus.ERROR); + assertTrue(expected.equals(status.getMessage())); + } + + @Test + public void testCreateRecordWithAbstractMethodStubs() throws Exception { + fJProject1= projectSetup.getProject(); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + fpack1= fSourceFolder.createPackageFragment("test1", false, null); + + NewRecordWizardPage wizardPage= new NewRecordWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("Rec1", true); + + wizardPage.setMethodStubSelection(false, true, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test1;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public record Rec1() {\n" + + "\n" + + " /**\n" + + " * Overridden\n" + + " */\n" + + " @Override\n" + + " public boolean equals(Object arg0) {\n" + + " return false;\n" + + " }\n" + + "\n" + + " /**\n" + + " * Overridden\n" + + " */\n" + + " @Override\n" + + " public int hashCode() {\n" + + " return 0;\n" + + " }\n" + + "\n" + + " /**\n" + + " * Overridden\n" + + " */\n" + + " @Override\n" + + " public String toString() {\n" + + " return null;\n" + + " }\n" + + "\n" + + "}" ; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + @Test + public void testCreateRecordWithOutAbstractMethodStubsAndMain() throws Exception { + fJProject1= projectSetup.getProject(); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + fpack1= fSourceFolder.createPackageFragment("test1", false, null); + + NewRecordWizardPage wizardPage= new NewRecordWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("Rec1", true); + + wizardPage.setMethodStubSelection(false, false, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test1;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public record Rec1() {\n" + + "\n" + + "}" ; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + @Test + public void testCreateRecordWithMain() throws Exception { + fJProject1= projectSetup.getProject(); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + fpack1= fSourceFolder.createPackageFragment("test1", false, null); + + NewRecordWizardPage wizardPage= new NewRecordWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("Rec1", true); + + wizardPage.setMethodStubSelection(true, false, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test1;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public record Rec1() {\n" + + "\n" + + " /**\n" + + " * Method\n" + + " */\n" + + " public static void main(String[] args) {\n" + + "\n" + + " }\n" + + "\n" + + "}" ; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + @Test + public void testCreateRecordWithAbstractMethodStubsAndMain() throws Exception { + fJProject1= projectSetup.getProject(); + fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src"); + fpack1= fSourceFolder.createPackageFragment("test1", false, null); + + NewRecordWizardPage wizardPage= new NewRecordWizardPage(); + wizardPage.setPackageFragmentRoot(fSourceFolder, true); + wizardPage.setPackageFragment(fpack1, true); + wizardPage.setEnclosingTypeSelection(false, true); + wizardPage.setTypeName("Rec1", true); + + wizardPage.setMethodStubSelection(true, true, true); + + List interfaces= new ArrayList<>(); + wizardPage.setSuperInterfacesList(interfaces, true); + + wizardPage.setAddComments(true, true); + wizardPage.enableCommentControl(true); + + wizardPage.createType(null); + + String actual= wizardPage.getCreatedType().getCompilationUnit().getSource(); + + String expected= "" + + "/**\n" + + " * File\n" + + " */\n" + + "package test1;\n" + + "\n" + + "/**\n" + + " * Type\n" + + " */\n" + + "public record Rec1() {\n" + + "\n" + + " /**\n" + + " * Overridden\n" + + " */\n" + + " @Override\n" + + " public boolean equals(Object arg0) {\n" + + " return false;\n" + + " }\n" + + "\n" + + " /**\n" + + " * Overridden\n" + + " */\n" + + " @Override\n" + + " public int hashCode() {\n" + + " return 0;\n" + + " }\n" + + "\n" + + " /**\n" + + " * Overridden\n" + + " */\n" + + " @Override\n" + + " public String toString() {\n" + + " return null;\n" + + " }\n\n" + + " /**\n" + + " * Method\n" + + " */\n" + + " public static void main(String[] args) {\n" + + "\n" + + " }\n" + + "\n" + + "}" ; + + StringAsserts.assertEqualStringIgnoreDelim(actual, expected); + } + + protected static CompilationUnit getASTRoot(ICompilationUnit cu) { + return ASTResolving.createQuickFixAST(cu, null); + } + + private static ITypeBinding getTypeBinding(ICompilationUnit cu) { + CompilationUnit compUnit= ASTResolving.createQuickFixAST(cu, null); + ITypeBinding tBinding= null; + if (compUnit != null) { + Object typeDecl= compUnit.types().get(0); + if (typeDecl instanceof AbstractTypeDeclaration) { + tBinding= ((AbstractTypeDeclaration) typeDecl).resolveBinding(); + } + } + return tBinding; + } +} diff --git a/org.eclipse.jdt.ui.unittest.junit.feature/feature.xml b/org.eclipse.jdt.ui.unittest.junit.feature/feature.xml index f0b19764..36452ac4 100644 --- a/org.eclipse.jdt.ui.unittest.junit.feature/feature.xml +++ b/org.eclipse.jdt.ui.unittest.junit.feature/feature.xml @@ -2,11 +2,11 @@ - + %description diff --git a/org.eclipse.jdt.ui.unittest.junit.feature/pom.xml b/org.eclipse.jdt.ui.unittest.junit.feature/pom.xml index dfc62c54..9e3d6307 100644 --- a/org.eclipse.jdt.ui.unittest.junit.feature/pom.xml +++ b/org.eclipse.jdt.ui.unittest.junit.feature/pom.xml @@ -16,11 +16,11 @@ eclipse.jdt.ui eclipse.jdt.ui - 4.21.0-SNAPSHOT + 4.26.0-SNAPSHOT org.eclipse.jdt.feature org.eclipse.jdt.ui.unittest.junit.feature - 1.0.100-SNAPSHOT + 1.0.400-SNAPSHOT eclipse-feature diff --git a/org.eclipse.jdt.ui.unittest.junit/META-INF/MANIFEST.MF b/org.eclipse.jdt.ui.unittest.junit/META-INF/MANIFEST.MF index 11ec5130..ecc20e87 100644 --- a/org.eclipse.jdt.ui.unittest.junit/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.ui.unittest.junit/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.jdt.ui.unittest.junit Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.ui.unittest.junit;singleton:=true -Bundle-Version: 1.0.200.qualifier +Bundle-Version: 1.0.500.qualifier Bundle-Activator: org.eclipse.jdt.ui.unittest.junit.JUnitTestPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName @@ -22,9 +22,9 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)", org.eclipse.jdt.launching;bundle-version="[3.5.0,4.0.0)", org.eclipse.jdt.debug.ui;bundle-version="[3.3.0,4.0.0)", - org.eclipse.jdt.junit.core;bundle-version="[3.10.800,4.0.0]", + org.eclipse.jdt.junit.core;bundle-version="[3.11.200,4.0.0]", org.eclipse.jdt.junit.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.core.variables;bundle-version="[3.2.200,4.0.0)", org.eclipse.jdt.core.manipulation;bundle-version="1.9.0", - org.eclipse.jdt.junit;bundle-version="3.11.0" + org.eclipse.jdt.junit;bundle-version="3.14.0" Bundle-RequiredExecutionEnvironment: JavaSE-11 diff --git a/org.eclipse.jdt.ui.unittest.junit/pom.xml b/org.eclipse.jdt.ui.unittest.junit/pom.xml index 9e5e2784..101dbd06 100644 --- a/org.eclipse.jdt.ui.unittest.junit/pom.xml +++ b/org.eclipse.jdt.ui.unittest.junit/pom.xml @@ -14,11 +14,11 @@ eclipse.jdt.ui eclipse.jdt.ui - 4.21.0-SNAPSHOT + 4.26.0-SNAPSHOT org.eclipse.jdt org.eclipse.jdt.ui.unittest.junit - 1.0.200-SNAPSHOT + 1.0.500-SNAPSHOT eclipse-plugin true diff --git a/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchConfigurationDelegate.java b/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchConfigurationDelegate.java index ea343f26..711af039 100644 --- a/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchConfigurationDelegate.java +++ b/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchConfigurationDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -228,6 +228,34 @@ private VMRunnerConfiguration getVMRunnerConfiguration(ILaunchConfiguration conf new Status(IStatus.ERROR, JUnitTestPlugin.PLUGIN_ID, IStatus.ERROR, "", e)); //$NON-NLS-1$ } } + if (!Arrays.stream(classpath).anyMatch( + s -> s.contains("junit-jupiter-engine") || s.contains("org.junit.jupiter.engine"))) { //$NON-NLS-1$ //$NON-NLS-2$ + try { + JUnitRuntimeClasspathEntry x = new JUnitRuntimeClasspathEntry("junit-jupiter-engine", //$NON-NLS-1$ + null); + String entryString = new ClasspathLocalizer(false).entryString(x); + int length = classpath.length; + System.arraycopy(classpath, 0, classpath = new String[length + 1], 0, length); + classpath[length] = entryString; + } catch (IOException | URISyntaxException e) { + throw new CoreException( + new Status(IStatus.ERROR, JUnitCorePlugin.CORE_PLUGIN_ID, IStatus.ERROR, "", e)); //$NON-NLS-1$ + } + } + if (!Arrays.stream(classpath) + .anyMatch(s -> s.contains("junit-jupiter-api") || s.contains("org.junit.jupiter.api"))) { //$NON-NLS-1$ //$NON-NLS-2$ + try { + JUnitRuntimeClasspathEntry x = new JUnitRuntimeClasspathEntry("junit-jupiter-api", //$NON-NLS-1$ + null); + String entryString = new ClasspathLocalizer(false).entryString(x); + int length = classpath.length; + System.arraycopy(classpath, 0, classpath = new String[length + 1], 0, length); + classpath[length] = entryString; + } catch (IOException | URISyntaxException e) { + throw new CoreException( + new Status(IStatus.ERROR, JUnitCorePlugin.CORE_PLUGIN_ID, IStatus.ERROR, "", e)); //$NON-NLS-1$ + } + } } } diff --git a/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchConfigurationTab.java b/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchConfigurationTab.java index 0c166239..7b6c8fae 100644 --- a/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchConfigurationTab.java +++ b/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchConfigurationTab.java @@ -596,7 +596,7 @@ private void handleSearchButtonSelected() { IJavaProject javaProject = getJavaProject(); - IType[] types = new IType[0]; + final Set types; boolean[] radioSetting = new boolean[2]; try { // fix for 66922 Wrong radio behaviour when switching @@ -1125,12 +1125,12 @@ private void initializeTestType(IJavaElement javaElement, ILaunchConfigurationWo ITestKind testKind = JUnitTestPlugin.getJUnitVersion(javaElement).getJUnitTestKind(); testKindId = testKind.getId(); - IType[] types = TestSearchEngine.findTests(getLaunchConfigurationDialog(), javaElement, testKind); - if ((types == null) || (types.length < 1)) { + var types = TestSearchEngine.findTests(getLaunchConfigurationDialog(), javaElement, testKind); + if ((types == null) || (types.isEmpty())) { return; } // Simply grab the first main type found in the searched element - name = types[0].getFullyQualifiedName('.'); + name = types.iterator().next().getFullyQualifiedName('.'); } } catch (InterruptedException | InvocationTargetException ie) { diff --git a/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchShortcut.java b/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchShortcut.java index be103190..48a281af 100644 --- a/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchShortcut.java +++ b/org.eclipse.jdt.ui.unittest.junit/src/org/eclipse/jdt/ui/unittest/junit/launcher/JUnitLaunchShortcut.java @@ -16,13 +16,17 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.unittest.ui.ConfigureViewerSupport; +import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; @@ -36,6 +40,8 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.window.Window; import org.eclipse.jface.text.ITextSelection; @@ -43,6 +49,7 @@ import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ElementListSelectionDialog; +import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; @@ -207,16 +214,16 @@ private void showNoTestsFoundDialog() { private IType findTypeToLaunch(ICompilationUnit cu, String mode) throws InterruptedException, InvocationTargetException { - IType[] types = findTypesToLaunch(cu); - if (types.length == 0) { + var types= findTypesToLaunch(cu); + if (types.isEmpty()) { return null; - } else if (types.length > 1) { + } else if (types.size() > 1) { return chooseType(types, mode); } - return types[0]; + return types.iterator().next(); } - private IType[] findTypesToLaunch(ICompilationUnit cu) throws InterruptedException, InvocationTargetException { + private Set findTypesToLaunch(ICompilationUnit cu) throws InterruptedException, InvocationTargetException { return TestSearchEngine.findTests(PlatformUI.getWorkbench().getActiveWorkbenchWindow(), cu, JUnitTestPlugin.getJUnitVersion(cu).getJUnitTestKind()); } @@ -231,17 +238,63 @@ private void performLaunch(IJavaElement element, String mode) throws Interrupted DebugUITools.launch(config, mode); } - private IType chooseType(IType[] types, String mode) throws InterruptedException { - ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), - new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_POST_QUALIFIED)); - dialog.setElements(types); + static class TreeProvider implements ITreeContentProvider { + private final static Object ROOT= new Object(); + + private final Map> tree= new HashMap<>(); + + public TreeProvider(Set types) { + for (var type : types) { + var parent= type.getParent(); + var parentInTree= types.contains(parent) ? parent : ROOT; + tree.compute(parentInTree, (key, value) -> { + var list= value != null ? value : new ArrayList(); + list.add(type); + return list; + }); + } + } + + @Override + public Object[] getElements(Object inputElement) { + return tree.get(ROOT).toArray(); + } + + @Override + public Object[] getChildren(Object parentElement) { + var children= tree.get(parentElement); + return children != null ? children.toArray() : new Object[0]; + } + + @Override + public Object getParent(Object element) { + return null; + } + + @Override + public boolean hasChildren(Object element) { + var children= tree.get(element); + return children != null && !children.isEmpty(); + } + } + + private IType chooseType(Set types, String mode) throws InterruptedException { + var dialog = new ElementTreeSelectionDialog(getShell(), new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_POST_QUALIFIED), new TreeProvider(types)) { + @Override + protected TreeViewer createTreeViewer(Composite parent) { + var tree = super.createTreeViewer(parent); + tree.expandAll(); + return tree; + } + }; dialog.setTitle(Messages.UnitTestLaunchShortcut_dialog_title2); - if (mode.equals(ILaunchManager.DEBUG_MODE)) { + dialog.setAllowMultiple(false); + dialog.setInput(TreeProvider.ROOT); + if (ILaunchManager.DEBUG_MODE.equals(mode)) { dialog.setMessage(Messages.UnitTestLaunchShortcut_message_selectTestToDebug); } else { dialog.setMessage(Messages.UnitTestLaunchShortcut_message_selectTestToRun); } - dialog.setMultipleSelection(false); if (dialog.open() == Window.OK) { return (IType) dialog.getFirstResult(); } diff --git a/org.eclipse.jdt.ui/.settings/.api_filters b/org.eclipse.jdt.ui/.settings/.api_filters index 6a6c0330..83dd4ac9 100644 --- a/org.eclipse.jdt.ui/.settings/.api_filters +++ b/org.eclipse.jdt.ui/.settings/.api_filters @@ -113,9 +113,9 @@ - + - + @@ -194,4 +194,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.eclipse.jdt.ui/META-INF/MANIFEST.MF b/org.eclipse.jdt.ui/META-INF/MANIFEST.MF index dec433a2..1b4d2758 100644 --- a/org.eclipse.jdt.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.jdt.ui Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.ui; singleton:=true -Bundle-Version: 3.24.0.qualifier +Bundle-Version: 3.27.100.qualifier Bundle-Activator: org.eclipse.jdt.internal.ui.JavaPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName @@ -20,7 +20,6 @@ Export-Package: org.eclipse.jdt.internal.corext;x-friends:="org.eclipse.jdt.juni org.eclipse.jdt.internal.corext.refactoring.binary;x-internal:=true, org.eclipse.jdt.internal.corext.refactoring.changes;x-internal:=true, org.eclipse.jdt.internal.corext.refactoring.code;x-internal:=true, - org.eclipse.jdt.internal.corext.refactoring.generics;x-internal:=true, org.eclipse.jdt.internal.corext.refactoring.nls;x-internal:=true, org.eclipse.jdt.internal.corext.refactoring.participants;x-internal:=true, org.eclipse.jdt.internal.corext.refactoring.rename;x-internal:=true, @@ -30,9 +29,6 @@ Export-Package: org.eclipse.jdt.internal.corext;x-friends:="org.eclipse.jdt.juni org.eclipse.jdt.internal.corext.refactoring.structure;x-internal:=true, org.eclipse.jdt.internal.corext.refactoring.structure.constraints;x-internal:=true, org.eclipse.jdt.internal.corext.refactoring.surround;x-internal:=true, - org.eclipse.jdt.internal.corext.refactoring.typeconstraints;x-internal:=true, - org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets;x-internal:=true, - org.eclipse.jdt.internal.corext.refactoring.typeconstraints2;x-internal:=true, org.eclipse.jdt.internal.corext.refactoring.util;x-internal:=true, org.eclipse.jdt.internal.corext.template.java;x-friends:="org.eclipse.jdt.debug.ui", org.eclipse.jdt.internal.corext.util;x-friends:="org.eclipse.jdt.junit", @@ -45,6 +41,7 @@ Export-Package: org.eclipse.jdt.internal.corext;x-friends:="org.eclipse.jdt.juni org.eclipse.jdt.internal.ui.dialogs;x-friends:="org.eclipse.jdt.apt.ui,org.eclipse.jdt.junit", org.eclipse.jdt.internal.ui.dnd;x-internal:=true, org.eclipse.jdt.internal.ui.filters;x-internal:=true, + org.eclipse.jdt.internal.ui.filtertable;x-friends:="org.eclipse.jdt.junit,org.eclipse.jdt.debug.ui", org.eclipse.jdt.internal.ui.fix;x-internal:=true, org.eclipse.jdt.internal.ui.infoviews;x-internal:=true, org.eclipse.jdt.internal.ui.jarimport;x-internal:=true, @@ -85,7 +82,11 @@ Export-Package: org.eclipse.jdt.internal.corext;x-friends:="org.eclipse.jdt.juni org.eclipse.jdt.internal.ui.text.template.contentassist;x-friends:="org.eclipse.jdt.debug.ui", org.eclipse.jdt.internal.ui.text.template.preferences;x-internal:=true, org.eclipse.jdt.internal.ui.typehierarchy;x-internal:=true, - org.eclipse.jdt.internal.ui.util;x-friends:="org.eclipse.jdt.junit,org.eclipse.jdt.apt.ui,org.eclipse.jdt.debug.ui,org.eclipse.jdt.ui.unittest.junit", + org.eclipse.jdt.internal.ui.util; + x-friends:="org.eclipse.jdt.junit, + org.eclipse.jdt.apt.ui, + org.eclipse.jdt.debug.ui, + org.eclipse.jdt.ui.unittest.junit", org.eclipse.jdt.internal.ui.viewsupport;x-friends:="org.eclipse.jdt.junit,org.eclipse.jdt.debug.ui", org.eclipse.jdt.internal.ui.wizards;x-friends:="org.eclipse.jdt.junit,org.eclipse.jdt.apt.ui,org.eclipse.jdt.ui.unittest.junit", org.eclipse.jdt.internal.ui.wizards.buildpaths;x-internal:=true, @@ -112,28 +113,28 @@ Require-Bundle: org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)", org.eclipse.core.resources;bundle-version="[3.14.0,4.0.0)", org.eclipse.core.variables;bundle-version="[3.2.200,4.0.0)", - org.eclipse.jdt.core;bundle-version="[3.22.0,4.0.0)", + org.eclipse.jdt.core;bundle-version="[3.32.0,4.0.0)", org.eclipse.search;bundle-version="[3.10.0,4.0.0)", org.eclipse.debug.core;bundle-version="[3.10.0,4.0.0)", org.eclipse.debug.ui;bundle-version="[3.11.0,4.0.0)", - org.eclipse.jdt.launching;bundle-version="[3.8.0,4.0.0)", + org.eclipse.jdt.launching;bundle-version="[3.19.400,4.0.0)", org.eclipse.compare;bundle-version="[3.5.0,4.0.0)", org.eclipse.team.ui;bundle-version="[3.4.100,4.0.0)", org.eclipse.team.core;bundle-version="[3.4.100,4.0.0)", - org.eclipse.jface.text;bundle-version="[3.16.0,4.0.0)", + org.eclipse.jface.text;bundle-version="[3.20.0,4.0.0)", org.eclipse.ui;bundle-version="[3.117.0,4.0.0)", org.eclipse.ui.console;bundle-version="[3.4.0,4.0.0)", org.eclipse.ui.workbench.texteditor;bundle-version="[3.10.0,4.0.0)", org.eclipse.ui.ide;bundle-version="[3.15.0,4.0.0)", org.eclipse.ui.views;bundle-version="[3.3.100,4.0.0)", org.eclipse.ui.editors;bundle-version="[3.5.0,4.0.0)", - org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)", + org.eclipse.core.runtime;bundle-version="[3.25.0,4.0.0)", org.eclipse.ltk.core.refactoring;bundle-version="[3.7.0,4.0.0)", - org.eclipse.ltk.ui.refactoring;bundle-version="[3.8.0,4.0.0)", + org.eclipse.ltk.ui.refactoring;bundle-version="[3.12.0,4.0.0)", org.eclipse.ui.forms;bundle-version="[3.4.0,4.0.0)", org.eclipse.ui.navigator;bundle-version="[3.3.200,4.0.0)", org.eclipse.ui.navigator.resources;bundle-version="[3.4.0,4.0.0)", - org.eclipse.jdt.core.manipulation;bundle-version="[1.9.0,2.0.0)", + org.eclipse.jdt.core.manipulation;bundle-version="[1.15.200,2.0.0)", com.ibm.icu;bundle-version="4.4.2", org.eclipse.equinox.bidi;bundle-version="[0.10.0,2.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-11 diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchy.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchy.java index b1f04d7f..8a8cd726 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchy.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchy.java @@ -63,7 +63,7 @@ public boolean isSearchUsingImplementorsEnabled() { return settings.getBoolean(PREF_USE_IMPLEMENTORS); } - public void setSearchUsingImplementorsEnabled(boolean enabled) { + public static void setSearchUsingImplementorsEnabled(boolean enabled) { IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); settings.setValue(PREF_USE_IMPLEMENTORS, enabled); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddImportsOperation.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddImportsOperation.java index 94ec9eb5..d06b50c3 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddImportsOperation.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddImportsOperation.java @@ -11,6 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Nikolay Metchev - Import static (Ctrl+Shift+M) creates imports for private methods - https://bugs.eclipse.org/409594 + * Fabian Pfaff - Import static doesn't work when static method is referenced from subtype - https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/276 *******************************************************************************/ package org.eclipse.jdt.internal.corext.codemanipulation; @@ -21,10 +22,9 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.resources.IWorkspaceRunnable; @@ -163,37 +163,31 @@ public IStatus getStatus() { */ @Override public void run(IProgressMonitor monitor) throws CoreException, OperationCanceledException { - if (monitor == null) { - monitor= new NullProgressMonitor(); - } - try { - monitor.beginTask(CodeGenerationMessages.AddImportsOperation_description, 4); + SubMonitor subMonitor= SubMonitor.convert(monitor, CodeGenerationMessages.AddImportsOperation_description, 4); - CompilationUnit astRoot= SharedASTProviderCore.getAST(fCompilationUnit, SharedASTProviderCore.WAIT_YES, new SubProgressMonitor(monitor, 1)); - if (astRoot == null) - throw new OperationCanceledException(); + CompilationUnit astRoot= SharedASTProviderCore.getAST(fCompilationUnit, SharedASTProviderCore.WAIT_YES, subMonitor.split(1)); + if (astRoot == null) + throw new OperationCanceledException(); - ImportRewrite importRewrite= StubUtility.createImportRewrite(astRoot, true); + ImportRewrite importRewrite= StubUtility.createImportRewrite(astRoot, true); - MultiTextEdit res= new MultiTextEdit(); + MultiTextEdit res= new MultiTextEdit(); - TextEdit edit= evaluateEdits(astRoot, importRewrite, fSelectionOffset, fSelectionLength, new SubProgressMonitor(monitor, 1)); - if (edit == null) { - return; - } - res.addChild(edit); + TextEdit edit= evaluateEdits(astRoot, importRewrite, fSelectionOffset, fSelectionLength, subMonitor.split(1)); + if (edit == null) { + return; + } + res.addChild(edit); - TextEdit importsEdit= importRewrite.rewriteImports(new SubProgressMonitor(monitor, 1)); - res.addChild(importsEdit); + TextEdit importsEdit= importRewrite.rewriteImports(subMonitor.split(1)); + res.addChild(importsEdit); - fResultingEdit= res; + fResultingEdit= res; - if (fApply) { - JavaModelUtil.applyEdit(fCompilationUnit, res, fDoSave, new SubProgressMonitor(monitor, 1)); - } - } finally { - monitor.done(); + if (fApply) { + JavaModelUtil.applyEdit(fCompilationUnit, res, fDoSave, subMonitor.split(1)); } + subMonitor.setWorkRemaining(0); } /** @@ -206,6 +200,7 @@ public MultiTextEdit getResultingEdit() { } private TextEdit evaluateEdits(CompilationUnit root, ImportRewrite importRewrite, int offset, int length, IProgressMonitor monitor) throws JavaModelException { + SubMonitor subMonitor= SubMonitor.convert(monitor, 1); SimpleName nameNode= null; if (root != null) { // got an AST ASTNode node= NodeFinder.perform(root, offset, length); @@ -285,31 +280,29 @@ private TextEdit evaluateEdits(CompilationUnit root, ImportRewrite importRewrite } if (Modifier.isStatic(binding.getModifiers())) { if (containerName.length() > 0) { - if (containerName.equals(declaringClass.getName()) || containerName.equals(declaringClass.getQualifiedName()) ) { - ASTNode node= nameNode.getParent(); - boolean isDirectlyAccessible= false; - while (node != null) { - if (isTypeDeclarationSubTypeCompatible(node, declaringClass)) { - isDirectlyAccessible= true; - break; - } - node= node.getParent(); + ASTNode node= nameNode.getParent(); + boolean isDirectlyAccessible= false; + while (node != null) { + if (isTypeDeclarationSubTypeCompatible(node, declaringClass)) { + isDirectlyAccessible= true; + break; + } + node= node.getParent(); + } + if (!isDirectlyAccessible) { + if (Modifier.isPrivate(declaringClass.getModifiers())) { + fStatus= JavaUIStatus.createError(IStatus.ERROR, + Messages.format(CodeGenerationMessages.AddImportsOperation_error_not_visible_class, BasicElementLabels.getJavaElementName(declaringClass.getName())), + null); + return null; } - if (!isDirectlyAccessible) { - if (Modifier.isPrivate(declaringClass.getModifiers())) { - fStatus= JavaUIStatus.createError(IStatus.ERROR, - Messages.format(CodeGenerationMessages.AddImportsOperation_error_not_visible_class, BasicElementLabels.getJavaElementName(declaringClass.getName())), - null); - return null; - } - String res= importRewrite.addStaticImport(declaringClass.getQualifiedName(), binding.getName(), isField); - if (!res.equals(simpleName)) { - // adding import failed - return null; - } + String res= importRewrite.addStaticImport(declaringClass.getQualifiedName(), binding.getName(), isField); + if (!res.equals(simpleName)) { + // adding import failed + return null; } - return new ReplaceEdit(qualifierStart, simpleNameStart - qualifierStart, ""); //$NON-NLS-1$ } + return new ReplaceEdit(qualifierStart, simpleNameStart - qualifierStart, ""); //$NON-NLS-1$ } } return null; // no static imports for packages @@ -355,15 +348,12 @@ private TextEdit evaluateEdits(CompilationUnit root, ImportRewrite importRewrite } IJavaSearchScope searchScope= SearchEngine.createJavaSearchScope(new IJavaElement[] { fCompilationUnit.getJavaProject() }); - TypeNameMatch[] types= findAllTypes(simpleName, searchScope, nameNode, new SubProgressMonitor(monitor, 1)); + TypeNameMatch[] types= findAllTypes(simpleName, searchScope, nameNode, subMonitor.split(1)); if (types.length == 0) { fStatus= JavaUIStatus.createError(IStatus.ERROR, Messages.format(CodeGenerationMessages.AddImportsOperation_error_notresolved_message, BasicElementLabels.getJavaElementName(simpleName)), null); return null; } - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } TypeNameMatch chosen; if (types.length > 1 && fQuery != null) { chosen= fQuery.chooseImport(types, containerName); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddUnimplementedMethodsOperation.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddUnimplementedMethodsOperation.java index f56d717a..9bcba2b0 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddUnimplementedMethodsOperation.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/AddUnimplementedMethodsOperation.java @@ -201,7 +201,7 @@ public void run(IProgressMonitor monitor) throws CoreException { IMethodBinding[] methodsToImplement= fMethodsToImplement; if (methodsToImplement == null) { - methodsToImplement= StubUtility2Core.getUnimplementedMethods(currTypeBinding); + methodsToImplement= StubUtility2Core.getUnimplementedMethods(currTypeBinding, StubUtility2Core.IMPLEMENT_RECORD_SYNTHETICS); } Arrays.sort(methodsToImplement, new MethodsSourcePositionComparator(fType)); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java index 0a5f6c7d..2bf6e63c 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -125,7 +125,7 @@ public static MethodDeclaration createImplementationStub(ICompilationUnit unit, String bodyStatement= ""; //$NON-NLS-1$ if (Modifier.isAbstract(modifiers)) { - Expression expression= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions()); + Expression expression= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), bindingReturnType, decl.getExtraDimensions()); if (expression != null) { ReturnStatement returnStatement= ast.newReturnStatement(); returnStatement.setExpression(expression); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java index 1f936283..fecd868e 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018, 2020 IBM Corporation and others. + * Copyright (c) 2018, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -97,6 +97,7 @@ private static void setEclipseDefaultSettings(CleanUpOptions options) { options.setOption(REMOVE_UNUSED_CODE_PRIVATE_CONSTRUCTORS, CleanUpOptions.TRUE); options.setOption(REMOVE_UNUSED_CODE_PRIVATE_FELDS, CleanUpOptions.TRUE); options.setOption(REMOVE_UNUSED_CODE_PRIVATE_METHODS, CleanUpOptions.TRUE); + options.setOption(REMOVE_UNUSED_CODE_METHOD_PARAMETERS, CleanUpOptions.FALSE); options.setOption(REMOVE_UNUSED_CODE_PRIVATE_TYPES, CleanUpOptions.TRUE); options.setOption(REMOVE_UNUSED_CODE_LOCAL_VARIABLES, CleanUpOptions.FALSE); @@ -119,6 +120,7 @@ private static void setEclipseDefaultSettings(CleanUpOptions options) { options.setOption(COLLECTION_CLONING, CleanUpOptions.FALSE); options.setOption(MAP_CLONING, CleanUpOptions.FALSE); options.setOption(OVERRIDDEN_ASSIGNMENT, CleanUpOptions.FALSE); + options.setOption(OVERRIDDEN_ASSIGNMENT_MOVE_DECL, CleanUpOptions.TRUE); options.setOption(REMOVE_REDUNDANT_MODIFIERS, CleanUpOptions.FALSE); options.setOption(RAISE_EMBEDDED_IF, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_SEMICOLONS, CleanUpOptions.TRUE); @@ -185,6 +187,7 @@ private static void setEclipseDefaultSettings(CleanUpOptions options) { options.setOption(COMPARING_ON_CRITERIA, CleanUpOptions.FALSE); options.setOption(JOIN, CleanUpOptions.FALSE); options.setOption(TRY_WITH_RESOURCE, CleanUpOptions.FALSE); + options.setOption(STRINGCONCAT_TO_TEXTBLOCK, CleanUpOptions.FALSE); options.setOption(MULTI_CATCH, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_TYPE_ARGUMENTS, CleanUpOptions.TRUE); options.setOption(USE_AUTOBOXING, CleanUpOptions.FALSE); @@ -194,7 +197,7 @@ private static void setEclipseDefaultSettings(CleanUpOptions options) { options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_LINE_SEPARATOR, CleanUpOptions.FALSE); options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_PATH_SEPARATOR, CleanUpOptions.FALSE); options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_FILE_ENCODING, CleanUpOptions.FALSE); - options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_BOOLEAN, CleanUpOptions.FALSE); + options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_BOXED, CleanUpOptions.FALSE); options.setOption(CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED, CleanUpOptions.TRUE); options.setOption(CONTROL_STATEMENTS_CONVERT_FOR_LOOP_ONLY_IF_LOOP_VAR_USED, CleanUpOptions.TRUE); @@ -274,6 +277,7 @@ private static void setSaveParticipantSettings(CleanUpOptions options) { options.setOption(REMOVE_UNUSED_CODE_PRIVATE_CONSTRUCTORS, CleanUpOptions.TRUE); options.setOption(REMOVE_UNUSED_CODE_PRIVATE_FELDS, CleanUpOptions.TRUE); options.setOption(REMOVE_UNUSED_CODE_PRIVATE_METHODS, CleanUpOptions.TRUE); + options.setOption(REMOVE_UNUSED_CODE_METHOD_PARAMETERS, CleanUpOptions.FALSE); options.setOption(REMOVE_UNUSED_CODE_PRIVATE_TYPES, CleanUpOptions.TRUE); options.setOption(REMOVE_UNUSED_CODE_LOCAL_VARIABLES, CleanUpOptions.FALSE); @@ -296,6 +300,7 @@ private static void setSaveParticipantSettings(CleanUpOptions options) { options.setOption(COLLECTION_CLONING, CleanUpOptions.FALSE); options.setOption(MAP_CLONING, CleanUpOptions.FALSE); options.setOption(OVERRIDDEN_ASSIGNMENT, CleanUpOptions.FALSE); + options.setOption(OVERRIDDEN_ASSIGNMENT_MOVE_DECL, CleanUpOptions.TRUE); options.setOption(REMOVE_REDUNDANT_MODIFIERS, CleanUpOptions.FALSE); options.setOption(RAISE_EMBEDDED_IF, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_SEMICOLONS, CleanUpOptions.FALSE); @@ -364,6 +369,7 @@ private static void setSaveParticipantSettings(CleanUpOptions options) { options.setOption(COMPARING_ON_CRITERIA, CleanUpOptions.FALSE); options.setOption(JOIN, CleanUpOptions.FALSE); options.setOption(TRY_WITH_RESOURCE, CleanUpOptions.FALSE); + options.setOption(STRINGCONCAT_TO_TEXTBLOCK, CleanUpOptions.FALSE); options.setOption(MULTI_CATCH, CleanUpOptions.FALSE); options.setOption(REMOVE_REDUNDANT_TYPE_ARGUMENTS, CleanUpOptions.FALSE); options.setOption(USE_AUTOBOXING, CleanUpOptions.FALSE); @@ -373,7 +379,7 @@ private static void setSaveParticipantSettings(CleanUpOptions options) { options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_LINE_SEPARATOR, CleanUpOptions.FALSE); options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_PATH_SEPARATOR, CleanUpOptions.FALSE); options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_FILE_ENCODING, CleanUpOptions.FALSE); - options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_BOOLEAN, CleanUpOptions.FALSE); + options.setOption(CONSTANTS_FOR_SYSTEM_PROPERTY_BOXED, CleanUpOptions.FALSE); options.setOption(CONTROL_STATEMENTS_CONVERT_FOR_LOOP_TO_ENHANCED, CleanUpOptions.FALSE); options.setOption(CONTROL_STATEMENTS_CONVERT_FOR_LOOP_ONLY_IF_LOOP_VAR_USED, CleanUpOptions.FALSE); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CodeStyleFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CodeStyleFix.java index 6412abce..ea7895f4 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CodeStyleFix.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CodeStyleFix.java @@ -13,80 +13,17 @@ *******************************************************************************/ package org.eclipse.jdt.internal.corext.fix; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import org.eclipse.jdt.core.compiler.IProblem; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.manipulation.ICleanUpFixCore; - -import org.eclipse.jdt.internal.corext.fix.CodeStyleFixCore.AddThisQualifierOperation; -import org.eclipse.jdt.internal.corext.fix.CodeStyleFixCore.ToStaticAccessOperation; -import org.eclipse.jdt.internal.corext.util.Messages; import org.eclipse.jdt.ui.cleanup.ICleanUpFix; import org.eclipse.jdt.ui.text.java.IProblemLocation; import org.eclipse.jdt.internal.ui.fix.CleanUpFixWrapper; -import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; -import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation; /** * A fix which fixes code style issues. */ -public class CodeStyleFix extends CompilationUnitRewriteOperationsFix { - - - public static CompilationUnitRewriteOperationsFix[] createNonStaticAccessFixes(CompilationUnit compilationUnit, IProblemLocation problem) { - IProblemLocationCore problemLocation= (ProblemLocation)problem; - if (!CodeStyleFixCore.isNonStaticAccess(problemLocation)) - return null; - - ToStaticAccessOperation operations[]= CodeStyleFixCore.createToStaticAccessOperations(compilationUnit, new HashMap(), problemLocation, false); - if (operations == null) - return null; - - String label1= Messages.format(FixMessages.CodeStyleFix_ChangeAccessToStatic_description, operations[0].getAccessorName()); - CompilationUnitRewriteOperationsFix fix1= new CompilationUnitRewriteOperationsFix(label1, compilationUnit, - new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {operations[0]}); - - if (operations.length > 1) { - String label2= Messages.format(FixMessages.CodeStyleFix_ChangeAccessToStaticUsingInstanceType_description, operations[1].getAccessorName()); - CompilationUnitRewriteOperationsFix fix2= new CompilationUnitRewriteOperationsFix(label2, compilationUnit, - new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {operations[1]}); - return new CompilationUnitRewriteOperationsFix[] {fix1, fix2}; - } - return new CompilationUnitRewriteOperationsFix[] {fix1}; - } - - public static CompilationUnitRewriteOperationsFix createAddFieldQualifierFix(CompilationUnit compilationUnit, IProblemLocation problem) { - if (IProblem.UnqualifiedFieldAccess != problem.getProblemId()) - return null; - - IProblemLocationCore problemLocation= (ProblemLocation)problem; - AddThisQualifierOperation operation= CodeStyleFixCore.getUnqualifiedFieldAccessResolveOperation(compilationUnit, problemLocation); - if (operation == null) - return null; - - String groupName= operation.getDescription(); - return new CodeStyleFix(groupName, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {operation}); - } - - public static CompilationUnitRewriteOperationsFix createIndirectAccessToStaticFix(CompilationUnit compilationUnit, IProblemLocation problem) { - IProblemLocationCore problemLocation= (ProblemLocation)problem; - if (!CodeStyleFixCore.isIndirectStaticAccess(problemLocation)) - return null; - - ToStaticAccessOperation operations[]= CodeStyleFixCore.createToStaticAccessOperations(compilationUnit, new HashMap(), problemLocation, false); - if (operations == null) - return null; - - String label= Messages.format(FixMessages.CodeStyleFix_ChangeStaticAccess_description, operations[0].getAccessorName()); - return new CodeStyleFix(label, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {operations[0]}); - } +public class CodeStyleFix { public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, boolean addThisQualifier, @@ -98,9 +35,8 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, boolean removeFieldQualifier, boolean removeMethodQualifier) { - ICleanUpFixCore fix= CodeStyleFixCore.createCleanUp(compilationUnit, addThisQualifier, changeNonStaticAccessToStatic, qualifyStaticFieldAccess, - changeIndirectStaticAccessToDirect, qualifyMethodAccess, qualifyStaticMethodAccess, removeFieldQualifier, removeMethodQualifier); - return fix == null ? null : new CleanUpFixWrapper(fix); + return CleanUpFixWrapper.create(CodeStyleFixCore.createCleanUp(compilationUnit, addThisQualifier, changeNonStaticAccessToStatic, qualifyStaticFieldAccess, + changeIndirectStaticAccessToDirect, qualifyMethodAccess, qualifyStaticMethodAccess, removeFieldQualifier, removeMethodQualifier)); } public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProblemLocation[] problems, @@ -108,22 +44,9 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProble boolean changeNonStaticAccessToStatic, boolean changeIndirectStaticAccessToDirect) { - IProblemLocationCore[] problemLocationArray= null; - if (problems != null) { - List problemList= new ArrayList<>(); - for (IProblemLocation location : problems) { - IProblemLocationCore problem= (ProblemLocation)location; - problemList.add(problem); - } - problemLocationArray= problemList.toArray(new IProblemLocationCore[0]); - } - - ICleanUpFixCore fix= CodeStyleFixCore.createCleanUp(compilationUnit, problemLocationArray, addThisQualifier, changeNonStaticAccessToStatic, changeIndirectStaticAccessToDirect); - return fix == null ? null : new CleanUpFixWrapper(fix); - } - - private CodeStyleFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] operations) { - super(name, compilationUnit, operations); + return CleanUpFixWrapper.create(problems, problemLocations -> { + return CodeStyleFixCore.createCleanUp(compilationUnit, problemLocations, addThisQualifier, changeNonStaticAccessToStatic, changeIndirectStaticAccessToDirect); + }); } } diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ControlStatementsFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ControlStatementsFix.java index 282de9fb..4a517dbd 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ControlStatementsFix.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ControlStatementsFix.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -20,9 +20,12 @@ import org.eclipse.text.edits.TextEditGroup; +import org.eclipse.jdt.core.IBuffer; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.ChildPropertyDescriptor; +import org.eclipse.jdt.core.dom.Comment; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.DoStatement; import org.eclipse.jdt.core.dom.EnhancedForStatement; @@ -33,6 +36,7 @@ import org.eclipse.jdt.core.dom.ThrowStatement; import org.eclipse.jdt.core.dom.WhileStatement; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.jdt.internal.corext.dom.GenericVisitor; import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; @@ -181,18 +185,82 @@ public AddBlockOperation(ChildPropertyDescriptor bodyProperty, Statement body, S public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException { ASTRewrite rewrite= cuRewrite.getASTRewrite(); String label; + ASTNode expression= null; + int statementType= -1; if (fBodyProperty == IfStatement.THEN_STATEMENT_PROPERTY) { label = FixMessages.CodeStyleFix_ChangeIfToBlock_desription; + expression= ((IfStatement)fControlStatement).getExpression(); + if (((IfStatement)fControlStatement).getElseStatement() == null) { + statementType= ASTNode.IF_STATEMENT; + } } else if (fBodyProperty == IfStatement.ELSE_STATEMENT_PROPERTY) { label = FixMessages.CodeStyleFix_ChangeElseToBlock_description; + expression= ((IfStatement)fControlStatement).getExpression(); } else { label = FixMessages.CodeStyleFix_ChangeControlToBlock_description; + if (fBodyProperty == WhileStatement.BODY_PROPERTY) { + expression= ((WhileStatement)fControlStatement).getExpression(); + statementType= ASTNode.WHILE_STATEMENT; + } else if (fBodyProperty == ForStatement.BODY_PROPERTY) { + expression= ((ForStatement)fControlStatement).getExpression(); + statementType= ASTNode.FOR_STATEMENT; + } else if (fBodyProperty == EnhancedForStatement.BODY_PROPERTY) { + expression= ((EnhancedForStatement)fControlStatement).getExpression(); + statementType= ASTNode.ENHANCED_FOR_STATEMENT; + } } TextEditGroup group= createTextEditGroup(label, cuRewrite); - ASTNode moveTarget= rewrite.createMoveTarget(fBody); - Block replacingBody= cuRewrite.getRoot().getAST().newBlock(); - replacingBody.statements().add(moveTarget); + List commentsToPreserve= new ArrayList<>(); + CompilationUnit cuRoot= cuRewrite.getRoot(); + int controlStatementLine= cuRoot.getLineNumber(fControlStatement.getStartPosition()); + int bodyLine= cuRoot.getLineNumber(fBody.getStartPosition()); + // If single body statement is on next line, we need to preserve any comments pertaining to the + // control statement (e.g. NLS comment for if expression) + if (controlStatementLine != bodyLine) { + int startPosition= expression == null ? fControlStatement.getStartPosition() : (expression.getStartPosition() + cuRoot.getExtendedLength(expression)); + List comments= cuRoot.getCommentList(); + for (Comment comment : comments) { + int commentLine= cuRoot.getLineNumber(comment.getStartPosition()); + if (commentLine == controlStatementLine && comment.getStartPosition() > startPosition && + comment.getStartPosition() < fBody.getStartPosition()) { + commentsToPreserve.add(comment); + } + } + } + String blockString= "{"; //$NON-NLS-1$ + IBuffer cuBuffer= cuRewrite.getCu().getBuffer(); + Block replacingBody= null; + String blockPosition= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK); + boolean blockEndOfLine= blockPosition.equals(DefaultCodeFormatterConstants.END_OF_LINE); + if (!commentsToPreserve.isEmpty()) { + // Get extended body text and convert multiple indent tabs to be just one tab as they will be relative to control statement + String bodyString= cuBuffer.getText(cuRoot.getExtendedStartPosition(fBody), cuRoot.getExtendedLength(fBody)) + .replaceAll("\\r\\n|\\r|\\n(\\t|\\s)*", System.lineSeparator() + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ + if (blockEndOfLine || statementType == -1) { + // To ensure the comments to preserve end up on same line as the control statement, we need + // to build the block manually as a string and then create a Block placeholder from it + for (Comment comment : commentsToPreserve) { + String commentString= cuBuffer.getText(comment.getStartPosition(), comment.getLength()); + blockString += " " + commentString; //$NON-NLS-1$ + } + blockString += System.lineSeparator() + "\t" + bodyString + System.lineSeparator() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + replacingBody= (Block)rewrite.createStringPlaceholder(blockString, ASTNode.BLOCK); + } else { + Comment lastComment= commentsToPreserve.get(commentsToPreserve.size()-1); + String newControlStatement= cuBuffer.getText(cuRoot.getExtendedStartPosition(fControlStatement), + lastComment.getStartPosition() + lastComment.getLength() - cuRoot.getExtendedStartPosition(fControlStatement)); + newControlStatement += System.lineSeparator() + "{" + System.lineSeparator(); //$NON-NLS-1$ + newControlStatement += "\t" + bodyString + System.lineSeparator() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + Statement newStatement= (Statement)rewrite.createStringPlaceholder(newControlStatement, statementType); + rewrite.replace(fControlStatement, newStatement, group); + return; + } + } else { + ASTNode moveTarget= rewrite.createMoveTarget(fBody); + replacingBody= cuRewrite.getRoot().getAST().newBlock(); + replacingBody.statements().add(moveTarget); + } rewrite.set(fControlStatement, fBodyProperty, replacingBody, group); } diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ConvertLoopFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ConvertLoopFix.java deleted file mode 100644 index 062fb599..00000000 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ConvertLoopFix.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2020 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - * Red Hat Inc. - modified to use ConvertLoopFixCore - *******************************************************************************/ -/** - * - **/ -package org.eclipse.jdt.internal.corext.fix; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.IStatus; - -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.ForStatement; - -import org.eclipse.jdt.internal.corext.util.JavaModelUtil; - -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; - -public class ConvertLoopFix extends CompilationUnitRewriteOperationsFix { - - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, boolean convertForLoops, boolean convertIterableForLoops, - boolean makeFinal, boolean checkLoopVarUsed) { - if (!JavaModelUtil.is50OrHigher(compilationUnit.getJavaElement().getJavaProject())) - return null; - - if (!convertForLoops && !convertIterableForLoops) - return null; - - List operations= new ArrayList<>(); - ConvertLoopFixCore.ControlStatementFinder finder= new ConvertLoopFixCore.ControlStatementFinder(convertForLoops, convertIterableForLoops, makeFinal, - checkLoopVarUsed, operations); - compilationUnit.accept(finder); - - if (operations.isEmpty()) - return null; - - CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] ops= operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[operations.size()]); - return new ConvertLoopFix(FixMessages.ControlStatementsFix_change_name, compilationUnit, ops, null); - } - - public static ConvertLoopFix createConvertForLoopToEnhancedFix(CompilationUnit compilationUnit, ForStatement loop) { - ConvertLoopOperation convertForLoopOperation= new ConvertForLoopOperation(loop); - if (!convertForLoopOperation.satisfiesPreconditions().isOK()) - return null; - - return new ConvertLoopFix(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {convertForLoopOperation}, null); - } - - public static ConvertLoopFix createConvertIterableLoopToEnhancedFix(CompilationUnit compilationUnit, ForStatement loop) { - ConvertIterableLoopOperation loopConverter= new ConvertIterableLoopOperation(loop); - IStatus status= loopConverter.satisfiesPreconditions(); - if (status.getSeverity() == IStatus.ERROR) - return null; - - return new ConvertLoopFix(FixMessages.Java50Fix_ConvertToEnhancedForLoop_description, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {loopConverter}, status); - } - - private final IStatus fStatus; - - protected ConvertLoopFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations, IStatus status) { - super(name, compilationUnit, fixRewriteOperations); - fStatus= status; - } - - @Override - public IStatus getStatus() { - return fStatus; - } - -} diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/DoWhileRatherThanWhileFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/DoWhileRatherThanWhileFix.java deleted file mode 100644 index 48c18d52..00000000 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/DoWhileRatherThanWhileFix.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2021 Red Hat Inc. and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat Inc. - initial API and implementation - *******************************************************************************/ -package org.eclipse.jdt.internal.corext.fix; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.WhileStatement; - -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; - -public class DoWhileRatherThanWhileFix extends CompilationUnitRewriteOperationsFix { - - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit) { - List operations= new ArrayList<>(); - DoWhileRatherThanWhileFixCore.DoWhileRatherThanWhileFinder finder= new DoWhileRatherThanWhileFixCore.DoWhileRatherThanWhileFinder(operations); - compilationUnit.accept(finder); - if (operations.isEmpty()) - return null; - - CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] ops= operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[operations.size()]); - return new DoWhileRatherThanWhileFix(FixMessages.DoWhileRatherThanWhileFix_description, compilationUnit, ops); - } - - public static DoWhileRatherThanWhileFix createDoWhileFix(WhileStatement switchStatement) { - CompilationUnit root= (CompilationUnit) switchStatement.getRoot(); - List operations= new ArrayList<>(); - DoWhileRatherThanWhileFixCore.DoWhileRatherThanWhileFinder finder= new DoWhileRatherThanWhileFixCore.DoWhileRatherThanWhileFinder(operations); - switchStatement.accept(finder); - if (operations.isEmpty()) - return null; - return new DoWhileRatherThanWhileFix(FixMessages.DoWhileRatherThanWhileFix_description, root, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operations.get(0) }); - } - - protected DoWhileRatherThanWhileFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { - super(name, compilationUnit, fixRewriteOperations); - } - -} diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ExternalNullAnnotationChangeProposals.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ExternalNullAnnotationChangeProposals.java index 7b8e0b91..a49ba368 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ExternalNullAnnotationChangeProposals.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/ExternalNullAnnotationChangeProposals.java @@ -34,10 +34,10 @@ import org.eclipse.swt.graphics.Point; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -46,7 +46,6 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.IContextInformation; -import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; @@ -529,15 +528,12 @@ public static boolean hasAnnotationPathInWorkspace(IJavaProject javaProject, IJa if (root != null) { try { IClasspathEntry resolvedClasspathEntry= root.getResolvedClasspathEntry(); - for (IClasspathAttribute cpa : resolvedClasspathEntry.getExtraAttributes()) { - if (IClasspathAttribute.EXTERNAL_ANNOTATION_PATH.equals(cpa.getName())) { - Path annotationPath= new Path(cpa.getValue()); - IProject project= javaProject.getProject(); - if (project.exists(annotationPath)) - return true; - IWorkspaceRoot wsRoot= project.getWorkspace().getRoot(); - return wsRoot.exists(annotationPath); - } + IProject project= javaProject.getProject(); + IPath externalAnnotationPath= resolvedClasspathEntry.getExternalAnnotationPath(project, false); + if (externalAnnotationPath != null) { + IWorkspaceRoot wsRoot= project.getWorkspace().getRoot(); + if (wsRoot.exists(externalAnnotationPath)) + return true; } } catch (JavaModelException jme) { return false; diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFix.java deleted file mode 100644 index 054299b3..00000000 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/LambdaExpressionsFix.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2019 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - * Jerome Cambon - [1.8][clean up][quick assist] Convert lambda to anonymous must qualify references to 'this'/'super' - https://bugs.eclipse.org/430573 - * Stephan Herrmann - Contribution for Bug 463360 - [override method][null] generating method override should not create redundant null annotations - * Red Hat Inc. - modified to use LambdaExpressionsFixCore static classes - *******************************************************************************/ -package org.eclipse.jdt.internal.corext.fix; - -import java.util.ArrayList; -import java.util.Collections; - -import org.eclipse.jdt.core.dom.ClassInstanceCreation; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.LambdaExpression; - -import org.eclipse.jdt.internal.corext.fix.LambdaExpressionsFixCore.FunctionalAnonymousClassesFinder; -import org.eclipse.jdt.internal.corext.fix.LambdaExpressionsFixCore.LambdaExpressionsFinder; -import org.eclipse.jdt.internal.corext.util.JavaModelUtil; - -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; - -public class LambdaExpressionsFix extends CompilationUnitRewriteOperationsFix { - - private static boolean fConversionRemovesAnnotations; - - public static LambdaExpressionsFix createConvertToLambdaFix(ClassInstanceCreation cic) { - CompilationUnit root= (CompilationUnit) cic.getRoot(); - if (!JavaModelUtil.is1d8OrHigher(root.getJavaElement().getJavaProject())) - return null; - - if (!LambdaExpressionsFixCore.isFunctionalAnonymous(cic)) - return null; - - LambdaExpressionsFixCore.CreateLambdaOperation op= new LambdaExpressionsFixCore.CreateLambdaOperation(Collections.singletonList(cic)); - String message; - if (fConversionRemovesAnnotations) { - message= FixMessages.LambdaExpressionsFix_convert_to_lambda_expression_removes_annotations; - } else { - message= FixMessages.LambdaExpressionsFix_convert_to_lambda_expression; - } - return new LambdaExpressionsFix(message, root, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { op }); - } - - public static IProposableFix createConvertToAnonymousClassCreationsFix(LambdaExpression lambda) { - // offer the quick assist at pre 1.8 levels as well to get rid of the compilation error (TODO: offer this as a quick fix in that case) - - if (lambda.resolveTypeBinding() == null || lambda.resolveTypeBinding().getFunctionalInterfaceMethod() == null) - return null; - - LambdaExpressionsFixCore.CreateAnonymousClassCreationOperation op= new LambdaExpressionsFixCore.CreateAnonymousClassCreationOperation(Collections.singletonList(lambda)); - CompilationUnit root= (CompilationUnit) lambda.getRoot(); - return new LambdaExpressionsFix(FixMessages.LambdaExpressionsFix_convert_to_anonymous_class_creation, root, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { op }); - } - - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, boolean useLambda, boolean useAnonymous) { - if (!JavaModelUtil.is1d8OrHigher(compilationUnit.getJavaElement().getJavaProject())) - return null; - - if (useLambda) { - ArrayList convertibleNodes= FunctionalAnonymousClassesFinder.perform(compilationUnit); - if (convertibleNodes.isEmpty()) - return null; - - Collections.reverse(convertibleNodes); // process nested anonymous classes first - CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation op= new LambdaExpressionsFixCore.CreateLambdaOperation(convertibleNodes); - return new LambdaExpressionsFix(FixMessages.LambdaExpressionsFix_convert_to_lambda_expression, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { op }); - - } else if (useAnonymous) { - ArrayList convertibleNodes= LambdaExpressionsFinder.perform(compilationUnit); - if (convertibleNodes.isEmpty()) - return null; - - Collections.reverse(convertibleNodes); // process nested lambdas first - CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation op= new LambdaExpressionsFixCore.CreateAnonymousClassCreationOperation(convertibleNodes); - return new LambdaExpressionsFix(FixMessages.LambdaExpressionsFix_convert_to_anonymous_class_creation, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { op }); - - } - return null; - } - - protected LambdaExpressionsFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { - super(name, compilationUnit, fixRewriteOperations); - } - -} diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/PotentialProgrammingProblemsFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/PotentialProgrammingProblemsFix.java index 529c33fa..a17090be 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/PotentialProgrammingProblemsFix.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/PotentialProgrammingProblemsFix.java @@ -14,115 +14,17 @@ *******************************************************************************/ package org.eclipse.jdt.internal.corext.fix; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; - -import org.eclipse.ltk.core.refactoring.RefactoringStatus; - -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.compiler.IProblem; -import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.ITypeBinding; -import org.eclipse.jdt.core.dom.SimpleName; -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; import org.eclipse.jdt.ui.text.java.IProblemLocation; -import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation; -import org.eclipse.jdt.internal.ui.text.correction.ProblemLocationCore; -import org.eclipse.jdt.internal.ui.text.correction.SerialVersionHashOperationCore; +import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; -public class PotentialProgrammingProblemsFix extends CompilationUnitRewriteOperationsFix { - - private static PotentialProgrammingProblemsFixCore.ISerialVersionFixContext fCurrentContext; +public class PotentialProgrammingProblemsFix { public static IProposableFix[] createMissingSerialVersionFixes(CompilationUnit compilationUnit, IProblemLocation problem) { - if (problem.getProblemId() != IProblem.MissingSerialVersion) - return null; - - final ICompilationUnit unit= (ICompilationUnit)compilationUnit.getJavaElement(); - if (unit == null) - return null; - - final SimpleName simpleName= PotentialProgrammingProblemsFixCore.getSelectedName(compilationUnit, (ProblemLocationCore)problem); - if (simpleName == null) - return null; - - ASTNode declaringNode= PotentialProgrammingProblemsFixCore.getDeclarationNode(simpleName); - if (declaringNode == null) - return null; - - SerialVersionDefaultOperationCore defop= new SerialVersionDefaultOperationCore(unit, new ASTNode[] {declaringNode}); - IProposableFix fix1= new PotentialProgrammingProblemsFix(FixMessages.Java50Fix_SerialVersion_default_description, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {defop}); - - SerialVersionHashOperationCore hashop= new SerialVersionHashOperationCore(unit, new ASTNode[] {declaringNode}); - IProposableFix fix2= new PotentialProgrammingProblemsFix(FixMessages.Java50Fix_SerialVersion_hash_description, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {hashop}); - - return new IProposableFix[] {fix1, fix2}; - } - - public static RefactoringStatus checkPreConditions(IJavaProject project, ICompilationUnit[] compilationUnits, IProgressMonitor monitor, - boolean calculatedId, - boolean defaultId, - boolean randomId) throws CoreException { - - return PotentialProgrammingProblemsFixCore.checkPreConditions(project, compilationUnits, monitor, calculatedId, defaultId, randomId); - } - - public static RefactoringStatus checkPostConditions(IProgressMonitor monitor) { - return PotentialProgrammingProblemsFixCore.checkPostConditions(monitor); - } - - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, boolean addSerialVersionIds) { - - IProblem[] problems= compilationUnit.getProblems(); - IProblemLocation[] locations= new IProblemLocation[problems.length]; - for (int i= 0; i < problems.length; i++) { - locations[i]= new ProblemLocation(problems[i]); - } - return createCleanUp(compilationUnit, locations, addSerialVersionIds); + return PotentialProgrammingProblemsFixCore.createMissingSerialVersionFixes(compilationUnit, (IProblemLocationCore) problem); } - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProblemLocation[] problems, boolean addSerialVersionIds) { - if (addSerialVersionIds) { - - final ICompilationUnit unit= (ICompilationUnit)compilationUnit.getJavaElement(); - if (unit == null) - return null; - - List declarationNodes= new ArrayList<>(); - for (IProblemLocation problem : problems) { - if (problem.getProblemId() == IProblem.MissingSerialVersion) { - final SimpleName simpleName= PotentialProgrammingProblemsFixCore.getSelectedName(compilationUnit, (ProblemLocationCore)problem); - if (simpleName != null) { - ASTNode declarationNode= PotentialProgrammingProblemsFixCore.getDeclarationNode(simpleName); - if (declarationNode != null) { - declarationNodes.add(declarationNode); - } - } - } - } - if (declarationNodes.isEmpty()) - return null; - - for (ASTNode declarationNode : declarationNodes) { - ITypeBinding binding= PotentialProgrammingProblemsFixCore.getTypeBinding(declarationNode); - if (fCurrentContext.getSerialVersionId(binding) != null) { - PotentialProgrammingProblemsFixCore.SerialVersionHashBatchOperation op= new PotentialProgrammingProblemsFixCore.SerialVersionHashBatchOperation(unit, declarationNodes.toArray(new ASTNode[declarationNodes.size()]), fCurrentContext); - return new PotentialProgrammingProblemsFix(FixMessages.PotentialProgrammingProblemsFix_add_id_change_name, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {op}); - } - } - } - return null; - } - - protected PotentialProgrammingProblemsFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { - super(name, compilationUnit, fixRewriteOperations); - } } \ No newline at end of file diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFix.java deleted file mode 100644 index ccc3ee97..00000000 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFix.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Red Hat Inc. and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat Inc. - initial API and implementation - *******************************************************************************/ -package org.eclipse.jdt.internal.corext.fix; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.SwitchStatement; - -import org.eclipse.jdt.internal.corext.fix.SwitchExpressionsFixCore.SwitchExpressionsFixOperation; -import org.eclipse.jdt.internal.corext.util.JavaModelUtil; - -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; - -public class SwitchExpressionsFix extends CompilationUnitRewriteOperationsFix { - - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit) { - if (!JavaModelUtil.is14OrHigher(compilationUnit.getJavaElement().getJavaProject())) - return null; - - List operations= new ArrayList<>(); - SwitchExpressionsFixCore.SwitchStatementsFinder finder= new SwitchExpressionsFixCore.SwitchStatementsFinder(operations); - compilationUnit.accept(finder); - if (operations.isEmpty()) - return null; - - CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] ops= operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[operations.size()]); - return new SwitchExpressionsFix(FixMessages.SwitchExpressionsFix_convert_to_switch_expression, compilationUnit, ops); - } - - public static SwitchExpressionsFix createConvertToSwitchExpressionFix(SwitchStatement switchStatement) { - CompilationUnit root= (CompilationUnit) switchStatement.getRoot(); - if (!JavaModelUtil.is14OrHigher(root.getJavaElement().getJavaProject())) - return null; - - List operations= new ArrayList<>(); - SwitchExpressionsFixCore.SwitchStatementsFinder finder= new SwitchExpressionsFixCore.SwitchStatementsFinder(operations); - switchStatement.accept(finder); - if (operations.isEmpty()) - return null; - return new SwitchExpressionsFix(FixMessages.SwitchExpressionsFix_convert_to_switch_expression, root, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operations.get(0) }); - } - - protected SwitchExpressionsFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { - super(name, compilationUnit, fixRewriteOperations); - } - -} diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFix.java deleted file mode 100644 index 19482d9b..00000000 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/TypeParametersFix.java +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014, 2019 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - * Red Hat Inc. - modified to use TypeParametersFixCore - *******************************************************************************/ -package org.eclipse.jdt.internal.corext.fix; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.core.compiler.IProblem; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.ASTVisitor; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.ITypeBinding; -import org.eclipse.jdt.core.dom.ParameterizedType; - -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; -import org.eclipse.jdt.ui.text.java.IProblemLocation; - -import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; -import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation; - -public class TypeParametersFix extends CompilationUnitRewriteOperationsFix { - - public static final class InsertTypeArgumentsVisitor extends ASTVisitor { - - private final ArrayList fNodes; - - public InsertTypeArgumentsVisitor(ArrayList nodes) { - fNodes= nodes; - } - - @Override - public boolean visit(ParameterizedType createdType) { - if (createdType == null || createdType.typeArguments().size() != 0) { - return true; - } - - ITypeBinding binding= createdType.resolveBinding(); - if (binding == null) { - return true; - } - - ITypeBinding[] typeArguments= binding.getTypeArguments(); - if (typeArguments.length == 0) { - return true; - } - - fNodes.add(createdType); - return true; - } - } - - public static TypeParametersFix createInsertInferredTypeArgumentsFix(CompilationUnit compilationUnit, ParameterizedType node) { - if (node == null) - return null; - - final ArrayList changedNodes= new ArrayList<>(); - node.accept(new InsertTypeArgumentsVisitor(changedNodes)); - - if (changedNodes.isEmpty()) - return null; - - CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation op= new TypeParametersFixCore.InsertTypeArgumentsOperation(new ParameterizedType[] { node }); - return new TypeParametersFix(FixMessages.TypeParametersFix_insert_inferred_type_arguments_name, compilationUnit, - new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { op }); - } - - public static TypeParametersFix createRemoveRedundantTypeArgumentsFix(CompilationUnit compilationUnit, IProblemLocation problem) { - int id= problem.getProblemId(); - if (id == IProblem.RedundantSpecificationOfTypeArguments) { - IProblemLocationCore problemLocation= (ProblemLocation)problem; - ParameterizedType parameterizedType= TypeParametersFixCore.getParameterizedType(compilationUnit, problemLocation); - if (parameterizedType == null) - return null; - TypeParametersFixCore.RemoveTypeArgumentsOperation operation= new TypeParametersFixCore.RemoveTypeArgumentsOperation(parameterizedType); - return new TypeParametersFix(FixMessages.TypeParametersFix_remove_redundant_type_arguments_name, compilationUnit, - new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operation }); - } - return null; - } - - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, boolean insertInferredTypeArguments, boolean removeRedundantTypeArguments) { - - IProblem[] problems= compilationUnit.getProblems(); - IProblemLocation[] locations= new IProblemLocation[problems.length]; - for (int i= 0; i < problems.length; i++) { - locations[i]= new ProblemLocation(problems[i]); - } - - return createCleanUp(compilationUnit, locations, - insertInferredTypeArguments, - removeRedundantTypeArguments); - } - - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProblemLocation[] problems, boolean insertInferredTypeArguments, boolean removeRedundantTypeArguments) { - - if (insertInferredTypeArguments) { - final ArrayList changedNodes= new ArrayList<>(); - compilationUnit.accept(new InsertTypeArgumentsVisitor(changedNodes)); - - if (changedNodes.isEmpty()) - return null; - - CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation op= - new TypeParametersFixCore.InsertTypeArgumentsOperation(changedNodes.toArray(new ParameterizedType[changedNodes.size()])); - return new TypeParametersFix(FixMessages.TypeParametersFix_insert_inferred_type_arguments_name, compilationUnit, - new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { op }); - - } else if (removeRedundantTypeArguments) { - List result= new ArrayList<>(); - for (IProblemLocation location : problems) { - IProblemLocationCore problem= (ProblemLocation)location; - int id= problem.getProblemId(); - - if (id == IProblem.RedundantSpecificationOfTypeArguments) { - ParameterizedType parameterizedType= TypeParametersFixCore.getParameterizedType(compilationUnit, problem); - if (parameterizedType == null) - return null; - result.add(new TypeParametersFixCore.RemoveTypeArgumentsOperation(parameterizedType)); - } - } - if (!result.isEmpty()) { - return new TypeParametersFix(FixMessages.TypeParametersFix_remove_redundant_type_arguments_name, compilationUnit, - result.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[result.size()])); - } - } - return null; - } - - protected TypeParametersFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { - super(name, compilationUnit, fixRewriteOperations); - } -} diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnimplementedCodeFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnimplementedCodeFix.java deleted file mode 100644 index f540d096..00000000 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnimplementedCodeFix.java +++ /dev/null @@ -1,203 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2019 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - * Red Hat Inc. - modified to use UnimplementedCodeFixCore - *******************************************************************************/ -package org.eclipse.jdt.internal.corext.fix; - -import java.util.ArrayList; - -import org.eclipse.swt.widgets.Shell; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; - -import org.eclipse.text.edits.MultiTextEdit; - -import org.eclipse.jface.dialogs.ErrorDialog; - -import org.eclipse.ui.PlatformUI; - -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.NullChange; - -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; -import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; -import org.eclipse.jdt.core.dom.ClassInstanceCreation; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.EnumConstantDeclaration; -import org.eclipse.jdt.core.dom.TypeDeclaration; -import org.eclipse.jdt.core.refactoring.CompilationUnitChange; - -import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; -import org.eclipse.jdt.internal.corext.util.Messages; - -import org.eclipse.jdt.ui.JavaUI; -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; -import org.eclipse.jdt.ui.text.java.IProblemLocation; - -import org.eclipse.jdt.internal.ui.text.correction.CorrectionMessages; - -public class UnimplementedCodeFix extends CompilationUnitRewriteOperationsFix { - - public static ICleanUpFix createCleanUp(CompilationUnit root, boolean addMissingMethod, boolean makeTypeAbstract, IProblemLocation[] problems) { - Assert.isLegal(!addMissingMethod || !makeTypeAbstract); - if (!addMissingMethod && !makeTypeAbstract) - return null; - - if (problems.length == 0) - return null; - - ArrayList operations= new ArrayList<>(); - - for (IProblemLocation problem : problems) { - if (addMissingMethod) { - ASTNode typeNode= getSelectedTypeNode(root, problem); - if (typeNode != null && !isTypeBindingNull(typeNode)) { - operations.add(new AddUnimplementedMethodsOperation(typeNode)); - } - } else { - ASTNode typeNode= getSelectedTypeNode(root, problem); - if (typeNode instanceof TypeDeclaration) { - operations.add(new UnimplementedCodeFixCore.MakeTypeAbstractOperation((TypeDeclaration) typeNode)); - } - } - } - - if (operations.isEmpty()) - return null; - - String label; - if (addMissingMethod) { - label= CorrectionMessages.UnimplementedMethodsCorrectionProposal_description; - } else { - label= CorrectionMessages.UnimplementedCodeFix_MakeAbstractFix_label; - } - return new UnimplementedCodeFix(label, root, operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[operations.size()])); - } - - public static IProposableFix createAddUnimplementedMethodsFix(final CompilationUnit root, IProblemLocation problem) { - ASTNode typeNode= getSelectedTypeNode(root, problem); - if (typeNode == null) - return null; - - if (isTypeBindingNull(typeNode)) - return null; - - AddUnimplementedMethodsOperation operation= new AddUnimplementedMethodsOperation(typeNode); - if (operation.getMethodsToImplement().length > 0) { - return new UnimplementedCodeFix(CorrectionMessages.UnimplementedMethodsCorrectionProposal_description, root, - new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operation }); - } else { - return new IProposableFix() { - @Override - public CompilationUnitChange createChange(IProgressMonitor progressMonitor) throws CoreException { - CompilationUnitChange change= new CompilationUnitChange(CorrectionMessages.UnimplementedMethodsCorrectionProposal_description, (ICompilationUnit) root.getJavaElement()) { - @Override - public Change perform(IProgressMonitor pm) throws CoreException { - Shell shell= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); - String dialogTitle= CorrectionMessages.UnimplementedMethodsCorrectionProposal_description; - IStatus status= getStatus(); - ErrorDialog.openError(shell, dialogTitle, CorrectionMessages.UnimplementedCodeFix_DependenciesErrorMessage, status); - - return new NullChange(); - } - }; - change.setEdit(new MultiTextEdit()); - return change; - } - - @Override - public String getAdditionalProposalInfo() { - return ""; //$NON-NLS-1$ - } - - @Override - public String getDisplayString() { - return CorrectionMessages.UnimplementedMethodsCorrectionProposal_description; - } - - @Override - public IStatus getStatus() { - return new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, CorrectionMessages.UnimplementedCodeFix_DependenciesStatusMessage); - } - }; - } - } - - public static UnimplementedCodeFix createMakeTypeAbstractFix(CompilationUnit root, IProblemLocation problem) { - ASTNode typeNode= getSelectedTypeNode(root, problem); - if (!(typeNode instanceof TypeDeclaration)) - return null; - - TypeDeclaration typeDeclaration= (TypeDeclaration) typeNode; - UnimplementedCodeFixCore.MakeTypeAbstractOperation operation= new UnimplementedCodeFixCore.MakeTypeAbstractOperation(typeDeclaration); - - String label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_addabstract_description, BasicElementLabels.getJavaElementName(typeDeclaration.getName().getIdentifier())); - return new UnimplementedCodeFix(label, root, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operation }); - } - - public static ASTNode getSelectedTypeNode(CompilationUnit root, IProblemLocation problem) { - ASTNode selectedNode= problem.getCoveringNode(root); - if (selectedNode == null) - return null; - - if (selectedNode.getNodeType() == ASTNode.ANONYMOUS_CLASS_DECLARATION) { // bug 200016 - selectedNode= selectedNode.getParent(); - } - - if (selectedNode.getLocationInParent() == EnumConstantDeclaration.NAME_PROPERTY) { - selectedNode= selectedNode.getParent(); - } - if (selectedNode.getNodeType() == ASTNode.SIMPLE_NAME && selectedNode.getParent() instanceof AbstractTypeDeclaration) { - return selectedNode.getParent(); - } else if (selectedNode.getNodeType() == ASTNode.CLASS_INSTANCE_CREATION) { - return ((ClassInstanceCreation) selectedNode).getAnonymousClassDeclaration(); - } else if (selectedNode.getNodeType() == ASTNode.ENUM_CONSTANT_DECLARATION) { - EnumConstantDeclaration enumConst= (EnumConstantDeclaration) selectedNode; - if (enumConst.getAnonymousClassDeclaration() != null) - return enumConst.getAnonymousClassDeclaration(); - return enumConst; - } else { - return null; - } - } - - private static boolean isTypeBindingNull(ASTNode typeNode) { - if (typeNode instanceof AbstractTypeDeclaration) { - AbstractTypeDeclaration abstractTypeDeclaration= (AbstractTypeDeclaration) typeNode; - if (abstractTypeDeclaration.resolveBinding() == null) - return true; - - return false; - } else if (typeNode instanceof AnonymousClassDeclaration) { - AnonymousClassDeclaration anonymousClassDeclaration= (AnonymousClassDeclaration) typeNode; - if (anonymousClassDeclaration.resolveBinding() == null) - return true; - - return false; - } else if (typeNode instanceof EnumConstantDeclaration) { - return false; - } else { - return true; - } - } - - public UnimplementedCodeFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { - super(name, compilationUnit, fixRewriteOperations); - } -} diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnnecessaryArrayCreationFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnnecessaryArrayCreationFix.java index b8b68d54..ede783bf 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnnecessaryArrayCreationFix.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnnecessaryArrayCreationFix.java @@ -18,8 +18,8 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Set; +import java.util.stream.Stream; import org.eclipse.core.runtime.IStatus; @@ -30,16 +30,10 @@ import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.IMethodBinding; -import org.eclipse.jdt.core.dom.IPackageBinding; import org.eclipse.jdt.core.dom.ITypeBinding; -import org.eclipse.jdt.core.dom.ImportDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; -import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.NullLiteral; -import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.SuperMethodInvocation; -import org.eclipse.jdt.core.dom.ThisExpression; -import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.GenericVisitor; @@ -47,12 +41,15 @@ import org.eclipse.jdt.ui.cleanup.ICleanUpFix; +import org.eclipse.jdt.internal.ui.fix.CleanUpFixWrapper; + public class UnnecessaryArrayCreationFix extends CompilationUnitRewriteOperationsFix { public final static class UnnecessaryArrayCreationFinder extends GenericVisitor { + private static final Set fInvalidTypes= new HashSet<>(Arrays.asList("byte", "char", "short")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + private final List fResult; private final boolean fRemoveUnnecessaryArrayCreation; - private final Set fInvalidTypes= new HashSet<>(Arrays.asList("byte", "char", "short")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ public UnnecessaryArrayCreationFinder(boolean removeUnnecessaryArrayCreation, List resultingCollection) { fRemoveUnnecessaryArrayCreation= removeUnnecessaryArrayCreation; @@ -60,62 +57,64 @@ public UnnecessaryArrayCreationFinder(boolean removeUnnecessaryArrayCreation, Li } @Override - public boolean visit(ArrayCreation node) { + public boolean visit(ArrayCreation visited) { if (!fRemoveUnnecessaryArrayCreation - || node.getType().getDimensions() != 1) { + || visited.getType().getDimensions() != 1) { return true; } - ArrayInitializer initializer= node.getInitializer(); + ArrayInitializer initializer= visited.getInitializer(); if (initializer != null && initializer.expressions() != null && initializer.expressions().size() == 1) { List expressions= initializer.expressions(); ITypeBinding singleElement= expressions.get(0).resolveTypeBinding(); - NullLiteral nullLiteral= ASTNodes.as(expressions.get(0), NullLiteral.class); - if (nullLiteral != null + if (ASTNodes.is(expressions.get(0), NullLiteral.class) || singleElement == null || singleElement.isArray()) { return true; } } - ASTNode parent= node.getParent(); + ASTNode parent= visited.getParent(); - if (parent instanceof ClassInstanceCreation) { + if (parent instanceof ClassInstanceCreation + && visited.getLocationInParent() == ClassInstanceCreation.ARGUMENTS_PROPERTY) { ClassInstanceCreation cic= (ClassInstanceCreation) parent; - if (canArrayBeRemoved(node, cic.arguments(), cic.resolveConstructorBinding())) { - fResult.add(new UnwrapNewArrayOperation(node, cic)); + if (canArrayBeRemoved(visited, cic.arguments(), cic.resolveConstructorBinding())) { + fResult.add(new UnwrapNewArrayOperation(visited, cic)); } - } else if (parent instanceof MethodInvocation) { + } else if (parent instanceof MethodInvocation + && visited.getLocationInParent() == MethodInvocation.ARGUMENTS_PROPERTY) { MethodInvocation m= (MethodInvocation) parent; - if (canArrayBeRemoved(node, m.arguments(), m.resolveMethodBinding())) { - fResult.add(new UnwrapNewArrayOperation(node, m)); + if (canArrayBeRemoved(visited, m.arguments(), m.resolveMethodBinding())) { + fResult.add(new UnwrapNewArrayOperation(visited, m)); } - } else if (parent instanceof SuperMethodInvocation) { + } else if (parent instanceof SuperMethodInvocation + && visited.getLocationInParent() == SuperMethodInvocation.ARGUMENTS_PROPERTY) { SuperMethodInvocation sm= (SuperMethodInvocation) parent; - if (canArrayBeRemoved(node, sm.arguments(), sm.resolveMethodBinding())) { - fResult.add(new UnwrapNewArrayOperation(node, sm)); + if (canArrayBeRemoved(visited, sm.arguments(), sm.resolveMethodBinding())) { + fResult.add(new UnwrapNewArrayOperation(visited, sm)); } } return true; } - private boolean canArrayBeRemoved(ArrayCreation node, List arguments, IMethodBinding binding) { - return isUselessArrayCreation(node, arguments, binding) - && !hasEquivalentMethod(node, arguments, binding); + private boolean canArrayBeRemoved(ArrayCreation visited, List arguments, IMethodBinding binding) { + return isUselessArrayCreation(visited, arguments, binding) + && !ASTNodes.hasConflictingMethodOrConstructor(visited.getParent(), binding, getParameterTypesForConflictingMethod(arguments, visited)); } - private boolean isUselessArrayCreation(ArrayCreation node, List arguments, IMethodBinding binding) { - return (node.getInitializer() != null || (node.dimensions().size() == 1 && Long.valueOf(0L).equals(ASTNodes.getIntegerLiteral((Expression) node.dimensions().get(0))))) + private boolean isUselessArrayCreation(ArrayCreation visited, List arguments, IMethodBinding binding) { + return (visited.getInitializer() != null || (visited.dimensions().size() == 1 && Long.valueOf(0L).equals(ASTNodes.getIntegerLiteral((Expression) visited.dimensions().get(0))))) && !arguments.isEmpty() - && arguments.get(arguments.size() - 1) == node + && arguments.get(arguments.size() - 1) == visited && binding != null && binding.isVarargs() && binding.getParameterTypes().length == arguments.size() @@ -123,103 +122,8 @@ private boolean isUselessArrayCreation(ArrayCreation node, List argu && !fInvalidTypes.contains(binding.getParameterTypes()[arguments.size() - 1].getElementType().getName()); } - private boolean hasEquivalentMethod(ArrayCreation node, List arguments, IMethodBinding binding) { - TypeDeclaration typeDeclaration= ASTNodes.getTypedAncestor(node, TypeDeclaration.class); - - if (typeDeclaration == null) { - return true; - } - - ITypeBinding type= typeDeclaration.resolveBinding(); - - if (type == null) { - return true; - } - - boolean inSameClass= true; - ASTNode parent= node.getParent(); - ITypeBinding[] parameterTypesForConflictingMethod= getParameterTypesForConflictingMethod(arguments, node); - - // Figure out the type where we need to start looking at methods in the hierarchy. - // If we have a new class instance or super method call or this expression or - // we have a static call that is qualified, we use the referenced class as the starting point. - // If we have a non-qualified method call, we use the class containing the call. - // Otherwise, we bail on the clean-up. - if (parent instanceof ClassInstanceCreation) { - type= ((ClassInstanceCreation) parent).resolveTypeBinding(); - inSameClass= type.isNested(); - } else if (parent instanceof MethodInvocation) { - MethodInvocation methodInvocation= (MethodInvocation) parent; - Expression expression= methodInvocation.getExpression(); - - if (expression != null) { - if (!(expression instanceof ThisExpression)) { - inSameClass= binding.getDeclaringClass().isEqualTo(type); - type= expression.resolveTypeBinding(); - } - } else { - ASTNode root= node.getRoot(); - - if (root instanceof CompilationUnit) { - CompilationUnit compilationUnit= (CompilationUnit) root; - List imports= compilationUnit.imports(); - String localPackage= null; - - if (compilationUnit.getPackage() != null && compilationUnit.getPackage().getName() != null) { - localPackage= compilationUnit.getPackage().getName().getFullyQualifiedName(); - } - - for (ImportDeclaration oneImport : imports) { - if (oneImport.isStatic() - && !oneImport.isOnDemand() - && oneImport.getName() instanceof QualifiedName) { - QualifiedName methodName= (QualifiedName) oneImport.getName(); - String methodIdentifier= methodName.getName().getIdentifier(); - ITypeBinding conflictingType= methodName.getQualifier().resolveTypeBinding(); - - if (conflictingType == null) { - return true; // Error on side of caution - } - - String importPackage= null; - - if (conflictingType.getPackage() != null) { - importPackage= conflictingType.getPackage().getName(); - } - - boolean inSamePackage= Objects.equals(localPackage, importPackage); - - for (IMethodBinding declaredMethod : conflictingType.getDeclaredMethods()) { - if (methodIdentifier.equals(declaredMethod.getName()) - && isMethodMatching(parameterTypesForConflictingMethod, binding, false, inSamePackage, declaredMethod)) { - return true; - } - } - } - } - } - - if (Modifier.isStatic(binding.getModifiers())) { - inSameClass= binding.getDeclaringClass().isEqualTo(type); - type= binding.getDeclaringClass(); - } - } - } else if (parent instanceof SuperMethodInvocation) { - inSameClass= type.isNested(); - type= type.getSuperclass(); - } else { - return true; // Error on side of caution - } - - if (type == null) { - return true; - } - - return hasEquivalentMethodForInheritedTypes(parameterTypesForConflictingMethod, binding, type, type, inSameClass); - } - - private ITypeBinding[] getParameterTypesForConflictingMethod(List arguments, ArrayCreation node) { - ArrayInitializer initializer= node.getInitializer(); + private ITypeBinding[] getParameterTypesForConflictingMethod(List arguments, ArrayCreation visited) { + ArrayInitializer initializer= visited.getInitializer(); List initializerExpressions; if (initializer != null) { @@ -228,79 +132,7 @@ private ITypeBinding[] getParameterTypesForConflictingMethod(List ar initializerExpressions= Collections.EMPTY_LIST; } - ITypeBinding[] parameterTypesForConflictingMethod= new ITypeBinding[arguments.size() - 1 + initializerExpressions.size()]; - - for (int i= 0; i < arguments.size() - 1; i++) { - parameterTypesForConflictingMethod[i]= arguments.get(i).resolveTypeBinding(); - } - - for (int i= 0; i < initializerExpressions.size(); i++) { - parameterTypesForConflictingMethod[arguments.size() - 1 + i]= initializerExpressions.get(i).resolveTypeBinding(); - } - - return parameterTypesForConflictingMethod; - } - - private boolean hasEquivalentMethodForInheritedTypes(ITypeBinding[] parameterTypesForConflictingMethod, IMethodBinding binding, ITypeBinding type, - ITypeBinding origType, boolean inSameClass) { - while (type != null) { - IPackageBinding packageBinding= type.getPackage(); - boolean inSamePackage= packageBinding.isEqualTo(origType.getPackage()); - - if (hasEquivalentMethodForOneType(parameterTypesForConflictingMethod, binding, type, inSameClass, inSamePackage)) { - return true; - } - - if (type.isNested()) { - if (hasEquivalentMethodForInheritedTypes(parameterTypesForConflictingMethod, binding, type.getDeclaringClass(), origType, inSameClass)) { - return true; - } - - type= type.getSuperclass(); - inSameClass&= type.isNested(); - } else { - type= type.getSuperclass(); - inSameClass= false; - } - } - - return false; - } - - private boolean hasEquivalentMethodForOneType(ITypeBinding[] parameterTypesForConflictingMethod, IMethodBinding binding, - ITypeBinding type, boolean inSameClass, boolean inSamePackage) { - for (IMethodBinding method : type.getDeclaredMethods()) { - if (isMethodMatching(parameterTypesForConflictingMethod, binding, inSameClass, inSamePackage, method)) { - return true; - } - } - - return false; - } - - private boolean isMethodMatching(ITypeBinding[] parameterTypesForConflictingMethod, IMethodBinding binding, boolean inSameClass, boolean inSamePackage, IMethodBinding testedMethod) { - int methodModifiers= testedMethod.getModifiers(); - ITypeBinding[] parameterTypes= testedMethod.getParameterTypes(); - - if (!binding.isEqualTo(testedMethod) - && parameterTypesForConflictingMethod.length == parameterTypes.length - && binding.getName().equals(testedMethod.getName()) - && (inSameClass || Modifier.isPublic(methodModifiers) || Modifier.isProtected(methodModifiers) - || (inSamePackage && !Modifier.isPrivate(methodModifiers)))) { - for (int i= 0; i < parameterTypesForConflictingMethod.length; i++) { - if (parameterTypesForConflictingMethod[i] == null || parameterTypes[i] == null) { - return true; - } - - if (!parameterTypesForConflictingMethod[i].isAssignmentCompatible(parameterTypes[i])) { - return false; - } - } - - return true; - } - - return false; + return Stream.concat(arguments.stream().limit(arguments.size() - 1), initializerExpressions.stream()).map(Expression::resolveTypeBinding).toArray(ITypeBinding[]::new); } } @@ -319,7 +151,7 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, boolean return null; CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] ops= operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[operations.size()]); - return new ConvertLoopFix(FixMessages.ControlStatementsFix_change_name, compilationUnit, ops, null); + return new CleanUpFixWrapper(new ConvertLoopFixCore(FixMessages.ControlStatementsFix_change_name, compilationUnit, ops, null)); } public static UnnecessaryArrayCreationFix createUnnecessaryArrayCreationFix(CompilationUnit compilationUnit, Expression methodInvocation) { diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnusedCodeFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnusedCodeFix.java index dcf38dbc..d9458a10 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnusedCodeFix.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/UnusedCodeFix.java @@ -14,169 +14,78 @@ *******************************************************************************/ package org.eclipse.jdt.internal.corext.fix; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -import org.eclipse.jdt.core.compiler.IProblem; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.CastExpression; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.IBinding; -import org.eclipse.jdt.core.dom.ImportDeclaration; -import org.eclipse.jdt.core.dom.SimpleName; -import org.eclipse.jdt.core.manipulation.ICleanUpFixCore; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; -import org.eclipse.jdt.internal.corext.dom.ASTNodes; -import org.eclipse.jdt.internal.corext.fix.UnusedCodeFixCore.RemoveCastOperation; -import org.eclipse.jdt.internal.corext.fix.UnusedCodeFixCore.RemoveUnusedMemberOperation; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.refactoring.CompilationUnitChange; -import org.eclipse.jdt.ui.cleanup.CleanUpOptions; -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; import org.eclipse.jdt.ui.text.java.IProblemLocation; -import org.eclipse.jdt.internal.ui.fix.CleanUpFixWrapper; import org.eclipse.jdt.internal.ui.fix.UnusedCodeCleanUp; -import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; +import org.eclipse.jdt.internal.ui.fix.UnusedCodeCleanUpCore; import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation; /** * Fix which removes unused code. */ -public class UnusedCodeFix extends CompilationUnitRewriteOperationsFix { +public class UnusedCodeFix implements IProposableFix { + protected UnusedCodeFixCore cleanUpFixCore; - public static UnusedCodeFix createRemoveUnusedImportFix(CompilationUnit compilationUnit, IProblemLocation problem) { - if (isUnusedImport(problem)) { - IProblemLocationCore problemCore= (ProblemLocation)problem; - ImportDeclaration node= UnusedCodeFixCore.getImportDeclaration(problemCore, compilationUnit); - if (node != null) { - String label= FixMessages.UnusedCodeFix_RemoveImport_description; - UnusedCodeFixCore.RemoveImportOperation operation= new UnusedCodeFixCore.RemoveImportOperation(node); - Map options= new Hashtable<>(); - options.put(CleanUpConstants.REMOVE_UNUSED_CODE_IMPORTS, CleanUpOptions.TRUE); - return new UnusedCodeFix(label, compilationUnit, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {operation}, options); - } - } - return null; + public UnusedCodeFix(UnusedCodeFixCore cleanUpFixCore) { + this.cleanUpFixCore = cleanUpFixCore; } - public static boolean isUnusedImport(IProblemLocation problem) { - IProblemLocationCore problemCore= (ProblemLocation)problem; - return UnusedCodeFixCore.isUnusedImport(problemCore); - } + public UnusedCodeCleanUp getCleanUp() { + UnusedCodeCleanUpCore cleanUp= cleanUpFixCore.getCleanUp(); - public static UnusedCodeFix createUnusedMemberFix(CompilationUnit compilationUnit, IProblemLocation problem, boolean removeAllAssignements) { - if (isUnusedMember(problem)) { - IProblemLocationCore problemCore= (ProblemLocation)problem; - SimpleName name= UnusedCodeFixCore.getUnusedName(compilationUnit, problemCore); - if (name != null) { - IBinding binding= name.resolveBinding(); - if (binding != null) { - if (UnusedCodeFixCore.isFormalParameterInEnhancedForStatement(name)) - return null; - - String label= UnusedCodeFixCore.getDisplayString(name, binding, removeAllAssignements); - UnusedCodeFixCore.RemoveUnusedMemberOperation operation= new RemoveUnusedMemberOperation(new SimpleName[] { name }, removeAllAssignements); - return new UnusedCodeFix(label, compilationUnit, - new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operation }, UnusedCodeFixCore.getCleanUpOptions(binding, removeAllAssignements)); - } - } - } - return null; + return cleanUp == null ? null : new UnusedCodeCleanUp(cleanUp); } - public static UnusedCodeFix createUnusedTypeParameterFix(CompilationUnit compilationUnit, IProblemLocation problemLoc) { - if (problemLoc.getProblemId() == IProblem.UnusedTypeParameter) { - IProblemLocationCore problemLocCore= (ProblemLocation)problemLoc; - SimpleName name= UnusedCodeFixCore.getUnusedName(compilationUnit, problemLocCore); - if (name != null) { - IBinding binding= name.resolveBinding(); - if (binding != null) { - String label= FixMessages.UnusedCodeFix_RemoveUnusedTypeParameter_description; - UnusedCodeFixCore.RemoveUnusedTypeParameterOperation operation= new UnusedCodeFixCore.RemoveUnusedTypeParameterOperation(name); - return new UnusedCodeFix(label, compilationUnit, - new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operation }, UnusedCodeFixCore.getCleanUpOptions(binding, false)); - } - } - } - return null; + @Override + public CompilationUnitChange createChange(IProgressMonitor progressMonitor) throws CoreException { + return cleanUpFixCore.createChange(progressMonitor); } - public static boolean isUnusedMember(IProblemLocation problem) { - IProblemLocationCore problemCore= (ProblemLocation)problem; - return UnusedCodeFixCore.isUnusedMember(problemCore); + @Override + public String getDisplayString() { + return cleanUpFixCore.getDisplayString(); } - public static UnusedCodeFix createRemoveUnusedCastFix(CompilationUnit compilationUnit, IProblemLocation problem) { - if (problem.getProblemId() != IProblem.UnnecessaryCast) - return null; - - ASTNode selectedNode= ASTNodes.getUnparenthesedExpression(problem.getCoveringNode(compilationUnit)); - - if (!(selectedNode instanceof CastExpression)) - return null; - - return new UnusedCodeFix(FixMessages.UnusedCodeFix_RemoveCast_description, compilationUnit, - new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] {new RemoveCastOperation((CastExpression)selectedNode)}); + @Override + public String getAdditionalProposalInfo() { + return cleanUpFixCore.getAdditionalProposalInfo(); } - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, - boolean removeUnusedPrivateMethods, - boolean removeUnusedPrivateConstructors, - boolean removeUnusedPrivateFields, - boolean removeUnusedPrivateTypes, - boolean removeUnusedLocalVariables, - boolean removeUnusedImports, - boolean removeUnusedCast) { - - ICleanUpFixCore fix= UnusedCodeFixCore.createCleanUp(compilationUnit, removeUnusedPrivateMethods, removeUnusedPrivateConstructors, - removeUnusedPrivateFields, removeUnusedPrivateTypes, removeUnusedLocalVariables, removeUnusedImports, removeUnusedCast); - - return fix == null ? null : new CleanUpFixWrapper(fix); + @Override + public IStatus getStatus() { + return cleanUpFixCore.getStatus(); } - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProblemLocation[] problems, - boolean removeUnusedPrivateMethods, - boolean removeUnusedPrivateConstructors, - boolean removeUnusedPrivateFields, - boolean removeUnusedPrivateTypes, - boolean removeUnusedLocalVariables, - boolean removeUnusedImports, - boolean removeUnusedCast) { - - IProblemLocationCore[] problemsCore= null; - if (problems != null) { - List problemList= new ArrayList<>(); - for (IProblemLocation problem : problems) { - problemList.add((ProblemLocation)problem); - } - problemsCore= problemList.toArray(new IProblemLocationCore[0]); - } - - ICleanUpFixCore fix= UnusedCodeFixCore.createCleanUp(compilationUnit, problemsCore, removeUnusedPrivateMethods, - removeUnusedPrivateConstructors, removeUnusedPrivateFields, removeUnusedPrivateTypes, removeUnusedLocalVariables, removeUnusedImports, removeUnusedCast); - - return fix == null ? null : new CleanUpFixWrapper(fix); + public static UnusedCodeFix createRemoveUnusedImportFix(CompilationUnit compilationUnit, IProblemLocation problem) { + return wrap(UnusedCodeFixCore.createRemoveUnusedImportFix(compilationUnit, (ProblemLocation)problem)); } - private final Map fCleanUpOptions; + private static UnusedCodeFix wrap(UnusedCodeFixCore coreFix) { + return coreFix == null ? null : new UnusedCodeFix(coreFix); + } - private UnusedCodeFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { - this(name, compilationUnit, fixRewriteOperations, null); + public static UnusedCodeFix createUnusedMemberFix(CompilationUnit compilationUnit, IProblemLocation problem, boolean removeAllAssignements) { + return wrap(UnusedCodeFixCore.createUnusedMemberFix(compilationUnit, (ProblemLocation)problem, removeAllAssignements)); } - private UnusedCodeFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations, Map options) { - super(name, compilationUnit, fixRewriteOperations); - fCleanUpOptions= options; + public static UnusedCodeFix createUnusedParameterFix(CompilationUnit compilationUnit, IProblemLocation problem) { + return wrap(UnusedCodeFixCore.createUnusedParameterFix(compilationUnit, (ProblemLocation)problem)); } - public UnusedCodeCleanUp getCleanUp() { - if (fCleanUpOptions == null) - return null; + public static UnusedCodeFix createUnusedTypeParameterFix(CompilationUnit compilationUnit, IProblemLocation problemLoc) { + return wrap(UnusedCodeFixCore.createUnusedTypeParameterFix(compilationUnit, (ProblemLocation)problemLoc)); + } - return new UnusedCodeCleanUp(fCleanUpOptions); + public static UnusedCodeFix createRemoveUnusedCastFix(CompilationUnit compilationUnit, IProblemLocation problem) { + return wrap(UnusedCodeFixCore.createRemoveUnusedCastFix(compilationUnit, (ProblemLocation)problem)); } } diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/VariableDeclarationFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/VariableDeclarationFix.java deleted file mode 100644 index c28ceaed..00000000 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/VariableDeclarationFix.java +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - * Chris West (Faux) - [clean up] "Use modifier 'final' where possible" can introduce compile errors - https://bugs.eclipse.org/bugs/show_bug.cgi?id=272532 - * Red Hat Inc. - modified to use VariableDelcarationFixCore - *******************************************************************************/ -package org.eclipse.jdt.internal.corext.fix; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.IBinding; -import org.eclipse.jdt.core.dom.SimpleName; - -import org.eclipse.jdt.ui.cleanup.ICleanUpFix; - -public class VariableDeclarationFix extends CompilationUnitRewriteOperationsFix { - - public static VariableDeclarationFix createChangeModifierToFinalFix(final CompilationUnit compilationUnit, ASTNode[] selectedNodes) { - HashMap> writtenNames= new HashMap<>(); - VariableDeclarationFixCore.WrittenNamesFinder finder= new VariableDeclarationFixCore.WrittenNamesFinder(writtenNames); - compilationUnit.accept(finder); - List ops= new ArrayList<>(); - VariableDeclarationFixCore.VariableDeclarationFinder visitor= new VariableDeclarationFixCore.VariableDeclarationFinder(true, true, true, ops, writtenNames); - if (selectedNodes.length == 1) { - selectedNodes[0].accept(visitor); - } else { - for (ASTNode selectedNode : selectedNodes) { - selectedNode.accept(visitor); - } - } - if (ops.isEmpty()) - return null; - - CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] result= ops.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[ops.size()]); - String label; - if (result.length == 1) { - label= FixMessages.VariableDeclarationFix_changeModifierOfUnknownToFinal_description; - } else { - label= FixMessages.VariableDeclarationFix_ChangeMidifiersToFinalWherPossible_description; - } - return new VariableDeclarationFix(label, compilationUnit, result); - } - - public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, - boolean addFinalFields, boolean addFinalParameters, boolean addFinalLocals) { - - if (!addFinalFields && !addFinalParameters && !addFinalLocals) - return null; - - HashMap> writtenNames= new HashMap<>(); - VariableDeclarationFixCore.WrittenNamesFinder finder= new VariableDeclarationFixCore.WrittenNamesFinder(writtenNames); - compilationUnit.accept(finder); - - List operations= new ArrayList<>(); - VariableDeclarationFixCore.VariableDeclarationFinder visitor= new VariableDeclarationFixCore.VariableDeclarationFinder(addFinalFields, addFinalParameters, addFinalLocals, operations, writtenNames); - compilationUnit.accept(visitor); - - if (operations.isEmpty()) - return null; - - return new VariableDeclarationFix(FixMessages.VariableDeclarationFix_add_final_change_name, compilationUnit, operations.toArray(new CompilationUnitRewriteOperation[operations.size()])); - } - - - protected VariableDeclarationFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) { - super(name, compilationUnit, fixRewriteOperations); - } - -} diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/javadoc/JavaDocLocations.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/javadoc/JavaDocLocations.java index a1acd97f..cbed5ce9 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/javadoc/JavaDocLocations.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/javadoc/JavaDocLocations.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -60,6 +60,10 @@ import org.eclipse.jdt.internal.corext.CorextMessages; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; +import org.eclipse.jdt.launching.AbstractVMInstall; +import org.eclipse.jdt.launching.IVMInstall; +import org.eclipse.jdt.launching.JavaRuntime; + import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jdt.internal.ui.JavaPlugin; @@ -378,10 +382,10 @@ private static IModuleDescription getModuleDescription(IPackageFragment pack) { IModuleDescription moduleDescription= null; /* * The Javadoc tool for Java SE 11 uses module name in the created URL. - * We can't know what format is required, so we just guess by the project's compiler compliance. + * We can't know what format is required, so we just guess by the project's execution environment or compiler compliance. */ IJavaProject javaProject= pack.getJavaProject(); - if (javaProject != null && JavaModelUtil.is11OrHigher(javaProject)) { + if (javaProject != null && is11OrHigher(javaProject)) { if (pack.isReadOnly()) { IPackageFragmentRoot root= (IPackageFragmentRoot) pack.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); if (root != null) { @@ -398,6 +402,79 @@ private static IModuleDescription getModuleDescription(IPackageFragment pack) { return moduleDescription; } + /** + * This function finds out which jvm/source compliance is being used to see if its version 11 or higher. + * @param javaProject the java project for which the version number is to be verified. + * @return true if the jvm used is version 11 or higher (If no jvm is found then the source compliance is used) + * else returns false + */ + private static boolean is11OrHigher(IJavaProject javaProject) { + boolean is11orHigher= false; + if (javaProject != null) { + try { + IVMInstall install= JavaRuntime.getVMInstall(javaProject); + if (install instanceof AbstractVMInstall) { + String vmver = ((AbstractVMInstall)install).getJavaVersion(); + is11orHigher= JavaModelUtil.is11OrHigher(vmver); + } else { + is11orHigher= JavaModelUtil.is11OrHigher(javaProject); + } + } catch (CoreException e) { + is11orHigher= JavaModelUtil.is11OrHigher(javaProject); + } + } + return is11orHigher; + } + + /** + * This function finds out which jvm/source compliance is being used to see if its version 10 or higher. + * @param javaProject the java project for which the version number is to be verified. + * @return true if the jvm used is version 10 or higher (If no jvm is found then the source compliance is used) + * else returns false + */ + private static boolean is10OrHigher(IJavaProject javaProject) { + boolean is10orHigher= false; + if (javaProject != null) { + try { + IVMInstall install= JavaRuntime.getVMInstall(javaProject); + if (install instanceof AbstractVMInstall) { + String vmver = ((AbstractVMInstall)install).getJavaVersion(); + is10orHigher= JavaModelUtil.is10OrHigher(vmver); + } else { + is10orHigher= JavaModelUtil.is10OrHigher(javaProject); + } + } catch (CoreException e) { + is10orHigher= JavaModelUtil.is10OrHigher(javaProject); + } + } + return is10orHigher; + } + + /** + * This function finds out which jvm/source compliance is being used to see if its version 1.8 or 9. + * @param javaProject the java project for which the version number is to be verified. + * @return true if the jvm used is 1.8 or 9 (If no jvm is found then the source compliance is used) + * else returns false + */ + private static boolean is1d8Or9(IJavaProject javaProject) { + boolean is1d8Or9= false; + String compliance= JavaModelUtil.getSourceCompliance(javaProject); + if (javaProject != null) { + try { + IVMInstall install= JavaRuntime.getVMInstall(javaProject); + if (install instanceof AbstractVMInstall) { + String vmver = ((AbstractVMInstall)install).getJavaVersion(); + is1d8Or9 = JavaModelUtil.is1d8OrHigher(vmver) && !JavaModelUtil.is10OrHigher(vmver); + } else { + is1d8Or9= JavaCore.compareJavaVersions(compliance, JavaCore.VERSION_1_8) == 0 || JavaCore.compareJavaVersions(compliance, JavaCore.VERSION_9) == 0; + } + } catch (CoreException e) { + is1d8Or9= JavaCore.compareJavaVersions(compliance, JavaCore.VERSION_1_8) == 0 || JavaCore.compareJavaVersions(compliance, JavaCore.VERSION_9) == 0; + } + } + return is1d8Or9; + } + private static void appendFieldReference(IField field, StringBuffer buf) { buf.append(field.getElementName()); } @@ -411,9 +488,8 @@ private static void appendMethodReference(IMethod meth, StringBuffer buf) throws * We can't know what format is required, so we just guess by the project's compiler compliance. */ IJavaProject javaProject= meth.getJavaProject(); - String compliance= JavaModelUtil.getSourceCompliance(javaProject); - boolean is1d8Or9= JavaCore.compareJavaVersions(compliance, JavaCore.VERSION_1_8) == 0 || JavaCore.compareJavaVersions(compliance, JavaCore.VERSION_9) == 0; - boolean is10OrHigher= JavaModelUtil.is10OrHigher(javaProject); + boolean is1d8Or9= is1d8Or9(javaProject); + boolean is10OrHigher= is10OrHigher(javaProject); buf.append(is1d8Or9 ? '-' : '('); String[] params= meth.getParameterTypes(); IType declaringType= meth.getDeclaringType(); diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/TypeInfoFilter.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/TypeInfoFilter.java index bc74c1cf..6e6cb250 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/TypeInfoFilter.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/TypeInfoFilter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -29,17 +29,111 @@ public class TypeInfoFilter { private final String fText; + private final IJavaSearchScope fSearchScope; + private final boolean fIsWorkspaceScope; + private final int fElementKind; + private final ITypeInfoFilterExtension fFilterExtension; + private final TypeInfoRequestorAdapter fAdapter= new TypeInfoRequestorAdapter(); private final PatternMatcher fPackageMatcher; + private final PatternMatcher fNameMatcher; private static final int TYPE_MODIFIERS= Flags.AccEnum | Flags.AccAnnotation | Flags.AccInterface; + /* reduces filenames and stack traces to class name */ + public static String simplifySearchText(String input) { + String s= input; + try { + int i; + // skip any bracket and anything behind ("[native]" from thread dump) + i= s.lastIndexOf('['); + if (i != -1) { + s= s.substring(0, i); + } + // skip any bracket, anything behind and the segment before (method name) + i= s.lastIndexOf('('); + if (i != -1) { + s= s.substring(0, i); + i= s.lastIndexOf('.'); + if (i != -1) { + s= s.substring(0, i); + } + } + // skip any "$$Lambda" and anything behind (Lambda) + i= s.lastIndexOf("$$Lambda"); //$NON-NLS-1$ + if (i != -1) { + s= s.substring(0, i); + } + // skip any backslash and the text before (windows path) + s= skipBefore(s, "\\"); //$NON-NLS-1$ + // skip any slash and the text before (unix path) + s= skipBefore(s, "/"); //$NON-NLS-1$ + // skip initial "at " and the text before (StackTraceElement) + s= skipBefore(s, "at "); //$NON-NLS-1$ + // simplify + s= s.strip(); + // skip last single ".java" and anything behind (file name) + s= skipEnding(s, ".java"); //$NON-NLS-1$ + s= skipEnding(s, ".class"); //$NON-NLS-1$ + // skip $1, $2 ... - typenames cannot start with a number + s= skipSynthetic(s); + // binary name of Inner Class to qualified name + int inner= countContains(s, '$'); + if (inner > 0) { + s= s.replace('$', '.'); + } + if (s.isEmpty()) { + // oversimplified + return input; + } + // partially qualified names need a asterisk wildcard to be found by Open Type dialog: + if (inner > 0 && !input.trim().equals(s.trim()) && countContains(s, '.') == inner && !s.contains("*")) { //$NON-NLS-1$ + s= "*." + s; //$NON-NLS-1$ + } + } catch (Exception e) { + // just in case anything bad happened: + return input; + } + return s; + } + + private static int countContains(String s, char c) { + return (int) s.chars().filter(i -> c == (char) i).count(); + } + + private static String skipBefore(String s, String skip) { + int i= s.lastIndexOf(skip); + if (i != -1) { + s= s.substring(i + skip.length()); + } + return s; + } + + private static String skipEnding(String s, String skip) { + int i= s.lastIndexOf(skip); + int length= skip.length(); + char nextChar= s.length() > i + length ? s.charAt(i + length) : ' '; + if (i != -1 && !Character.isJavaIdentifierPart(nextChar) && !(nextChar == '.')) { + s= s.substring(0, i); + } + return s; + } + private static String skipSynthetic(String s) { + int i= s.lastIndexOf('$'); + int length= 1; + char nextChar= s.length() > i + length ? s.charAt(i + length) : ' '; + if (i != -1 && !Character.isJavaIdentifierStart(nextChar) && !(nextChar == '.')) { + s= s.substring(0, i); + } + return s; + } + public TypeInfoFilter(String text, IJavaSearchScope scope, int elementKind, ITypeInfoFilterExtension extension) { fText= text; fSearchScope= scope; @@ -52,7 +146,12 @@ public TypeInfoFilter(String text, IJavaSearchScope scope, int elementKind, ITyp fNameMatcher= new PatternMatcher(text); fPackageMatcher= null; } else { - fPackageMatcher= new PatternMatcher(evaluatePackagePattern(text.substring(0, index))); + if (Character.isUpperCase(text.charAt(0))) { + // might be referring to class so add wild-card at front + fPackageMatcher= new PatternMatcher(evaluatePackagePattern("*" + text.substring(0, index))); //$NON-NLS-1$ + } else { + fPackageMatcher= new PatternMatcher(evaluatePackagePattern(text.substring(0, index))); + } String name= text.substring(index + 1); if (name.length() == 0) name= "*"; //$NON-NLS-1$ @@ -74,7 +173,7 @@ private String evaluatePackagePattern(String s) { buf.append('*'); } hasWildCard= false; - } else if (ch == '*' || ch =='?') { + } else if (ch == '*' || ch == '?') { hasWildCard= true; } buf.append(ch); @@ -96,18 +195,17 @@ public String getText() { * Checks whether this filter is a subFilter of the given text. *

    * WARNING: This is the reverse interpretation compared to - * {@link org.eclipse.ui.dialogs.SearchPattern#isSubPattern(org.eclipse.ui.dialogs.SearchPattern)} and - * {@link org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#isSubFilter}. - * + * {@link org.eclipse.ui.dialogs.SearchPattern#isSubPattern(org.eclipse.ui.dialogs.SearchPattern)} + * and {@link org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#isSubFilter}. *

    * * @param text another filter text * @return true if this filter is a subFilter of text - * e.g. "List" is a subFilter of "L". In this case, the filters matches a proper subset of - * the items matched by text. + * e.g. "List" is a subFilter of "L". In this case, the filters matches a proper subset + * of the items matched by text. */ public boolean isSubFilter(String text) { - if (! fText.startsWith(text)) + if (!fText.startsWith(text)) return false; return fText.indexOf('.', text.length()) == -1; diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java index 117bc7cb..f6317078 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2021 IBM Corporation and others. + * Copyright (c) 2005, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -1174,7 +1174,6 @@ public static boolean isRenameElementAvailable(IJavaElement element, boolean isT case IJavaElement.LOCAL_VARIABLE: return isRenameAvailable((ILocalVariable) element); case IJavaElement.JAVA_MODULE: { - if (isTextSelection) return false; return isRenameAvailable((IModuleDescription) element); } default: diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodAnalyzer.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodAnalyzer.java index 3e091a74..c6d2c27f 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodAnalyzer.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodAnalyzer.java @@ -921,7 +921,7 @@ public boolean visit(LambdaExpression node) { int bodyExclusiveEnd= bodyStart + body.getLength(); boolean isValidSelection= false; - if ((body instanceof Block) && (bodyStart < selectionStart && selectionExclusiveEnd <= bodyExclusiveEnd)) { + if ((body instanceof Block) && (bodyStart <= selectionStart && selectionExclusiveEnd <= bodyExclusiveEnd)) { // if selection is inside lambda body's block isValidSelection= true; } else if (body instanceof Expression) { diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodRefactoring.java index d63540b3..d7ae6d57 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodRefactoring.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -77,6 +77,7 @@ import org.eclipse.jdt.core.dom.Initializer; import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.LabeledStatement; +import org.eclipse.jdt.core.dom.LambdaExpression; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Modifier; @@ -1243,9 +1244,25 @@ private Block createMethodBody(ASTNode[] selectedNodes, TextEditGroup substitute fAnalyzer.getReturnTypeBinding().equals(fAST.resolveWellKnownType("void")); //$NON-NLS-1$ if (selectedNodes.length == 1) { if (!isReturnVoid) { - statements.insertLast(fRewriter.createMoveTarget(selectedNodes[0]), substitute); + if (selectedNodes[0] instanceof Block) { + Block block= (Block)selectedNodes[0]; + List blockStatements= block.statements(); + for (Statement blockStatement : blockStatements) { + statements.insertLast(fRewriter.createMoveTarget(blockStatement), substitute); + } + } else { + statements.insertLast(fRewriter.createMoveTarget(selectedNodes[0]), substitute); + } + } + if (selectedNodes[0].getLocationInParent() == LambdaExpression.BODY_PROPERTY) { + if (replacementNode instanceof ExpressionStatement) { + fRewriter.replace(selectedNodes[0], ((ExpressionStatement)replacementNode).getExpression(), substitute); + } else if (replacementNode instanceof ReturnStatement) { + fRewriter.replace(selectedNodes[0], ((ReturnStatement)replacementNode).getExpression(), substitute); + } + } else { + fRewriter.replace(selectedNodes[0], replacementNode, substitute); } - fRewriter.replace(selectedNodes[0], replacementNode, substitute); } else if (selectedNodes.length > 1) { if (isReturnVoid) { fRewriter.remove(selectedNodes[selectedNodes.length - 1], substitute); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractTempRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractTempRefactoring.java index 7f11a671..bd50e0c1 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractTempRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractTempRefactoring.java @@ -13,6 +13,7 @@ * Nikolay Metchev - [extract local] Extract to local variable not replacing multiple occurrences in same statement - https://bugs.eclipse.org/406347 * Nicolaj Hoess - [extract local] puts declaration at wrong position - https://bugs.eclipse.org/65875 * Pierre-Yves B. - [inline] Allow inlining of local variable initialized to null. - https://bugs.eclipse.org/93850 + * Xiaye Chi - [extract local] Extract to local variable may result in NullPointerException. - https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/39 *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.code; @@ -33,7 +34,10 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.text.edits.CopySourceEdit; +import org.eclipse.text.edits.TextEdit; import org.eclipse.text.edits.TextEditGroup; +import org.eclipse.text.edits.TextEditVisitor; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.Refactoring; @@ -133,6 +137,7 @@ import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; import org.eclipse.jdt.internal.corext.refactoring.util.JavaStatusContext; import org.eclipse.jdt.internal.corext.refactoring.util.NoCommentSourceRangeComputer; +import org.eclipse.jdt.internal.corext.refactoring.util.NullChecker; import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; @@ -149,7 +154,9 @@ public class ExtractTempRefactoring extends Refactoring { private static final String ATTRIBUTE_REPLACE= "replace"; //$NON-NLS-1$ + private static final String ATTRIBUTE_FINAL= "final"; //$NON-NLS-1$ + private static final String ATTRIBUTE_TYPE_VAR= "varType"; //$NON-NLS-1$ private static final class ForStatementChecker extends ASTVisitor { @@ -328,7 +335,7 @@ private static boolean isUsedInForInitializerOrUpdater(Expression expression) { return false; } - private static IASTFragment[] retainOnlyReplacableMatches(IASTFragment[] allMatches) { + private IASTFragment[] retainOnlyReplacableMatches(IASTFragment[] allMatches) { List result= new ArrayList<>(allMatches.length); for (IASTFragment match : allMatches) { if (canReplace(match)) { @@ -360,6 +367,7 @@ private static IASTFragment[] retainOnlyReplacableMatches(IASTFragment[] allMatc private int fSelectionStart; private String fTempName; + private String[] fGuessedTempNames; private boolean fCheckResultForCompileProblems; @@ -369,11 +377,19 @@ private static IASTFragment[] retainOnlyReplacableMatches(IASTFragment[] allMatc private LinkedProposalModel fLinkedProposalModel; private static final String KEY_NAME= "name"; //$NON-NLS-1$ + private static final String KEY_TYPE= "type"; //$NON-NLS-1$ + private int fStartPoint; + + private int fEndPoint; + + private HashSet fSeen= new HashSet<>(); + /** * Creates a new extract temp refactoring + * * @param unit the compilation unit, or null if invoked by scripting * @param selectionStart start of selection * @param selectionLength length of selection @@ -393,6 +409,9 @@ public ExtractTempRefactoring(ICompilationUnit unit, int selectionStart, int sel fLinkedProposalModel= null; fCheckResultForCompileProblems= true; + + fStartPoint= -1; // default + fEndPoint= -1; // default } public ExtractTempRefactoring(CompilationUnit astRoot, int selectionStart, int selectionLength) { @@ -412,13 +431,24 @@ public ExtractTempRefactoring(CompilationUnit astRoot, int selectionStart, int s fLinkedProposalModel= null; fCheckResultForCompileProblems= true; + + fStartPoint= -1; // default + fEndPoint= -1; // default + + } + + public ExtractTempRefactoring(JavaRefactoringArguments arguments, RefactoringStatus status) { + this((ICompilationUnit) null, 0, 0); + + fStartPoint= -1; // default + fEndPoint= -1; // default + + + RefactoringStatus initializeStatus= initialize(arguments); + status.merge(initializeStatus); + } - public ExtractTempRefactoring(JavaRefactoringArguments arguments, RefactoringStatus status) { - this((ICompilationUnit) null, 0, 0); - RefactoringStatus initializeStatus= initialize(arguments); - status.merge(initializeStatus); - } public void setCheckResultForCompileProblems(boolean checkResultForCompileProblems) { fCheckResultForCompileProblems= checkResultForCompileProblems; @@ -430,15 +460,16 @@ public void setLinkedProposalModel(LinkedProposalModel linkedProposalModel) { } private void addReplaceExpressionWithTemp() throws JavaModelException { - IASTFragment[] fragmentsToReplace= retainOnlyReplacableMatches(getMatchingFragments()); + IASTFragment[] fragmentsToReplace= reSortRetainOnlyReplacableMatches(); + if (fragmentsToReplace.length == 0) { return; } //TODO: should not have to prune duplicates here... ASTRewrite rewrite= fCURewrite.getASTRewrite(); - HashSet seen= new HashSet<>(); - for (IASTFragment fragment : fragmentsToReplace) { - if (!seen.add(fragment)) + for (int i= fEndPoint; i >= fStartPoint; --i) { + IASTFragment fragment= fragmentsToReplace[i]; + if (!fSeen.add(fragment)) continue; SimpleName tempName= fCURewrite.getAST().newSimpleName(fTempName); TextEditGroup description= fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_replace); @@ -465,7 +496,8 @@ private RefactoringStatus checkExpression() throws JavaModelException { } else if (selectedExpression instanceof SimpleName) { if ((((SimpleName) selectedExpression)).isDeclaration()) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_names_in_declarations); - if (parent instanceof QualifiedName && selectedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY || parent instanceof FieldAccess && selectedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY) + if (parent instanceof QualifiedName && selectedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY + || parent instanceof FieldAccess && selectedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY) return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_select_expression); } else if (selectedExpression instanceof VariableDeclarationExpression && parent instanceof TryStatement) { return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_resource_in_try_with_resources); @@ -479,9 +511,11 @@ private RefactoringStatus checkExpression() throws JavaModelException { private RefactoringStatus checkExpressionFragmentIsRValue() throws JavaModelException { switch (Checks.checkExpressionIsRValue(getSelectedExpression().getAssociatedExpression())) { case Checks.NOT_RVALUE_MISC: - return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_select_expression, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE, null); + return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_select_expression, null, Corext.getPluginId(), + RefactoringStatusCodes.EXPRESSION_NOT_RVALUE, null); case Checks.NOT_RVALUE_VOID: - return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_no_void, null, Corext.getPluginId(), RefactoringStatusCodes.EXPRESSION_NOT_RVALUE_VOID, null); + return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.ExtractTempRefactoring_no_void, null, Corext.getPluginId(), + RefactoringStatusCodes.EXPRESSION_NOT_RVALUE_VOID, null); case Checks.IS_RVALUE_GUESSED: case Checks.IS_RVALUE: return new RefactoringStatus(); @@ -511,13 +545,27 @@ public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreEx fChange= fCURewrite.createChange(RefactoringCoreMessages.ExtractTempRefactoring_change_name, true, new SubProgressMonitor(pm, 1)); + fChange.getEdit().accept(new TextEditVisitor() { + @Override + public void preVisit(TextEdit edit) { + TextEdit[] children= edit.getChildren(); + for (TextEdit te : children) + if (te instanceof CopySourceEdit) { + CopySourceEdit cse= (CopySourceEdit) te; + if (cse.getTargetEdit() == null || cse.getTargetEdit().getOffset() == 0) { + edit.removeChild(te); + } + } + super.preVisit(edit); + } + }); RefactoringStatus result= new RefactoringStatus(); if (Arrays.asList(getExcludedVariableNames()).contains(fTempName)) result.addWarning(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_another_variable, BasicElementLabels.getJavaElementName(fTempName))); result.merge(checkMatchingFragments()); - fChange.setKeepPreviewEdits(true); + fChange.setKeepPreviewEdits(false); if (fCheckResultForCompileProblems) { result.merge(RefactoringAnalyzeUtil.checkNewSource(fChange, fCu, fCompilationUnitNode, pm)); @@ -537,13 +585,16 @@ private final ExtractLocalDescriptor createRefactoringDescriptor() { project= javaProject.getElementName(); final String description= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description_short, BasicElementLabels.getJavaElementName(fTempName)); final String expression= ASTNodes.asString(fSelectedExpression.getAssociatedExpression()); - final String header= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description, new String[] { BasicElementLabels.getJavaElementName(fTempName), BasicElementLabels.getJavaCodeString(expression)}); + final String header= Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_descriptor_description, + new String[] { BasicElementLabels.getJavaElementName(fTempName), BasicElementLabels.getJavaCodeString(expression) }); final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header); comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_name_pattern, BasicElementLabels.getJavaElementName(fTempName))); final BodyDeclaration decl= ASTNodes.getParent(fSelectedExpression.getAssociatedExpression(), BodyDeclaration.class); if (decl instanceof MethodDeclaration) { final IMethodBinding method= ((MethodDeclaration) decl).resolveBinding(); - final String label= method != null ? BindingLabelProvider.getBindingLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED) : BasicElementLabels.getJavaElementName('{' + JavaElementLabels.ELLIPSIS_STRING + '}'); + final String label= method != null + ? BindingLabelProvider.getBindingLabel(method, JavaElementLabels.ALL_FULLY_QUALIFIED) + : BasicElementLabels.getJavaElementName('{' + JavaElementLabels.ELLIPSIS_STRING + '}'); comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_destination_pattern, label)); } comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractTempRefactoring_expression_pattern, BasicElementLabels.getJavaCodeString(expression))); @@ -567,22 +618,89 @@ private void doCreateChange(IProgressMonitor pm) throws CoreException { try { pm.beginTask(RefactoringCoreMessages.ExtractTempRefactoring_checking_preconditions, 1); try { + int cnt= 1; + getSelectedExpression(); + fSelectionStart= fSelectedExpression.getAssociatedNode().getStartPosition(); + fSelectionLength= fSelectedExpression.getAssociatedNode().getLength(); + IASTFragment[] reSortRetainOnlyReplacableMatches= reSortRetainOnlyReplacableMatches(); + int tmpFSelectionStart= fSelectionStart; + int tmpFSelectionLength= fSelectionLength; + + IExpressionFragment tmpFSelectedExpression= fSelectedExpression; + Collection usedNames= getUsedLocalNames(fSelectedExpression.getAssociatedNode()); + String newName= fTempName; createTempDeclaration(); + if (fStartPoint != -1 && fEndPoint != -1) { + addReplaceExpressionWithTemp(); + fTempName= newName + ++cnt; + while (usedNames.contains(fTempName)) { + fTempName= newName + ++cnt; + } + } + while (replaceAllOccurrences() && reSortRetainOnlyReplacableMatches.length > fSeen.size()) { + fStartPoint= -1; + fEndPoint= -1; + boolean flag= false; + for (int i= 0; i < reSortRetainOnlyReplacableMatches.length; ++i) { + if (!fSeen.contains(reSortRetainOnlyReplacableMatches[i])) { + fSelectionStart= reSortRetainOnlyReplacableMatches[i].getAssociatedNode().getStartPosition(); + fSelectionLength= reSortRetainOnlyReplacableMatches[i].getAssociatedNode().getLength(); + fSelectedExpression= null; + getSelectedExpression(); + flag= true; + break; + } + } + if (flag == false) + break; + createTempDeclaration(); + if (fStartPoint != -1 && fEndPoint != -1) { + addReplaceExpressionWithTemp(); + fTempName= newName + ++cnt; + while (usedNames.contains(fTempName)) { + fTempName= newName + ++cnt; + } + } + } + fSelectionStart= tmpFSelectionStart; + fSelectionLength= tmpFSelectionLength; + fSelectedExpression= tmpFSelectedExpression; + fTempName= newName; } catch (CoreException exception) { JavaPlugin.log(exception); } - addReplaceExpressionWithTemp(); } finally { pm.done(); } } + /** + * Retrieves used names for the block containing a node. + * @param selected the selected node + * + * @return an array of used variable names to avoid + */ + private Collection getUsedLocalNames(ASTNode selected) { + ASTNode surroundingBlock= selected; + while ((surroundingBlock= surroundingBlock.getParent()) != null) { + if (surroundingBlock instanceof Block || surroundingBlock instanceof MethodDeclaration) { + break; + } + } + if (surroundingBlock == null) { + return new ArrayList<>(); + } + Collection localUsedNames= new ScopeAnalyzer((CompilationUnit) selected.getRoot()).getUsedVariableNames(surroundingBlock.getStartPosition(), surroundingBlock.getLength()); + return localUsedNames; + } + + @Override public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { try { pm.beginTask("", 6); //$NON-NLS-1$ - RefactoringStatus result= Checks.validateModifiesFiles(ResourceUtil.getFiles(new ICompilationUnit[] { fCu}), getValidationContext(), pm); + RefactoringStatus result= Checks.validateModifiesFiles(ResourceUtil.getFiles(new ICompilationUnit[] { fCu }), getValidationContext(), pm); if (result.hasFatalError()) return result; @@ -695,32 +813,139 @@ private void createAndInsertTempDeclaration() throws CoreException { ASTNode node= ASTResolving.findParentStatement(getSelectedExpression().getAssociatedNode()); if (node instanceof SwitchCase) { /* VariableDeclarationStatement must be final for switch/case */ + if (!hasFinalModifer(vds.modifiers())) { vds.modifiers().add(vds.getAST().newModifier(ModifierKeyword.FINAL_KEYWORD)); } node= ASTNodes.getParent(node, SwitchStatement.class); fDeclareFinal= true; } + + IASTFragment[] reSortRetainOnlyReplacableMatches= reSortRetainOnlyReplacableMatches(); + if (reSortRetainOnlyReplacableMatches == null) { + return; + } + + int selectNumber= -1; + + for (int i= 0; i < reSortRetainOnlyReplacableMatches.length; ++i) { + if (fSelectionStart == reSortRetainOnlyReplacableMatches[i].getAssociatedNode().getStartPosition()) { + selectNumber= i; + break; + } + } if (node instanceof SwitchStatement) { /* must insert above switch statement */ + fStartPoint= 0; + fEndPoint= reSortRetainOnlyReplacableMatches.length - 1; insertAt(node, vds); return; } else { if (insertAtSelection) { - insertAt(getSelectedExpression().getAssociatedNode(), vds); + ASTNode realCommonASTNode= null; + realCommonASTNode= evalStartAndEnd(reSortRetainOnlyReplacableMatches, selectNumber); + if (realCommonASTNode == null && selectNumber >=0 ) { + fSeen.add(reSortRetainOnlyReplacableMatches[selectNumber]); + } + if (realCommonASTNode != null || reSortRetainOnlyReplacableMatches.length ==0) { + insertAt(getSelectedExpression().getAssociatedNode(), vds); + } return; } } + ASTNode realCommonASTNode= null; + realCommonASTNode= evalStartAndEnd(reSortRetainOnlyReplacableMatches, selectNumber); + if (realCommonASTNode == null && selectNumber >= 0) { + fSeen.add(reSortRetainOnlyReplacableMatches[selectNumber]); + } + if (realCommonASTNode != null) { + insertAt(realCommonASTNode, vds); + } + return; + } - ASTNode[] firstReplaceNodeParents= getParents(getFirstReplacedExpression().getAssociatedNode()); - ASTNode[] commonPath= findDeepestCommonSuperNodePathForReplacedNodes(); - Assert.isTrue(commonPath.length <= firstReplaceNodeParents.length); + private ASTNode evalStartAndEnd(IASTFragment[] reSortRetainOnlyReplacableMatches, int selectNumber) throws JavaModelException { + ASTNode realCommonASTNode= null; + if (selectNumber < 0) { + return realCommonASTNode; + } + ASTNode firstReplaceExpression; + int start= selectNumber; + int end= selectNumber; + int expandFlag= 2; // 2:backward 1:forward 0:break + while (expandFlag > 0 && start <= end) { + IASTFragment iASTFragment= reSortRetainOnlyReplacableMatches[start]; + firstReplaceExpression= getCertainReplacedExpression(reSortRetainOnlyReplacableMatches, start).getAssociatedNode(); + ASTNode[] firstReplaceNodeParents= getParents(firstReplaceExpression); + ASTNode[] commonPath= findDeepestCommonSuperNodePathForReplacedNodes(start, end); + Assert.isTrue(commonPath.length <= firstReplaceNodeParents.length); + ASTNode deepestCommonParent= firstReplaceNodeParents[commonPath.length - 1]; + int startOffset; + ASTNode expression= iASTFragment.getAssociatedNode(); + int endOffset= expression.getStartPosition(); + ASTNode commonASTNode; + if (deepestCommonParent instanceof Block) { + commonASTNode= firstReplaceNodeParents[commonPath.length]; + } else { + commonASTNode= deepestCommonParent; + } + commonASTNode= convertToExtractNode(commonASTNode); + startOffset= commonASTNode.getStartPosition() - 1; + NullChecker nullChecker= new NullChecker(fCompilationUnitNode, fCu, commonASTNode, expression, startOffset, endOffset); + if (!nullChecker.hasNullCheck()) {//at least one be extracted + fStartPoint= start; + fEndPoint= end; + realCommonASTNode= commonASTNode; + if (expandFlag == 2 && (end == reSortRetainOnlyReplacableMatches.length - 1 + || fSeen.contains(reSortRetainOnlyReplacableMatches[end + 1]))) { + expandFlag= 1; + } + if (expandFlag == 1 && (start == 0 + || fSeen.contains(reSortRetainOnlyReplacableMatches[start - 1]))) { + expandFlag= 0; + } + if (expandFlag == 1) { + start--; + } else if (expandFlag == 2) { + end++; + } + } else { + if (expandFlag == 2) { + expandFlag= 1; + if (end != selectNumber)//restore + end--; + if (start == 0) { + expandFlag= 0; + } else { + start--; + } + } else { + expandFlag= 0; + } + } + } + return realCommonASTNode; + } - ASTNode deepestCommonParent= firstReplaceNodeParents[commonPath.length - 1]; - if (deepestCommonParent instanceof Block) - insertAt(firstReplaceNodeParents[commonPath.length], vds); - else - insertAt(deepestCommonParent, vds); + private ASTNode convertToExtractNode(ASTNode target) { + ASTNode parent= target.getParent(); + StructuralPropertyDescriptor locationInParent= target.getLocationInParent(); + while (locationInParent != Block.STATEMENTS_PROPERTY && locationInParent != SwitchStatement.STATEMENTS_PROPERTY) { + if (locationInParent == IfStatement.THEN_STATEMENT_PROPERTY + || locationInParent == IfStatement.ELSE_STATEMENT_PROPERTY + || locationInParent == ForStatement.BODY_PROPERTY + || locationInParent == EnhancedForStatement.BODY_PROPERTY + || locationInParent == DoStatement.BODY_PROPERTY + || locationInParent == WhileStatement.BODY_PROPERTY) { + break; + } else if (locationInParent == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) parent).getBody() instanceof Expression) { + break; + } + target= parent; + parent= parent.getParent(); + locationInParent= target.getLocationInParent(); + } + return target; } private VariableDeclarationStatement createTempDeclaration(Expression initializer) throws CoreException { @@ -757,7 +982,6 @@ private VariableDeclarationStatement createTempDeclaration(Expression initialize private void insertAt(ASTNode target, Statement declaration) { ASTRewrite rewrite= fCURewrite.getASTRewrite(); TextEditGroup groupDescription= fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable); - ASTNode parent= target.getParent(); StructuralPropertyDescriptor locationInParent= target.getLocationInParent(); while (locationInParent != Block.STATEMENTS_PROPERTY && locationInParent != SwitchStatement.STATEMENTS_PROPERTY) { @@ -796,7 +1020,7 @@ private void insertAt(ASTNode target, Statement declaration) { parent= parent.getParent(); locationInParent= target.getLocationInParent(); } - ListRewrite listRewrite= rewrite.getListRewrite(parent, (ChildListPropertyDescriptor)locationInParent); + ListRewrite listRewrite= rewrite.getListRewrite(parent, (ChildListPropertyDescriptor) locationInParent); listRewrite.insertBefore(declaration, target, groupDescription); } @@ -828,12 +1052,13 @@ public boolean declareVarType() { return fDeclareVarType; } - private ASTNode[] findDeepestCommonSuperNodePathForReplacedNodes() throws JavaModelException { + private ASTNode[] findDeepestCommonSuperNodePathForReplacedNodes(int start, int end) throws JavaModelException { ASTNode[] matchNodes= getMatchNodes(); - - ASTNode[][] matchingNodesParents= new ASTNode[matchNodes.length][]; - for (int i= 0; i < matchNodes.length; i++) { - matchingNodesParents[i]= getParents(matchNodes[i]); + Comparator comparator= (o1, o2) -> o1.getStartPosition() - o2.getStartPosition(); + Arrays.sort(matchNodes, comparator); + ASTNode[][] matchingNodesParents= new ASTNode[end + 1 - start][]; + for (int i= start; i < matchNodes.length && i < end + 1; ++i) { + matchingNodesParents[i - start]= getParents(matchNodes[i]); } List l= Arrays.asList(getLongestArrayPrefix(matchingNodesParents)); return l.toArray(new ASTNode[l.size()]); @@ -898,15 +1123,15 @@ private String[] getExcludedVariableNames() { return fExcludedVariableNames; } - private IExpressionFragment getFirstReplacedExpression() throws JavaModelException { + private IExpressionFragment getCertainReplacedExpression(IASTFragment[] nodesToReplace, int index) throws JavaModelException { if (!fReplaceAllOccurrences) return getSelectedExpression(); - IASTFragment[] nodesToReplace= retainOnlyReplacableMatches(getMatchingFragments()); if (nodesToReplace.length == 0) return getSelectedExpression(); - Comparator comparator= (o1, o2) -> o1.getStartPosition() - o2.getStartPosition(); - Arrays.sort(nodesToReplace, comparator); - return (IExpressionFragment) nodesToReplace[0]; + if (index >= nodesToReplace.length) { + return (IExpressionFragment) nodesToReplace[nodesToReplace.length - 1]; + } + return (IExpressionFragment) nodesToReplace[index]; } private IASTFragment[] getMatchingFragments() throws JavaModelException { @@ -914,7 +1139,7 @@ private IASTFragment[] getMatchingFragments() throws JavaModelException { IASTFragment[] allMatches= ASTFragmentFactory.createFragmentForFullSubtree(getEnclosingBodyNode()).getSubFragmentsMatching(getSelectedExpression()); return allMatches; } else - return new IASTFragment[] { getSelectedExpression()}; + return new IASTFragment[] { getSelectedExpression() }; } private ASTNode[] getMatchNodes() throws JavaModelException { @@ -935,7 +1160,6 @@ private IExpressionFragment getSelectedExpression() throws JavaModelException { if (fSelectedExpression != null) return fSelectedExpression; IASTFragment selectedFragment= ASTFragmentFactory.createFragmentForSourceRange(new SourceRange(fSelectionStart, fSelectionLength), fCompilationUnitNode, fCu); - if (selectedFragment instanceof IExpressionFragment && !Checks.isInsideJavadoc(selectedFragment.getAssociatedNode())) { fSelectedExpression= (IExpressionFragment) selectedFragment; } else if (selectedFragment != null) { @@ -1006,7 +1230,8 @@ public String guessTempName() { } /** - * @return proposed variable names (may be empty, but not null). The first proposal should be used as "best guess" (if it exists). + * @return proposed variable names (may be empty, but not null). The first proposal should be + * used as "best guess" (if it exists). */ public String[] guessTempNames() { if (fGuessedTempNames == null) { @@ -1057,6 +1282,8 @@ public boolean replaceAllOccurrences() { } private void replaceSelectedExpressionWithTempDeclaration() throws CoreException { + fStartPoint= 0; + fEndPoint= retainOnlyReplacableMatches(getMatchingFragments()).length - 1; ASTRewrite rewrite= fCURewrite.getASTRewrite(); Expression selectedExpression= getSelectedExpression().getAssociatedExpression(); // whole expression selected @@ -1107,7 +1334,7 @@ public void setTempName(String newName) { private boolean shouldReplaceSelectedExpressionWithTempDeclaration() throws JavaModelException { IExpressionFragment selectedFragment= getSelectedExpression(); - IExpressionFragment firstExpression= getFirstReplacedExpression(); + IExpressionFragment firstExpression= getCertainReplacedExpression(reSortRetainOnlyReplacableMatches(), 0); if (firstExpression.getStartPosition() < selectedFragment.getStartPosition()) return false; ASTNode associatedNode= selectedFragment.getAssociatedNode(); @@ -1129,7 +1356,8 @@ private RefactoringStatus initialize(JavaRefactoringArguments arguments) { fSelectionStart= offset; fSelectionLength= length; } else - return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION})); + return RefactoringStatus.createFatalErrorStatus( + Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION })); } else return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION)); final String handle= arguments.getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT); @@ -1177,4 +1405,11 @@ public boolean isVarTypeAllowed() { } return isAllowed; } + + private IASTFragment[] reSortRetainOnlyReplacableMatches() throws JavaModelException { + IASTFragment[] nodesToReplace= retainOnlyReplacableMatches(getMatchingFragments()); + Comparator comparator= (o1, o2) -> o1.getStartPosition() - o2.getStartPosition(); + Arrays.sort(nodesToReplace, comparator); + return nodesToReplace; + } } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceFactoryRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceFactoryRefactoring.java index 97c35751..e52efe5a 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceFactoryRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceFactoryRefactoring.java @@ -483,7 +483,11 @@ private SearchResultGroup[] excludeBinaryUnits(SearchResultGroup[] groups) { */ private SearchResultGroup[] searchForCallsTo(IMethodBinding methodBinding, IProgressMonitor pm, RefactoringStatus status) throws JavaModelException { IMethod method= (IMethod) methodBinding.getJavaElement(); - final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(createSearchPattern(method, methodBinding)); + SearchPattern searchPattern= createSearchPattern(method, methodBinding); + if (searchPattern == null) { + return new SearchResultGroup[0]; + } + final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(searchPattern); engine.setFiltering(true, true); engine.setScope(createSearchScope(method, methodBinding)); engine.setStatus(status); @@ -512,6 +516,9 @@ private SearchResultGroup[] findAllCallsTo(IMethodBinding ctorBinding, IProgress private IType findNonPrimaryType(String fullyQualifiedName, IProgressMonitor pm, RefactoringStatus status) throws JavaModelException { SearchPattern p= SearchPattern.createPattern(fullyQualifiedName, IJavaSearchConstants.TYPE, IJavaSearchConstants.DECLARATIONS, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (p == null) { + return null; + } final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(p); engine.setFiltering(true, true); @@ -656,7 +663,7 @@ private MethodDeclaration createFactoryMethod(AST ast, IMethodBinding ctorBindin } private IMethodBinding[] getUnimplementedMethods(ITypeBinding binding) { - IMethodBinding[] unimplementedMethods= StubUtility2Core.getUnimplementedMethods(binding, true); + IMethodBinding[] unimplementedMethods= StubUtility2Core.getUnimplementedMethods(binding, null); Arrays.sort(unimplementedMethods, new MethodsSourcePositionComparator(binding)); return unimplementedMethods; } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java index 0019c426..8ffbd940 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -424,16 +424,19 @@ public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws Core // Allow invocation on super methods calls. makes sense as other // calls or even only the declaration can be updated. targetMethodBinding= ((SuperMethodInvocation) selectionNode).resolveMethodBinding(); - } else { + } + if (targetMethodBinding != null) { + fTargetMethodBinding= targetMethodBinding.getMethodDeclaration(); // resolve generics + if (fTargetMethodBinding != null) { + fTargetMethod= (IMethod) fTargetMethodBinding.getJavaElement(); + //allow single updating mode if an invocation was selected and the invocation can be updated + if (selectionNode instanceof MethodInvocation && fSelectionCompilationUnit != null) + fSelectionMethodInvocation= (MethodInvocation) selectionNode; + } + } + if (targetMethodBinding == null || fTargetMethodBinding == null) { return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.IntroduceIndirectionRefactoring_not_available_on_this_selection); } - fTargetMethodBinding= targetMethodBinding.getMethodDeclaration(); // resolve generics - fTargetMethod= (IMethod) fTargetMethodBinding.getJavaElement(); - - //allow single updating mode if an invocation was selected and the invocation can be updated - if (selectionNode instanceof MethodInvocation && fSelectionCompilationUnit != null) - fSelectionMethodInvocation= (MethodInvocation) selectionNode; - } else { // (2) invoked on an IMethod: Source may not be available diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/nls/NLSHintHelper.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/nls/NLSHintHelper.java index 02dd769d..766e9ca9 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/nls/NLSHintHelper.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/nls/NLSHintHelper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -127,8 +127,13 @@ public static AccessorClassReference getAccessorClassReference(CompilationUnit a IBinding binding= name.resolveBinding(); if (binding instanceof IVariableBinding) { IVariableBinding variableBinding= (IVariableBinding)binding; - if (Modifier.isStatic(variableBinding.getModifiers())) + if (Modifier.isStatic(variableBinding.getModifiers())) { accessorBinding= variableBinding.getDeclaringClass(); + if (accessorBinding != null && getResourceBundleName(accessorBinding) == null) { + parent= parent.getParent(); + accessorBinding= null; + } + } } } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RefactoringScanner.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RefactoringScanner.java index 7d7c6888..7f040736 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RefactoringScanner.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RefactoringScanner.java @@ -19,6 +19,8 @@ import org.eclipse.core.runtime.Assert; import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.ToolFactory; import org.eclipse.jdt.core.compiler.IScanner; @@ -71,7 +73,14 @@ public RefactoringScanner(String name, String qualifier) { public void scan(ICompilationUnit cu) throws JavaModelException { char[] chars= cu.getBuffer().getCharacters(); fMatches= new HashSet<>(); - fScanner= ToolFactory.createScanner(true, true, false, true); + IJavaProject javaProject= cu.getJavaProject(); + if (javaProject != null) { + String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); + String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); + fScanner = ToolFactory.createScanner(true, true, true, sourceLevel, complianceLevel); + } else { + fScanner= ToolFactory.createScanner(true, true, false, true); + } fScanner.setSource(chars); // IImportContainer importContainer= cu.getImportContainer(); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameFieldProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameFieldProcessor.java index 63716214..60575b08 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameFieldProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameFieldProcessor.java @@ -627,6 +627,9 @@ private RefactoringStatus checkNewRecordComponentAccessor(String newAccessorName private RefactoringStatus checkAccessorDeclarations(IProgressMonitor pm, IMethod existingAccessor) throws CoreException{ RefactoringStatus result= new RefactoringStatus(); SearchPattern pattern= SearchPattern.createPattern(existingAccessor, IJavaSearchConstants.DECLARATIONS, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return result; + } IJavaSearchScope scope= SearchEngine.createHierarchyScope(fField.getDeclaringType()); SearchResultGroup[] groupDeclarations= RefactoringSearchEngine.search(pattern, scope, pm, result); Assert.isTrue(groupDeclarations.length > 0); @@ -712,7 +715,11 @@ private SearchResultGroup[] getReferences(IProgressMonitor pm, RefactoringStatus String binaryRefsDescription= Messages.format(RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description , BasicElementLabels.getJavaElementName(getCurrentElementName())); ReferencesInBinaryContext binaryRefs= new ReferencesInBinaryContext(binaryRefsDescription); - SearchResultGroup[] result= RefactoringSearchEngine.search(createSearchPattern(), createRefactoringScope(), + SearchPattern searchPattern= createSearchPattern(); + if (searchPattern == null) { + return new SearchResultGroup[0]; + } + SearchResultGroup[] result= RefactoringSearchEngine.search(searchPattern, createRefactoringScope(), new CuCollectingSearchRequestor(binaryRefs), pm, status); binaryRefs.addErrorIfNecessary(status); result= filterAccessorMethods(result, true); @@ -975,6 +982,9 @@ private void addAccessorOccurrences(IProgressMonitor pm, IMethod accessor, Strin IJavaSearchScope scope= RefactoringScopeFactory.create(accessor); SearchPattern pattern= SearchPattern.createPattern(accessor, IJavaSearchConstants.ALL_OCCURRENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return; + } SearchResultGroup[] groupedResults= RefactoringSearchEngine.search( pattern, scope, new MethodOccurenceCollector(accessor.getElementName()), pm, status); @@ -1017,7 +1027,11 @@ private void addFieldAccessorOccurrences(IProgressMonitor pm, String editName, S String binaryRefsDescription= Messages.format(RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description , BasicElementLabels.getJavaElementName(getCurrentElementName())); ReferencesInBinaryContext binaryRefs= new ReferencesInBinaryContext(binaryRefsDescription); - SearchResultGroup[] result= RefactoringSearchEngine.search(createSearchPattern(), scope, + SearchPattern searchPattern= createSearchPattern(); + if (searchPattern == null) { + return; + } + SearchResultGroup[] result= RefactoringSearchEngine.search(searchPattern, scope, new CuCollectingSearchRequestor(binaryRefs), pm, status); binaryRefs.addErrorIfNecessary(status); result= filterAccessorMethods(result, false); @@ -1115,6 +1129,9 @@ public void acceptSearchMatch(SearchMatch match) throws CoreException { requestor= new CollectingSearchRequestor(); SearchPattern newPattern= SearchPattern.createPattern(field, IJavaSearchConstants.REFERENCES); + if (newPattern == null) { + return new SearchResultGroup[0]; + } IJavaSearchScope scope= RefactoringScopeFactory.create(fField, true, true); return RefactoringSearchEngine.search(newPattern, owner, scope, requestor, new SubProgressMonitor(pm, 1), status); } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameMethodProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameMethodProcessor.java index 15e34967..7ded35ec 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameMethodProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameMethodProcessor.java @@ -446,6 +446,9 @@ public void acceptSearchMatch(SearchMatch match) throws CoreException { private IMethod[] searchForDeclarationsOfClashingMethods(IProgressMonitor pm) throws CoreException { final List results= new ArrayList<>(); SearchPattern pattern= createNewMethodPattern(); + if (pattern == null) { + return new IMethod[0]; + } IJavaSearchScope scope= RefactoringScopeFactory.create(getMethod().getJavaProject()); SearchRequestor requestor= new SearchRequestor() { @Override @@ -616,7 +619,7 @@ private SearchResultGroup[] batchFindNewOccurrences(IMethod[] wcNewMethods, fina SearchPattern refsPattern= RefactoringSearchEngine.createOrPattern(wcNewMethods, IJavaSearchConstants.REFERENCES); SearchParticipant[] searchParticipants= SearchUtils.getDefaultSearchParticipants(); - IJavaSearchScope scope= RefactoringScopeFactory.create(wcNewMethods); + IJavaSearchScope scope= RefactoringScopeFactory.createProjectsScope(wcNewMethods, true); MethodOccurenceCollector requestor; if (getDelegateUpdating()) { diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameModuleProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameModuleProcessor.java index 4c8263a9..04753f53 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameModuleProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameModuleProcessor.java @@ -311,6 +311,9 @@ private SearchResultGroup[] getNewReferences(IProgressMonitor pm, RefactoringSta CollectingSearchRequestor requestor= new CollectingSearchRequestor(); SearchPattern newPattern= SearchPattern.createPattern(module, IJavaSearchConstants.REFERENCES); + if (newPattern == null) { + return new SearchResultGroup[0]; + } IJavaSearchScope scope= RefactoringScopeFactory.create(fModule, true, true); return RefactoringSearchEngine.search(newPattern, owner, scope, requestor, new SubProgressMonitor(pm, 1), status); } @@ -438,7 +441,11 @@ private SearchResultGroup[] getReferences(IProgressMonitor pm, RefactoringStatus String binaryRefsDescription= Messages.format(RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description , BasicElementLabels.getJavaElementName(getCurrentElementName())); ReferencesInBinaryContext binaryRefs= new ReferencesInBinaryContext(binaryRefsDescription); - SearchResultGroup[] result= RefactoringSearchEngine.search(createSearchPattern(), createRefactoringScope(), + SearchPattern searchPattern= createSearchPattern(); + if (searchPattern == null) { + return new SearchResultGroup[0]; + } + SearchResultGroup[] result= RefactoringSearchEngine.search(searchPattern, createRefactoringScope(), new CuCollectingSearchRequestor(binaryRefs), pm, status); binaryRefs.addErrorIfNecessary(status); return result; diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenamePackageProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenamePackageProcessor.java index a5899cd6..13f697cf 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenamePackageProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenamePackageProcessor.java @@ -736,6 +736,9 @@ void doRename(IProgressMonitor pm, RefactoringStatus result) throws CoreExceptio private SearchResultGroup[] getReferences(IProgressMonitor pm, ReferencesInBinaryContext binaryRefs, RefactoringStatus status) throws CoreException { IJavaSearchScope scope= RefactoringScopeFactory.create(fPackage, true, false); SearchPattern pattern= SearchPattern.createPattern(fPackage, IJavaSearchConstants.REFERENCES); + if (pattern == null) { + return new SearchResultGroup[0]; + } CollectingSearchRequestor requestor= new CuCollectingSearchRequestor(binaryRefs); return RefactoringSearchEngine.search(pattern, scope, requestor, pm, status); } @@ -902,7 +905,9 @@ private IType[] getTypesInPackage(IPackageFragment packageFragment) throws JavaM */ private IPackageFragment[] getNamesakePackages(IJavaSearchScope scope, IProgressMonitor pm) throws CoreException { SearchPattern pattern= SearchPattern.createPattern(fPackage.getElementName(), IJavaSearchConstants.PACKAGE, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE); - + if (pattern == null) { + return new IPackageFragment[0]; + } final HashSet packageFragments= new HashSet<>(); SearchRequestor requestor= new SearchRequestor() { @Override diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameTypeProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameTypeProcessor.java index 412bc48a..d0164c86 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameTypeProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameTypeProcessor.java @@ -616,6 +616,7 @@ public RefactoringStatus initializeReferences(IProgressMonitor monitor) throws J try { SearchPattern pattern= SearchPattern.createPattern(fType, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + Assert.isNotNull(pattern); String binaryRefsDescription= Messages.format(RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description , BasicElementLabels.getJavaElementName(fType.getElementName())); ReferencesInBinaryContext binaryRefs= new ReferencesInBinaryContext(binaryRefsDescription); @@ -981,6 +982,9 @@ private RefactoringStatus checkConflictingTypes(IProgressMonitor pm) throws Core IJavaSearchScope scope= RefactoringScopeFactory.create(fType); SearchPattern pattern= SearchPattern.createPattern(getNewElementName(), IJavaSearchConstants.TYPE, IJavaSearchConstants.ALL_OCCURRENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return result; + } ICompilationUnit[] cusWithReferencesToConflictingTypes= RefactoringSearchEngine.findAffectedCompilationUnits(pattern, scope, pm, result); if (cusWithReferencesToConflictingTypes.length == 0) return result; diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameVirtualMethodProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameVirtualMethodProcessor.java index dba9de05..043c3609 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameVirtualMethodProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RenameVirtualMethodProcessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Nikolay Metchev - [rename] https://bugs.eclipse.org/99622 *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.rename; @@ -90,10 +91,6 @@ public RenameVirtualMethodProcessor(IMethod method, JavaRefactoringArguments arg setMethodsToRename(ripples); } - public IMethod getOriginalMethod() { - return fOriginalMethod; - } - private ITypeHierarchy getCachedHierarchy(IType declaring, IProgressMonitor monitor) throws JavaModelException { if (fCachedHierarchy != null && declaring.equals(fCachedHierarchy.getType())) return fCachedHierarchy; @@ -101,6 +98,10 @@ private ITypeHierarchy getCachedHierarchy(IType declaring, IProgressMonitor moni return fCachedHierarchy; } + public IMethod getOriginalMethod() { + return fOriginalMethod; + } + @Override public boolean isApplicable() throws CoreException { return RefactoringAvailabilityTester.isRenameVirtualMethodAvailable(getMethod()); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RippleMethodFinder2.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RippleMethodFinder2.java index 7ab3b4d1..3a7faffc 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RippleMethodFinder2.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/rename/RippleMethodFinder2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Nikolay Metchev - [rename] https://bugs.eclipse.org/99622 *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.rename; @@ -28,10 +29,10 @@ import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IRegion; import org.eclipse.jdt.core.IType; @@ -50,14 +51,15 @@ import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory; import org.eclipse.jdt.internal.corext.refactoring.base.ReferencesInBinaryContext; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; +import org.eclipse.jdt.internal.corext.util.MethodOverrideTester; import org.eclipse.jdt.internal.corext.util.SearchUtils; public class RippleMethodFinder2 { private final IMethod fMethod; - private List fDeclarations; + private Set fDeclarations; private ITypeHierarchy fHierarchy; - private Map fTypeToMethod; + private MultiMap fTypeToMethod; private Set fRootTypes; private MultiMap fRootReps; private Map fRootHierarchies; @@ -66,6 +68,7 @@ public class RippleMethodFinder2 { private final boolean fExcludeBinaries; private final ReferencesInBinaryContext fBinaryRefs; private Map fDeclarationToMatch; + private boolean fSearchOnlyInCompilationUnit = false; private static class MultiMap { HashMap> fImplementation= new HashMap<>(); @@ -131,9 +134,10 @@ public void union(IType rep1, IType rep2) { } - private RippleMethodFinder2(IMethod method, boolean excludeBinaries){ + private RippleMethodFinder2(IMethod method, boolean excludeBinaries, boolean searchOnlyInCompilationUnit){ fMethod= method; fExcludeBinaries= excludeBinaries; + fSearchOnlyInCompilationUnit= searchOnlyInCompilationUnit; fBinaryRefs= null; } @@ -149,7 +153,17 @@ public static IMethod[] getRelatedMethods(IMethod method, boolean excludeBinarie if (! MethodChecks.isVirtual(method)) return new IMethod[]{ method }; - return new RippleMethodFinder2(method, excludeBinaries).getAllRippleMethods(pm, owner); + return new RippleMethodFinder2(method, excludeBinaries, false).getAllRippleMethods(pm, owner); + } finally{ + pm.done(); + } + } + public static IMethod[] getRelatedMethodsInCompilationUnit(IMethod method, NullProgressMonitor pm, WorkingCopyOwner owner) throws CoreException { + try{ + if (! MethodChecks.isVirtual(method)) + return new IMethod[]{ method }; + + return new RippleMethodFinder2(method, true, true).getAllRippleMethods(pm, owner); } finally{ pm.done(); } @@ -194,10 +208,16 @@ private IMethod[] findAllRippleMethods(IProgressMonitor pm, WorkingCopyOwner own //TODO: report assertion as error status and fall back to only return fMethod //check for bug 81058: - if (! fDeclarations.contains(fMethod)) - Assert.isTrue(false, "Search for method declaration did not find original element: " + fMethod.toString()); //$NON-NLS-1$ + if (! fDeclarations.contains(fMethod)) { + if (fSearchOnlyInCompilationUnit) { + return new IMethod[0]; + } else { + Assert.isTrue(false, "Search for method declaration did not find original element: " + fMethod.toString()); //$NON-NLS-1$ + } + } createHierarchyOfDeclarations(new SubProgressMonitor(pm, 1), owner); + addMissedSuperTypes(); createTypeToMethod(); createUnionFind(); checkCanceled(pm); @@ -206,7 +226,7 @@ private IMethod[] findAllRippleMethods(IProgressMonitor pm, WorkingCopyOwner own fRootTypes= null; Map> partitioning= new HashMap<>(); - for (IType type : fTypeToMethod.keySet()) { + for (IType type : fTypeToMethod.fImplementation.keySet()) { IType rep= fUnionFind.find(type); List types= partitioning.get(rep); if (types == null) @@ -225,7 +245,7 @@ private IMethod[] findAllRippleMethods(IProgressMonitor pm, WorkingCopyOwner own boolean hasRelatedInterfaces= false; List relatedMethods= new ArrayList<>(); for (IType relatedType : relatedTypes) { - relatedMethods.add(fTypeToMethod.get(relatedType)); + relatedMethods.addAll(fTypeToMethod.get(relatedType)); if (relatedType.isInterface()) hasRelatedInterfaces= true; } @@ -283,15 +303,17 @@ private IMethod[] findAllRippleMethods(IProgressMonitor pm, WorkingCopyOwner own HashSet marriedAlienTypeReps= new HashSet<>(); for (IType alienType : alienTypes) { checkCanceled(pm); - IMethod alienMethod= fTypeToMethod.get(alienType); - ITypeHierarchy hierarchy= hierarchy(pm, owner, alienType); - - for (IType subtype : hierarchy.getAllSubtypes(alienType)) { - if (relatedSubTypes.contains(subtype)) { - if (JavaModelUtil.isVisibleInHierarchy(alienMethod, subtype.getPackageFragment())) { - marriedAlienTypeReps.add(fUnionFind.find(alienType)); - } else { - // not overridden + Collection alienMethods= fTypeToMethod.get(alienType); + for (IMethod alienMethod : alienMethods) { + ITypeHierarchy hierarchy= hierarchy(pm, owner, alienType); + + for (IType subtype : hierarchy.getAllSubtypes(alienType)) { + if (relatedSubTypes.contains(subtype)) { + if (JavaModelUtil.isVisibleInHierarchy(alienMethod, subtype.getPackageFragment())) { + marriedAlienTypeReps.add(fUnionFind.find(alienType)); + } else { + // not overridden + } } } } @@ -303,7 +325,7 @@ private IMethod[] findAllRippleMethods(IProgressMonitor pm, WorkingCopyOwner own for (IType marriedAlienTypeRep : marriedAlienTypeReps) { List marriedAlienTypes= partitioning.get(marriedAlienTypeRep); for (IType marriedAlienInterfaceType : marriedAlienTypes) { - relatedMethods.add(fTypeToMethod.get(marriedAlienInterfaceType)); + relatedMethods.addAll(fTypeToMethod.get(marriedAlienInterfaceType)); } alienTypes.removeAll(marriedAlienTypes); //not alien any more relatedTypesToProcess.addAll(marriedAlienTypes); //process freshly married types again @@ -385,6 +407,16 @@ private ITypeHierarchy hierarchy(IProgressMonitor pm, WorkingCopyOwner owner, IT return hierarchy; } + private void addMissedSuperTypes() throws JavaModelException { + Set newDeclarations = new HashSet<>(); + for (IMethod method : fDeclarations) { + MethodOverrideTester methodOverrideTester= new MethodOverrideTester(method.getDeclaringType(), fHierarchy); + newDeclarations.addAll(methodOverrideTester.findAllOverridenMethods(method)); + } + fDeclarations.addAll(newDeclarations); + + } + private ITypeHierarchy getCachedHierarchy(IType type, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException { IType rep= fUnionFind.find(type); if (rep != null) { @@ -402,7 +434,7 @@ private ITypeHierarchy getCachedHierarchy(IType type, WorkingCopyOwner owner, IP } private void findAllDeclarations(IProgressMonitor monitor, WorkingCopyOwner owner) throws CoreException { - fDeclarations= new ArrayList<>(); + fDeclarations= new HashSet<>(); class MethodRequestor extends SearchRequestor { @Override @@ -426,8 +458,16 @@ public void acceptSearchMatch(SearchMatch match) throws CoreException { int limitTo= IJavaSearchConstants.DECLARATIONS | IJavaSearchConstants.IGNORE_DECLARING_TYPE | IJavaSearchConstants.IGNORE_RETURN_TYPE; int matchRule= SearchPattern.R_ERASURE_MATCH | SearchPattern.R_CASE_SENSITIVE; SearchPattern pattern= SearchPattern.createPattern(fMethod, limitTo, matchRule); + if (pattern == null) { + return; + } SearchParticipant[] participants= SearchUtils.getDefaultSearchParticipants(); - IJavaSearchScope scope= RefactoringScopeFactory.createRelatedProjectsScope(fMethod.getJavaProject(), IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SYSTEM_LIBRARIES); + IJavaSearchScope scope; + if (fSearchOnlyInCompilationUnit) { + scope= RefactoringScopeFactory.create(fMethod.getCompilationUnit()); + } else { + scope= RefactoringScopeFactory.createRelatedProjectsScope(fMethod.getJavaProject(), IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SYSTEM_LIBRARIES); + } MethodRequestor requestor= new MethodRequestor(); SearchEngine searchEngine= owner != null ? new SearchEngine(owner) : new SearchEngine(); @@ -449,19 +489,19 @@ private static ITypeHierarchy createHierarchyOfTypes(IProgressMonitor pm, Workin } private void createTypeToMethod() { - fTypeToMethod= new HashMap<>(); + fTypeToMethod= new MultiMap<>(); for (IMethod declaration : fDeclarations) { fTypeToMethod.put(declaration.getDeclaringType(), declaration); } } private void createUnionFind() throws JavaModelException { - fRootTypes= new HashSet<>(fTypeToMethod.keySet()); + fRootTypes= new HashSet<>(fTypeToMethod.fImplementation.keySet()); fUnionFind= new UnionFind(); - for (IType type : fTypeToMethod.keySet()) { + for (IType type : fTypeToMethod.fImplementation.keySet()) { fUnionFind.init(type); } - for (IType type : fTypeToMethod.keySet()) { + for (IType type : fTypeToMethod.fImplementation.keySet()) { uniteWithSupertypes(type, type); } fRootReps= new MultiMap<>(); @@ -481,15 +521,17 @@ private void uniteWithSupertypes(IType anchor, IType type) throws JavaModelExcep uniteWithSupertypes(anchor, supertype); } else { //check whether method in supertype is really overridden: - IMember superMethod= fTypeToMethod.get(supertype); - if (JavaModelUtil.isVisibleInHierarchy(superMethod, anchor.getPackageFragment())) { - IType rep= fUnionFind.find(anchor); - fUnionFind.union(rep, superRep); - // current type is no root anymore - fRootTypes.remove(anchor); - uniteWithSupertypes(supertype, supertype); - } else { - //Not overridden -> overriding chain ends here. + Collection superMethods= fTypeToMethod.get(supertype); + for (IMethod superMethod : superMethods) { + if (JavaModelUtil.isVisibleInHierarchy(superMethod, anchor.getPackageFragment())) { + IType rep= fUnionFind.find(anchor); + fUnionFind.union(rep, superRep); + // current type is no root anymore + fRootTypes.remove(anchor); + uniteWithSupertypes(supertype, supertype); + } else { + //Not overridden -> overriding chain ends here. + } } } } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/reorg/CreateCopyOfCompilationUnitChange.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/reorg/CreateCopyOfCompilationUnitChange.java index 332a198f..7c2af2c2 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/reorg/CreateCopyOfCompilationUnitChange.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/reorg/CreateCopyOfCompilationUnitChange.java @@ -39,6 +39,7 @@ import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.core.search.SearchPattern; +import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.refactoring.IRefactoringSearchRequestor; import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine; @@ -55,7 +56,6 @@ import org.eclipse.jdt.internal.corext.util.SearchUtils; import org.eclipse.jdt.internal.ui.JavaPlugin; -import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; public final class CreateCopyOfCompilationUnitChange extends CreateTextFileChange { @@ -80,6 +80,9 @@ private static TextChangeManager createChangeManager(IProgressMonitor monitor, I private static SearchPattern createSearchPattern(IType type) throws JavaModelException { SearchPattern pattern= SearchPattern.createPattern(type, IJavaSearchConstants.ALL_OCCURRENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return null; + } IMethod[] constructors= JavaElementUtil.getAllConstructors(type); if (constructors.length == 0) return pattern; @@ -105,6 +108,9 @@ private static SearchResultGroup getReferences(final ICompilationUnit copy, IPro if (type == null) return null; SearchPattern pattern= createSearchPattern(type); + if (pattern == null) { + return null; + } final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(pattern); engine.setScope(scope); engine.setWorkingCopies(copies); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/reorg/MoveCuUpdateCreator.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/reorg/MoveCuUpdateCreator.java index c0d88491..19d2e3db 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/reorg/MoveCuUpdateCreator.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/reorg/MoveCuUpdateCreator.java @@ -39,8 +39,10 @@ import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IImportDeclaration; import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.ToolFactory; import org.eclipse.jdt.core.compiler.IScanner; @@ -54,6 +56,8 @@ import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.TypeReferenceMatch; +import org.eclipse.jdt.internal.core.manipulation.StubUtility; +import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; import org.eclipse.jdt.internal.corext.refactoring.CollectingSearchRequestor; import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory; @@ -69,9 +73,6 @@ import org.eclipse.jdt.internal.ui.JavaPlugin; -import org.eclipse.jdt.internal.core.manipulation.StubUtility; -import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; - public class MoveCuUpdateCreator { private final String fNewPackage; @@ -318,7 +319,14 @@ private final static class Collector extends CollectingSearchRequestor { public Collector(IPackageFragment source, ReferencesInBinaryContext binaryRefs) { super(binaryRefs); fSource= source; - fScanner= ToolFactory.createScanner(false, false, false, false); + IJavaProject javaProject= source.getJavaProject(); + if (javaProject != null) { + String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); + String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); + fScanner = ToolFactory.createScanner(false, false, false, sourceLevel, complianceLevel); + } else { + fScanner= ToolFactory.createScanner(false, false, false, false); + } } @Override diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/sef/SelfEncapsulateFieldRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/sef/SelfEncapsulateFieldRefactoring.java index d24cfcfb..350ed34f 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/sef/SelfEncapsulateFieldRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/sef/SelfEncapsulateFieldRefactoring.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -53,7 +53,9 @@ import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; +import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.Block; @@ -64,6 +66,7 @@ import org.eclipse.jdt.core.dom.Dimension; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.IExtendedModifier; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; @@ -75,6 +78,7 @@ import org.eclipse.jdt.core.dom.ReturnStatement; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; @@ -92,6 +96,7 @@ import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil; import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.dom.AbortSearchException; import org.eclipse.jdt.internal.corext.dom.Bindings; import org.eclipse.jdt.internal.corext.dom.DimensionRewrite; import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; @@ -357,12 +362,17 @@ public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreEx return result; pm.setTaskName(RefactoringCoreMessages.SelfEncapsulateField_searching_for_cunits); final SubProgressMonitor subPm= new SubProgressMonitor(pm, 5); + SearchPattern pattern= SearchPattern.createPattern(fField, IJavaSearchConstants.REFERENCES); + if (pattern == null) { + return result; + } ICompilationUnit[] affectedCUs= RefactoringSearchEngine.findAffectedCompilationUnits( - SearchPattern.createPattern(fField, IJavaSearchConstants.REFERENCES), + pattern, RefactoringScopeFactory.create(fField, fConsiderVisibility), subPm, result, true); + checkAffectedCUs(result, affectedCUs); checkInHierarchy(result, usingLocalGetter, usingLocalSetter); if (result.hasFatalError()) return result; @@ -423,6 +433,55 @@ public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreEx return result; } + private class AffectedCUVisitor extends ASTVisitor { + private String fTypeName= null; + private boolean fGetterConflict= false; + + public String getTypeName() { + return fTypeName; + } + + public boolean isGetterConflict() { + return fGetterConflict; + } + + @Override + public boolean visit(TypeDeclaration node) { + ITypeBinding typeBinding= node.resolveBinding(); + while (typeBinding != null) { + IMethodBinding[] methodBindings= typeBinding.getDeclaredMethods(); + for (IMethodBinding methodBinding : methodBindings) { + if (methodBinding.getName().equals(getGetterName()) && methodBinding.getParameterNames().length == 0) { + fTypeName= typeBinding.getName(); + fGetterConflict= true; + throw new AbortSearchException(); + } + if (methodBinding.getName().equals(getSetterName()) && methodBinding.getParameterNames().length == 1) { + if (methodBinding.getParameterTypes()[0].isEqualTo(fFieldDeclaration.resolveBinding().getType())) { + fTypeName= typeBinding.getName(); + throw new AbortSearchException(); + } + } + } + typeBinding= typeBinding.getSuperclass(); + } + return true; + } + + } + + private void checkAffectedCUs(RefactoringStatus result, ICompilationUnit[] affectedCUs) { + AffectedCUVisitor visitor= new AffectedCUVisitor(); + try { + for (ICompilationUnit cu : affectedCUs) { + CompilationUnit root= new RefactoringASTParser(IASTSharedValues.SHARED_AST_LEVEL).parse(cu, true); + root.accept(visitor); + } + } catch (AbortSearchException e) { + result.addError(Messages.format(RefactoringCoreMessages.SelfEncapsulateField_subtype_method_exists, new String[] { visitor.isGetterConflict() ? getGetterName() : getSetterName(), visitor.getTypeName() })); + } + } + private void createEdits(ICompilationUnit unit, ASTRewrite rewriter, List groups, ImportRewrite importRewrite) throws CoreException { TextChange change= fChangeManager.get(unit); MultiTextEdit root= new MultiTextEdit(); @@ -643,6 +702,17 @@ private MethodDeclaration createSetterMethod(AST ast, ASTRewrite rewriter, Strin result.parameters().add(param); param.setName(ast.newSimpleName(fArgName)); param.setType((Type)rewriter.createCopyTarget(type)); + List modifiers= field.modifiers(); + for (IExtendedModifier modifier : modifiers) { + if (modifier.isAnnotation()) { + String annotationName= ((Annotation)modifier).getTypeName().getFullyQualifiedName(); + if ("NonNull".equals(annotationName) || "Nullable".equals(annotationName)) { //$NON-NLS-1$ //$NON-NLS-2$ + Annotation fieldAnnotation= (Annotation)rewriter.createCopyTarget((Annotation)modifier); + param.modifiers().add(fieldAnnotation); + } + } + } + List extraDimensions= DimensionRewrite.copyDimensions(fFieldDeclaration.extraDimensions(), rewriter); param.extraDimensions().addAll(extraDimensions); @@ -685,6 +755,16 @@ private MethodDeclaration createGetterMethod(AST ast, ASTRewrite rewriter, Strin MethodDeclaration result= ast.newMethodDeclaration(); result.setName(ast.newSimpleName(fGetterName)); result.modifiers().addAll(ASTNodeFactory.newModifiers(ast, createModifiers())); + List modifiers= field.modifiers(); + for (IExtendedModifier modifier : modifiers) { + if (modifier.isAnnotation()) { + String annotationName= ((Annotation)modifier).getTypeName().getFullyQualifiedName(); + if ("NonNull".equals(annotationName) || "Nullable".equals(annotationName)) { //$NON-NLS-1$ //$NON-NLS-2$ + Annotation fieldAnnotation= (Annotation)rewriter.createCopyTarget((Annotation)modifier); + result.modifiers().add(fieldAnnotation); + } + } + } Type returnType= DimensionRewrite.copyTypeAndAddDimensions(type, fFieldDeclaration.extraDimensions(), rewriter); result.setReturnType2(returnType); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeSignatureProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeSignatureProcessor.java index 46a38a32..d00df368 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeSignatureProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeSignatureProcessor.java @@ -1571,7 +1571,13 @@ protected void acceptSearchMatch(ICompilationUnit unit, SearchMatch match) throw // SearchPattern occPattern= SearchPattern.createPattern(fMethod, IJavaSearchConstants.ALL_OCCURRENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); SearchPattern declPattern= SearchPattern.createPattern(fMethod, IJavaSearchConstants.DECLARATIONS, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (declPattern == null) { + return new SearchResultGroup[0]; + } SearchPattern refPattern= SearchPattern.createPattern(fMethod, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (refPattern == null) { + return new SearchResultGroup[0]; + } // pattern= SearchPattern.createOrPattern(declPattern, refPattern); // pattern= occPattern; diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeTypeRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeTypeRefactoring.java index 712fe905..ea915009 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeTypeRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeTypeRefactoring.java @@ -1571,6 +1571,10 @@ private ICompilationUnit[] collectAffectedUnits(IProgressMonitor pm) throws Core } SearchPattern pattern= SearchPattern.createPattern( iField, IJavaSearchConstants.ALL_OCCURRENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + fAffectedUnits = new ICompilationUnit[0]; + return fAffectedUnits; + } IJavaSearchScope scope= RefactoringScopeFactory.create(iField); CollectingSearchRequestor csr= new CollectingSearchRequestor(); SearchResultGroup[] groups= diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractSupertypeProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractSupertypeProcessor.java index 1f1774a0..43848017 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractSupertypeProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractSupertypeProcessor.java @@ -638,7 +638,7 @@ public void endVisit(MethodDeclaration node) { } Expression newExp= (Expression)rewriter.createCopyTarget(exp); newSuperCall.arguments().add(newExp); - Statement stmt= (Statement)ASTNodes.getFirstAncestorOrNull(exp, Statement.class); + Statement stmt= ASTNodes.getFirstAncestorOrNull(exp, Statement.class); constructorRewrite.remove(stmt, null); } constructorRewrite.replace(currentSuperCall, newSuperCall, null); @@ -650,7 +650,7 @@ public void endVisit(MethodDeclaration node) { } Expression newExp= (Expression)rewriter.createCopyTarget(exp); newSuperCall.arguments().add(newExp); - Statement stmt= (Statement)ASTNodes.getFirstAncestorOrNull(exp, Statement.class); + Statement stmt= ASTNodes.getFirstAncestorOrNull(exp, Statement.class); constructorRewrite.remove(stmt, null); } constructorRewrite.insertFirst(newSuperCall, null); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/HierarchyProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/HierarchyProcessor.java index f31d7efe..58392e7e 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/HierarchyProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/HierarchyProcessor.java @@ -666,7 +666,11 @@ protected IType[] getTypesReferencedInMovedMembers(final IProgressMonitor monito protected boolean hasNonMovedReferences(final IMember member, final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException { if (!fCachedMembersReferences.containsKey(member)) { - final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); + SearchPattern pattern= SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return false; + } + final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(pattern); engine.setFiltering(true, true); engine.setStatus(status); engine.setOwner(fOwner); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ParameterObjectFactory.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ParameterObjectFactory.java index 33a36d48..fef90829 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ParameterObjectFactory.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ParameterObjectFactory.java @@ -36,6 +36,7 @@ import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.NamingConventions; import org.eclipse.jdt.core.ToolFactory; import org.eclipse.jdt.core.compiler.IScanner; @@ -692,20 +693,28 @@ protected String getFileComment(ICompilationUnit parentCU, String lineDelimiter) } protected String getTypeComment(ICompilationUnit parentCU, String lineDelimiter) throws CoreException { - if (StubUtility.doAddComments(parentCU.getJavaProject())) { + IJavaProject javaProject= parentCU.getJavaProject(); + if (StubUtility.doAddComments(javaProject)) { StringBuilder typeName= new StringBuilder(); typeName.append(getClassName()); String[] typeParamNames= new String[0]; String comment= CodeGeneration.getTypeComment(parentCU, typeName.toString(), typeParamNames, lineDelimiter); - if (comment != null && isValidComment(comment)) { + if (comment != null && isValidComment(comment, javaProject)) { return comment; } } return null; } - private boolean isValidComment(String template) { - IScanner scanner= ToolFactory.createScanner(true, false, false, false); + private boolean isValidComment(String template, IJavaProject javaProject) { + IScanner scanner; + if (javaProject != null) { + String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); + String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); + scanner = ToolFactory.createScanner(true, false, false, sourceLevel, complianceLevel); + } else { + scanner= ToolFactory.createScanner(true, false, false, false); + } scanner.setSource(template.toCharArray()); try { int next= scanner.getNextToken(); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PullUpRefactoringProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PullUpRefactoringProcessor.java index a445e385..44d641f3 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PullUpRefactoringProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PullUpRefactoringProcessor.java @@ -70,6 +70,7 @@ import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.ASTRequestor; +import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; import org.eclipse.jdt.core.dom.Block; @@ -88,6 +89,7 @@ import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.NodeFinder; import org.eclipse.jdt.core.dom.QualifiedName; +import org.eclipse.jdt.core.dom.QualifiedType; import org.eclipse.jdt.core.dom.ReturnStatement; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SimpleType; @@ -116,6 +118,7 @@ import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2Core; import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; import org.eclipse.jdt.internal.corext.dom.ASTNodes; +import org.eclipse.jdt.internal.corext.dom.AbortSearchException; import org.eclipse.jdt.internal.corext.dom.Bindings; import org.eclipse.jdt.internal.corext.dom.BodyDeclarationRewrite; import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; @@ -237,6 +240,29 @@ public final boolean visit(final SuperFieldAccess node) { return false; } + @Override + public final boolean visit(final SimpleType node) { + if (node.getName().isSimpleName()) { + ITypeBinding binding= node.resolveBinding(); + if (binding == null) { + return false; + } + CheckTypeNameInTarget check= new CheckTypeNameInTarget(binding); + try { + fTargetRewriter.getRoot().accept(check); + } catch (AbortSearchException e) { + // do nothing + } + if (check.isQualificationRequired() && binding.getPackage() != null && !binding.getPackage().getName().isEmpty()) { + String newName= binding.getPackage().getName() + "." + node.getName().getFullyQualifiedName(); //$NON-NLS-1$ + QualifiedType newQualifiedType= (QualifiedType)fRewrite.createStringPlaceholder(newName, ASTNode.QUALIFIED_TYPE); + fRewrite.replace(node, newQualifiedType, null); + return false; + } + } + return false; + } + @Override public final boolean visit(final SuperMethodInvocation node) { if (!fAnonymousClassDeclaration && !fTypeDeclarationStatement) { @@ -278,6 +304,35 @@ public final boolean visit(final TypeDeclarationStatement node) { fTypeDeclarationStatement= true; return super.visit(node); } + + private class CheckTypeNameInTarget extends ASTVisitor { + + private final ITypeBinding fBinding; + private boolean fQualificationRequired; + + public CheckTypeNameInTarget(ITypeBinding binding) { + this.fBinding= binding; + } + + @Override + public boolean visit(SimpleType node) { + if (!node.getName().isSimpleName() || !node.getName().getFullyQualifiedName().equals(fBinding.getName())) { + return false; + } + ITypeBinding binding= node.resolveBinding(); + if (binding != null) { + if (!binding.isEqualTo(fBinding)) { + fQualificationRequired= true; + throw new AbortSearchException(); + } + } + return false; + } + + public boolean isQualificationRequired() { + return fQualificationRequired; + } + } } protected static final String ATTRIBUTE_ABSTRACT= "abstract"; //$NON-NLS-1$ diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PushDownRefactoringProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PushDownRefactoringProcessor.java index 76c94bb8..7831cb2c 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PushDownRefactoringProcessor.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/PushDownRefactoringProcessor.java @@ -301,8 +301,12 @@ private static CompilationUnitRewrite getCompilationUnitRewrite(final Map> getReferencingCompilat engine.setFiltering(true, true); engine.setStatus(status); engine.setScope(RefactoringScopeFactory.create(type)); - engine.setPattern(SearchPattern.createPattern(type, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); + SearchPattern pattern= SearchPattern.createPattern(type, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE); + if (pattern == null) { + return Map.of(); + } + engine.setPattern(pattern); engine.searchPattern(new SubProgressMonitor(monitor, 100)); @SuppressWarnings("unchecked") Map> result= (Map>) engine.getAffectedProjects(); diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchAnalyzer.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchAnalyzer.java index c5469324..a020a589 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchAnalyzer.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchAnalyzer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -13,13 +13,24 @@ *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.surround; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.dom.MethodReference; +import org.eclipse.jdt.core.dom.PatternInstanceofExpression; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; import org.eclipse.jdt.internal.corext.dom.Selection; import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; @@ -54,4 +65,38 @@ public void endVisit(CompilationUnit node) { } } } + + public Map getVariableStatementBinding(ASTNode astNode) { + Map variableBindings= new HashMap<>(); + astNode.accept(new ASTVisitor() { + @Override + public boolean visit(VariableDeclarationStatement node) { + for (Object o : node.fragments()) { + if (o instanceof VariableDeclarationFragment) { + VariableDeclarationFragment vdf= (VariableDeclarationFragment) o; + SimpleName name= vdf.getName(); + IBinding binding= name.resolveBinding(); + if (binding instanceof IVariableBinding) { + variableBindings.put(name, (IVariableBinding) binding); + break; + } + } + } + return false; + } + + @Override + public boolean visit(PatternInstanceofExpression node) { + SingleVariableDeclaration svd= node.getRightOperand(); + SimpleName name= svd.getName(); + IBinding binding= name.resolveBinding(); + if (binding instanceof IVariableBinding) { + variableBindings.put(name, (IVariableBinding) binding); + } + return false; + } + }); + return variableBindings; + } + } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java index e8ef5c1e..170dade8 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -17,6 +17,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; @@ -37,6 +38,7 @@ import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.CatchClause; @@ -47,9 +49,11 @@ import org.eclipse.jdt.core.dom.IExtendedModifier; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.dom.LambdaExpression; import org.eclipse.jdt.core.dom.MethodReference; import org.eclipse.jdt.core.dom.Modifier; +import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.TryStatement; @@ -72,6 +76,7 @@ import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.CodeScopeBuilder; import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; +import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder; import org.eclipse.jdt.internal.corext.dom.Selection; import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel; import org.eclipse.jdt.internal.corext.refactoring.Checks; @@ -79,8 +84,9 @@ import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil; import org.eclipse.jdt.internal.corext.refactoring.util.SelectionAwareSourceRangeComputer; +import org.eclipse.jdt.internal.corext.util.JavaModelUtil; -import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessor; +import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessorUtil; /** * Surround a set of statements with a try/catch block or a try/multi-catch block. @@ -375,15 +381,58 @@ private void createTryCatchStatement(org.eclipse.jdt.core.IBuffer buffer, String } else { replacementNode= fRewriter.createGroupNode(result.toArray(new ASTNode[result.size()])); } - if (fSelectedNodes.length == 1) { + ASTNode node= fSelectedNodes[0]; + List nodesInRange= new ArrayList<>(); + + // for JVM 16 or higher, check if we have any variables declared via Pattern instanceof that + // need references added inside try/catch statement + if (JavaModelUtil.is16OrHigher(fCUnit.getJavaProject())) { + if (node instanceof Block || node.getLocationInParent() == Block.STATEMENTS_PROPERTY) { + ASTNode parentBodyDeclaration= (node instanceof Block) ? + node : ASTNodes.getFirstAncestorOrNull(node, Block.class); + int start= fSelectedNodes[0].getStartPosition(); + ASTNode lastSelectedNode= fSelectedNodes[fSelectedNodes.length - 1]; + int end= lastSelectedNode.getStartPosition() + lastSelectedNode.getLength(); + + for (ASTNode astNode : fSelectedNodes) { + if (!variableDeclarations.contains(astNode)) { + int endPosition= findEndPosition(astNode); + end= Math.max(end, endPosition); + } + } + + // recursive loop to find all nodes affected by wrapping in try block + nodesInRange= findNodesInRange(parentBodyDeclaration, start, end); + int oldEnd= end; + int newEnd= end; + while (true) { + newEnd= oldEnd; + for (ASTNode astNode : nodesInRange) { + if (!variableDeclarations.contains(astNode)) { + int endPosition= findEndPosition(astNode); + newEnd= Math.max(newEnd, endPosition); + } + } + if (newEnd > oldEnd) { + oldEnd= newEnd; + nodesInRange= findNodesInRange(parentBodyDeclaration, start, newEnd); + continue; + } + break; + } + nodesInRange.removeAll(Arrays.asList(fSelectedNodes)); + } + } + + if (fSelectedNodes.length == 1 && nodesInRange.isEmpty()) { ASTNode selectedNode= fSelectedNodes[0]; if (selectedNode instanceof MethodReference) { MethodReference methodReference= (MethodReference) selectedNode; - IMethodBinding functionalMethod= QuickAssistProcessor.getFunctionalMethodForMethodReference(methodReference); + IMethodBinding functionalMethod= QuickAssistProcessorUtil.getFunctionalMethodForMethodReference(methodReference); // functionalMethod is non-null and non-generic. See ExceptionAnalyzer.handleMethodReference(MethodReference node). Assert.isTrue(functionalMethod != null && !functionalMethod.isGenericMethod()); - LambdaExpression lambda= QuickAssistProcessor.convertMethodRefernceToLambda(methodReference, functionalMethod, fRootNode, fRewriter, null, true); + LambdaExpression lambda= QuickAssistProcessorUtil.convertMethodRefernceToLambda(methodReference, functionalMethod, fRootNode, fRewriter, null, true); ASTNode statementInBlock= (ASTNode) ((Block) lambda.getBody()).statements().get(0); fRewriter.replace(statementInBlock, replacementNode, null); statements.insertLast(statementInBlock, null); @@ -392,7 +441,7 @@ private void createTryCatchStatement(org.eclipse.jdt.core.IBuffer buffer, String LambdaExpression enclosingLambda= ASTResolving.findEnclosingLambdaExpression(selectedNode); if (enclosingLambda != null && selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY && enclosingLambda.resolveMethodBinding() != null) { - QuickAssistProcessor.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter); + QuickAssistProcessorUtil.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter); Block blockBody= (Block) fRewriter.get(enclosingLambda, LambdaExpression.BODY_PROPERTY); ASTNode statementInBlock= (ASTNode) blockBody.statements().get(0); fRewriter.replace(statementInBlock, replacementNode, null); @@ -412,12 +461,64 @@ private void createTryCatchStatement(org.eclipse.jdt.core.IBuffer buffer, String fSelectedNodes[0].getParent(), (ChildListPropertyDescriptor)fSelectedNodes[0].getLocationInParent()); ASTNode toMove= source.createMoveTarget( - fSelectedNodes[0], fSelectedNodes[fSelectedNodes.length - 1], + fSelectedNodes[0], (nodesInRange.isEmpty() ? fSelectedNodes[fSelectedNodes.length - 1] : nodesInRange.get(nodesInRange.size()-1)), replacementNode, null); statements.insertLast(toMove, null); } } + private int findEndPosition(ASTNode node) { + int end= node.getStartPosition() + node.getLength(); + Map nodeSimpleNameBindings= fAnalyzer.getVariableStatementBinding(node); + List nodeNames= new ArrayList<>(nodeSimpleNameBindings.keySet()); + if (nodeNames.isEmpty()) { + return -1; + } + SimpleName nodeSimpleName= nodeNames.get(0); + SimpleName[] coveredNodeBindings= LinkedNodeFinder.findByNode(node.getRoot(), nodeSimpleName); + if (coveredNodeBindings.length == 0) { + return -1; + } + for (ASTNode astNode : coveredNodeBindings) { + end= Math.max(end, (astNode.getStartPosition() + astNode.getLength())); + } + return end; + } + + // find all nodes (statements) that are within the start/end positions + public static List findNodesInRange(ASTNode astNode, final int start, final int end) { + List nodesInRange= new ArrayList<>(); + astNode.accept(new ASTVisitor() { + int pre= start; + + @Override + public void preVisit(ASTNode preNode) { + pre= preNode.getStartPosition(); + super.preVisit(preNode); + } + + @Override + public void postVisit(ASTNode postNode) { + int post= postNode.getStartPosition() + postNode.getLength(); + if (pre >= start && post <= end) { + Statement statement= ASTResolving.findParentStatement(postNode); + while (statement != null && statement.getParent() != astNode) { + ASTNode parent= statement.getParent(); + if (parent == null) { + return; + } + statement= ASTResolving.findParentStatement(parent); + } + if (statement != null && !nodesInRange.contains(statement)) { + nodesInRange.add(statement); + } + } + super.postVisit(postNode); + } + }); + return nodesInRange; + } + public static List filterSubtypeExceptions(ITypeBinding[] exceptions) { List filteredExceptions= new ArrayList<>(Arrays.asList(exceptions)); for (Iterator subtypeIterator= filteredExceptions.iterator(); subtypeIterator.hasNext();) { diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoring.java index 4209ae56..cb2fa1a3 100644 --- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoring.java +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoring.java @@ -13,82 +13,13 @@ *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.surround; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; - -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.text.edits.TextEdit; -import org.eclipse.text.edits.TextEditGroup; - import org.eclipse.jface.text.ITextSelection; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.Refactoring; -import org.eclipse.ltk.core.refactoring.RefactoringStatus; -import org.eclipse.ltk.core.refactoring.TextFileChange; - import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.dom.AST; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.ASTVisitor; -import org.eclipse.jdt.core.dom.Assignment; -import org.eclipse.jdt.core.dom.Block; -import org.eclipse.jdt.core.dom.CatchClause; -import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.Expression; -import org.eclipse.jdt.core.dom.ExpressionStatement; -import org.eclipse.jdt.core.dom.IExtendedModifier; -import org.eclipse.jdt.core.dom.IMethodBinding; -import org.eclipse.jdt.core.dom.ITypeBinding; -import org.eclipse.jdt.core.dom.IVariableBinding; -import org.eclipse.jdt.core.dom.LambdaExpression; -import org.eclipse.jdt.core.dom.MethodReference; -import org.eclipse.jdt.core.dom.Modifier; -import org.eclipse.jdt.core.dom.SimpleName; -import org.eclipse.jdt.core.dom.SingleVariableDeclaration; -import org.eclipse.jdt.core.dom.Statement; -import org.eclipse.jdt.core.dom.ThrowStatement; -import org.eclipse.jdt.core.dom.TryStatement; -import org.eclipse.jdt.core.dom.Type; -import org.eclipse.jdt.core.dom.UnionType; -import org.eclipse.jdt.core.dom.VariableDeclaration; -import org.eclipse.jdt.core.dom.VariableDeclarationExpression; -import org.eclipse.jdt.core.dom.VariableDeclarationFragment; -import org.eclipse.jdt.core.dom.VariableDeclarationStatement; -import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; -import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; -import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; -import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation; -import org.eclipse.jdt.core.dom.rewrite.ListRewrite; -import org.eclipse.jdt.core.refactoring.CompilationUnitChange; -import org.eclipse.jdt.internal.core.manipulation.StubUtility; -import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving; -import org.eclipse.jdt.internal.core.manipulation.util.Strings; -import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; -import org.eclipse.jdt.internal.corext.dom.ASTNodes; -import org.eclipse.jdt.internal.corext.dom.CodeScopeBuilder; -import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; -import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder; import org.eclipse.jdt.internal.corext.dom.Selection; import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel; -import org.eclipse.jdt.internal.corext.refactoring.Checks; -import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; -import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; -import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil; - -import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessor; +import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore; /** * Surround a set of statements with a try-with-resources block. @@ -102,30 +33,10 @@ * only consists of new assignments. In this case we can't move the * selected nodes (e.g. the declaration) into the try block. */ -public class SurroundWithTryWithResourcesRefactoring extends Refactoring { - - public final String GROUP_EXC_TYPE= "exc_type"; //$NON-NLS-1$ - public final String GROUP_EXC_NAME= "exc_name"; //$NON-NLS-1$ - public final String GROUP_TRY_STATEMENT= "try_stmt"; //$NON-NLS-1$ - - private Selection fSelection; - private SurroundWithTryWithResourcesAnalyzer fAnalyzer; - private boolean fLeaveDirty; - - private ICompilationUnit fCUnit; - private CompilationUnit fRootNode; - private ASTRewrite fRewriter; - private ImportRewrite fImportRewrite; - private CodeScopeBuilder.Scope fScope; - private ASTNode[] fSelectedNodes; - private List fAutoClosableNodes; - - private LinkedProposalModel fLinkedProposalModel; +public class SurroundWithTryWithResourcesRefactoring extends SurroundWithTryWithResourcesRefactoringCore { private SurroundWithTryWithResourcesRefactoring(ICompilationUnit cu, Selection selection) { - fCUnit= cu; - fSelection= selection; - fLeaveDirty= false; + super(cu, selection); } public static SurroundWithTryWithResourcesRefactoring create(ICompilationUnit cu, int offset, int length) { @@ -136,560 +47,13 @@ public static SurroundWithTryWithResourcesRefactoring create(ICompilationUnit cu return new SurroundWithTryWithResourcesRefactoring(cu, Selection.createFromStartLength(selection.getOffset(), selection.getLength())); } - public LinkedProposalModel getLinkedProposalModel() { - return fLinkedProposalModel; - } - - public void setLeaveDirty(boolean leaveDirty) { - fLeaveDirty= leaveDirty; - } - - public boolean stopExecution() { - if (fAnalyzer == null) - return true; - ITypeBinding[] exceptions= fAnalyzer.getExceptions(fAnalyzer.getSelection()); - List autoClosableNodes= fAnalyzer.getCoveredAutoClosableNodes(); - return (exceptions == null || exceptions.length == 0) && (autoClosableNodes == null || autoClosableNodes.isEmpty()); - } - - /* non Java-doc - * @see IRefactoring#getName() - */ - @Override - public String getName() { - return RefactoringCoreMessages.SurroundWithTryWithResourcesRefactoring_name; - } - - public RefactoringStatus checkActivationBasics(CompilationUnit rootNode) throws CoreException { - RefactoringStatus result= new RefactoringStatus(); - fRootNode= rootNode; - - fAnalyzer= new SurroundWithTryWithResourcesAnalyzer(fCUnit, fSelection); - fRootNode.accept(fAnalyzer); - result.merge(fAnalyzer.getStatus()); - fAutoClosableNodes= fAnalyzer.getCoveredAutoClosableNodes(); - if (fAutoClosableNodes == null || fAutoClosableNodes.isEmpty()) { - result.merge(RefactoringStatus.createWarningStatus(RefactoringCoreMessages.SurroundWithTryWithResourcesRefactoring_notAutoclosable)); - } - return result; - } - - - /* - * @see Refactoring#checkActivation(IProgressMonitor) - */ - @Override - public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { - CompilationUnit rootNode= new RefactoringASTParser(IASTSharedValues.SHARED_AST_LEVEL).parse(fCUnit, true, pm); - return checkActivationBasics(rootNode); - } - - /* - * @see Refactoring#checkInput(IProgressMonitor) - */ - @Override - public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException { - return Checks.validateModifiesFiles( - ResourceUtil.getFiles(new ICompilationUnit[]{fCUnit}), - getValidationContext(), pm); - } - - /* non Java-doc - * @see IRefactoring#createChange(IProgressMonitor) - */ @Override - public Change createChange(IProgressMonitor pm) throws CoreException { - final String NN= ""; //$NON-NLS-1$ - if (pm == null) pm= new NullProgressMonitor(); - pm.beginTask(NN, 2); - try { - final CompilationUnitChange result= new CompilationUnitChange(getName(), fCUnit); - if (fLeaveDirty) - result.setSaveMode(TextFileChange.LEAVE_DIRTY); - MultiTextEdit root= new MultiTextEdit(); - result.setEdit(root); - fRewriter= ASTRewrite.create(fAnalyzer.getEnclosingBodyDeclaration().getAST()); - fImportRewrite= StubUtility.createImportRewrite(fRootNode, true); - - fLinkedProposalModel= new LinkedProposalModel(); - - fScope= CodeScopeBuilder.perform(fAnalyzer.getEnclosingBodyDeclaration(), fSelection). - findScope(fSelection.getOffset(), fSelection.getLength()); - fScope.setCursor(fSelection.getOffset()); - - fSelectedNodes= fAnalyzer.getSelectedNodes(); - - createTryWithResourcesStatement(fCUnit.getBuffer(), fCUnit.findRecommendedLineSeparator()); - - if (fImportRewrite.hasRecordedChanges()) { - TextEdit edit= fImportRewrite.rewriteImports(null); - root.addChild(edit); - result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {edit} )); - } - TextEdit change= fRewriter.rewriteAST(); - root.addChild(change); - result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {change} )); - return result; - } finally { - pm.done(); - } - } - - private AST getAST() { - return fRootNode.getAST(); + protected LinkedProposalModelCore createLinkedProposalModel() { + return new LinkedProposalModel(); } - @SuppressWarnings("null") - private void createTryWithResourcesStatement(org.eclipse.jdt.core.IBuffer buffer, String lineDelimiter) throws CoreException { - List result= new ArrayList<>(1); - boolean modifyExistingTry= false; - TryStatement tryStatement= null; - ITypeBinding[] exceptions= fAnalyzer.getExceptions(fAnalyzer.getSelection()); - ImportRewriteContext context= new ContextSensitiveImportRewriteContext(fAnalyzer.getEnclosingBodyDeclaration(), fImportRewrite); - - TryStatement enclosingTry= (TryStatement)ASTResolving.findAncestor(fSelectedNodes[0], ASTNode.TRY_STATEMENT); - ListRewrite resourcesRewriter= null; - ListRewrite clausesRewriter= null; - ListRewrite statements= null; - if (enclosingTry == null || enclosingTry.getBody() == null || enclosingTry.getBody().statements().get(0) != fSelectedNodes[0]) { - tryStatement= getAST().newTryStatement(); - statements= fRewriter.getListRewrite(tryStatement.getBody(), Block.STATEMENTS_PROPERTY); - } else { - modifyExistingTry= true; - resourcesRewriter= fRewriter.getListRewrite(enclosingTry, TryStatement.RESOURCES2_PROPERTY); - clausesRewriter= fRewriter.getListRewrite(enclosingTry, TryStatement.CATCH_CLAUSES_PROPERTY); - } - - CatchClause catchClause= getAST().newCatchClause(); - SingleVariableDeclaration decl= getAST().newSingleVariableDeclaration(); - String varName= StubUtility.getExceptionVariableName(fCUnit.getJavaProject()); - String name= fScope.createName(varName, false); - decl.setName(getAST().newSimpleName(name)); - - - boolean selectedNodeRemoved= false; - ASTNode expressionStatement= null; - ASTNode replacementNode= null; - List nodesInRange= new ArrayList<>(); - - if (!modifyExistingTry) { - List variableDeclarations= getSpecialVariableDeclarationStatements(); - for (ASTNode node : fSelectedNodes) { - if (fAutoClosableNodes.contains(node)) { - continue; - } - if (node instanceof VariableDeclarationStatement && variableDeclarations.contains(node)) { - AST ast= getAST(); - VariableDeclarationStatement statement= (VariableDeclarationStatement)node; - // Create a copy and remove the initializer - VariableDeclarationStatement copy= (VariableDeclarationStatement)ASTNode.copySubtree(ast, statement); - List modifiers= copy.modifiers(); - for (Iterator iter= modifiers.iterator(); iter.hasNext();) { - IExtendedModifier modifier= iter.next(); - if (modifier.isModifier() && Modifier.isFinal(((Modifier)modifier).getKeyword().toFlagValue())) { - iter.remove(); - } - } - List fragments= copy.fragments(); - for (VariableDeclarationFragment fragment : fragments) { - fragment.setInitializer(null); - } - - // "var" type cannot have null initializer, so change to inferred type - if (ASTNodes.isVarType(statement, fRootNode)) { - ITypeBinding binding= statement.getType().resolveBinding(); - if (binding != null) { - Type varType= fImportRewrite.addImport(binding, getAST(), context, TypeLocation.LOCAL_VARIABLE); - copy.setType(varType); - } - } - - CompilationUnit root= (CompilationUnit)statement.getRoot(); - int extendedStart= root.getExtendedStartPosition(statement); - // we have a leading comment and the comment is covered by the selection - if (extendedStart != statement.getStartPosition() && extendedStart >= fSelection.getOffset()) { - String commentToken= buffer.getText(extendedStart, statement.getStartPosition() - extendedStart); - commentToken= Strings.trimTrailingTabsAndSpaces(commentToken); - Type type= statement.getType(); - String typeName= buffer.getText(type.getStartPosition(), type.getLength()); - copy.setType((Type)fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType())); - } - result.add(copy); - // convert the fragments into expression statements - fragments= statement.fragments(); - if (!fragments.isEmpty()) { - List newExpressionStatements= new ArrayList<>(); - for (VariableDeclarationFragment fragment : fragments) { - Expression initializer= fragment.getInitializer(); - if (initializer != null) { - Assignment assignment= ast.newAssignment(); - assignment.setLeftHandSide((Expression)fRewriter.createCopyTarget(fragment.getName())); - assignment.setRightHandSide((Expression)fRewriter.createCopyTarget(initializer)); - newExpressionStatements.add(ast.newExpressionStatement(assignment)); - } - } - if (!newExpressionStatements.isEmpty()) { - if (fSelectedNodes.length == 1) { - expressionStatement= fRewriter.createGroupNode(newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()])); - } else { - fRewriter.replace( - statement, - fRewriter.createGroupNode(newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()])), - null); - } - } else { - fRewriter.remove(statement, null); - selectedNodeRemoved= true; - } - } else { - fRewriter.remove(statement, null); - selectedNodeRemoved= true; - } - } - } - result.add(tryStatement); - if (result.size() == 1) { - replacementNode= result.get(0); - } else { - replacementNode= fRewriter.createGroupNode(result.toArray(new ASTNode[result.size()])); - } - - ASTNode node= fSelectedNodes[0]; - List coveredStatements= new ArrayList<>(); - for (ASTNode coveredNode : fSelectedNodes) { - Statement statement= ASTResolving.findParentStatement(coveredNode); - if (statement == null) { - continue; - } - if (!coveredStatements.contains(statement)) { - coveredStatements.add(statement); - } - } - - Selection nodesInRangeSelection= fAnalyzer.getSelection(); - if (!fAutoClosableNodes.isEmpty()) { - ASTNode parentBodyDeclaration= ASTResolving.findParentBodyDeclaration(node); - int start= fAutoClosableNodes.get(0).getStartPosition(); - ASTNode lastSelectedNode= fSelectedNodes[fSelectedNodes.length - 1]; - int end= lastSelectedNode.getStartPosition() + lastSelectedNode.getLength(); - - for (ASTNode astNode : fAutoClosableNodes) { - int endPosition= findEndPosition(astNode); - end= Math.max(end, endPosition); - } - - // recursive loop to find all nodes affected by wrapping in try block - nodesInRange= findNodesInRange(parentBodyDeclaration, start, end); - int oldEnd= end; - int newEnd= end; - while (true) { - newEnd= oldEnd; - for (ASTNode astNode : nodesInRange) { - int endPosition= findEndPosition(astNode); - newEnd= Math.max(newEnd, endPosition); - } - if (newEnd > oldEnd) { - oldEnd= newEnd; - nodesInRange= findNodesInRange(parentBodyDeclaration, start, newEnd); - continue; - } - break; - } - if (nodesInRange.size() > 0) { - // must recalculate exceptions as additional lines are now in try statement - ASTNode lastNode= nodesInRange.get(nodesInRange.size() - 1); - nodesInRangeSelection= Selection.createFromStartEnd(start, lastNode.getStartPosition() + lastNode.getLength()); - exceptions= fAnalyzer.getExceptions(nodesInRangeSelection); - } - nodesInRange.removeAll(fAutoClosableNodes); - nodesInRange.removeAll(Arrays.asList(fSelectedNodes)); - } - } - - // add required resource statements - CompilationUnit cu= (CompilationUnit)fSelectedNodes[0].getRoot(); - AST ast= fSelectedNodes[0].getAST(); - Set resourceNameList= new HashSet<>(); - List allExceptions= new ArrayList<>(Arrays.asList(exceptions)); - for (ASTNode coveredNode : fAutoClosableNodes) { - ASTNode findAncestor= ASTResolving.findAncestor(coveredNode, ASTNode.VARIABLE_DECLARATION_STATEMENT); - if (findAncestor == null) { - findAncestor= ASTResolving.findAncestor(coveredNode, ASTNode.ASSIGNMENT); - } - if (findAncestor instanceof VariableDeclarationStatement) { - VariableDeclarationStatement vds= (VariableDeclarationStatement) findAncestor; - String commentToken= null; - int extendedStatementStart= cu.getExtendedStartPosition(vds); - if(vds.getStartPosition() > extendedStatementStart) { - commentToken= buffer.getText(extendedStatementStart, vds.getStartPosition() - extendedStatementStart); - } - Type type= vds.getType(); - ITypeBinding typeBinding= type.resolveBinding(); - if (typeBinding != null) { - IMethodBinding close= findAutocloseMethod(typeBinding); - if (close != null) { - for (ITypeBinding exceptionType : close.getExceptionTypes()) { - if (!allExceptions.contains(exceptionType)) { - allExceptions.add(exceptionType); - } - } - } - } - String typeName= buffer.getText(type.getStartPosition(), type.getLength()); - - for (Object object : vds.fragments()) { - VariableDeclarationFragment variableDeclarationFragment= (VariableDeclarationFragment) object; - VariableDeclarationFragment newVariableDeclarationFragment= ast.newVariableDeclarationFragment(); - SimpleName vdsName= variableDeclarationFragment.getName(); - - if(commentToken == null) { - int extendedStart= cu.getExtendedStartPosition(variableDeclarationFragment); - commentToken= buffer.getText(extendedStart, variableDeclarationFragment.getStartPosition() - extendedStart); - } - commentToken= Strings.trimTrailingTabsAndSpaces(commentToken); - commentToken += commentToken.isEmpty() ? "" : " "; //$NON-NLS-1$ //$NON-NLS-2$ - - newVariableDeclarationFragment.setName(ast.newSimpleName(vdsName.getIdentifier())); - Expression newExpression= null; - Expression initializer= variableDeclarationFragment.getInitializer(); - if (initializer == null) { - fRewriter.remove(coveredNode, null); - continue; - } else { - newExpression= (Expression) fRewriter.createMoveTarget(initializer); - } - resourceNameList.add(vdsName.getIdentifier()); - newVariableDeclarationFragment.setInitializer(newExpression); - VariableDeclarationExpression newVariableDeclarationExpression= ast.newVariableDeclarationExpression(newVariableDeclarationFragment); - newVariableDeclarationExpression.setType( - (Type) fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType())); - if (modifyExistingTry) { - if (enclosingTry.resources().isEmpty()) { - resourcesRewriter.insertFirst(newVariableDeclarationExpression, null); - } else { - resourcesRewriter.insertLast(newVariableDeclarationExpression, null); - } - } else { - tryStatement.resources().add(newVariableDeclarationExpression); - } - commentToken= null; - } -// String commentToken2= ""; //$NON-NLS-1$ -// int extendedStart= cu.getExtendedStartPosition(vds); -// int extendedLength= cu.getExtendedLength(vds); -// int endCommentLength= extendedLength - (vds.getStartPosition() - extendedStart) - vds.getLength(); -// if (endCommentLength > 0) { -// commentToken2= buffer.getText(vds.getStartPosition() + vds.getLength(), -// endCommentLength); -// commentToken2= Strings.trimLeadingTabsAndSpaces(commentToken2); -// } - } - } - - List mustRethrowList= new ArrayList<>(); - List catchExceptions= fAnalyzer.calculateCatchesAndRethrows(ASTNodes.filterSubtypes(allExceptions), mustRethrowList); - List filteredExceptions= ASTNodes.filterSubtypes(catchExceptions); - if (catchExceptions.size() > 0) { - LinkedProposalModel linkedProposalModel= new LinkedProposalModel(); - int i= 0; - if (!modifyExistingTry) { - for (ITypeBinding mustThrow : mustRethrowList) { - CatchClause newClause= ast.newCatchClause(); - SingleVariableDeclaration newDecl= ast.newSingleVariableDeclaration(); - newDecl.setName(ast.newSimpleName(name)); - Type importType= fImportRewrite.addImport(mustThrow, ast, context, TypeLocation.EXCEPTION); - newDecl.setType(importType); - newClause.setException(newDecl); - ThrowStatement newThrowStatement= ast.newThrowStatement(); - newThrowStatement.setExpression(ast.newSimpleName(name)); - linkedProposalModel.getPositionGroup(GROUP_EXC_NAME + i, true).addPosition(fRewriter.track(decl.getName()), false); - newClause.getBody().statements().add(newThrowStatement); - tryStatement.catchClauses().add(newClause); - ++i; - } - } - UnionType unionType= getAST().newUnionType(); - List types= unionType.types(); - for (ITypeBinding exception : filteredExceptions) { - Type type= fImportRewrite.addImport(exception, getAST(), context, TypeLocation.EXCEPTION); - types.add(type); - fLinkedProposalModel.getPositionGroup(GROUP_EXC_TYPE + i, true).addPosition(fRewriter.track(type), i == 0); - i++; - } - - decl.setType(unionType); - catchClause.setException(decl); - fLinkedProposalModel.getPositionGroup(GROUP_EXC_NAME + 0, true).addPosition(fRewriter.track(decl.getName()), false); - Statement st= getCatchBody("Exception", name, lineDelimiter); //$NON-NLS-1$ - if (st != null) { - catchClause.getBody().statements().add(st); - } - if (modifyExistingTry) { - clausesRewriter.insertLast(catchClause, null); - } else { - tryStatement.catchClauses().add(catchClause); - } - } - - - if (fSelectedNodes.length == 1 && fAutoClosableNodes.isEmpty()) { - ASTNode selectedNode= fSelectedNodes[0]; - - if (selectedNode instanceof MethodReference) { - MethodReference methodReference= (MethodReference) selectedNode; - IMethodBinding functionalMethod= QuickAssistProcessor.getFunctionalMethodForMethodReference(methodReference); - // functionalMethod is non-null and non-generic. See ExceptionAnalyzer.handleMethodReference(MethodReference node). - Assert.isTrue(functionalMethod != null && !functionalMethod.isGenericMethod()); - LambdaExpression lambda= QuickAssistProcessor.convertMethodRefernceToLambda(methodReference, functionalMethod, fRootNode, fRewriter, null, true); - ASTNode statementInBlock= (ASTNode) ((Block) lambda.getBody()).statements().get(0); - fRewriter.replace(statementInBlock, replacementNode, null); - statements.insertLast(statementInBlock, null); - return; - } - - LambdaExpression enclosingLambda= ASTResolving.findEnclosingLambdaExpression(selectedNode); - if (enclosingLambda != null && selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY && enclosingLambda.resolveMethodBinding() != null) { - QuickAssistProcessor.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter); - Block blockBody= (Block) fRewriter.get(enclosingLambda, LambdaExpression.BODY_PROPERTY); - ASTNode statementInBlock= (ASTNode) blockBody.statements().get(0); - fRewriter.replace(statementInBlock, replacementNode, null); - statements.insertLast(statementInBlock, null); - return; - } - - if (expressionStatement != null) { - statements.insertLast(expressionStatement, null); - } else { - if (!selectedNodeRemoved) - statements.insertLast(fRewriter.createMoveTarget(selectedNode), null); - } - fRewriter.replace(selectedNode, replacementNode, null); - } else if (modifyExistingTry) { - ListRewrite source= fRewriter.getListRewrite(enclosingTry.getBody(), Block.STATEMENTS_PROPERTY); - for (ASTNode node : fAutoClosableNodes) { - source.remove(node, null); - } - } else { - ListRewrite source= fRewriter.getListRewrite( - fSelectedNodes[0].getParent(), - (ChildListPropertyDescriptor)fSelectedNodes[0].getLocationInParent()); - List nodes= new ArrayList<>(Arrays.asList(fSelectedNodes)); - if (!nodesInRange.isEmpty()) { - nodes.addAll(nodesInRange); - } - int index= fAutoClosableNodes.size(); - if (index < nodes.size()) { - ASTNode toMove= source.createMoveTarget(nodes.get(index), nodes.get(nodes.size() - 1), - index == 0 ? replacementNode : null, null); - statements.insertLast(toMove, null); - } - if (index > 0) { - source.replace(fAutoClosableNodes.get(0), replacementNode, null); - for (int i= 1; i < index; ++i) { - source.remove(fAutoClosableNodes.get(i), null); - } - } - } - - } - - public static IMethodBinding findAutocloseMethod(ITypeBinding type) { - while (type != null) { - IMethodBinding[] methods= type.getDeclaredMethods(); - for (IMethodBinding method : methods) { - if ("close".equals(method.getName()) && method.getParameterTypes().length == 0) { //$NON-NLS-1$ - return method; - } - } - type= type.getSuperclass(); - } - return null; - } - - private int findEndPosition(ASTNode node) { - int end= node.getStartPosition() + node.getLength(); - Map nodeSimpleNameBindings= fAnalyzer.getVariableStatementBinding(node); - List nodeNames= new ArrayList<>(nodeSimpleNameBindings.keySet()); - if (nodeNames.isEmpty()) { - return -1; - } - SimpleName nodeSimpleName= nodeNames.get(0); - SimpleName[] coveredNodeBindings= LinkedNodeFinder.findByNode(node.getRoot(), nodeSimpleName); - if (coveredNodeBindings.length == 0) { - return -1; - } - for (ASTNode astNode : coveredNodeBindings) { - end= Math.max(end, (astNode.getStartPosition() + astNode.getLength())); - } - return end; - } - - // find all nodes (statements) that are within the start/end positions - public static List findNodesInRange(ASTNode astNode, final int start, final int end) { - List nodesInRange= new ArrayList<>(); - astNode.accept(new ASTVisitor() { - int pre= start; - - @Override - public void preVisit(ASTNode preNode) { - pre= preNode.getStartPosition(); - super.preVisit(preNode); - } - - @Override - public void postVisit(ASTNode postNode) { - int post= postNode.getStartPosition() + postNode.getLength(); - if (pre >= start && post <= end) { - Statement statement= ASTResolving.findParentStatement(postNode); - loop: while (statement != null) { - if (statement.getParent() instanceof Statement) { - Statement pStatement= (Statement) statement.getParent(); - switch (pStatement.getNodeType()) { - case ASTNode.BLOCK: - if (pStatement.getParent().getNodeType() != ASTNode.METHOD_DECLARATION && - pStatement.getParent().getNodeType() != ASTNode.TRY_STATEMENT) { - statement= pStatement; - continue; - } else { - break loop; - } - case ASTNode.METHOD_DECLARATION: - break loop; - default: - break; - } - statement= pStatement; - } else { - break; - } - } - if (statement != null && !nodesInRange.contains(statement)) { - nodesInRange.add(statement); - } - } - super.postVisit(postNode); - } - }); - return nodesInRange; - } - - private List getSpecialVariableDeclarationStatements() { - List result= new ArrayList<>(3); - for (VariableDeclaration local : fAnalyzer.getAffectedLocals()) { - ASTNode parent= local.getParent(); - if (parent instanceof VariableDeclarationStatement && !result.contains(parent)) - result.add(parent); - } - return result; - + public LinkedProposalModel getLinkedProposalModel() { + return (LinkedProposalModel)getLinkedProposalModelCore(); } - private Statement getCatchBody(String type, String name, String lineSeparator) throws CoreException { - String s= StubUtility.getCatchBodyContent(fCUnit, type, name, fSelectedNodes[0], lineSeparator); - if (s == null) { - return null; - } else { - return (Statement)fRewriter.createStringPlaceholder(s, ASTNode.RETURN_STATEMENT); - } - } } diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/NullChecker.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/NullChecker.java new file mode 100644 index 00000000..1d7f97ac --- /dev/null +++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/NullChecker.java @@ -0,0 +1,230 @@ +/******************************************************************************* + * Copyright (c) 2000, 2022 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + * Xiaye Chi - [extract local] Extract to local variable may result in NullPointerException. - https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/39 + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.refactoring.util; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.SourceRange; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.ArrayAccess; +import org.eclipse.jdt.core.dom.BodyDeclaration; +import org.eclipse.jdt.core.dom.CastExpression; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.FieldAccess; +import org.eclipse.jdt.core.dom.IBinding; +import org.eclipse.jdt.core.dom.InfixExpression; +import org.eclipse.jdt.core.dom.InfixExpression.Operator; +import org.eclipse.jdt.core.dom.Initializer; +import org.eclipse.jdt.core.dom.LambdaExpression; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.Name; +import org.eclipse.jdt.core.dom.ParenthesizedExpression; +import org.eclipse.jdt.core.dom.QualifiedName; +import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; + +import org.eclipse.jdt.internal.corext.dom.fragments.ASTFragmentFactory; +import org.eclipse.jdt.internal.corext.dom.fragments.IASTFragment; + +public class NullChecker { + private ASTNode fExpression; + + private int fStartOffset; + + private int fEndOffset; + + private ASTNode fCommonNode; + + private Set fInvocationSet; + + private CompilationUnit fCompilationUnitNode; + + private ICompilationUnit fCu; + + private Set fMatchNodePosSet; + + public NullChecker(CompilationUnit fCompilationUnitNode, ICompilationUnit fCu, ASTNode commonNode, ASTNode expression, int startOffset, int endOffset) { + this.fCompilationUnitNode= fCompilationUnitNode; + this.fCu= fCu; + this.fCommonNode= commonNode; + this.fExpression= expression; + this.fStartOffset= startOffset; + this.fEndOffset= endOffset; + InvocationVisitor iv= new InvocationVisitor(); + this.fExpression.accept(iv); + this.fInvocationSet= iv.invocationSet; + this.fMatchNodePosSet= iv.matchNodePosSet; + } + + public boolean hasNullCheck() { + NullMiddleCodeVisitor nullMiddleCodeVisitor= new NullMiddleCodeVisitor(this.fInvocationSet, this.fMatchNodePosSet, this.fStartOffset, this.fEndOffset); + this.fCommonNode.accept(nullMiddleCodeVisitor); + return nullMiddleCodeVisitor.hasNullCheck(); + } + + private IASTFragment getIASTFragment(ASTNode astNode) throws JavaModelException { + int length= astNode.getLength(); + int startPosition= astNode.getStartPosition(); + return ASTFragmentFactory.createFragmentForSourceRange(new SourceRange(startPosition, length), this.fCompilationUnitNode, this.fCu); + + } + + private ASTNode getEnclosingBodyNode(ASTNode node) { + StructuralPropertyDescriptor location= null; + while (node != null && !(node instanceof BodyDeclaration)) { + location= node.getLocationInParent(); + node= node.getParent(); + if (node instanceof LambdaExpression) { + break; + } + } + if (node != null) { + if (location == MethodDeclaration.BODY_PROPERTY || location == Initializer.BODY_PROPERTY + || (location == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) node).resolveMethodBinding() != null)) { + return (ASTNode) node.getStructuralProperty(location); + } + } + return null; + } + + private Expression getOriginalExpression(Expression expr) { + while (expr instanceof ParenthesizedExpression || expr instanceof CastExpression) { + if (expr instanceof ParenthesizedExpression) { + ParenthesizedExpression pe= (ParenthesizedExpression) expr; + expr= pe.getExpression(); + } else { + CastExpression ce= (CastExpression) expr; + expr= ce.getExpression(); + } + } + return expr; + + } + + private class InvocationVisitor extends ASTVisitor { + Set invocationSet; + + Set matchNodePosSet; + + InvocationVisitor() { + this.invocationSet= new HashSet<>(); + this.matchNodePosSet= new HashSet<>(); + } + + @Override + public void preVisit(ASTNode node) { + Expression temp= null; + if (node instanceof MethodInvocation) { + MethodInvocation mi= (MethodInvocation) node; + temp= mi.getExpression(); + } else if (node instanceof FieldAccess) { + FieldAccess fa= (FieldAccess) node; + temp= fa.getExpression(); + } else if (node instanceof QualifiedName) { + QualifiedName qn= (QualifiedName) node; + temp= qn.getQualifier(); + } else if (node instanceof ArrayAccess) { + ArrayAccess aa= (ArrayAccess) node; + temp= aa.getArray(); + } + + if (temp != null) { + try { + temp= getOriginalExpression(temp); + IASTFragment[] allMatches= ASTFragmentFactory.createFragmentForFullSubtree(getEnclosingBodyNode(temp)).getSubFragmentsMatching(getIASTFragment(temp)); + for (IASTFragment match : allMatches) { + if (match.getAssociatedNode() != null) { + this.matchNodePosSet.add(match.getAssociatedNode().getStartPosition()); + } + } + } catch (JavaModelException e) { + e.printStackTrace(); + } + IBinding resolveBinding= null; + if (temp instanceof Name) + resolveBinding= ((Name) temp).resolveBinding(); + if (resolveBinding != null) + this.invocationSet.add(resolveBinding); + } + } + + } + + private class NullMiddleCodeVisitor extends ASTVisitor { + int startPosition; + + int endPosition; + + boolean nullFlag; + + Set invocationSet; + + Set matchNodePosSet; + + public NullMiddleCodeVisitor(Set invocationSet, Set matchNodePosSet, int startPosition, int endPosition) { + this.invocationSet= invocationSet; + this.matchNodePosSet= matchNodePosSet; + this.startPosition= startPosition; + this.endPosition= endPosition; + this.nullFlag= false; + } + + public boolean hasNullCheck() { + return this.nullFlag; + } + + @Override + public boolean preVisit2(ASTNode node) { + int sl= node.getStartPosition(); + int el= node.getStartPosition() + node.getLength(); + if (el < startPosition || sl > endPosition || this.nullFlag == true) { + return false; + } + Expression target= null; + if (sl >= startPosition && el <= endPosition && node instanceof InfixExpression) { + InfixExpression infixExpression= (InfixExpression) node; + Operator op= infixExpression.getOperator(); + if (Operator.toOperator(op.toString()) == Operator.EQUALS || Operator.toOperator(op.toString()) == Operator.NOT_EQUALS) { + Expression leftExpression= infixExpression.getLeftOperand(); + Expression rightExpression= infixExpression.getRightOperand(); + if (rightExpression.getNodeType() == ASTNode.NULL_LITERAL) { + target= leftExpression; + } else if (leftExpression.getNodeType() == ASTNode.NULL_LITERAL) { + target= rightExpression; + } + } + } + + if (target != null) { + target= getOriginalExpression(target); + IBinding targetBinding= null; + if (target instanceof Name && (targetBinding= ((Name)target).resolveBinding()) != null && this.invocationSet.contains(targetBinding)) { + this.nullFlag= true; + return false; + } else if (this.matchNodePosSet.contains(target.getStartPosition())) { + this.nullFlag= true; + return false; + } + } + return super.preVisit2(node); + } + } + +} diff --git a/org.eclipse.jdt.ui/dictionaries/en_GB.dictionary b/org.eclipse.jdt.ui/dictionaries/en_GB.dictionary index cdf5629b..ec789020 100644 --- a/org.eclipse.jdt.ui/dictionaries/en_GB.dictionary +++ b/org.eclipse.jdt.ui/dictionaries/en_GB.dictionary @@ -1,5 +1,10 @@ +Aargau ACM ANSI +Antigua +Appenzell +Argovia +Armenia ASAP ASCII ATM's @@ -175,6 +180,28 @@ Austria's Austrian Austrian's Ave +Azerbaijan +Baden-Württemberg +Bahamas +Bahrain +Barbuda +Basel-City +Basel-Country +Basel-Landschaft +Basel-Stadt +Basle-City +Basle-Country +Bavaria +Belarus +Belize +Benin +Bern +Berne +Bhutan +Bosnia +Brandenburg +Bremen +Brunei BSD Babel Babel's @@ -269,10 +296,25 @@ Briton's Britons Buehring Buehring's +Bulgaria +Burgenland +Burundi +califate +califates +Cambodia +Cameroon +Carinthia CDC CDC's CEO +Chad +Chile +China CMOS +Colombia +Comoros +Congo +Connecticut CPU CPU's CPUs @@ -308,12 +350,19 @@ Comdex's Cray Cray's Crays +Croatia +Cuba Cupertino Cupertino's +Cyprus +Czech Czechoslovakian +Dakota DARPA DARPA's DECNET +Djibouti +Dominica DOS Dan Dan's @@ -333,33 +382,45 @@ Dijkstra's Diophantine Dylan Dylan's +Ecuador EDP EGA EGA's Edsger Edsger's +Egypt Ellen Ellen's Elvis Elvis's +emirate +emirates English English's +Eritrea Erlang Erlang's +Estonia +Eswatini Ethernet Ethernet's Ethernets +Ethiopia Europe Europe's European European's Europeans +federate +federated FIFO Fairbanks Februaries February February's Felder +Fiji +Finland Florida Florida's Fortran @@ -371,9 +432,17 @@ France's Frances French French's +Fribourg +Friburg Friday Friday's Fridays +Gabon +Gambia +Geneva +Georgia +Ghana +Glarus GPSS Galvin Galvin's @@ -396,15 +465,31 @@ Git Godzilla Godzilla's Gothic +Graubünden +Greece Greek Greek's Greeks Greg Greg's +Grenada +Grisons +Guam +Guatemala +Guinea +Guinea-Bissau +Guyana +Haiti +Hamburg +Hampshire +Hawaii Heinlein Heinlein's +Herzegovina +Hesse Hewlett Hewlett's +Hokkaido Holland Holland's Hollander @@ -412,6 +497,9 @@ Hollanders Hollands Honda Honda's +Honduras +Honshu +Hungary Hz I'd I'll @@ -419,7 +507,14 @@ I'm I've IBM IBM's +Iceland +Idaho IEEE +Indonesia +Iowa +Iraq +Islamic +Italy ITCorp ITCorp's ITcorp @@ -449,6 +544,7 @@ Israelis Italian Italian's Italians +Jamaica James Januaries January @@ -459,10 +555,12 @@ Japanese Japanese's Jefferson Jefferson's +Jersey Jill Jill's Johnnie Johnnie's +Jordan Jr Julie Julie's @@ -473,6 +571,12 @@ Julys June June's Junes +Jura +Kansas +Kazakhstan +Kentucky +Kenya +Kiribati Klein Klein's Kleinrock @@ -481,8 +585,16 @@ Kline Kline's Knuth Knuth's +Korea Kuenning Kuenning's +Kuwait +Kyrgyzstan +Kyushu +Lao +Laos +Latvia +Lebanon LED's LEDs LaTeX @@ -496,12 +608,36 @@ Latin's Laurie Laurie's Lenten +Lesotho +Liberia +Libya +Liechtenstein Linux +Lithuania Liz Liz's +Louisiana +Lucerne +Luxembourg Lyle Lyle's +Macedonia +Madagascar +Maine +Malawi +Malaysia +Maldives +Mali +Malta +Marshall +Mauritania +Mauritius +Mecklenburg-Vorpommern +Mexico MHz +Micronesia +Mississippi +Missouri MIT MIT's MacDraw @@ -551,18 +687,24 @@ Microsoft's Midwest Minnesota Minnesota's +Moldova +Monaco Monday Monday's Mondays +Mongolia Montana Montana's Montanan Montanan's +Montenegro +Morocco Moslem Moslem's Moslems Motorola Motorola's +Mozambique Mr Mrs Ms @@ -574,6 +716,11 @@ Munsey's Muslim Muslim's Muslims +Myanmar +Namibia +Nauru +Neuchâtel +Nevada NFS Nazi Nazi's @@ -590,13 +737,24 @@ Nepal Nepal's Netherlands Newtonian +Nicaragua +Nidwald +Nidwalden +Niger +Nigeria +Norway November November's Novembers +Obwald +Obwalden OEM OEM's OEMS OK +Okinawa +Oman +Oregon OS OS's October @@ -613,6 +771,11 @@ Oklahoma's Oklahoman Oklahoman's Oliver's +Pakistan +Palau +Palestine +Panama +Paraguay PC PC's PCs @@ -625,10 +788,12 @@ Pascal Pascal's Pennsylvania Pennsylvania's +Peru Peter's Petkiewicz Petkiewicz's PhD +Philippines Planck Planck's Poland @@ -636,15 +801,21 @@ Poland's Popek Popek's Popeks +Portugal Prime's Prokofiev Prokofiev's QA +Qatar RCS +Rhine-Westphalia +Rhineland-Palatinate ROM +Romania RSX Redford Redford's +Rhode Rick Rick's Ritchie @@ -660,10 +831,27 @@ Romans Roy Roy's Rubens +Russia Russian Russian's Russians +Rwanda +Saarland +Salzburg +Samoa +Saxony +Saxony-Anhalt SCCS +Schaffhausen +Schaffhouse +Schleswig-Holstein +Schwyz +Senegal +Serbia +Seychelles +Shikoku +Slovakia +Slovenia SMTP Sally's Salz @@ -688,6 +876,10 @@ Silverstein Silverstein's Singapore Singapore's +Soleure +Solomon +Solothurn +Somalia Spafford Spafford's Spain @@ -698,10 +890,36 @@ Spencer Spencer's Spuds Sr +Styria +Sudan Sunday Sunday's Sundays +Suriname +Sweden +Switzerland +Syria +Syrian +Taiwan +Tajikistan +Tanzania TCP +Tessin +Thailand +Thurgau +Thurgovia +Thuringia +Ticino +Timor +Timor-Leste +Tobago +Togo +Tonga +Trinidad +Tunisia +Turkey +Turkmenistan +Tuvalu TV's TeX TeX's @@ -726,9 +944,14 @@ Tuesday's Tuesdays Turing Turing's +Tyrol UART UCLA +Uganda +Ukraine UNIX's +Uri +Uruguay USC USC's USG @@ -743,8 +966,17 @@ Usenix Usenix's Utah Utah's +Uzbekistan +Valais +Vanuatu VAR +Vatican +Vaud VCR +Venezuela +Vermont +Vienna +Vietnam VMS VMS's Vanessa @@ -755,6 +987,9 @@ Ventura Ventura's Virginia Virginia's +Vorarlberg +Wales +Wallis Warnock Warnock's Washington @@ -770,6 +1005,8 @@ Willisson Willisson's Wilson Wilson's +Wisconsin +Wyoming Xenix Xenix's Xeroxed @@ -777,6 +1014,7 @@ Xeroxes Xeroxing Yamaha Yamaha's +Yemen Yentl Yentl's York @@ -784,8 +1022,12 @@ York's Yorker Yorkers Yorks +Zambia Zealand Zealand's +Zimbabwe +Zoug +Zug Zulu Zulu's Zulus @@ -1323,11 +1565,11 @@ acing acknowledge acknowledged acknowledgedly -acknowledgement acknowledger acknowledgers acknowledges acknowledging +acknowledgment acme acne acned @@ -14795,6 +15037,7 @@ downfallen downier downing download +downloaded downloading downloads downplay @@ -26757,7 +27000,6 @@ met meta metacircular metacircularity -metadata metal metal's metalanguage diff --git a/org.eclipse.jdt.ui/dictionaries/en_US.dictionary b/org.eclipse.jdt.ui/dictionaries/en_US.dictionary index 068753a4..5fa9e1bf 100644 --- a/org.eclipse.jdt.ui/dictionaries/en_US.dictionary +++ b/org.eclipse.jdt.ui/dictionaries/en_US.dictionary @@ -1,5 +1,10 @@ +Aargau ACM ANSI +Antigua +Appenzell +Argovia +Armenia ASAP ASCII ATM's @@ -175,6 +180,28 @@ Austria's Austrian Austrian's Ave +Azerbaijan +Baden-Württemberg +Bahamas +Bahrain +Barbuda +Basel-City +Basel-Country +Basel-Landschaft +Basel-Stadt +Basle-City +Basle-Country +Bavaria +Belarus +Belize +Benin +Bern +Berne +Bhutan +Bosnia +Brandenburg +Bremen +Brunei BSD Babel Babel's @@ -269,10 +296,25 @@ Briton's Britons Buehring Buehring's +Bulgaria +Burgenland +Burundi +califate +califates +Cambodia +Cameroon +Carinthia CDC CDC's CEO +Chad +Chile +China CMOS +Colombia +Comoros +Congo +Connecticut CPU CPU's CPUs @@ -308,12 +350,19 @@ Comdex's Cray Cray's Crays +Croatia +Cuba Cupertino Cupertino's +Cyprus +Czech Czechoslovakian +Dakota DARPA DARPA's DECNET +Djibouti +Dominica DOS Dan Dan's @@ -333,33 +382,45 @@ Dijkstra's Diophantine Dylan Dylan's +Ecuador EDP EGA EGA's Edsger Edsger's +Egypt Ellen Ellen's Elvis Elvis's +emirate +emirates English English's +Eritrea Erlang Erlang's +Estonia +Eswatini Ethernet Ethernet's Ethernets +Ethiopia Europe Europe's European European's Europeans +federate +federated FIFO Fairbanks Februaries February February's Felder +Fiji +Finland Florida Florida's Fortran @@ -371,9 +432,17 @@ France's Frances French French's +Fribourg +Friburg Friday Friday's Fridays +Gabon +Gambia +Geneva +Georgia +Ghana +Glarus GPSS Galvin Galvin's @@ -396,15 +465,31 @@ Git Godzilla Godzilla's Gothic +Graubünden +Greece Greek Greek's Greeks Greg Greg's +Grenada +Grisons +Guam +Guatemala +Guinea +Guinea-Bissau +Guyana +Haiti +Hamburg +Hampshire +Hawaii Heinlein Heinlein's +Herzegovina +Hesse Hewlett Hewlett's +Hokkaido Holland Holland's Hollander @@ -412,6 +497,9 @@ Hollanders Hollands Honda Honda's +Honduras +Honshu +Hungary Hz I'd I'll @@ -419,7 +507,14 @@ I'm I've IBM IBM's +Iceland +Idaho IEEE +Indonesia +Iowa +Iraq +Islamic +Italy ITCorp ITCorp's ITcorp @@ -449,6 +544,7 @@ Israelis Italian Italian's Italians +Jamaica James Januaries January @@ -459,10 +555,12 @@ Japanese Japanese's Jefferson Jefferson's +Jersey Jill Jill's Johnnie Johnnie's +Jordan Jr Julie Julie's @@ -473,6 +571,12 @@ Julys June June's Junes +Jura +Kansas +Kazakhstan +Kentucky +Kenya +Kiribati Klein Klein's Kleinrock @@ -481,8 +585,16 @@ Kline Kline's Knuth Knuth's +Korea Kuenning Kuenning's +Kuwait +Kyrgyzstan +Kyushu +Lao +Laos +Latvia +Lebanon LED's LEDs LaTeX @@ -496,12 +608,36 @@ Latin's Laurie Laurie's Lenten +Lesotho +Liberia +Libya +Liechtenstein Linux +Lithuania Liz Liz's +Louisiana +Lucerne +Luxembourg Lyle Lyle's +Macedonia +Madagascar +Maine +Malawi +Malaysia +Maldives +Mali +Malta +Marshall +Mauritania +Mauritius +Mecklenburg-Vorpommern +Mexico MHz +Micronesia +Mississippi +Missouri MIT MIT's MacDraw @@ -551,18 +687,24 @@ Microsoft's Midwest Minnesota Minnesota's +Moldova +Monaco Monday Monday's Mondays +Mongolia Montana Montana's Montanan Montanan's +Montenegro +Morocco Moslem Moslem's Moslems Motorola Motorola's +Mozambique Mr Mrs Ms @@ -574,6 +716,11 @@ Munsey's Muslim Muslim's Muslims +Myanmar +Namibia +Nauru +Neuchâtel +Nevada NFS Nazi Nazi's @@ -590,13 +737,24 @@ Nepal Nepal's Netherlands Newtonian +Nicaragua +Nidwald +Nidwalden +Niger +Nigeria +Norway November November's Novembers +Obwald +Obwalden OEM OEM's OEMS OK +Okinawa +Oman +Oregon OS OS's October @@ -613,6 +771,11 @@ Oklahoma's Oklahoman Oklahoman's Oliver's +Pakistan +Palau +Palestine +Panama +Paraguay PC PC's PCs @@ -625,10 +788,12 @@ Pascal Pascal's Pennsylvania Pennsylvania's +Peru Peter's Petkiewicz Petkiewicz's PhD +Philippines Planck Planck's Poland @@ -636,15 +801,21 @@ Poland's Popek Popek's Popeks +Portugal Prime's Prokofiev Prokofiev's QA +Qatar RCS +Rhine-Westphalia +Rhineland-Palatinate ROM +Romania RSX Redford Redford's +Rhode Rick Rick's Ritchie @@ -660,10 +831,27 @@ Romans Roy Roy's Rubens +Russia Russian Russian's Russians +Rwanda +Saarland +Salzburg +Samoa +Saxony +Saxony-Anhalt SCCS +Schaffhausen +Schaffhouse +Schleswig-Holstein +Schwyz +Senegal +Serbia +Seychelles +Shikoku +Slovakia +Slovenia SMTP Sally's Salz @@ -688,6 +876,10 @@ Silverstein Silverstein's Singapore Singapore's +Soleure +Solomon +Solothurn +Somalia Spafford Spafford's Spain @@ -698,10 +890,36 @@ Spencer Spencer's Spuds Sr +Styria +Sudan Sunday Sunday's Sundays +Suriname +Sweden +Switzerland +Syria +Syrian +Taiwan +Tajikistan +Tanzania TCP +Tessin +Thailand +Thurgau +Thurgovia +Thuringia +Ticino +Timor +Timor-Leste +Tobago +Togo +Tonga +Trinidad +Tunisia +Turkey +Turkmenistan +Tuvalu TV's TeX TeX's @@ -726,9 +944,14 @@ Tuesday's Tuesdays Turing Turing's +Tyrol UART UCLA +Uganda +Ukraine UNIX's +Uri +Uruguay USC USC's USG @@ -743,8 +966,17 @@ Usenix Usenix's Utah Utah's +Uzbekistan +Valais +Vanuatu VAR +Vatican +Vaud VCR +Venezuela +Vermont +Vienna +Vietnam VMS VMS's Vanessa @@ -755,6 +987,9 @@ Ventura Ventura's Virginia Virginia's +Vorarlberg +Wales +Wallis Warnock Warnock's Washington @@ -770,6 +1005,8 @@ Willisson Willisson's Wilson Wilson's +Wisconsin +Wyoming Xenix Xenix's Xeroxed @@ -777,6 +1014,7 @@ Xeroxes Xeroxing Yamaha Yamaha's +Yemen Yentl Yentl's York @@ -784,8 +1022,12 @@ York's Yorker Yorkers Yorks +Zambia Zealand Zealand's +Zimbabwe +Zoug +Zug Zulu Zulu's Zulus @@ -14794,6 +15036,7 @@ downfallen downier downing download +downloaded downloading downloads downplay diff --git a/org.eclipse.jdt.ui/forceQualifierUpdate.txt b/org.eclipse.jdt.ui/forceQualifierUpdate.txt index 7294d915..9a354e0b 100644 --- a/org.eclipse.jdt.ui/forceQualifierUpdate.txt +++ b/org.eclipse.jdt.ui/forceQualifierUpdate.txt @@ -8,4 +8,8 @@ Bug 566471 - I20200828-0150 - Comparator Errors Found Bug 566668 - Comparator errors in I20200904-0210 Comparator errors in I20201204-0340 Bug 574012 - Comparator errors in I20210604-0350 -Bug 574522 - 4.21 I-Build: I20210628-1800 - Comparator Errors Found \ No newline at end of file +Bug 574522 - 4.21 I-Build: I20210628-1800 - Comparator Errors Found +Bug 577483 - Comparator errors in I20211126-0230 +Bug 579126 - 4.24 I-Build: I20220307-0340 - Comparator Errors Found +https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/pull/439 - Update ICU4J to version 71.1 +Comparator errors in I20220902-1100 diff --git a/org.eclipse.jdt.ui/plugin.xml b/org.eclipse.jdt.ui/plugin.xml index 8de7bff2..ff06bd40 100644 --- a/org.eclipse.jdt.ui/plugin.xml +++ b/org.eclipse.jdt.ui/plugin.xml @@ -125,6 +125,7 @@ + %java.perspective.description @@ -7100,10 +7102,14 @@ id="org.eclipse.jdt.ui.cleanup.loop" runAfter="org.eclipse.jdt.ui.cleanup.control_statements"> + + runAfter="org.eclipse.jdt.ui.cleanup.toolscleanup"> - + + + runAfter="org.eclipse.jdt.ui.cleanup.stringconcattotextblock"> + + + + diff --git a/org.eclipse.jdt.ui/pom.xml b/org.eclipse.jdt.ui/pom.xml index b1c5e3d0..aa697929 100644 --- a/org.eclipse.jdt.ui/pom.xml +++ b/org.eclipse.jdt.ui/pom.xml @@ -1,6 +1,6 @@ - compare-attached-artifacts-with-release - - compare-version-with-baselines - - - true - - - - -
    -
    diff --git a/tests-pom/pom.xml b/tests-pom/pom.xml index 5d8f3b74..b2a0fef7 100644 --- a/tests-pom/pom.xml +++ b/tests-pom/pom.xml @@ -14,7 +14,7 @@ eclipse.jdt.ui eclipse.jdt.ui - 4.21.0-SNAPSHOT + 4.26.0-SNAPSHOT tests-pom pom