diff --git a/org.ntlab.refactoring.decouplingClasses/.classpath b/org.ntlab.refactoring.decouplingClasses/.classpath new file mode 100644 index 0000000..b1dabee --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.ntlab.refactoring.decouplingClasses/.project b/org.ntlab.refactoring.decouplingClasses/.project new file mode 100644 index 0000000..0964d6e --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/.project @@ -0,0 +1,28 @@ + + + org.ntlab.refactoring.decouplingClasses + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.ntlab.refactoring.decouplingClasses/.settings/org.eclipse.jdt.core.prefs b/org.ntlab.refactoring.decouplingClasses/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..11f6e46 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/org.ntlab.refactoring.decouplingClasses/META-INF/MANIFEST.MF b/org.ntlab.refactoring.decouplingClasses/META-INF/MANIFEST.MF new file mode 100644 index 0000000..ea34033 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/META-INF/MANIFEST.MF @@ -0,0 +1,24 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Refactor +Bundle-SymbolicName: org.ntlab.refactoring.decouplingClasses;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.ntlab.refactoring.decouplingClasses.DecoupleClassesRefactoringPlugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.ui.ide;bundle-version="3.10.0", + org.eclipse.core.resources, + org.eclipse.jdt.core, + org.eclipse.ui.workbench, + org.eclipse.jdt.ui, + org.eclipse.ltk.core.refactoring, + org.eclipse.jdt.core.manipulation +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-ActivationPolicy: lazy +Import-Package: org.eclipse.core.filesystem, + org.eclipse.jdt.internal.ui.actions, + org.eclipse.jface.text, + org.eclipse.jface.text.source, + org.eclipse.ltk.ui.refactoring, + org.eclipse.text.edits, + org.eclipse.ui.texteditor diff --git a/org.ntlab.refactoring.decouplingClasses/build.properties b/org.ntlab.refactoring.decouplingClasses/build.properties new file mode 100644 index 0000000..6f20375 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/Classes.txt b/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/Classes.txt new file mode 100644 index 0000000..55da286 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/Classes.txt @@ -0,0 +1,10 @@ +RefactoringContribution + +org.eclipse.ltk.core.refactoring.Refactoring +org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring + +org.eclipse.ltk.core.refactoring.RefactoringDescriptor + +org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant + +org.eclipse.ltk.core.refactoring.Change diff --git a/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/class.uxf b/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/class.uxf new file mode 100644 index 0000000..b887cf0 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/class.uxf @@ -0,0 +1,613 @@ + + + 8 + + com.umlet.element.Relation + + 1152 + 480 + 40 + 80 + + lt=<<. + 24;24;24;64 + + + com.umlet.element.Interface + + 1056 + 488 + 240 + 72 + + org.eclipse.jdt.internal.corext.refactoring.tagging +IDelegateUpdating + + + + com.umlet.element.Relation + + 1792 + 200 + 208 + 88 + + lt=<<- + 192;24;24;72 + + + com.umlet.element.Interface + + 1904 + 112 + 160 + 72 + + java.lang +Comparable + + + + com.umlet.element.Class + + 24 + 216 + 280 + 256 + + /org.eclipse.ltk.core.refactoring.Change/ +-- +-fParent: Change +-fIsEnabled: boolean +-- +#Change() ++getDescriptor(): ChangeDescriptor +/+getName(): String/ ++isEnabled(): boolean ++setEnabled(enabled: boolean): void ++setEnabledShallow(enabled: boolean): void ++getParent(): Change +~setParent(parent: Change): void +/+initializeValidationData(pm: IProgressMonitor): void/ +/+isValid(pm: IProgressMonitor): RefactoringStatus/ +/+perform(pm: IProgressMonitor): Change/ ++dispose(): void +/+getModifiedElement(): Object/ ++getAffectedObjects(): Object[] ++getAdapter(adapter: Class): Object + + + + com.umlet.element.Interface + + 576 + 120 + 176 + 72 + + org.eclipse.core.runtime.IAdaptable +-- ++getAdapter(adapter: Class<T>): T + + + + com.umlet.element.Class + + 2448 + 304 + 336 + 80 + + org.eclipse.ltk.core.refactoring.participants +RenameParticipant +-- + +-- ++getArguments(): RenameArguments +#initialize(arguments: RefactoringArguments): void + + + + com.umlet.element.Class + + 928 + 272 + 264 + 56 + + /org.eclipse.ltk.ui.refactoring/ +/RefactoringWizard/ +-- + +-- + + + + + com.umlet.element.Relation + + 624 + 744 + 40 + 72 + + lt=<<- + 24;24;24;56 + + + com.umlet.element.Class + + 1648 + 272 + 352 + 56 + + org.eclipse.ltk.core.refactoring.resource +RenameResourceDescriptor +-- + +-- + + + + + com.umlet.element.Relation + + 2160 + 304 + 40 + 72 + + lt=<<- + 24;24;24;56 + + + com.umlet.element.Class + + 960 + 184 + 192 + 56 + + /org.eclipse.jface.wizard/ +/Wizard/ +-- + +-- + + + + + com.umlet.element.Relation + + 640 + 112 + 40 + 88 + + lt=<<. + 24;24;24;72 + + + com.umlet.element.Class + + 496 + 280 + 352 + 176 + + /org.eclipse.ltk.core.refactoring.Refactoring/ +-- +-fValidationContext: Object +-- ++setValidationContext(context: Object): void ++getValidationContext(): Object +/+getName(): String/ ++getRefactoringTickProvider(): RefactoringTickProvider +#doGetRefactoringTickProvider(): RefactoringTickProvider ++checkAllConditions(pm: IProgressMonitor): RefactoringStatus +/+checkInitialConditions(pm: IProgressMonitor): RefactoringStatus/ +/+checkFinalConditions(pm: IProgressMonitor): RefactoringStatus/ +/+createChange(pm: IProgressMonitor): Change/ ++getadapter(adapter: Class): Object ++toString(): String + + + + com.umlet.element.Class + + 896 + 368 + 328 + 80 + + org.eclipse.ltk.ui.refactoring.resource +RenameResourceWizard +-- + +-- +RenameResourceWizard(resource: IResource) +#addUserInputPages(): void + + + + com.umlet.element.Relation + + 1032 + 216 + 40 + 72 + + lt=<<- + 24;24;24;56 + + + com.umlet.element.Relation + + 2592 + 256 + 40 + 64 + + lt=<<- + 24;24;24;48 + + + com.umlet.element.Class + + 0 + 680 + 336 + 128 + + /org.eclipse.ltk.core.refactoring.resource.RenameResourceChange/ +-- + +-- +RenameResourceChange(resourcePath: IPath, newName: String) ++getDescriptor(): ChangeDescriptor +#getModifiedResource(): IResource ++getName(): String ++getNewName(): String ++perform(pm: IProgressMonitor): Change ++setDescriptor(descriptor: ChangeDescriptor): void + + + + + com.umlet.element.Class + + 888 + 544 + 560 + 256 + + org.eclipse.jdt.internal.corext.refactoring.code +IntroduceParameterRefactoring +-- +-fSourceCU: ICompilationUnit +-fSelectionStart: int +-fSelectionLength +-fMethod: IMethod +-fChandeSignatureRefactoring: Refactoring +-fChangeSignatureProcessor: ChangeSignatureProcessor +-fParameter: ParameterInfo +-fParameterName: String +-fArguments: JavaRefactoringArguments +-fSelectedExpression: Expression +-fExcludedParameterNames: String[] +-- ++IntroduceParameterRefactoring(unit: ICompilationUnit, selectionStart: int, selectionLength: int) ++IntroduceParameterRefactoring(arguments: JavaRefactoringArguments, status: RefactoringStatus) + + + + + com.umlet.element.Relation + + 128 + 600 + 40 + 96 + + lt=<<- + 24;24;24;80 + + + com.umlet.element.Class + + 488 + 512 + 368 + 256 + + /org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring/ +-- +-fProcessor: RefactoringProcessor +-fParticipants: List<RefactoringParticipant> +-fPreChangeParticipants: List<RefactoringParticipant> +-fTextChangeMap: Map<Object, TextChange> +/-EMPTY_PARTICIPANTS: List<RefactoringParticipant>/ +-- ++ProcessorBasedRefactoring(processor: RefactoringProcessor) ++getProcessor(): RefactoringProcessor ++setProcessor(processor: RefactoringProcessor): void ++isApplicable(): boolean ++getName(): String ++checkInitialConditions(pm: IProgressMonitor): RefactoringStatus ++checkFinalConditions(pm: IProgressMonitor): RefactoringStatus ++createChange(pm: IProgressMonitor): Change ++getTextChange(element: Object): TextChange ++getAdapter(clazz: Class): Object ++toString(): String +- +- +- + + + + com.umlet.element.Relation + + 136 + 120 + 40 + 112 + + lt=<<. + 24;24;24;96 + + + com.umlet.element.Interface + + 976 + 128 + 160 + 72 + + org.eclipse.jface.wizard.IWizard + + + + com.umlet.element.Class + + 2016 + 272 + 352 + 56 + + /org.eclipse.jdt.core.refactoring.descriptors/ +/JavaRefactoringDescriptor/ +-- + +-- + + + + + com.umlet.element.Class + + 0 + 520 + 328 + 104 + + /org.eclipse.ltk.core.refactoring.resource.ResourceChange/ +-- + +-- ++getModifiedElement(): Object +/#getModifiedResource(): IResource/ ++initializeValidationData(pm: IProgressMonitor): void ++isValid(pm: IProgressMonitor): RefactoringStatus ++setValidationMethod(validationMethod: int): void + + + + com.umlet.element.Relation + + 640 + 224 + 40 + 72 + + lt=<<- + 24;24;24;56 + + + com.umlet.element.Relation + + 1032 + 120 + 40 + 80 + + lt=<<. + 24;24;24;64 + + + com.umlet.element.Relation + + 1960 + 200 + 160 + 88 + + lt=<<- + 24;24;144;72 + + + com.umlet.element.Relation + + 128 + 448 + 40 + 88 + + lt=<<- + 24;24;24;72 + + + com.umlet.element.Relation + + 632 + 432 + 448 + 128 + + lt=<<- + 24;24;432;112 + + + com.umlet.element.Interface + + 72 + 128 + 176 + 72 + + org.eclipse.core.runtime.IAdaptable +-- ++getAdapter(adapter: Class<T>): T + + + + com.umlet.element.Relation + + 1960 + 104 + 40 + 80 + + lt=<<. + 24;24;24;64 + + + com.umlet.element.Relation + + 632 + 432 + 40 + 96 + + lt=<<- + 24;24;24;80 + + + com.umlet.element.Class + + 1848 + 168 + 272 + 56 + + /org.eclipse.ltk.core.refactoring/ +/RefactoringDescriptor/ +-- + +-- + + + + + com.umlet.element.Class + + 552 + 184 + 216 + 64 + + /org.eclipse.core.runtime.PlatformObject/ +-- +-fProcessor: RenameProcessor +-- ++PlatformObject() ++getAdapter(adapter: Class<T>): T + + + + com.umlet.element.Class + + 488 + 800 + 336 + 64 + + org.eclipse.ltk.core.refactoring.participants.RenameRefactoring +-- +-fProcessor: RenameProcessor +-- ++RenameRefactoring(processor: RenameProcessor) ++getProcessor(): RefactoringProcessor + + + + com.umlet.element.Class + + 2408 + 112 + 536 + 168 + + /org.eclipse.ltk.core.refactoring.participants/ +/RefactoringParticipant/ +-- + +-- +/+checkConditions(pm: IProgressMonitor, context: CheckConditionsContext): RefactoringStatus/ +/+createChange(pm: IprogressMonitor): Change/ ++createPreChbange(pm: IProgressMonitor): Change +/+getName(): String/ ++getProcessor(): RefactoringProcessor ++getTextChange(element: Object): TextChange +/#initialize(element: Object): boolean/ +/#initialize(arguments: RefactoringArguments): boolean/ ++initialize(processor: RefactoringProcessor, element: Object, arguments: RefactoringArguments): boolean + + + + com.umlet.element.Relation + + 1032 + 304 + 40 + 80 + + lt=<<- + 24;24;24;64 + + + com.umlet.element.Class + + 1288 + 128 + 384 + 104 + + org.eclipse.ltk.ui.refactoring +RefactoringWizardOpenOperation +-- + +-- ++RefactoringWizardOpenOperation(wizard: RefactoringWizard) ++getInitialConditionCheckingStatus(): RefactoringStatus ++run(parent: Shell, dialogTitle: String): int ++run(parent: Shell, dialogTitle: String, context: IRunnableContext): int + + + + com.umlet.element.Class + + 2016 + 360 + 352 + 56 + + org.eclipse.jdt.core.refactoring.descriptors +ChangeMethodSignatureDescriptor +-- + +-- + + + + diff --git a/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/introduceParameterObject.uxf b/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/introduceParameterObject.uxf new file mode 100644 index 0000000..38094da --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/introduceParameterObject.uxf @@ -0,0 +1,558 @@ + + + 9 + + com.baselet.element.old.element.Relation + + 1701 + 531 + 89 + 44 + + lt=<<<- + 27;27;72;27 + + + com.baselet.element.old.element.Class + + 2304 + 252 + 369 + 99 + + org.eclipse.ltk.core.refactoring.participants. +ProcessorBasedRefactoring +-- + +-- ++ProcessorBasedRefactoring(processor: RefactoringProcessor) ++createChange(pm: IProgressMonitor): Change + + + + com.baselet.element.old.element.Class + + 2412 + 639 + 351 + 207 + + org.eclipse.jdt.core.refactoring.descriptors. +IntroduceParameterObjectDescriptor +-- +-fClassName: String +-fDelegate: boolean +-fDeprecateDelegate: boolean +-fGetters: boolean +-fMethod: IMethod +-fPackageName: String +-fParameterName: String +-fSetters: boolean +-fTopLevel: boolean +-- ++IntroduceParameterObjectDescriptor() + + + + com.baselet.element.old.element.Class + + 2412 + 504 + 351 + 99 + + /org.eclipse.jdt.core.refactoring.descriptors./ +/JavaRefactoringDescriptor/ +-- + +-- +#JavaRefactoringDescriptor(id: String) ++createRefactoring(status: RefactoringStatus): Refactoring + + + + com.baselet.element.old.element.Class + + 963 + 54 + 189 + 81 + + /org.eclipse.ltk.ui.refactoring./ +/RefactoringWizard/ +-- + +-- +/#addUserInputPages(): void/ + + + + com.baselet.element.old.element.Class + + 1773 + 522 + 576 + 117 + + org.eclipse.jdt.internal.corext.refactoring.structure. +IntroduceParameterObjectProcessor +-- + +-- ++IntroduceParameterObjectProcessor(descriptor: IntroduceParameterObjectDescriptor) ++checkFinalConditions(pm: IProgressMonitor, context: CheckConditionsContext): RefactoringStatus ++checkInitialConditions(pm: IProgressMonitor): RefactoringStatus + + + + com.baselet.element.old.element.Relation + + 2736 + 711 + 161 + 63 + + lt=<<<- +fParameters +m2=* + 27;45;144;45 + + + com.baselet.element.old.element.Class + + 1431 + 504 + 297 + 99 + + org.eclipse.jdt.internal.ui.refactoring. +IntrodudeParameterObjectWizard$ +IntroduceParameterObjectInputPage +-- +-fProcessor: IntroduceParameterObjectProcessor +-- ++createControl(parent: Composite): void + + + + com.baselet.element.old.element.Relation + + 2421 + 189 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Class + + 0 + 153 + 396 + 90 + + org.eclipse.jdt.internal.corext.refactoring. +RefactoringExecutionStarter +-- + +-- +_+startIntroduceParameterObject(method: IMethod, shell: Shell): void_ + + + + com.baselet.element.old.element.Relation + + 2142 + 261 + 179 + 44 + + lt=<<<- + 27;27;162;27 + + + com.baselet.element.old.element.Relation + + 2124 + 441 + 62 + 62 + + + 27;27;45;45 + + + com.baselet.element.old.element.Relation + + 1026 + 108 + 44 + 98 + + lt=<<- + 27;27;27;81 + + + com.baselet.element.old.element.Class + + 2304 + 144 + 297 + 72 + + /org.eclipse.ltk.core.refactoring/ +/Refactoring/ +-- + +-- + + + + + com.baselet.element.old.element.Class + + 1809 + 252 + 360 + 99 + + /org.eclipse.ltk.core.refactoring.participants./ +/RefactoringProcessor/ +-- + +-- +/+createChange(pm: IProgressMonitor): Change/ ++setRefactoring(refactoringProcessorBasedRefactoring): void + + + + com.baselet.element.old.element.Note + + 2007 + 711 + 243 + 81 + + Refer to +ParameterObjectFactory.class +DelegateCreator.class +ASTRewrite +for how to create and replace source. + + + + com.baselet.element.old.element.Relation + + 1548 + 432 + 44 + 89 + + lt=<<- + 27;27;27;72 + + + com.baselet.element.old.element.Relation + + 1935 + 324 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Class + + 1431 + 387 + 297 + 72 + + /org.eclipse.ltk.ui.refactoring./ +/UserInputWizardPage/ +-- + +-- + + + + + com.baselet.element.old.element.Class + + 1818 + 387 + 333 + 99 + + org.eclipse.jdt.internal.corext.refactoring.structure. +ChangeSignatureProcessor +-- +-fBaseCuRewrite: CompilationUnitRewrite +-fChangeManager: TextChangeManager +-- ++createChange(pm: IProgressMonitor): Change + + + + com.baselet.element.old.element.Relation + + 2556 + 441 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Class + + 1431 + 270 + 297 + 72 + + /org.eclipse.ltk.ui.refactoring./ +/RefactoringWizardPage/ +-- + +-- + + + + + com.baselet.element.old.element.Class + + 1431 + 153 + 297 + 72 + + /org.eclipse.jface.wizard./ +/WizardPage/ +-- + +-- + + + + + com.baselet.element.old.element.Relation + + 2142 + 261 + 179 + 63 + + lt=<<<- +fProcessor + 162;45;27;45 + + + com.baselet.element.old.element.Class + + 2880 + 693 + 252 + 117 + + org.eclipse.jdt.core.refactoring.descriptors. +IntroduceParameterObjectDescriptor$ +Parameter +-- +-fCreateField: boolean +-fFieldName: String +-fIndex: int +-- + + + + + com.baselet.element.old.element.Relation + + 1548 + 198 + 44 + 89 + + lt=<<- + 27;27;27;72 + + + com.baselet.element.old.element.Relation + + 1935 + 459 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Class + + 2412 + 387 + 351 + 81 + + /org.eclipse.ltk.core.refactoring./ +/RefactoringDescriptor/ +-- + +-- +/+createRefactoring(status: RefactoringStatus): Refactoring/ + + + + com.baselet.element.old.element.Relation + + 1548 + 63 + 44 + 107 + + lt=<<. + 27;27;27;90 + + + com.baselet.element.old.element.Relation + + 2556 + 576 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Note + + 2169 + 477 + 234 + 27 + + DynamicValidationRefactoringChange + + + + com.baselet.element.old.element.Relation + + 1125 + 54 + 458 + 44 + + lt=<<<- + 27;27;441;27 + + + com.baselet.element.old.element.Interface + + 1503 + 72 + 144 + 81 + + org.eclipse.jface.wizard. +IWizardPage + + + + + com.baselet.element.old.element.Note + + 1944 + 801 + 333 + 45 + + Processor pattern: IntroduceParameterObjectProcessor +Non processor pattern: ExtractClassRefactoring + + + + com.baselet.element.old.element.Class + + 756 + 189 + 630 + 99 + + org.eclipse.jdt.internal.ui.refactoring. +IntroduceParameterObjectWizard +-- + +-- ++IntrodeceParameterObjectWizard(processor: IntroduceParameterObjectProcessor, refactoring: Refactoring) +#addUserInputPages(): void + + + + com.baselet.element.old.element.Relation + + 1548 + 315 + 44 + 89 + + lt=<<- + 27;27;27;72 + + + com.baselet.element.old.element.Class + + 9 + 0 + 369 + 117 + + org.eclipse.jdt.internal.ui.actions. +IntroduceParameterObjectAction +-- + +-- ++run(selection: ITextSelection): void +-run(method: IMethod): void +-getSingleSelectedMethod(selection: ITextSelection): IMethod + + + + + com.baselet.element.old.element.Class + + 459 + 27 + 405 + 126 + + org.eclipse.ltk.ui.refactoring +RefactoringWizardOpenOperation +-- + +-- ++RefactoringWizardOpenOperation(wizard: RefactoringWizard) ++getInitialConditionCheckingStatus(): RefactoringStatus ++run(parent: Shell, dialogTitle: String): int ++run(parent: Shell, dialogTitle: String, context: IRunnableContext): int + + + + com.baselet.element.old.element.Relation + + 837 + 72 + 143 + 44 + + lt=<<<- + 27;27;126;27 + + diff --git a/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/jdt.core.uxf b/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/jdt.core.uxf new file mode 100644 index 0000000..0df5c73 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/investigationOfAutomatedRefactoring/jdt.core.uxf @@ -0,0 +1,213 @@ + + + 10 + + com.umlet.element.Interface + + 270 + 530 + 120 + 110 + + org.eclipse.jdt.core +ICompilationUnit + + + + com.umlet.element.Relation + + 630 + 470 + 50 + 150 + + lt=<<. + 30;30;30;130 + + + com.umlet.element.Interface + + 70 + 530 + 120 + 110 + + org.eclipse.jdt.core +IClassFile + + + + com.umlet.element.Relation + + 100 + 390 + 140 + 160 + + lt=<<- + 120;30;120;90;30;90;30;140 + + + com.umlet.element.Relation + + 630 + 390 + 50 + 110 + + lt=<<- + 30;30;30;90 + + + com.umlet.element.Relation + + 100 + 520 + 50 + 140 + + lt=<<. + 30;30;30;120 + + + com.umlet.element.Relation + + 190 + 390 + 160 + 160 + + lt=<<- + 30;30;30;90;140;90;140;140 + + + com.umlet.element.Interface + + 390 + 170 + 120 + 110 + + org.eclipse.jdt.core +IJavaElement + + + + com.umlet.element.Relation + + 190 + 160 + 280 + 260 + + lt=<<- + 260;30;260;200;30;200;30;240 + + + com.umlet.element.Class + + 570 + 600 + 180 + 80 + + org.eclipse.jdt.internal.core +SourceMethod +-- + +-- + + + + + com.umlet.element.Class + + 240 + 640 + 180 + 80 + + org.eclipse.jdt.internal.core +CompilationUnit +-- + +-- + + + + + com.umlet.element.Relation + + 300 + 520 + 50 + 140 + + lt=<<. + 30;30;30;120 + + + com.umlet.element.Class + + 40 + 640 + 180 + 80 + + org.eclipse.jdt.internal.core +ClassFile +-- + +-- + + + + + com.umlet.element.Interface + + 160 + 400 + 120 + 110 + + org.eclipse.jdt.core +ITypeRoot + + + + com.umlet.element.Interface + + 600 + 400 + 120 + 110 + + org.eclipse.jdt.core +IMember +-- + + + + com.umlet.element.Relation + + 420 + 160 + 260 + 260 + + lt=<<- + 30;30;30;200;240;200;240;240 + + + com.umlet.element.Interface + + 570 + 480 + 180 + 110 + + org.eclipse.jdt.core +IMethod + + + diff --git a/org.ntlab.refactoring.decouplingClasses/doc/plugin UI.pptx b/org.ntlab.refactoring.decouplingClasses/doc/plugin UI.pptx new file mode 100644 index 0000000..975e33f --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/plugin UI.pptx Binary files differ diff --git a/org.ntlab.refactoring.decouplingClasses/doc/research of automated refactoring/Introduce Parameter Object.uxf b/org.ntlab.refactoring.decouplingClasses/doc/research of automated refactoring/Introduce Parameter Object.uxf new file mode 100644 index 0000000..38094da --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/research of automated refactoring/Introduce Parameter Object.uxf @@ -0,0 +1,558 @@ + + + 9 + + com.baselet.element.old.element.Relation + + 1701 + 531 + 89 + 44 + + lt=<<<- + 27;27;72;27 + + + com.baselet.element.old.element.Class + + 2304 + 252 + 369 + 99 + + org.eclipse.ltk.core.refactoring.participants. +ProcessorBasedRefactoring +-- + +-- ++ProcessorBasedRefactoring(processor: RefactoringProcessor) ++createChange(pm: IProgressMonitor): Change + + + + com.baselet.element.old.element.Class + + 2412 + 639 + 351 + 207 + + org.eclipse.jdt.core.refactoring.descriptors. +IntroduceParameterObjectDescriptor +-- +-fClassName: String +-fDelegate: boolean +-fDeprecateDelegate: boolean +-fGetters: boolean +-fMethod: IMethod +-fPackageName: String +-fParameterName: String +-fSetters: boolean +-fTopLevel: boolean +-- ++IntroduceParameterObjectDescriptor() + + + + com.baselet.element.old.element.Class + + 2412 + 504 + 351 + 99 + + /org.eclipse.jdt.core.refactoring.descriptors./ +/JavaRefactoringDescriptor/ +-- + +-- +#JavaRefactoringDescriptor(id: String) ++createRefactoring(status: RefactoringStatus): Refactoring + + + + com.baselet.element.old.element.Class + + 963 + 54 + 189 + 81 + + /org.eclipse.ltk.ui.refactoring./ +/RefactoringWizard/ +-- + +-- +/#addUserInputPages(): void/ + + + + com.baselet.element.old.element.Class + + 1773 + 522 + 576 + 117 + + org.eclipse.jdt.internal.corext.refactoring.structure. +IntroduceParameterObjectProcessor +-- + +-- ++IntroduceParameterObjectProcessor(descriptor: IntroduceParameterObjectDescriptor) ++checkFinalConditions(pm: IProgressMonitor, context: CheckConditionsContext): RefactoringStatus ++checkInitialConditions(pm: IProgressMonitor): RefactoringStatus + + + + com.baselet.element.old.element.Relation + + 2736 + 711 + 161 + 63 + + lt=<<<- +fParameters +m2=* + 27;45;144;45 + + + com.baselet.element.old.element.Class + + 1431 + 504 + 297 + 99 + + org.eclipse.jdt.internal.ui.refactoring. +IntrodudeParameterObjectWizard$ +IntroduceParameterObjectInputPage +-- +-fProcessor: IntroduceParameterObjectProcessor +-- ++createControl(parent: Composite): void + + + + com.baselet.element.old.element.Relation + + 2421 + 189 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Class + + 0 + 153 + 396 + 90 + + org.eclipse.jdt.internal.corext.refactoring. +RefactoringExecutionStarter +-- + +-- +_+startIntroduceParameterObject(method: IMethod, shell: Shell): void_ + + + + com.baselet.element.old.element.Relation + + 2142 + 261 + 179 + 44 + + lt=<<<- + 27;27;162;27 + + + com.baselet.element.old.element.Relation + + 2124 + 441 + 62 + 62 + + + 27;27;45;45 + + + com.baselet.element.old.element.Relation + + 1026 + 108 + 44 + 98 + + lt=<<- + 27;27;27;81 + + + com.baselet.element.old.element.Class + + 2304 + 144 + 297 + 72 + + /org.eclipse.ltk.core.refactoring/ +/Refactoring/ +-- + +-- + + + + + com.baselet.element.old.element.Class + + 1809 + 252 + 360 + 99 + + /org.eclipse.ltk.core.refactoring.participants./ +/RefactoringProcessor/ +-- + +-- +/+createChange(pm: IProgressMonitor): Change/ ++setRefactoring(refactoringProcessorBasedRefactoring): void + + + + com.baselet.element.old.element.Note + + 2007 + 711 + 243 + 81 + + Refer to +ParameterObjectFactory.class +DelegateCreator.class +ASTRewrite +for how to create and replace source. + + + + com.baselet.element.old.element.Relation + + 1548 + 432 + 44 + 89 + + lt=<<- + 27;27;27;72 + + + com.baselet.element.old.element.Relation + + 1935 + 324 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Class + + 1431 + 387 + 297 + 72 + + /org.eclipse.ltk.ui.refactoring./ +/UserInputWizardPage/ +-- + +-- + + + + + com.baselet.element.old.element.Class + + 1818 + 387 + 333 + 99 + + org.eclipse.jdt.internal.corext.refactoring.structure. +ChangeSignatureProcessor +-- +-fBaseCuRewrite: CompilationUnitRewrite +-fChangeManager: TextChangeManager +-- ++createChange(pm: IProgressMonitor): Change + + + + com.baselet.element.old.element.Relation + + 2556 + 441 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Class + + 1431 + 270 + 297 + 72 + + /org.eclipse.ltk.ui.refactoring./ +/RefactoringWizardPage/ +-- + +-- + + + + + com.baselet.element.old.element.Class + + 1431 + 153 + 297 + 72 + + /org.eclipse.jface.wizard./ +/WizardPage/ +-- + +-- + + + + + com.baselet.element.old.element.Relation + + 2142 + 261 + 179 + 63 + + lt=<<<- +fProcessor + 162;45;27;45 + + + com.baselet.element.old.element.Class + + 2880 + 693 + 252 + 117 + + org.eclipse.jdt.core.refactoring.descriptors. +IntroduceParameterObjectDescriptor$ +Parameter +-- +-fCreateField: boolean +-fFieldName: String +-fIndex: int +-- + + + + + com.baselet.element.old.element.Relation + + 1548 + 198 + 44 + 89 + + lt=<<- + 27;27;27;72 + + + com.baselet.element.old.element.Relation + + 1935 + 459 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Class + + 2412 + 387 + 351 + 81 + + /org.eclipse.ltk.core.refactoring./ +/RefactoringDescriptor/ +-- + +-- +/+createRefactoring(status: RefactoringStatus): Refactoring/ + + + + com.baselet.element.old.element.Relation + + 1548 + 63 + 44 + 107 + + lt=<<. + 27;27;27;90 + + + com.baselet.element.old.element.Relation + + 2556 + 576 + 44 + 80 + + lt=<<- + 27;27;27;63 + + + com.baselet.element.old.element.Note + + 2169 + 477 + 234 + 27 + + DynamicValidationRefactoringChange + + + + com.baselet.element.old.element.Relation + + 1125 + 54 + 458 + 44 + + lt=<<<- + 27;27;441;27 + + + com.baselet.element.old.element.Interface + + 1503 + 72 + 144 + 81 + + org.eclipse.jface.wizard. +IWizardPage + + + + + com.baselet.element.old.element.Note + + 1944 + 801 + 333 + 45 + + Processor pattern: IntroduceParameterObjectProcessor +Non processor pattern: ExtractClassRefactoring + + + + com.baselet.element.old.element.Class + + 756 + 189 + 630 + 99 + + org.eclipse.jdt.internal.ui.refactoring. +IntroduceParameterObjectWizard +-- + +-- ++IntrodeceParameterObjectWizard(processor: IntroduceParameterObjectProcessor, refactoring: Refactoring) +#addUserInputPages(): void + + + + com.baselet.element.old.element.Relation + + 1548 + 315 + 44 + 89 + + lt=<<- + 27;27;27;72 + + + com.baselet.element.old.element.Class + + 9 + 0 + 369 + 117 + + org.eclipse.jdt.internal.ui.actions. +IntroduceParameterObjectAction +-- + +-- ++run(selection: ITextSelection): void +-run(method: IMethod): void +-getSingleSelectedMethod(selection: ITextSelection): IMethod + + + + + com.baselet.element.old.element.Class + + 459 + 27 + 405 + 126 + + org.eclipse.ltk.ui.refactoring +RefactoringWizardOpenOperation +-- + +-- ++RefactoringWizardOpenOperation(wizard: RefactoringWizard) ++getInitialConditionCheckingStatus(): RefactoringStatus ++run(parent: Shell, dialogTitle: String): int ++run(parent: Shell, dialogTitle: String, context: IRunnableContext): int + + + + com.baselet.element.old.element.Relation + + 837 + 72 + 143 + 44 + + lt=<<<- + 27;27;126;27 + + diff --git a/org.ntlab.refactoring.decouplingClasses/doc/research of automated refactoring/class.uxf b/org.ntlab.refactoring.decouplingClasses/doc/research of automated refactoring/class.uxf new file mode 100644 index 0000000..b887cf0 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/research of automated refactoring/class.uxf @@ -0,0 +1,613 @@ + + + 8 + + com.umlet.element.Relation + + 1152 + 480 + 40 + 80 + + lt=<<. + 24;24;24;64 + + + com.umlet.element.Interface + + 1056 + 488 + 240 + 72 + + org.eclipse.jdt.internal.corext.refactoring.tagging +IDelegateUpdating + + + + com.umlet.element.Relation + + 1792 + 200 + 208 + 88 + + lt=<<- + 192;24;24;72 + + + com.umlet.element.Interface + + 1904 + 112 + 160 + 72 + + java.lang +Comparable + + + + com.umlet.element.Class + + 24 + 216 + 280 + 256 + + /org.eclipse.ltk.core.refactoring.Change/ +-- +-fParent: Change +-fIsEnabled: boolean +-- +#Change() ++getDescriptor(): ChangeDescriptor +/+getName(): String/ ++isEnabled(): boolean ++setEnabled(enabled: boolean): void ++setEnabledShallow(enabled: boolean): void ++getParent(): Change +~setParent(parent: Change): void +/+initializeValidationData(pm: IProgressMonitor): void/ +/+isValid(pm: IProgressMonitor): RefactoringStatus/ +/+perform(pm: IProgressMonitor): Change/ ++dispose(): void +/+getModifiedElement(): Object/ ++getAffectedObjects(): Object[] ++getAdapter(adapter: Class): Object + + + + com.umlet.element.Interface + + 576 + 120 + 176 + 72 + + org.eclipse.core.runtime.IAdaptable +-- ++getAdapter(adapter: Class<T>): T + + + + com.umlet.element.Class + + 2448 + 304 + 336 + 80 + + org.eclipse.ltk.core.refactoring.participants +RenameParticipant +-- + +-- ++getArguments(): RenameArguments +#initialize(arguments: RefactoringArguments): void + + + + com.umlet.element.Class + + 928 + 272 + 264 + 56 + + /org.eclipse.ltk.ui.refactoring/ +/RefactoringWizard/ +-- + +-- + + + + + com.umlet.element.Relation + + 624 + 744 + 40 + 72 + + lt=<<- + 24;24;24;56 + + + com.umlet.element.Class + + 1648 + 272 + 352 + 56 + + org.eclipse.ltk.core.refactoring.resource +RenameResourceDescriptor +-- + +-- + + + + + com.umlet.element.Relation + + 2160 + 304 + 40 + 72 + + lt=<<- + 24;24;24;56 + + + com.umlet.element.Class + + 960 + 184 + 192 + 56 + + /org.eclipse.jface.wizard/ +/Wizard/ +-- + +-- + + + + + com.umlet.element.Relation + + 640 + 112 + 40 + 88 + + lt=<<. + 24;24;24;72 + + + com.umlet.element.Class + + 496 + 280 + 352 + 176 + + /org.eclipse.ltk.core.refactoring.Refactoring/ +-- +-fValidationContext: Object +-- ++setValidationContext(context: Object): void ++getValidationContext(): Object +/+getName(): String/ ++getRefactoringTickProvider(): RefactoringTickProvider +#doGetRefactoringTickProvider(): RefactoringTickProvider ++checkAllConditions(pm: IProgressMonitor): RefactoringStatus +/+checkInitialConditions(pm: IProgressMonitor): RefactoringStatus/ +/+checkFinalConditions(pm: IProgressMonitor): RefactoringStatus/ +/+createChange(pm: IProgressMonitor): Change/ ++getadapter(adapter: Class): Object ++toString(): String + + + + com.umlet.element.Class + + 896 + 368 + 328 + 80 + + org.eclipse.ltk.ui.refactoring.resource +RenameResourceWizard +-- + +-- +RenameResourceWizard(resource: IResource) +#addUserInputPages(): void + + + + com.umlet.element.Relation + + 1032 + 216 + 40 + 72 + + lt=<<- + 24;24;24;56 + + + com.umlet.element.Relation + + 2592 + 256 + 40 + 64 + + lt=<<- + 24;24;24;48 + + + com.umlet.element.Class + + 0 + 680 + 336 + 128 + + /org.eclipse.ltk.core.refactoring.resource.RenameResourceChange/ +-- + +-- +RenameResourceChange(resourcePath: IPath, newName: String) ++getDescriptor(): ChangeDescriptor +#getModifiedResource(): IResource ++getName(): String ++getNewName(): String ++perform(pm: IProgressMonitor): Change ++setDescriptor(descriptor: ChangeDescriptor): void + + + + + com.umlet.element.Class + + 888 + 544 + 560 + 256 + + org.eclipse.jdt.internal.corext.refactoring.code +IntroduceParameterRefactoring +-- +-fSourceCU: ICompilationUnit +-fSelectionStart: int +-fSelectionLength +-fMethod: IMethod +-fChandeSignatureRefactoring: Refactoring +-fChangeSignatureProcessor: ChangeSignatureProcessor +-fParameter: ParameterInfo +-fParameterName: String +-fArguments: JavaRefactoringArguments +-fSelectedExpression: Expression +-fExcludedParameterNames: String[] +-- ++IntroduceParameterRefactoring(unit: ICompilationUnit, selectionStart: int, selectionLength: int) ++IntroduceParameterRefactoring(arguments: JavaRefactoringArguments, status: RefactoringStatus) + + + + + com.umlet.element.Relation + + 128 + 600 + 40 + 96 + + lt=<<- + 24;24;24;80 + + + com.umlet.element.Class + + 488 + 512 + 368 + 256 + + /org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring/ +-- +-fProcessor: RefactoringProcessor +-fParticipants: List<RefactoringParticipant> +-fPreChangeParticipants: List<RefactoringParticipant> +-fTextChangeMap: Map<Object, TextChange> +/-EMPTY_PARTICIPANTS: List<RefactoringParticipant>/ +-- ++ProcessorBasedRefactoring(processor: RefactoringProcessor) ++getProcessor(): RefactoringProcessor ++setProcessor(processor: RefactoringProcessor): void ++isApplicable(): boolean ++getName(): String ++checkInitialConditions(pm: IProgressMonitor): RefactoringStatus ++checkFinalConditions(pm: IProgressMonitor): RefactoringStatus ++createChange(pm: IProgressMonitor): Change ++getTextChange(element: Object): TextChange ++getAdapter(clazz: Class): Object ++toString(): String +- +- +- + + + + com.umlet.element.Relation + + 136 + 120 + 40 + 112 + + lt=<<. + 24;24;24;96 + + + com.umlet.element.Interface + + 976 + 128 + 160 + 72 + + org.eclipse.jface.wizard.IWizard + + + + com.umlet.element.Class + + 2016 + 272 + 352 + 56 + + /org.eclipse.jdt.core.refactoring.descriptors/ +/JavaRefactoringDescriptor/ +-- + +-- + + + + + com.umlet.element.Class + + 0 + 520 + 328 + 104 + + /org.eclipse.ltk.core.refactoring.resource.ResourceChange/ +-- + +-- ++getModifiedElement(): Object +/#getModifiedResource(): IResource/ ++initializeValidationData(pm: IProgressMonitor): void ++isValid(pm: IProgressMonitor): RefactoringStatus ++setValidationMethod(validationMethod: int): void + + + + com.umlet.element.Relation + + 640 + 224 + 40 + 72 + + lt=<<- + 24;24;24;56 + + + com.umlet.element.Relation + + 1032 + 120 + 40 + 80 + + lt=<<. + 24;24;24;64 + + + com.umlet.element.Relation + + 1960 + 200 + 160 + 88 + + lt=<<- + 24;24;144;72 + + + com.umlet.element.Relation + + 128 + 448 + 40 + 88 + + lt=<<- + 24;24;24;72 + + + com.umlet.element.Relation + + 632 + 432 + 448 + 128 + + lt=<<- + 24;24;432;112 + + + com.umlet.element.Interface + + 72 + 128 + 176 + 72 + + org.eclipse.core.runtime.IAdaptable +-- ++getAdapter(adapter: Class<T>): T + + + + com.umlet.element.Relation + + 1960 + 104 + 40 + 80 + + lt=<<. + 24;24;24;64 + + + com.umlet.element.Relation + + 632 + 432 + 40 + 96 + + lt=<<- + 24;24;24;80 + + + com.umlet.element.Class + + 1848 + 168 + 272 + 56 + + /org.eclipse.ltk.core.refactoring/ +/RefactoringDescriptor/ +-- + +-- + + + + + com.umlet.element.Class + + 552 + 184 + 216 + 64 + + /org.eclipse.core.runtime.PlatformObject/ +-- +-fProcessor: RenameProcessor +-- ++PlatformObject() ++getAdapter(adapter: Class<T>): T + + + + com.umlet.element.Class + + 488 + 800 + 336 + 64 + + org.eclipse.ltk.core.refactoring.participants.RenameRefactoring +-- +-fProcessor: RenameProcessor +-- ++RenameRefactoring(processor: RenameProcessor) ++getProcessor(): RefactoringProcessor + + + + com.umlet.element.Class + + 2408 + 112 + 536 + 168 + + /org.eclipse.ltk.core.refactoring.participants/ +/RefactoringParticipant/ +-- + +-- +/+checkConditions(pm: IProgressMonitor, context: CheckConditionsContext): RefactoringStatus/ +/+createChange(pm: IprogressMonitor): Change/ ++createPreChbange(pm: IProgressMonitor): Change +/+getName(): String/ ++getProcessor(): RefactoringProcessor ++getTextChange(element: Object): TextChange +/#initialize(element: Object): boolean/ +/#initialize(arguments: RefactoringArguments): boolean/ ++initialize(processor: RefactoringProcessor, element: Object, arguments: RefactoringArguments): boolean + + + + com.umlet.element.Relation + + 1032 + 304 + 40 + 80 + + lt=<<- + 24;24;24;64 + + + com.umlet.element.Class + + 1288 + 128 + 384 + 104 + + org.eclipse.ltk.ui.refactoring +RefactoringWizardOpenOperation +-- + +-- ++RefactoringWizardOpenOperation(wizard: RefactoringWizard) ++getInitialConditionCheckingStatus(): RefactoringStatus ++run(parent: Shell, dialogTitle: String): int ++run(parent: Shell, dialogTitle: String, context: IRunnableContext): int + + + + com.umlet.element.Class + + 2016 + 360 + 352 + 56 + + org.eclipse.jdt.core.refactoring.descriptors +ChangeMethodSignatureDescriptor +-- + +-- + + + + diff --git a/org.ntlab.refactoring.decouplingClasses/doc/test case/test case 2.pptx b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case 2.pptx new file mode 100644 index 0000000..39c4339 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case 2.pptx Binary files differ diff --git a/org.ntlab.refactoring.decouplingClasses/doc/test case/test case 2.txt b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case 2.txt new file mode 100644 index 0000000..e348729 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case 2.txt @@ -0,0 +1,14 @@ +�P���ȌĂяo�����E���H�邾���ł͕s�B +�I�u�W�F�N�g�̗����ǂ��K�v������B + +�Q�ƌ�: A, B, C, D +�Q�Ɛ�: E +�V�K: F + +�K�p�̎��ɂȂ����N���X�@���t�@�N�^�����O�@cvs���̃^�O + +C �߂�l�I�u�W�F�N�g�̓��� TEST_CASE_1_S1 +B �I�u�W�F�N�g���̂��̂̕ԋp TEST_CASE_1_S2 +A �B���ɂ��^�̒u������ TEST_CASE_1_S3 +A �I�u�W�F�N�g���̂��̂̎󂯓n�� TEST_CASE_1_S4 +D �B���ɂ��^�̒u������ TEST_CASE_1_S5 \ No newline at end of file diff --git a/org.ntlab.refactoring.decouplingClasses/doc/test case/test case 2.uxf b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case 2.uxf new file mode 100644 index 0000000..fdb06e6 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case 2.uxf @@ -0,0 +1,620 @@ + + + 8 + + UMLUseCase + + 392 + 208 + 56 + 24 + + Target + + + + UMLClass + + 392 + 272 + 80 + 24 + + A mA() + + + + Relation + + 408 + 224 + 24 + 64 + + lt=<. + 10.0;60.0;10.0;10.0 + + + Relation + + 424 + 288 + 24 + 120 + + lt=<- + 10.0;130.0;10.0;10.0 + + + UMLClass + + 392 + 392 + 80 + 24 + + F mF() + + + + Relation + + 408 + 288 + 24 + 120 + + lt=<. + 10.0;130.0;10.0;10.0 + + + UMLClass + + 392 + 592 + 80 + 32 + + I mI() + + + + Relation + + 392 + 408 + 24 + 200 + + lt=<. + 10.0;230.0;10.0;10.0 + + + Relation + + 408 + 408 + 24 + 200 + + lt=<- + 10.0;230.0;10.0;10.0 + + + UMLClass + + 528 + 456 + 80 + 32 + + H mH() + + + + Relation + + 448 + 408 + 96 + 72 + + lt=<- + 100.0;70.0;10.0;70.0;10.0;10.0 + + + Relation + + 432 + 408 + 112 + 88 + + lt=<. + 120.0;90.0;10.0;90.0;10.0;10.0 + + + UMLUseCase + + 536 + 208 + 56 + 24 + + Target + + + + UMLClass + + 536 + 272 + 80 + 24 + + B mB() + + + + Relation + + 552 + 224 + 24 + 64 + + lt=<. + 10.0;60.0;10.0;10.0 + + + Relation + + 568 + 288 + 24 + 120 + + lt=<- + 10.0;130.0;10.0;10.0 + + + UMLClass + + 536 + 392 + 80 + 24 + + G mG() + + + + Relation + + 552 + 288 + 24 + 120 + + lt=<. + 10.0;130.0;10.0;10.0 + + + Relation + + 568 + 408 + 24 + 64 + + lt=<- + 10.0;60.0;10.0;10.0 + + + Relation + + 552 + 408 + 24 + 64 + + lt=<. + 10.0;60.0;10.0;10.0 + + + Relation + + 456 + 480 + 136 + 128 + + lt=<- + 10.0;140.0;10.0;100.0;150.0;100.0;150.0;10.0 + + + Relation + + 440 + 480 + 136 + 128 + + lt=<. + 10.0;140.0;10.0;80.0;150.0;80.0;150.0;10.0 + + + UMLClass + + 392 + 720 + 80 + 32 + + N mN() + + + + Relation + + 416 + 616 + 24 + 120 + + lt=<. + 10.0;130.0;10.0;10.0 + + + Relation + + 432 + 616 + 24 + 120 + + lt=<- + 10.0;130.0;10.0;10.0 + + + UMLClass + + 392 + 848 + 120 + 24 + + Target printMessage() + + + + Relation + + 408 + 744 + 24 + 120 + + lt=<- + 10.0;130.0;10.0;10.0 + + + UMLUseCase + + 720 + 208 + 56 + 24 + + Target + + + + UMLClass + + 712 + 272 + 80 + 24 + + C mC() + + + + Relation + + 736 + 224 + 24 + 64 + + lt=<. + 10.0;60.0;10.0;10.0 + + + Relation + + 600 + 288 + 176 + 208 + + lt=<- + 10.0;240.0;200.0;240.0;200.0;10.0 + + + Relation + + 600 + 288 + 160 + 192 + + lt=<. + 10.0;220.0;180.0;220.0;180.0;10.0 + + + UMLUseCase + + 1048 + 208 + 56 + 24 + + Target + + + + UMLClass + + 1040 + 272 + 80 + 24 + + E mE() + + + + Relation + + 1064 + 224 + 24 + 64 + + lt=<. + 10.0;60.0;10.0;10.0 + + + Relation + + 1080 + 288 + 24 + 120 + + lt=<- + 10.0;130.0;10.0;10.0 + + + UMLClass + + 1040 + 392 + 80 + 24 + + J mJ() + + + + Relation + + 1064 + 288 + 24 + 120 + + lt=<. + 10.0;130.0;10.0;10.0 + + + Relation + + 1080 + 408 + 24 + 120 + + lt=<- + 10.0;130.0;10.0;10.0 + + + UMLClass + + 1040 + 512 + 80 + 24 + + K mK() + + + + Relation + + 1064 + 408 + 24 + 120 + + lt=<. + 10.0;130.0;10.0;10.0 + + + Relation + + 464 + 528 + 640 + 232 + + lt=<- + 10.0;270.0;780.0;270.0;780.0;10.0 + + + Relation + + 464 + 528 + 624 + 216 + + lt=<. + 10.0;250.0;760.0;250.0;760.0;10.0 + + + UMLUseCase + + 872 + 208 + 56 + 24 + + Target + + + + UMLClass + + 872 + 272 + 80 + 24 + + D mD() + + + + Relation + + 888 + 224 + 24 + 64 + + lt=<. + 10.0;60.0;10.0;10.0 + + + Relation + + 464 + 288 + 464 + 344 + + lt=<- + 10.0;410.0;560.0;410.0;560.0;10.0 + + + Relation + + 464 + 288 + 448 + 328 + + lt=<. + 10.0;390.0;540.0;390.0;540.0;10.0 + + + Relation + + 392 + 104 + 136 + 32 + + lt=<- +Method Invocation + 150.0;20.0;10.0;20.0 + + + Relation + + 392 + 136 + 136 + 32 + + lt=<. +Instance Flow + 150.0;20.0;10.0;20.0 + + + Text + + 320 + 360 + 72 + 48 + + 1: Introduce +Parameter +Object + + + + Text + + 592 + 344 + 72 + 48 + + 1: Introduce +Parameter +Object + + + + Text + + 1120 + 384 + 72 + 48 + + 1: Introduce +Parameter +Object + + + + Text + + 576 + 488 + 80 + 32 + + 2: Preserve +Whole Object + + + + Text + + 56 + 784 + 280 + 128 + + あるメソッド定義を中心に見ると、前提条件は全ての呼び出し元の実引数がwrapper.getTarget()の形になっていること。 +また、いずれの呼び出し元からリファクタリングをはじめようと構わない。 +メソッドを呼び出している側からすると、呼び出しているメソッドの自分を含む全ての呼び出し元がwrapper.getTarget()の形になっていなければリファクタリングを実行できない。 + + + diff --git a/org.ntlab.refactoring.decouplingClasses/doc/test case/test case.pptx b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case.pptx new file mode 100644 index 0000000..2b6c480 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case.pptx Binary files differ diff --git a/org.ntlab.refactoring.decouplingClasses/doc/test case/test case.uxf b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case.uxf new file mode 100644 index 0000000..ff512e0 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/doc/test case/test case.uxf @@ -0,0 +1,182 @@ + + + 8 + + UMLUseCase + + 392 + 584 + 56 + 24 + + E(Target) + + + + UMLClass + + 400 + 296 + 80 + 24 + + A m() + + + + Relation + + 416 + 544 + 24 + 56 + + lt=<. + 10.0;10.0;10.0;50.0 + + + Relation + + 400 + 312 + 24 + 120 + + lt=<- + 10.0;130.0;10.0;10.0 + + + UMLClass + + 376 + 416 + 80 + 24 + + B getE() + + + + Relation + + 416 + 432 + 24 + 112 + + lt=<. + 10.0;10.0;10.0;120.0 + + + Relation + + 400 + 432 + 24 + 112 + + lt=<- + 10.0;120.0;10.0;10.0 + + + Relation + + 400 + 128 + 136 + 32 + + lt=<- +Method Invocation + 150.0;20.0;10.0;20.0 + + + Relation + + 400 + 160 + 136 + 32 + + lt=<. +Instance Flow + 150.0;20.0;10.0;20.0 + + + UMLClass + + 496 + 416 + 80 + 24 + + D setE() + + + + Relation + + 440 + 312 + 96 + 120 + + lt=<- + 100.0;130.0;10.0;10.0 + + + UMLClass + + 376 + 528 + 80 + 24 + + C createE() + + + + UMLClass + + 400 + 240 + 80 + 24 + + Start main() + + + + Relation + + 432 + 256 + 24 + 56 + + lt=<- + 10.0;50.0;10.0;10.0 + + + Relation + + 416 + 312 + 24 + 120 + + lt=<. + 10.0;10.0;10.0;130.0 + + + Relation + + 456 + 312 + 96 + 120 + + lt=<. + 100.0;130.0;10.0;10.0 + + diff --git a/org.ntlab.refactoring.decouplingClasses/icons/infoHide.png b/org.ntlab.refactoring.decouplingClasses/icons/infoHide.png new file mode 100644 index 0000000..d111feb --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/icons/infoHide.png Binary files differ diff --git a/org.ntlab.refactoring.decouplingClasses/icons/infoHideOriginal.png b/org.ntlab.refactoring.decouplingClasses/icons/infoHideOriginal.png new file mode 100644 index 0000000..6f20f3e --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/icons/infoHideOriginal.png Binary files differ diff --git a/org.ntlab.refactoring.decouplingClasses/icons/sample.gif b/org.ntlab.refactoring.decouplingClasses/icons/sample.gif new file mode 100644 index 0000000..34fb3c9 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/icons/sample.gif Binary files differ diff --git a/org.ntlab.refactoring.decouplingClasses/plugin.xml b/org.ntlab.refactoring.decouplingClasses/plugin.xml new file mode 100644 index 0000000..9f1973a --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/plugin.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoring.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoring.java new file mode 100644 index 0000000..20bdcae --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoring.java @@ -0,0 +1,12 @@ +package org.ntlab.refactoring.decouplingClasses; + +import org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring; + +public class DecoupleClassesRefactoring extends ProcessorBasedRefactoring { + public static final String ID = "org.ntlab.refactoring.decouplingClasses"; + public static final String NAME = "Decouple Classes"; + + public DecoupleClassesRefactoring(DecoupleClassesRefactoringProcessor processor) { + super(processor); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringHandler.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringHandler.java new file mode 100644 index 0000000..8552941 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringHandler.java @@ -0,0 +1,203 @@ +package org.ntlab.refactoring.decouplingClasses; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.commands.IHandlerListener; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.ICodeAssist; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.ITypeRoot; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.ui.JavaElementLabels; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.ltk.core.refactoring.RefactoringCore; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.ui.refactoring.RefactoringWizard; +import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.handlers.HandlerUtil; +import org.ntlab.refactoring.decouplingClasses.descriptors.DecoupleClassesDescriptor; +import org.ntlab.refactoring.decouplingClasses.descriptors.DecoupleClassesRefactoringContribution; +import org.ntlab.refactoring.decouplingClasses.ui.DecoupleClassesWizard; + +public class DecoupleClassesRefactoringHandler implements IHandler { + + @Override + public void addHandlerListener(IHandlerListener handlerListener) { + System.out.println("InformationHidingHandler#addHandlerListener()"); + } + + @Override + public void dispose() { + System.out.println("InformationHidingHandler#dispose()"); + } + + /** + * �Ăяo������H��@�\��t�������e�X�g + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IType targetType = getTargetType(event); + + if (targetType == null) { + return null; + } + + RefactoringStatus availability = checkAvailability(targetType); + if (availability.hasError()){ + MessageDialog.openError( + HandlerUtil.getActiveShell(event), + DecoupleClassesRefactoringPlugin.REFACTORING_NAME, + "Some Probrems"); + return null; + } + + DecoupleClassesRefactoringContribution contribution = (DecoupleClassesRefactoringContribution) RefactoringCore.getRefactoringContribution(DecoupleClassesRefactoring.ID); + DecoupleClassesDescriptor descriptor = (DecoupleClassesDescriptor) contribution.createDescriptor(); + descriptor.setTargetType(targetType); + descriptor.setNewClassName(targetType.getElementName() + "Wrapper"); + descriptor.setPackage(targetType.getPackageFragment().getElementName()); + + // ���s���ɑI�����Ă���v���O�����Ђ��͂��Ă��郁�\�b�h���擾����B + // IJavaElement enclosingMethod = getEnclosingMethod(typeRoot, selection); + // new SearchClassByUsingSearchEngineTest().search(enclosingMethod, new NullProgressMonitor()); + + DecoupleClassesRefactoring refactoring = null; + try { + refactoring = (DecoupleClassesRefactoring) descriptor.createRefactoring(availability); + } catch (CoreException e) { + e.printStackTrace(); + return null; + } + + DecoupleClassesWizard wizard = new DecoupleClassesWizard(refactoring); + Shell shell = HandlerUtil.getActiveShell(event); + activate(wizard, shell, "Refactoring"); + + return null; + } + + private IType getTargetType(ExecutionEvent event) { + IJavaElement targetType = null; + + try { + targetType = codeResolve(event); + } catch (JavaModelException e) { + return null; + } + + if (!(targetType instanceof IType)) { + return null; + } + + return (IType) targetType; + } + + private IJavaElement codeResolve(ExecutionEvent event) throws JavaModelException { + IEditorInput editorInput = HandlerUtil.getActiveEditorInput(event); + ITypeRoot typeRoot = JavaUI.getEditorInputTypeRoot(editorInput); + + if (typeRoot instanceof ICodeAssist) { + if (typeRoot instanceof ICompilationUnit) { + ((ICompilationUnit) typeRoot).reconcile( + ICompilationUnit.NO_AST, + false /* don't force problem detection */, + null /* use primary owner */, + null /* no progress monitor */); + } +// ITextSelection selection = (ITextSelection) HandlerUtil.getCurrentSelection(event); + ITextSelection selection = (ITextSelection) HandlerUtil.getActiveMenuSelection(event); + IJavaElement[] elements = ((ICodeAssist)typeRoot).codeSelect(selection.getOffset() + selection.getLength(), 0); + if (elements.length > 0) { + return elements[0]; + } + } + + return null; + } + + private RefactoringStatus checkAvailability(IJavaElement element) { + RefactoringStatus result = new RefactoringStatus(); + if (!element.exists()) { + result.addFatalError(JavaElementLabels.getElementLabel(element, JavaElementLabels.ALL_DEFAULT) + " does not exist in the model"); + } +// if (element.isReadOnly()) { +// result.addFatalError(JavaElementLabels.getElementLabel(element, JavaElementLabels.ALL_DEFAULT) + " is read-only"); +// } + try { + if (element.exists() && !element.isStructureKnown()) { + result.addFatalError(JavaElementLabels.getElementLabel(element, JavaElementLabels.ALL_DEFAULT) + " - unknown structure"); + } + } catch (JavaModelException e) { + e.printStackTrace(); + } +// if (element instanceof IMember && ((IMember)element).isBinary()) { +// result.addFatalError(JavaElementLabels.getElementLabel(element, JavaElementLabels.ALL_DEFAULT) + " is binary"); +// } + return result; + } + +// private IJavaElement getEnclosingMethod(ITypeRoot typeRoot, ITextSelection selection) { +// try { +// IJavaElement enclosingElement = typeRoot.getElementAt(selection.getOffset()); +// if (enclosingElement instanceof IMethod) { +// return enclosingElement; +// } +// } catch (JavaModelException e) { +// e.printStackTrace(); +// } +// +// return null; +// } + + public boolean activate(RefactoringWizard wizard, Shell parent, String dialogTitle) { + RefactoringSaveHelper saveHelper = new RefactoringSaveHelper(RefactoringSaveHelper.SAVE_REFACTORING); + if (!canActivate(saveHelper, parent)) { + return false; + } + + try { + RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard); + int result = op.run(parent, dialogTitle); + // RefactoringStatus fStatus = op.getInitialConditionCheckingStatus(); + if (result == IDialogConstants.CANCEL_ID || result == RefactoringWizardOpenOperation.INITIAL_CONDITION_CHECKING_FAILED) { + saveHelper.triggerIncrementalBuild(); + return false; + } else { + return true; + } + } catch (InterruptedException e) { + return false; + } + } + + private boolean canActivate(RefactoringSaveHelper saveHelper, Shell shell) { + return saveHelper.saveEditors(shell); + } + + @Override + public boolean isEnabled() { + System.out.println(this.getClass().getSimpleName() + "#" + "isEnabled()"); + return true; + } + + @Override + public boolean isHandled() { + System.out.println(this.getClass().getSimpleName() + "#" + "isHandled()"); + return true; + } + + @Override + public void removeHandlerListener(IHandlerListener handlerListener) { + System.out.println(this.getClass().getSimpleName() + "#" + "removeHandlerListener()"); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringPlugin.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringPlugin.java new file mode 100644 index 0000000..4cb143d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringPlugin.java @@ -0,0 +1,29 @@ +package org.ntlab.refactoring.decouplingClasses; + +import org.eclipse.ui.plugin.AbstractUIPlugin; + +public class DecoupleClassesRefactoringPlugin extends AbstractUIPlugin { +// public static final String IMG_DESCRIPTION = "Refactoring.Description.Image"; + public static final String REFACTORING_NAME = "Decouple Classes"; + private static DecoupleClassesRefactoringPlugin plugin; + + public DecoupleClassesRefactoringPlugin() { + plugin = this; + } + +// @Override +// protected void initializeImageRegistry(ImageRegistry reg) { +// registerImage(reg, IMG_DESCRIPTION, "infoHide.png"); +// } + +// private void registerImage(ImageRegistry reg, String key, String fileName) { +// URL url = FileLocator.find(getBundle(), new Path("icons/" + fileName), null); +// if (url == null) return; +// reg.put(key, ImageDescriptor.createFromURL(url)); +// } + + public static DecoupleClassesRefactoringPlugin getInstance() { + return plugin; + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringProcessor.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringProcessor.java new file mode 100644 index 0000000..59da7c7 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringProcessor.java @@ -0,0 +1,427 @@ +package org.ntlab.refactoring.decouplingClasses; + +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.NullChange; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; +import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; +import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; +import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; +import org.ntlab.refactoring.decouplingClasses.descriptors.DecoupleClassesDescriptor; + +import test.pseudocode.core.DepthFirstTopologicalSorter; +import test.pseudocode.core.Node; + +public class DecoupleClassesRefactoringProcessor extends RefactoringProcessor { + private DecoupleClassesDescriptor descriptor = null; + + public DecoupleClassesRefactoringProcessor(DecoupleClassesDescriptor descriptor) { + this.descriptor = descriptor; + } + + @Override + public Object[] getElements() { + System.out.println(this.getClass().getSimpleName() + "#getElements()"); + return null; + } + + @Override + public String getIdentifier() { + System.out.println(this.getClass().getSimpleName() + "#getIdentifier()"); + return null; + } + + @Override + public String getProcessorName() { + System.out.println(this.getClass().getSimpleName() + "#getProcessorName()"); + return DecoupleClassesRefactoringPlugin.REFACTORING_NAME; + } + + @Override + public boolean isApplicable() throws CoreException { + System.out.println(this.getClass().getSimpleName() + "#isApplicable()"); + return false; + } + + @Override + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { + System.out.println(this.getClass().getSimpleName() + "#checkInitialConditions()"); + + return new RefactoringStatus(); + } + + @Override + public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException, OperationCanceledException { + System.out.println(this.getClass().getSimpleName() + "#checkFinalConditions()"); + + RefactoringTaskGenerator taskGenerator = new RefactoringTaskGenerator(); + taskGenerator.setCfrom(descriptor.getClients()); + taskGenerator.setTargetClass(descriptor.getTargetType()); + List refactoringTasks = taskGenerator.generateTasks(); + + new DepthFirstTopologicalSorter().sort(refactoringTasks); + + for (int i = 0; i < refactoringTasks.size(); i++) { + System.out.println((i + 1) + ": " + refactoringTasks.get(i).toString()); + } + + return new RefactoringStatus(); + } + + @Override + public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + System.out.println(this.getClass().getSimpleName() + "#createChange()"); + + // Change change = createRenameChange(); + Change change = new NullChange();// createNewClassChanges(); + + return change; + } + + // private Change createRenameChange() throws JavaModelException { + // ICompilationUnit cu = descriptor.getTargetType().getCompilationUnit(); + // + // TextChange change = new CompilationUnitChange(cu.getElementName(), cu); + // + // ISourceRange nameRange = descriptor.getTargetType().getNameRange(); + // int offset = nameRange.getOffset(); + // int length = nameRange.getLength(); + // TextEdit root = change.getEdit(); + // if (root == null) { + // root = new MultiTextEdit(); + // change.setEdit(root); + // } + // ReplaceEdit edit = new ReplaceEdit(offset, length, descriptor.getNewClassName()); + // root.addChild(edit); + // + // return change; + // } + + @Override + public RefactoringParticipant[] loadParticipants(RefactoringStatus status, SharableParticipants sharedParticipants) throws CoreException { + System.out.println(this.getClass().getSimpleName() + "#loadParticipants()"); + return new RefactoringParticipant[0]; + } + + public DecoupleClassesDescriptor getDescriptor() { + return descriptor; + } + +// private Change createNewClassChanges() throws CoreException { +// CompositeChange change = new CompositeChange(DecoupleClassesRefactoring.NAME); +// +// // TODO: �w��̃p�b�P�[�W�̗L���̊m�F�ƁA�Ȃ���ΐ�������Change�̒lj��B +// +// IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) descriptor.getTargetType().getCompilationUnit().getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); +// IPackageFragment packageFragment = packageFragmentRoot.getPackageFragment(descriptor.getPackage()); +// +// ICompilationUnit cu = packageFragment.getCompilationUnit(descriptor.getNewClassName() + ".java"); +// ICompilationUnit workingCopy = cu.getWorkingCopy(null); +// workingCopy.getBuffer().setContents("class " + descriptor.getNewClassName() + " {}"); +// +// ASTParser parser = ASTParser.newParser(AST.JLS8); +// parser.setKind(ASTParser.K_COMPILATION_UNIT); +// parser.setResolveBindings(true); +// parser.setSource(workingCopy); +// +// CompilationUnit unit = (CompilationUnit) parser.createAST(null); +// unit.recordModifications(); +// +// ASTRewrite rewrite = ASTRewrite.create(unit.getAST()); +// +// TypeDeclaration typeDeclaration = createClassDeclaration(unit.getAST()); +// +// ListRewrite typesRewrite = rewrite.getListRewrite(unit, CompilationUnit.TYPES_PROPERTY); +// typesRewrite.replace((ASTNode) typesRewrite.getOriginalList().get(0), typeDeclaration, null); +// +// Document document = new Document(workingCopy.getSource()); +// TextEdit edit = rewrite.rewriteAST(document, null); +// try { +// edit.apply(document); +// } catch (MalformedTreeException | BadLocationException e) { +// e.printStackTrace(); +// } +// +// String newSource = document.get(); +// workingCopy.getBuffer().setContents(newSource); +// +// change.add(new CreateNewClassChange(cu, document.get())); +// +// workingCopy.discardWorkingCopy(); +// +// return change; +// } + + // private static String getProjectLineDelimiter(IJavaProject javaProject) { + // IProject project= null; + // if (javaProject != null) + // project= javaProject.getProject(); + // + // String lineDelimiter= getLineDelimiterPreference(project); + // if (lineDelimiter != null) + // return lineDelimiter; + // + // return System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + // } + + // public static String getLineDelimiterPreference(IProject project) { + // IScopeContext[] scopeContext; + // if (project != null) { + // // project preference + // scopeContext= new IScopeContext[] { new ProjectScope(project) }; + // String lineDelimiter= Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, scopeContext); + // if (lineDelimiter != null) + // return lineDelimiter; + // } + // // workspace preference + // scopeContext= new IScopeContext[] { InstanceScope.INSTANCE }; + // String platformDefault= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + // return Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, platformDefault, scopeContext); + // } + + // private String getTypeComment(ICompilationUnit parentCU, String lineDelimiter) throws CoreException { + // if (Boolean.valueOf(PreferenceConstants.getPreference(PreferenceConstants.CODEGEN_ADD_COMMENTS, parentCU.getJavaProject())).booleanValue()) { + // StringBuffer typeName = new StringBuffer(); + // typeName.append(descriptor.getNewClassName()); + // String[] typeParamNames= new String[0]; + // String comment= CodeGeneration.getTypeComment(parentCU, typeName.toString(), typeParamNames, lineDelimiter); + // if (comment != null && isValidComment(comment)) { + // return comment; + // } + // } + // return null; + // } + + // private boolean isValidComment(String template) { + // IScanner scanner = ToolFactory.createScanner(true, false, false, false); + // scanner.setSource(template.toCharArray()); + // try { + // int next = scanner.getNextToken(); + // while (next == ITerminalSymbols.TokenNameCOMMENT_BLOCK || next == ITerminalSymbols.TokenNameCOMMENT_JAVADOC || next == ITerminalSymbols.TokenNameCOMMENT_LINE) { + // next= scanner.getNextToken(); + // } + // return next == ITerminalSymbols.TokenNameEOF; + // } catch (InvalidInputException e) { + // } + // return false; + // } + +// @SuppressWarnings("unchecked") +// private TypeDeclaration createClassDeclaration(AST ast) { +// TypeDeclaration typeDeclaration = ast.newTypeDeclaration(); +// +// typeDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); +// typeDeclaration.setName(ast.newSimpleName(descriptor.getNewClassName())); +// List body = typeDeclaration.bodyDeclarations(); +// +// FieldDeclaration fieldDeclaration = createField(ast); +// body.add(fieldDeclaration); +// +// return typeDeclaration; +// } + +// @SuppressWarnings("unchecked") +// private FieldDeclaration createField(AST ast) { +// VariableDeclarationFragment fragment = ast.newVariableDeclarationFragment(); +// String fieldName = Character.toLowerCase(descriptor.getTargetName().charAt(0)) + descriptor.getTargetName().substring(1); +// fragment.setName(ast.newSimpleName(fieldName)); +// FieldDeclaration fieldDeclaration = ast.newFieldDeclaration(fragment); +// fieldDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PRIVATE_KEYWORD)); +// +// ASTParser parser = ASTParser.newParser(AST.JLS8); +// IType targetType = descriptor.getTargetType(); +// ICompilationUnit compilationUnit = targetType.getCompilationUnit(); +// parser.setSource(compilationUnit); +// parser.setResolveBindings(true); +// CompilationUnit unit = (CompilationUnit) parser.createAST(null); +// final List results = new ArrayList<>(); +// unit.accept(new ASTVisitor() { +// }); +// fieldDeclaration.setType(results.get(0)); +// +// return fieldDeclaration; +// } + +// @SuppressWarnings("unchecked") +// private TypeDeclaration test(CompilationUnit unit) { +// AST ast = unit.getAST(); +// +// PackageDeclaration packageDeclaration = ast.newPackageDeclaration(); +// packageDeclaration.setName(ast.newSimpleName("example")); +// unit.setPackage(packageDeclaration); +// +// ImportDeclaration importDeclaration = ast.newImportDeclaration(); +// QualifiedName name = ast.newQualifiedName(ast.newSimpleName("java"), ast.newSimpleName("util")); +// importDeclaration.setName(name); +// importDeclaration.setOnDemand(true); +// unit.imports().add(importDeclaration); +// +// TypeDeclaration type = ast.newTypeDeclaration(); +// type.setInterface(false); +// type.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); +// type.setName(ast.newSimpleName("HelloWorld")); +// +// MethodDeclaration methodDeclaration = ast.newMethodDeclaration(); +// methodDeclaration.setConstructor(false); +// List modifiers = methodDeclaration.modifiers(); +// modifiers.add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); +// modifiers.add(ast.newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD)); +// methodDeclaration.setName(ast.newSimpleName("main")); +// methodDeclaration.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); +// SingleVariableDeclaration variableDeclaration = ast.newSingleVariableDeclaration(); +// variableDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newSimpleName("String")))); +// variableDeclaration.setName(ast.newSimpleName("args")); +// methodDeclaration.parameters().add(variableDeclaration); +// +// org.eclipse.jdt.core.dom.Block block = ast.newBlock(); +// MethodInvocation methodInvocation = ast.newMethodInvocation(); +// name = ast.newQualifiedName(ast.newSimpleName("System"), ast.newSimpleName("out")); +// methodInvocation.setExpression(name); +// methodInvocation.setName(ast.newSimpleName("println")); +// InfixExpression infixExpression = ast.newInfixExpression(); +// infixExpression.setOperator(InfixExpression.Operator.PLUS); +// StringLiteral literal = ast.newStringLiteral(); +// literal.setLiteralValue("Hello"); +// infixExpression.setLeftOperand(literal); +// literal = ast.newStringLiteral(); +// literal.setLiteralValue(" world"); +// infixExpression.setRightOperand(literal); +// methodInvocation.arguments().add(infixExpression); +// ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation); +// block.statements().add(expressionStatement); +// methodDeclaration.setBody(block); +// type.bodyDeclarations().add(methodDeclaration); +// +// unit.types().add(type); +// +// return type; +// } + +// private class CreateNewClassChange extends ResourceChange { +// private IPath path; +// private String fSource; +// private String encoding; +// private boolean explicitEncoding; +// +// public CreateNewClassChange(ICompilationUnit newClassCu, String source) throws CoreException { +// path = newClassCu.getResource().getFullPath(); +// this.fSource = source; +// encoding = ResourceUtil.getFile(newClassCu).getCharset(false); +// explicitEncoding = encoding != null; +// } +// +// @Override +// public String getName() { +// return MessageFormat.format("Create class", new Object[] {getPathLabel(path, false)}); +// } +// +// public String getPathLabel(IPath path, boolean isOSPath) { +// String label; +// if (isOSPath) { +// label= path.toOSString(); +// } else { +// label= path.makeRelative().toString(); +// } +// return markLTR(label); +// } +// +// public String markLTR(String string) { +// String testString= "args : String[]"; //$NON-NLS-1$ +// +// if (!(testString != TextProcessor.process(testString))) { +// return string; +// } +// +// return TextProcessor.process(string); +// } +// +// @Override +// protected IResource getModifiedResource() { +// return ResourcesPlugin.getWorkspace().getRoot().getFile(path); +// } +// +// @Override +// public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException { +// return null; +// } +// +// @Override +// public Change perform(IProgressMonitor pm) throws CoreException, OperationCanceledException { +// InputStream inputStream = null; +// try { +// pm.beginTask("Creating java file...", 3); +// +// initializeEncoding(); +// IFile file = getOldFile(new SubProgressMonitor(pm, 1)); +// try { +// inputStream= new ByteArrayInputStream(fSource.getBytes(encoding)); +// file.create(inputStream, false, new SubProgressMonitor(pm, 1)); +// if (explicitEncoding) { +// file.setCharset(encoding, new SubProgressMonitor(pm, 1)); +// } else { +// pm.worked(1); +// } +// return new DeleteResourceChange(file.getFullPath(), true); +// } catch (UnsupportedEncodingException e) { +// throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); +// } +// } finally { +// try { +// if (inputStream != null) +// inputStream.close(); +// } catch (IOException ioe) { +// throw new JavaModelException(ioe, IJavaModelStatusConstants.IO_EXCEPTION); +// } finally { +// pm.done(); +// } +// } +// } +// +// protected IFile getOldFile(IProgressMonitor pm) throws OperationCanceledException { +// pm.beginTask("", 1); //$NON-NLS-1$ +// try { +// return ResourcesPlugin.getWorkspace().getRoot().getFile(path); +// } finally { +// pm.done(); +// } +// } +// +// private void initializeEncoding() { +// if (encoding == null) { +// explicitEncoding= false; +// IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(path); +// if (file != null) { +// try { +// if (file.exists()) { +// encoding= file.getCharset(false); +// if (encoding == null) { +// encoding= file.getCharset(true); +// } else { +// explicitEncoding = true; +// } +// } else { +// IContentType contentType= Platform.getContentTypeManager().findContentTypeFor(file.getName()); +// if (contentType != null) +// encoding = contentType.getDefaultCharset(); +// if (encoding == null) +// encoding = file.getCharset(true); +// } +// } catch (CoreException e) { +// encoding= ResourcesPlugin.getEncoding(); +// explicitEncoding= true; +// } +// } else { +// encoding= ResourcesPlugin.getEncoding(); +// explicitEncoding= true; +// } +// } +// Assert.isNotNull(encoding); +// } +// } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/InformationHidingHandlerOld.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/InformationHidingHandlerOld.java new file mode 100644 index 0000000..8fc5868 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/InformationHidingHandlerOld.java @@ -0,0 +1,305 @@ +package org.ntlab.refactoring.decouplingClasses; + +import java.util.Collection; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.commands.IHandlerListener; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.core.ICodeAssist; +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.ILocalVariable; +import org.eclipse.jdt.core.IMethod; +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; +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.NodeFinder; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder; +import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; +import org.eclipse.jdt.internal.ui.actions.SelectionConverter; +import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; +import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jdt.ui.SharedASTProvider; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.ntlab.refactoring.decouplingClasses.ui.DecoupleClassesWizard; + +public class InformationHidingHandlerOld implements IHandler { + private static IJavaElement element; + + @Override + public void addHandlerListener(IHandlerListener handlerListener) { + System.out.println("InformationHidingHandler#addHandlerListener()"); + } + + @Override + public void dispose() { + System.out.println("InformationHidingHandler#dispose()"); + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + System.out.println("InformationHidingHandler#execute()"); + JavaEditor editor = (JavaEditor) HandlerUtil.getActiveEditor(event); + ISelection activeMenuSelection = HandlerUtil.getActiveMenuSelection(event); // TextSelection������ꂽ + + IJavaElement[] elements = null; + + try { + elements= SelectionConverter.codeResolve(editor); + } catch (JavaModelException e) { + e.printStackTrace(); + } + + element = elements[0]; + + for (int i = 0; i < elements.length; i++) { + if (elements[i] != null && elements[i].getElementType() == IJavaElement.METHOD) { + try { + IMethod method = (IMethod) elements[i]; + if (method.isMainMethod()) { + System.out.println("MainMethod : " + method); + } else { + System.out.println("Method : " + method); + } + } catch (JavaModelException e) { + } + } else if (elements[i] != null && elements[i].getElementType() == IJavaElement.TYPE) { + try { + IType type = (IType) elements[i]; + if (type.isClass()) { + System.out.println("Class : " + type); +// startingClassName = type.toString(); + } + } catch (JavaModelException e) { + } + } else if (elements[i] != null && elements[i].getElementType() == IJavaElement.LOCAL_VARIABLE) { + System.out.println("Var"); + ILocalVariable var = (ILocalVariable) elements[i]; + if (var.isParameter()) { + System.out.println("Var : " + var); + } else { + System.out.println("Var2 : " + var); + } + } else if (elements[i] != null && elements[i].getElementType() == IJavaElement.FIELD) { + System.out.println("Field"); + IField field = (IField) elements[i]; + try { + if (field.isEnumConstant()) { + System.out.println("Field : " + field); + } + } catch (JavaModelException e) { + e.printStackTrace(); + } + } + } + + checkingHandlerUtil(event); + + ITypeRoot typeRoot = SelectionConverter.getInput((JavaEditor) HandlerUtil.getActiveEditor(event)); + IJavaProject javaProject = typeRoot.getJavaProject(); + IJavaElement[] codeSelect = null; + try { + codeSelect = typeRoot.codeSelect(((ITextSelection) activeMenuSelection).getOffset(), ((ITextSelection) activeMenuSelection).getLength()); + } catch (JavaModelException e) { + e.printStackTrace(); + } + + CompilationUnit node = RefactoringASTParser.parseWithASTProvider(typeRoot, true, null); + parseASTNodeByUsingVisitor((ICompilationUnit) typeRoot); + + // �I�������v�f�̂��ׂĂ̏o���ꏊ������ + ASTNode[] sameNodes = findSameNodes(editor); + for (int i = 0; i < sameNodes.length; i++) { + System.out.println(sameNodes[i].getRoot().toString()); + } + + ASTNode target = findASTNodeByNodeFinderPerform(typeRoot, node, (ITextSelection) activeMenuSelection); + ASTNode root = target.getRoot(); + IJavaElement[] javaElement = findJavaElement(editor); + + tryInformationHidindRefactoring(typeRoot, node, (ITextSelection) activeMenuSelection, HandlerUtil.getActiveShell(event)); + + return null; + } + + /** + * HandlerUtil#getCurrentSelection()�ł͐�����Selection�����Ȃ��Ⴊ������(length, offset����0�ɂȂ�)���߁A�������g�����Ƃɂ����B + */ + private ITextSelection getCurrentITextSelection(ExecutionEvent event) { + ITextSelection selection = (ITextSelection) HandlerUtil.getCurrentSelection(event); + + if (selection.getOffset() == 0 && selection.getLength() == 0) { + selection = (ITextSelection) HandlerUtil.getActiveMenuSelection(event); + } + + return selection; + } + + private void checkingHandlerUtil(ExecutionEvent event) { + Collection activeContexts = HandlerUtil.getActiveContexts(event); + IEditorPart activeEditor = HandlerUtil.getActiveEditor(event); + String activeEditorId = HandlerUtil.getActiveEditorId(event); + IEditorInput activeEditorInput = HandlerUtil.getActiveEditorInput(event); + ISelection activeMenuEditorInput = HandlerUtil.getActiveMenuEditorInput(event); + Collection activeMenus = HandlerUtil.getActiveMenus(event); + ISelection activeMenuSelection = HandlerUtil.getActiveMenuSelection(event); + System.out.println("InformationHidingHandler#checkingHandlerUtil() activeMenuSelection: " + ((ITextSelection) activeMenuSelection).getText()); + IWorkbenchPart activePart = HandlerUtil.getActivePart(event); + String activePartId = HandlerUtil.getActivePartId(event); + Shell activeShell = HandlerUtil.getActiveShell(event); + IWorkbenchSite activeSite = HandlerUtil.getActiveSite(event); + IWorkbenchWindow activeWorkbenchWindow = HandlerUtil.getActiveWorkbenchWindow(event); + ISelection currentSelection = HandlerUtil.getCurrentSelection(event); + System.out.println("InformationHidingHandler#checkingHandlerUtil() currentSelection: " + ((ITextSelection) currentSelection).getText()); + Object showInInput = HandlerUtil.getShowInInput(event); + ISelection showInSelection = HandlerUtil.getShowInSelection(event); + + IJavaElement javaElement = JavaUI.getEditorInputJavaElement(activeEditorInput); + ITypeRoot typeRoot = JavaUI.getEditorInputTypeRoot(activeEditorInput); + + System.err.println(); + } + + private void parseASTNodeByUsingVisitor(ICompilationUnit element) { + ASTParser parser = ASTParser.newParser(AST.JLS8); + parser.setSource(element); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + CompilationUnit node = (CompilationUnit) parser.createAST(new NullProgressMonitor()); +// node.accept(new ASTVisitorImpl()); + } + + private IJavaElement[] findJavaElement(JavaEditor editor) { + IJavaElement[] javaElement = null; + try { + javaElement = SelectionConverter.codeResolve(editor); + } catch (JavaModelException e) { + e.printStackTrace(); + } + return javaElement; + } + + private ASTNode[] findSameNodes(JavaEditor editor) { + ISourceViewer viewer= editor.getViewer(); + Point fOriginalSelection= viewer.getSelectedRange(); + CompilationUnit root= SharedASTProvider.getAST((ICompilationUnit) EditorUtility.getEditorInputJavaElement(editor, false), SharedASTProvider.WAIT_YES, null); + ASTNode selectedNode= NodeFinder.perform(root, fOriginalSelection.x, fOriginalSelection.y); + return LinkedNodeFinder.findByNode(root, (SimpleName) selectedNode); + } + + private IJavaElement[] codeResolve(ExecutionEvent event) throws JavaModelException { + IEditorInput activeEditorInput = HandlerUtil.getActiveEditorInput(event); + ITypeRoot input = JavaUI.getEditorInputTypeRoot(activeEditorInput); + + if (input instanceof ICodeAssist) { + if (input instanceof ICompilationUnit) { + reconcile(input); + } + ITextSelection selection = getCurrentITextSelection(event); + IJavaElement[] elements = ((ICodeAssist)input).codeSelect(selection.getOffset() + selection.getLength(), 0); + if (elements.length > 0) { + return elements; + } + } + + return new IJavaElement[0]; + } + + private void reconcile(ITypeRoot input) throws JavaModelException { + ((ICompilationUnit) input).reconcile( + 0, // no AST + false /* don't force problem detection */, + null /* use primary owner */, + null /* no progress monitor */); + } + + private void tryInformationHidindRefactoring(ITypeRoot typeRoot, CompilationUnit node, ITextSelection selection, Shell shell) { + ASTNode target = findASTNodeByNodeFinderPerform(typeRoot, node, selection); + + DecoupleClassesRefactoring refactoring = null; + refactoring = new DecoupleClassesRefactoring(new DecoupleClassesRefactoringProcessor(null)); + + if (target.getNodeType() == ASTNode.TYPE_METHOD_REFERENCE) { + System.out.println("TYPE_METHOD_REFERENCE"); + } + + if (refactoring != null) { + openWizard(shell, refactoring); + } + } + + private void openWizard(Shell shell, DecoupleClassesRefactoring refactoring) { + WizardDialog dialog = new WizardDialog(null, new DecoupleClassesWizard(refactoring)); + dialog.setPageSize(500, 300); + dialog.open(); + // // new RefactoringStarter().activate(new InformationHidingWizard(refactoring), shell, refactoring.getName(), RefactoringSaveHelper.SAVE_REFACTORING); + // RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(new InformationHidingWizard(refactoring)); + // try { + // op.run(shell, refactoring.getName()); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // return; + } + + private ASTNode findASTNodeByNodeFinderPerform(ITypeRoot typeRoot, CompilationUnit node, ITextSelection selection) { + ASTNode target = null; + + try { + target = NodeFinder.perform(node, selection.getOffset(), selection.getLength(), typeRoot); + } catch (JavaModelException e) { + } + + if (target == null) { + target = NodeFinder.perform(node, selection.getOffset(), selection.getLength()); + } + + return target; + } + + @Override + public boolean isEnabled() { + System.out.println("InformationHidingHandler#isEnabled()"); + return true; + } + + @Override + public boolean isHandled() { + System.out.println("InformationHidingHandler#isHandled()"); + return true; + } + + @Override + public void removeHandlerListener(IHandlerListener handlerListener) { + System.out.println("InformationHidingHandler#removeHandlerListener()"); + } + + public static IJavaElement getElement() { + return element; + } + + public void setElement(IJavaElement element) { + this.element = element; + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/RefactoringTaskGenerator.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/RefactoringTaskGenerator.java new file mode 100644 index 0000000..6face45 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/RefactoringTaskGenerator.java @@ -0,0 +1,423 @@ +package org.ntlab.refactoring.decouplingClasses; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IType; +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.ASTVisitor; +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.IBinding; +import org.eclipse.jdt.core.dom.IMethodBinding; +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.Name; +import org.eclipse.jdt.core.dom.ReturnStatement; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; +import org.eclipse.jdt.core.dom.TypeDeclaration; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.ntlab.refactoring.decouplingClasses.refactoringApplication.ContractedRefactoring; +import org.ntlab.refactoring.decouplingClasses.refactoringApplication.HideDelegate; +import org.ntlab.refactoring.decouplingClasses.refactoringApplication.IntroduceParameterObject; +import org.ntlab.refactoring.decouplingClasses.refactoringApplication.PreserveWholeObject; +import org.ntlab.refactoring.decouplingClasses.refactoringApplication.PrimitiveRefactoring; +import org.ntlab.refactoring.decouplingClasses.refactoringApplication.RefactoringApplication; +import org.ntlab.refactoring.decouplingClasses.refactoringApplication.ReplaceTypeByHiding; +import org.ntlab.refactoring.decouplingClasses.refactoringApplication.ReturnWholeObject; + +import test.pseudocode.core.Node; + +public class RefactoringTaskGenerator { + private IType targetClass = null; + private List cFrom = null; + + /** Refactoring Unit, Refactoring*/ + public Map> refactoringTasks = new HashMap<>(); + + public List generateTasks() { + refactoringTasks.clear(); + + exploreClasses(); + resolveDependenceOfTasks(); + contractRefactorings(); + + return refactoringTasksToList(); + } + + private void exploreClasses() { + ASTParser parser = ASTParser.newParser(AST.JLS8); + + parser.setResolveBindings(true); + parser.setBindingsRecovery(true); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + + for (IType clientType: cFrom) { + parser.setSource(clientType.getCompilationUnit()); + + CompilationUnit cuNode = (CompilationUnit) parser.createAST(null); + System.out.println("--- " + cuNode.getJavaElement().getElementName() + " ---"); + // �^�[�Q�b�g�N���X�̏o���ʒu�ɉ����Ċ�{���t�@�N�^�����O��lj�����B + cuNode.accept(new ASTVisitor() { + @Override + public boolean visit(MethodDeclaration node) { + for (Object obj: node.parameters()) { + SingleVariableDeclaration parameter = (SingleVariableDeclaration) obj; + + String targetName = targetClass.getElementName(); + String parameterTypeName = parameter.getType().toString(); + if (parameterTypeName.equals(targetName)) { + System.out.println("Formal Parameter: " + node.toString()); + TypeDeclaration declaringType = c(node); + if (!isCfrom(declaringType)) { + addRefactoringTask(node, new IntroduceParameterObject(node)); + break; + } + } + } + + return super.visit(node); + } + + private boolean isCfrom(TypeDeclaration declaringType) { + for (IType type: cFrom) { + if (type.getElementName().equals(declaringType.getName().toString())) { + return true; + } + } + return false; + } + + @Override + public boolean visit(VariableDeclarationStatement node) { + String targetName = targetClass.getElementName(); + String typeName = node.getType().toString(); + if (typeName.equals(targetName)) { + System.out.println("Variable Declaration Statement: " + node.toString()); + addRefactoringTask(c(node), new ReplaceTypeByHiding(node)); + } + return super.visit(node); + } + + @Override + public boolean visit(FieldDeclaration node) { + String targetName = targetClass.getElementName(); + String nodeName = node.getType().toString(); + if (targetName.equals(nodeName)) { + System.out.println("Field Declaration: " + node.toString()); + addRefactoringTask(c(node), new ReplaceTypeByHiding(node)); + } + return super.visit(node); + } + + @Override + public boolean visit(MethodInvocation node) { + // ���̂��������Ő錾���ꂽ�ϐ��ւ̃��\�b�h�Ăяo������Binding�����Ȃ��B + // ���l�ɁA���̃��V�[�o�̌^���������邱�Ƃ��ł��Ȃ��B + IMethodBinding methodBinding = node.resolveMethodBinding(); + ITypeBinding typeBinding = node.resolveTypeBinding(); + if (methodBinding == null) { + System.out.println(); + } + + Expression receiver = node.getExpression(); + ITypeBinding receiverTypeBinding = null; + if (receiver != null) { + receiverTypeBinding = receiver.resolveTypeBinding(); + } + +// MethodDeclaration declaration = toASTNode(methodBinding); +// if (!isCfrom((IType) methodBinding.getDeclaringClass().getJavaElement())) { +// addRefactoringTask(declaration, new IntroduceReturnValueObject(node)); +// } + + for (Object obj: node.arguments()) { + String parameterTypeName = ""; + if (obj instanceof Name) { + IBinding binding = ((Name) obj).resolveBinding(); + parameterTypeName = binding.getName(); + } +// ITypeBinding typeBinding = ((Expression) obj).resolveTypeBinding(); + String targetName = targetClass.getElementName(); + if (parameterTypeName.equals(targetName)) { + System.out.println("Method Invocation: " + node.toString()); +// addRefactoringTask(m(node), new PreserveWholeObject(node.declaration())); + break; + } + } +// Expression receiver = node.getExpression(); +// ITypeBinding receiverTypeBinding = receiver.resolveTypeBinding(); +// if (receiver.getTypeName().equals(targetName)) { +// addRefactoringTask(m(node), new HideDelegate(node)); +// break; +// } + + return super.visit(node); + } + + private MethodDeclaration toASTNode(final IMethodBinding methodBinding) { + + IMethod javaelement = (IMethod) methodBinding.getJavaElement(); + ASTParser parser = ASTParser.newParser(AST.JLS8); + + parser.setResolveBindings(true); + parser.setBindingsRecovery(true); + parser.setSource(javaelement.getCompilationUnit()); + + CompilationUnit cu = (CompilationUnit) parser.createAST(null); + final List result = new ArrayList<>(); + cu.accept(new ASTVisitor() { + @Override + public boolean visit(MethodDeclaration node) { + if (node.getName().toString().equals(methodBinding.getName())) { + result.add(node); + } + return super.visit(node); + } + }); + System.out.println(); + + return result.get(0); + } + + private boolean isCfrom(IType classType) { + String targetTypeName = targetClass.getElementName(); + for (IType type: cFrom) { + String typeName = type.getElementName(); + if (typeName.equals(targetTypeName)) { + return true; + } + } + return false; + } + + @Override + public boolean visit(ReturnStatement node) { + System.out.println("Return Statement: " + node.toString()); + MethodDeclaration mDec = m(node); + String returnTypeName = mDec.getReturnType2().toString(); + String targetTypeName = targetClass.getElementName(); + if (returnTypeName.equals(targetTypeName)) { + addRefactoringTask(mDec, new ReturnWholeObject(node)); + } + + return super.visit(node); + } + + private MethodDeclaration m(ASTNode l) { + while (l != null && !(l instanceof MethodDeclaration)) { + l = l.getParent(); + } + return (MethodDeclaration) l; + } + + private TypeDeclaration c(ASTNode l) { + while (l != null && !(l instanceof TypeDeclaration)) { + l = l.getParent(); + } + return (TypeDeclaration) l; + } + + private void addRefactoringTask(ASTNode refactoringUnit, RefactoringApplication refactoring) { + List list = refactoringTasks.get(refactoringUnit); + if (list == null) { + list = new ArrayList(); + refactoringTasks.put(refactoringUnit, list); + } + list.add(refactoring); + } + }); + System.out.println(); + } + } + + // private boolean isConstructorOfTarget(MethodInvocation invocation) { + // if (!invocation.isConstructor()) { + // return false; + // } + // return invocation.getValueType().equals(targetClass); + // } + + // private boolean isCFrom(ASTNode node) { + // TypeDeclaration targetClass = null; + // if (node instanceof TypeDeclaration) { + // targetClass = (TypeDeclaration) node; + // } else if (node instanceof MethodDeclaration) { + // targetClass = (TypeDeclaration) node.getParent(); + // } else if (node instanceof MethodInvocation) { + // targetClass = ((MethodInvocation) node).getDeclaration().getParent(); + // } + // + // return cFrom.contains(targetClass); + // } + + private void resolveDependenceOfTasks() { + for (Iterator> i = refactoringTasks.values().iterator(); i.hasNext();) { + for (RefactoringApplication refactoring: i.next()) { + establishDependenceFor((PrimitiveRefactoring) refactoring); + } + } + } + + @SuppressWarnings("unchecked") + private void establishDependenceFor(PrimitiveRefactoring refactoring) { + // // �R�����g�͂��ׂ�ApplicationPoint���N�_�Ƃ���B + // if (refactoring.isInstanceOf(IntroduceParameterObject.class)) { + // // �ˑ����Ȃ� + // } else if (refactoring.isInstanceOf(IntroduceReturnValueObject.class)) { + // // �ˑ����Ȃ� + // } else if (refactoring.isInstanceOf(ReplaceTypeByHiding.class)) { + // ASTNode applicationPoint = refactoring.getApplicationPoint(); + // if (applicationPoint instanceof FieldDeclaration) { + // FieldDeclaration l = (FieldDeclaration) applicationPoint; + // TypeDeclaration parentType = l.getParent(); + // for (MethodDeclaration m: parentType.getMethods()) { + // refactoring.dependsOn(findRefactorings(m, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class})); + // for (MethodInvocation l2: m.getInvocations()) { + // MethodDeclaration mDash = l2.getDeclaration(); + // refactoring.dependsOn(findRefactorings(mDash, new Class[] {ReturnWholeObject.class, IntroduceReturnValueObject.class})); + // } + // } + // } + // if (applicationPoint instanceof VariableDeclaration) { + // VariableDeclaration l = (VariableDeclaration) applicationPoint; + // MethodDeclaration ml = m(l); + // refactoring.dependsOn(findRefactorings(ml, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class})); + // + // for (MethodInvocation l2: ml.getInvocations()) { + // MethodDeclaration m = l2.getDeclaration(); + // refactoring.dependsOn(findRefactorings(m, new Class[] {ReturnWholeObject.class, IntroduceReturnValueObject.class})); + // } + // } + // refactoring.dependsOn(findRefactorings(applicationPoint, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class})); + // } else if (refactoring.isInstanceOf(HideDelegate.class)) { + // // ���\�b�h����ReplaceTypeByHiding�Ɉˑ�����B + // MethodInvocation invocation = (MethodInvocation) refactoring.getApplicationPoint(); + // MethodDeclaration enclosing = (MethodDeclaration) invocation.getParent(); + // refactoring.dependsOn(findRefactorings(enclosing, new Class[] { + // IntroduceParameterObject.class, + // PreserveWholeObject.class, + // IntroduceReturnValueObject.class, + // ReturnWholeObject.class, + // ReplaceTypeByHiding.class})); + // } else if (refactoring.isInstanceOf(PreserveWholeObject.class)) { + // // �Ăяo�����̒�`�ɑ΂�������ύX�Ɉˑ�����B + // // �Ăяo������ReplaceTypeByHiding�Ɉˑ�����? + // MethodInvocation applicationPoint = (MethodInvocation) refactoring.getApplicationPoint(); + // MethodDeclaration enclosing = (MethodDeclaration) applicationPoint.getParent(); + // refactoring.dependsOn(findRefactorings(enclosing, new Class[] {IntroduceParameterObject.class, + // PreserveWholeObject.class})); + // TypeDeclaration type = enclosing.getParent(); + // refactoring.dependsOn(findRefactorings(type, new Class[] {ReplaceTypeByHiding.class})); + // + // // �Ăяo����̒�`�ɑ΂���߂�l�̌^�ύX�Ɉˑ�����B + // for (MethodInvocation invocation: enclosing.getInvocations()) { + // if (invocation.equals(applicationPoint)) { + // continue; + // } + // MethodDeclaration declaration = invocation.getDeclaration(); + // refactoring.dependsOn(findRefactorings(declaration, new Class[] { ReturnWholeObject.class, + // IntroduceReturnValueObject.class})); + // } + // } else if (refactoring.isInstanceOf(ReturnWholeObject.class)) { + // // �e�Ăяo����̒�`�ɑ΂���߂�l�̌^�ύX�Ɉˑ�����B + // ReturnValue returnStatement = (ReturnValue) refactoring.getApplicationPoint(); + // MethodDeclaration enclosing = (MethodDeclaration) m(returnStatement); + // refactoring.dependsOn(findRefactorings(enclosing, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class})); + // TypeDeclaration type = enclosing.getParent(); + // refactoring.dependsOn(findRefactorings(type, new Class[] {ReplaceTypeByHiding.class})); + // for (MethodInvocation invocation: enclosing.getInvocations()) { + // MethodDeclaration invokeeDeclaration = invocation.getDeclaration(); + // refactoring.dependsOn(findRefactorings(invokeeDeclaration, new Class[] {IntroduceReturnValueObject.class, ReturnWholeObject.class})); + // } + // } + } + + private MethodDeclaration m(ASTNode node) { + ASTNode result = node; + + do { + result = result.getParent(); + } while(result != null && !(result instanceof MethodDeclaration)); + + return (MethodDeclaration) result; + } + + private List findRefactorings(ASTNode refactoringUnit, Class[] refactoringTypes) { + List list = refactoringTasks.get(refactoringUnit); + return findRefactorings(list, refactoringTypes); + } + + private List findRefactorings(List findFrom, Class[] refactoringTypes) { + List result = new ArrayList<>(); + + if (findFrom == null) { + return result; + } + + for (RefactoringApplication candidate: findFrom) { + for (Class type: refactoringTypes) { + if (candidate.isInstanceOf(type)) { + result.add(candidate); + } + } + } + return result; + } + + /** + * �����ɓK�p���郊�t�@�N�^�����O���܂Ƃ߂�B + */ + @SuppressWarnings("unchecked") + private void contractRefactorings() { + for (Iterator> i = refactoringTasks.values().iterator(); i.hasNext();) { + // ����JavaElement�ɑ΂��ēK�p���郊�t�@�N�^�����O�Q + List list = i.next(); + contractRefactorings("Change Signature", list, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class}); + contractRefactorings("Hide Delegates", list, new Class[] {HideDelegate.class}); + } + } + + private void contractRefactorings(String name, List list, Class[] refactoringTypes) { + List primitives = findRefactorings(list, refactoringTypes); + + // ����”\�ȃ��t�@�N�^�����O��2�ˆȏ゠��΍�������B + if (primitives.size() >= 2) { + ContractedRefactoring composition = new ContractedRefactoring(name); + composition.addAll(primitives); + replace(list, primitives, composition); + } + } + + private void replace(List list, List primitives, ContractedRefactoring composition) { + list.add(composition); + list.removeAll(primitives); + } + + private List refactoringTasksToList() { + List list = new ArrayList<>(); + + for (Iterator> i = refactoringTasks.values().iterator(); i.hasNext();) { + list.addAll(i.next()); + } + + return list; + } + + public void setCfrom(List cFrom) { + this.cFrom = cFrom; + } + + public void setTargetClass(IType targetClass) { + this.targetClass = targetClass; + } + +} \ No newline at end of file diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/TargetOccurenceSearchEngine.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/TargetOccurenceSearchEngine.java new file mode 100644 index 0000000..97bb9ec --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/TargetOccurenceSearchEngine.java @@ -0,0 +1,135 @@ +package org.ntlab.refactoring.decouplingClasses; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.core.search.SearchMatch; +import org.eclipse.jdt.core.search.SearchParticipant; +import org.eclipse.jdt.core.search.SearchPattern; +import org.eclipse.jdt.core.search.SearchRequestor; + +public class TargetOccurenceSearchEngine { + private final SearchEngine defaultSearchEngine = new SearchEngine(); + private final SearchParticipant[] defaultParticipant = new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}; + private final IJavaSearchScope defaultScope = SearchEngine.createWorkspaceScope(); + + public List findOccurences(final IType target) { + if (target == null) { + return new ArrayList<>(); + } + + CollectingRequestor requestor = new CollectingRequestor() { + @Override + public void acceptSearchMatch(SearchMatch match) throws CoreException { + IJavaElement element = (IJavaElement) match.getElement(); + collect(element); + if (element instanceof IMethod) { + searchMethodInvocations((IMethod) element, this); + } + } + }; + searchTypeOccurences(target, requestor); + + return requestor.getResults(); + } + + public List findClients(final IType target) { + if (target == null) { + return new ArrayList<>(); + } + + CollectingRequestor requestor = new CollectingRequestor() { + @Override + public void acceptSearchMatch(SearchMatch match) throws CoreException { + IJavaElement element = (IJavaElement) match.getElement(); + + if (element instanceof IMethod) { + searchMethodInvocations((IMethod) element, this); + } + + IType client = getEnclosingType(element); + if (client == null || client.equals(target)) { + return; + } + if (!contains(client)) { + collect(client); + } + } + }; + searchTypeOccurences(target, requestor); + + return requestor.getResults(); + } + + /** + * IJavaElement���͂�ł���IType���擾����B + */ + private IType getEnclosingType(IJavaElement element) { + while (element != null) { + if (element instanceof IType) { + return (IType) element; + } + element = element.getParent(); + } + return null; + } + + private void searchTypeOccurences(IType target, SearchRequestor requestor) { + SearchPattern pattern = SearchPattern.createPattern( + target, + IJavaSearchConstants.ALL_OCCURRENCES, + SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH); + + try { + defaultSearchEngine.search(pattern, defaultParticipant, defaultScope, requestor, new NullProgressMonitor()); + } catch (CoreException e) { + e.printStackTrace(); + return; + } + } + + private void searchMethodInvocations(IMethod target, SearchRequestor requestor) { + SearchPattern pattern = SearchPattern.createPattern( + target, + IJavaSearchConstants.REFERENCES, + SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH); + + try { + defaultSearchEngine.search(pattern, defaultParticipant, defaultScope, requestor, new NullProgressMonitor()); + } catch (CoreException e) { + e.printStackTrace(); + return; + } + } + + private class CollectingRequestor extends SearchRequestor { + protected List results = new ArrayList<>(); + + @Override + public void acceptSearchMatch(SearchMatch match) throws CoreException { + collect((IJavaElement) match.getElement()); + } + + public void collect(IJavaElement element) { + results.add(element); + } + + public List getResults() { + return results; + } + + public boolean contains(IJavaElement element) { + return results.contains(element); + } + + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/descriptors/DecoupleClassesDescriptor.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/descriptors/DecoupleClassesDescriptor.java new file mode 100644 index 0000000..ee270f7 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/descriptors/DecoupleClassesDescriptor.java @@ -0,0 +1,65 @@ +package org.ntlab.refactoring.decouplingClasses.descriptors; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor; +import org.ntlab.refactoring.decouplingClasses.DecoupleClassesRefactoring; + +public class DecoupleClassesDescriptor extends JavaRefactoringDescriptor { + private String newClassName = ""; + private String packageName = ""; + private IType targetClass = null; + private List clients = new ArrayList<>(); + + public DecoupleClassesDescriptor() { + super(DecoupleClassesRefactoring.ID); + } + + public DecoupleClassesDescriptor(String project, String description, String comment, Map arguments, int flags) throws IllegalArgumentException { + super(DecoupleClassesRefactoring.ID, project, description, comment, arguments, flags); + } + + public void setNewClassName(String text) { + this.newClassName = text; + } + + public String getNewClassName() { + return newClassName; + } + + public void setPackage(String packageName) { + this.packageName = packageName; + } + + public String getPackage() { + return packageName; + } + + public String getTargetName() { + return targetClass.getElementName(); + } + + public void setTargetType(IType targetClass) { + this.targetClass = targetClass; + } + + public IType getTargetType() { + return targetClass; + } + + public List getClients() { + return clients; + } + + public void addClient(IType client) { + clients.add(client); + } + + public void removeClient(IType client) { + clients.remove(client); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/descriptors/DecoupleClassesRefactoringContribution.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/descriptors/DecoupleClassesRefactoringContribution.java new file mode 100644 index 0000000..c6a76b0 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/descriptors/DecoupleClassesRefactoringContribution.java @@ -0,0 +1,37 @@ +package org.ntlab.refactoring.decouplingClasses.descriptors; + +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringContribution; +import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor; +import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.ntlab.refactoring.decouplingClasses.DecoupleClassesRefactoring; +import org.ntlab.refactoring.decouplingClasses.DecoupleClassesRefactoringProcessor; + +public class DecoupleClassesRefactoringContribution extends JavaRefactoringContribution { + + @Override + public Refactoring createRefactoring(JavaRefactoringDescriptor descriptor, RefactoringStatus status) throws CoreException { + if (!(descriptor instanceof DecoupleClassesDescriptor)) { + status.addFatalError("Unknown Descriptor"); + return null; + } + + return new DecoupleClassesRefactoring(new DecoupleClassesRefactoringProcessor((DecoupleClassesDescriptor) descriptor)); + } + + @Override + public RefactoringDescriptor createDescriptor() throws IllegalArgumentException { + return new DecoupleClassesDescriptor(); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public RefactoringDescriptor createDescriptor(String id, String project, String description, String comment, Map arguments, int flags) throws IllegalArgumentException { + return new DecoupleClassesDescriptor(project, description, comment, arguments, flags); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/ContractedRefactoring.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/ContractedRefactoring.java new file mode 100644 index 0000000..6a8d8be --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/ContractedRefactoring.java @@ -0,0 +1,97 @@ +package org.ntlab.refactoring.decouplingClasses.refactoringApplication; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.core.dom.ASTNode; + +import test.pseudocode.core.Node; + +public class ContractedRefactoring extends RefactoringApplication { + private List children = new ArrayList<>(); + + public ContractedRefactoring() { + super("Refactoring Composition"); + } + + public ContractedRefactoring(String name) { + super(name); + } + + public void add(RefactoringApplication primitive) { + children.add(primitive); + primitive.setParent(this); + } + + public void addAll(List primitives) { + children.addAll(primitives); + for (RefactoringApplication primitive: primitives) { + primitive.setParent(this); + } + } + + public List getPrimitives() { + return children; + } + + @Override + public boolean isInstanceOf(Class type) { + for (RefactoringApplication primitive: getPrimitives()) { + if (primitive.isInstanceOf(type)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + String nl = System.getProperty("line.separator"); + String result = "[" + getName() + "] to " + getApplicationPoint().toString() + " {" + nl; + if (!getPrimitives().isEmpty()) { + result += " Contains" + nl; + for (RefactoringApplication primitive: getPrimitives()) { + result += " L [" + primitive.getName() + "] to " + primitive.getApplicationPoint().toString() + nl; + } + } + if (!getDependents().isEmpty()) { + result += " Dependents" + nl; + for (Node dep: getDependents()) { + RefactoringApplication ref = (RefactoringApplication) dep; + ASTNode applicationPoint = ref.getApplicationPoint(); + result += " L [" + ref.getName() + "] to " + applicationPoint.toString() + nl; + } + } + result += "}"; + + return result; + } + + public int size() { + return children.size(); + } + + public RefactoringApplication get(int i) { + return children.get(i); + } + + @Override + public ASTNode getApplicationPoint() { + if (!children.isEmpty()) { + return children.get(0).getApplicationPoint(); + } + return null; + } + + public List getDependents() { + List result = new ArrayList<>(); + for (RefactoringApplication primitive: getPrimitives()) { + for (Node dependent: primitive.getDependents()) { + if (!result.contains(dependent)) { + result.add(dependent); + } + } + } + return result; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/HideDelegate.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/HideDelegate.java new file mode 100644 index 0000000..ef5aaf8 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/HideDelegate.java @@ -0,0 +1,15 @@ +package org.ntlab.refactoring.decouplingClasses.refactoringApplication; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.MethodInvocation; + +public class HideDelegate extends PrimitiveRefactoring { + + public HideDelegate(ASTNode applicationPoint) { + super("Hide Delegate", applicationPoint); + } + + public MethodInvocation getApplicationPoint() { + return (MethodInvocation) super.getApplicationPoint(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/IntroduceParameterObject.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/IntroduceParameterObject.java new file mode 100644 index 0000000..b593365 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/IntroduceParameterObject.java @@ -0,0 +1,17 @@ +package org.ntlab.refactoring.decouplingClasses.refactoringApplication; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.MethodDeclaration; + +public class IntroduceParameterObject extends PrimitiveRefactoring { + + public IntroduceParameterObject(ASTNode applicationPoint) { + super("Introduce Parameter Object", applicationPoint); + } + + @Override + public MethodDeclaration getApplicationPoint() { + return (MethodDeclaration) super.getApplicationPoint(); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/IntroduceReturnValueObject.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/IntroduceReturnValueObject.java new file mode 100644 index 0000000..46eb728 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/IntroduceReturnValueObject.java @@ -0,0 +1,11 @@ +package org.ntlab.refactoring.decouplingClasses.refactoringApplication; + +import org.eclipse.jdt.core.dom.ASTNode; + +public class IntroduceReturnValueObject extends PrimitiveRefactoring { + + public IntroduceReturnValueObject(ASTNode applicationPoint) { + super("Introduce Return Value Object", applicationPoint); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/PreserveWholeObject.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/PreserveWholeObject.java new file mode 100644 index 0000000..bb01358 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/PreserveWholeObject.java @@ -0,0 +1,16 @@ +package org.ntlab.refactoring.decouplingClasses.refactoringApplication; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.MethodInvocation; + +public class PreserveWholeObject extends PrimitiveRefactoring { + + public PreserveWholeObject(ASTNode applicationPoint) { + super("Preserve Whole Object", applicationPoint); + } + + @Override + public MethodInvocation getApplicationPoint() { + return (MethodInvocation) super.getApplicationPoint(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/PrimitiveRefactoring.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/PrimitiveRefactoring.java new file mode 100644 index 0000000..ab6932d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/PrimitiveRefactoring.java @@ -0,0 +1,60 @@ +package org.ntlab.refactoring.decouplingClasses.refactoringApplication; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.core.dom.ASTNode; + +import test.pseudocode.core.Node; + +public abstract class PrimitiveRefactoring extends RefactoringApplication { + private ASTNode applicationPoint; + private List dependents = new ArrayList<>(); + + public PrimitiveRefactoring(String name, ASTNode applicationPoint) { + super(name); + this.applicationPoint = applicationPoint; + } + + public ASTNode getApplicationPoint() { + return applicationPoint; + } + + @Override + public boolean isInstanceOf(Class type) { + return type.isInstance(this); + } + + @Override + public String toString() { + String result = "[" + getName() + "] to " + getApplicationPoint().toString(); + + if (!getDependents().isEmpty()) { + String nl = System.getProperty("line.separator"); + result += " {" + nl + " Dependents" + nl; + for (Node dep: getDependents()) { + RefactoringApplication ref = (RefactoringApplication) dep; + ASTNode applicationPoint = ref.getApplicationPoint(); + result += " L [" + ref.getName() + "] to " + applicationPoint.toString() + nl; + } + result += "}"; + } + return result; + } + + public void dependsOn(RefactoringApplication refactroing) { + dependents.add(refactroing); + } + + public void dependsOn(List refactorings) { + dependents.addAll(refactorings); + } + + public List getDependents() { + List result = new ArrayList<>(); + for (Node dependent: dependents) { + result.add(((RefactoringApplication) dependent).getRoot()); + } + return result; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/RefactoringApplication.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/RefactoringApplication.java new file mode 100644 index 0000000..395b53c --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/RefactoringApplication.java @@ -0,0 +1,47 @@ +package org.ntlab.refactoring.decouplingClasses.refactoringApplication; + +import org.eclipse.jdt.core.dom.ASTNode; + +import test.pseudocode.core.Node; + +public abstract class RefactoringApplication implements Node { + protected String name = ""; + private boolean visited = false; + private RefactoringApplication parent = null; + + public RefactoringApplication(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public abstract boolean isInstanceOf(Class type); + + public abstract ASTNode getApplicationPoint(); + public abstract String toString(); + + public void visited() { + this.visited = true; + } + + public boolean isNotVisited() { + return !visited; + } + + public RefactoringApplication getRoot() { + if (parent == null) { + return this; + } + return parent.getRoot(); + } + + public RefactoringApplication getParent() { + return parent; + } + + public void setParent(RefactoringApplication parent) { + this.parent = parent; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/ReplaceTypeByHiding.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/ReplaceTypeByHiding.java new file mode 100644 index 0000000..ec7b442 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/ReplaceTypeByHiding.java @@ -0,0 +1,10 @@ +package org.ntlab.refactoring.decouplingClasses.refactoringApplication; + +import org.eclipse.jdt.core.dom.ASTNode; + +public class ReplaceTypeByHiding extends PrimitiveRefactoring { + + public ReplaceTypeByHiding(ASTNode applicationPoint) { + super("Replace Type by Hiding", applicationPoint); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/ReturnWholeObject.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/ReturnWholeObject.java new file mode 100644 index 0000000..b8b0582 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/refactoringApplication/ReturnWholeObject.java @@ -0,0 +1,16 @@ +package org.ntlab.refactoring.decouplingClasses.refactoringApplication; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ReturnStatement; + +public class ReturnWholeObject extends PrimitiveRefactoring { + + public ReturnWholeObject(ASTNode applicationPoint) { + super("Return Whole Object", applicationPoint); + } + + @Override + public ReturnStatement getApplicationPoint() { + return (ReturnStatement) super.getApplicationPoint(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/ui/DecoupleClassesWizard.java b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/ui/DecoupleClassesWizard.java new file mode 100644 index 0000000..ef1ee7c --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/ui/DecoupleClassesWizard.java @@ -0,0 +1,230 @@ +package org.ntlab.refactoring.decouplingClasses.ui; + +import java.util.List; + +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IType; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.ltk.ui.refactoring.RefactoringWizard; +import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; +import org.ntlab.refactoring.decouplingClasses.DecoupleClassesRefactoring; +import org.ntlab.refactoring.decouplingClasses.DecoupleClassesRefactoringPlugin; +import org.ntlab.refactoring.decouplingClasses.DecoupleClassesRefactoringProcessor; +import org.ntlab.refactoring.decouplingClasses.TargetOccurenceSearchEngine; +import org.ntlab.refactoring.decouplingClasses.descriptors.DecoupleClassesDescriptor; + +public class DecoupleClassesWizard extends RefactoringWizard { + private static final String SEARCHING = "Searching..."; + + private DecoupleClassesDescriptor descriptor = null; + + public DecoupleClassesWizard(DecoupleClassesRefactoring refactoring) { + super(refactoring, DIALOG_BASED_USER_INTERFACE); + descriptor = ((DecoupleClassesRefactoringProcessor) refactoring.getProcessor()).getDescriptor(); + setDefaultPageTitle(DecoupleClassesRefactoringPlugin.REFACTORING_NAME); + } + + @Override + protected void addUserInputPages() { + addPage(new DecoupleClassesUserInputPage(descriptor)); + } + + public class DecoupleClassesUserInputPage extends UserInputWizardPage { + private DecoupleClassesDescriptor descriptor; +// private static final String DESCRIPTION = "Specify where to hide the method invocation."; + + public DecoupleClassesUserInputPage(DecoupleClassesDescriptor descriptor) { + super(DecoupleClassesRefactoringPlugin.REFACTORING_NAME); + this.descriptor = descriptor; + setTitle(DecoupleClassesRefactoringPlugin.REFACTORING_NAME); +// setImageDescriptor(DecoupleClassesRefactoringPlugin.getInstance().getImageRegistry().getDescriptor(DecoupleClassesRefactoringPlugin.IMG_DESCRIPTION)); +// setDescription(DESCRIPTION); + } + + @Override + public void createControl(Composite parent) { + initializeDialogUnits(parent); + + Composite result = new Composite(parent, SWT.NONE); + result.setLayout(new GridLayout(1, false)); + + createNewClassInput(result); + createTargetClassesInput(result); + + setControl(result); + + validate(); + } + + private Group createGroup(Composite parent, String caption) { + Group group = new Group(parent, SWT.None); + group.setLayout(new GridLayout(2, false)); + group.setText(caption); + + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.horizontalSpan = 2; + group.setLayoutData(gridData); + + return group; + } + + private void createNewClassInput(Composite result) { + Group group = createGroup(result, "New class"); + + Label nameLabel = new Label(group, SWT.LEAD); + nameLabel.setText("Class name:"); + + Text nameText = new Text(group, SWT.SINGLE | SWT.BORDER); + nameText.setText(descriptor.getNewClassName()); + nameText.setFocus(); + nameText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + descriptor.setNewClassName(((Text) e.widget).getText()); + validate(); + } + }); + nameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label packageLabel = new Label(group, SWT.LEAD); + packageLabel.setText("Package name:"); + + Text packageText = new Text(group, SWT.SINGLE | SWT.BORDER); + packageText.setText(descriptor.getPackage()); + packageText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + descriptor.setPackage(((Text) e.widget).getText()); + validate(); + } + }); + packageText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + } + + private void createTargetClassesInput(Composite parent) { + Group group = createGroup(parent, "Classes to decouple"); + + Label targetLabel = new Label(group, SWT.LEAD); + targetLabel.setText("Target class:"); + + Text targetText = new Text(group, SWT.SINGLE | SWT.BORDER); + targetText.setText(descriptor.getTargetName()); + targetText.setEnabled(false); + targetText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label l = new Label(group, SWT.NONE); + l.setText("Client classes:"); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.horizontalSpan = 2; + gridData.verticalIndent = 5; + l.setLayoutData(gridData); + + final CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(group, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI); + Table table = tableViewer.getTable(); + table.setLinesVisible(true); + GridData tableGridData = new GridData(GridData.FILL_BOTH); + tableGridData.horizontalSpan = 2; + table.setLayoutData(tableGridData); + + // Table�̃r���[�𐧌䂷��v���o�C�_ + tableViewer.setLabelProvider(new ITableLabelProvider() { + @Override + public void removeListener(ILabelProviderListener listener) { + System.out.println(DecoupleClassesUserInputPage.class.getSimpleName() + "$" + ITableLabelProvider.class.getSimpleName() + "#removeListener()"); + } + @Override + public boolean isLabelProperty(Object element, String property) { + System.out.println(DecoupleClassesUserInputPage.class.getSimpleName() + "$" + ITableLabelProvider.class.getSimpleName() + "#isLabelProperty()"); + return false; + } + @Override + public void dispose() { + System.out.println(DecoupleClassesUserInputPage.class.getSimpleName() + "$" + ITableLabelProvider.class.getSimpleName() + "#dispose()"); + } + @Override + public void addListener(ILabelProviderListener listener) { + System.out.println(DecoupleClassesUserInputPage.class.getSimpleName() + "$" + ITableLabelProvider.class.getSimpleName() + "#addListener()"); + } + @Override + public String getColumnText(Object element, int columnIndex) { + System.out.println(DecoupleClassesUserInputPage.class.getSimpleName() + "$" + ITableLabelProvider.class.getSimpleName() + "#getColumnText()"); + + if (element instanceof String) { + return (String) element; + } + + IType type = (IType) element; + return type.getElementName() + " - " + type.getPackageFragment().getElementName(); + } + @Override + public Image getColumnImage(Object element, int columnIndex) { + System.out.println(DecoupleClassesUserInputPage.class.getSimpleName() + "#getColumnImage()"); + return null; + } + }); + + tableViewer.addCheckStateListener(new ICheckStateListener() { + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + if (!(event.getElement() instanceof IType)) { + return; + } + + IType type = (IType) event.getElement(); + if (event.getChecked()) { + descriptor.addClient(type); + } else { + descriptor.removeClient(type); + } + } + }); + + // �����Ɏ��Ԃ�������̂ŁA�_�C�A���O��\�����Ȃ���񓯊��Ɍ��������s����B + // ���‚�����A�_�C�A���O�ɔ��f����B + // �lj������Ɋւ��ẮA�{���͌�q�̂悤�ɂ���IStructuredContentProvider�ɔC�����ق����ǂ��̂����BtableViewer.setInput(clients); + // ���̏ꍇ�A�`�F�b�N�����鏈����ICheckStateProvider�ɔC���邱�ƂɂȂ�H + tableViewer.getControl().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + tableViewer.add(SEARCHING); + TargetOccurenceSearchEngine searchEngine = new TargetOccurenceSearchEngine(); +// List clients = searchEngine.findClients(descriptor.getTargetType()); + List clients = searchEngine.findClients(descriptor.getTargetType()); + tableViewer.refresh(); + for (IJavaElement client: clients) { + tableViewer.add(client); + tableViewer.setChecked(client, true); + descriptor.addClient((IType) client); + } + } + }); + } + + private void validate() { + setErrorMessage(null); + setPageComplete(true); + setMessage(null); + + if (descriptor.getNewClassName().isEmpty()) { + setErrorMessage("Nothing found to decouple!"); + setPageComplete(false); + return; + } + } + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/Class.java b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/Class.java new file mode 100644 index 0000000..41b0133 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/Class.java @@ -0,0 +1,69 @@ +package test.callGraphTraverser; + +import java.util.ArrayList; +import java.util.List; + +public class Class { + private String name; + private List methods = new ArrayList<>(); + private String packageName = ""; + + public Class(String name) { + this.name = name; + } + + public void rename(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setPackage(String name) { + packageName = name; + } + + public String getPackage() { + return packageName; + } + + public void addMethod(String methodName, Class returnType, Class... paramType) { + MethodDeclaration method = new MethodDeclaration(methodName, returnType, paramType); + method.setDeclaringClass(this); + methods.add(method); + } + + public MethodDeclaration getMethod(String name, Class... params) { + for (MethodDeclaration method: methods) { + if (method.equals(name, params)) { + return method; + } + } + + return null; + } + + public boolean equals(Class obj) { + if (!obj.getName().equals(name)) + return false; + + if (!obj.getPackage().equals(packageName)) + return false; + + return true; + } + + public void print() { + System.out.println(packageName + "." + name); + for (MethodDeclaration method: methods) { + method.print(); + } + System.out.println(); + } + + public List getMethods() { + return methods; + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/GraphBuilder.java b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/GraphBuilder.java new file mode 100644 index 0000000..1bb0827 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/GraphBuilder.java @@ -0,0 +1,111 @@ +package test.callGraphTraverser; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +public class GraphBuilder { + private Class target = null; + private Map classes = new HashMap<>(); + + public Class findClassByName(String name) { + return classes.get(name); + } + + public void addClass(String name) { + if (findClassByName(name) != null) { + System.err.println(this.getClass().toString() + " addClass(): Class " + name + " is already exists!"); + System.err.println("This operation has been ignored!"); + return; + } + + Class target = new Class(name); + classes.put(name, target); + } + + public void addMethod(String className, String methodName, String returnType, String... params) { + Class destinationClass = findClassByName(className); + + if (destinationClass == null) { + System.err.println(this.getClass().toString() + " addMethod(): Class " + className + " is not found!"); + System.err.println("This operation has been ignored!"); + return; + } + + Class[] paramClasses = toClasses(params); + if (destinationClass.getMethod(methodName, paramClasses) != null) { + System.err.println(this.getClass().toString() + " addClass(): Method " + methodName + " is already exists!"); + System.err.println("This operation has been ignored!"); + return; + } + + destinationClass.addMethod(methodName, findClassByName(returnType), paramClasses); + } + + private Class[] toClasses(String... params) { + Class[] paramClasses = new Class[params.length]; + for (int i = 0; i < params.length; i++) { + paramClasses[i] = findClassByName(params[i]); + } + return paramClasses; + } + + public void invoke(String sourceName, String sourceMethodName, String[] sourceMethodParams, String destName, String destMethodName, String[] destMethodParams) { + Class sourceClass = findClassByName(sourceName); + if (sourceClass == null) { + System.err.println(this.getClass().toString() + " invoke(" + sourceName + "#" + sourceMethodName + "() -> " + destName + "#" + destMethodName + "()" + ")"); + System.err.println("Class " + sourceName + " is not found!"); + System.err.println("This operation has been ignored!"); + return; + } + MethodDeclaration sourceMethod = sourceClass.getMethod(sourceMethodName, toClasses(sourceMethodParams)); + if (sourceMethod == null) { + System.err.println(this.getClass().toString() + " invoke(" + sourceName + "#" + sourceMethodName + "() -> " + destName + "#" + destMethodName + "()" + ")"); + System.err.println("Method " + sourceMethodName + " is not found!"); + System.err.println("This operation has been ignored!"); + return; + } + + Class destClass = findClassByName(destName); + if (destClass == null) { + System.err.println(this.getClass().toString() + " invoke(" + sourceName + "#" + sourceMethodName + "() -> " + destName + "#" + destMethodName + "()" + ")"); + System.err.println("Class " + destName + " is not found!"); + System.err.println("This operation has been ignored!"); + return; + } + MethodDeclaration destMethod = destClass.getMethod(destMethodName, toClasses(destMethodParams)); + if (destMethod == null) { + System.err.println(this.getClass().toString() + " invoke(" + sourceName + "#" + sourceMethodName + "() -> " + destName + "#" + destMethodName + "()" + ")"); + System.err.println("Method " + destMethodName + " is not found!"); + System.err.println("This operation has been ignored!"); + return; + } + + sourceMethod.invoke(destMethod); + } + + public void setTarget(String targetClassName) { + Class targetClass = findClassByName(targetClassName); + if (targetClass == null) { + System.err.println(this.getClass().toString() + " setTarget(): Class " + targetClassName + " is not found!"); + System.err.println("This operation has been ignored!"); + return; + } + target = targetClass; + } + + public Class getTarget() { + return target; + } + + public void print() { + System.out.println("Target: " + target.getName()); + System.out.println(); + + for (Iterator> i = classes.entrySet().iterator(); i.hasNext();) { + i.next().getValue().print(); + } + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/MethodDeclaration.java b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/MethodDeclaration.java new file mode 100644 index 0000000..d74d909 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/MethodDeclaration.java @@ -0,0 +1,133 @@ +package test.callGraphTraverser; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MethodDeclaration { + private Class declaringClass; + private String name; + private Class returnType; + private List parameters = new ArrayList<>(); + private boolean refactored = false; + + /** Invocations in this method body. */ + private List invocations = new ArrayList<>(); + + /** Invocations which invokes this method. */ + private List invokers = new ArrayList<>(); + + public MethodDeclaration(String methodName, Class returnType, Class... parameters) { + name = methodName; + this.returnType = returnType; + this.parameters.addAll(Arrays.asList(parameters)); + } + + public void setDeclaringClass(Class declaringClass) { + this.declaringClass = declaringClass; + } + + public Class getDeclaringClass() { + return declaringClass; + } + + public void rename(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void changeReturnType(Class returnType) { + this.returnType = returnType; + } + + public Class getReturnType() { + return returnType; + } + + /** + * ���̃��\�b�h�̌Ăяo����lj�����B + * @param invocation �Ăяo���� + */ + public void addInvocation(MethodInvocation invocation) { + invocations.add(invocation); + } + + public List getSource() { + return invokers; + } + + public boolean equals(String name, Class... params) { + if (!this.name.equals(name)) + return false; + + if (parameters.size() != params.length) + return false; + + for (int i = 0; i < parameters.size(); i++) { + parameters.get(i).equals(params[i]); + } + + return true; + } + + public void invoke(MethodDeclaration destinationMethod) { + MethodInvocation invocation = new MethodInvocation(this, destinationMethod); + invocations.add(invocation); + destinationMethod.invokedBy(invocation); + } + + private void invokedBy(MethodInvocation invocation) { + invokers.add(invocation); + } + + public void print() { + // Return Type, Method Name, Parameters... + System.out.print(returnType.getName() + " " + name + "("); + String paramSum = ""; + for (Class param: parameters) { + if (paramSum.length() != 0) + paramSum += ", "; + paramSum += param.getName(); + } + System.out.print(paramSum + ")"); + + if (invokers.size() != 0) { + // Invoked by ... + System.out.print(", Invoked By: "); + String invokerSum = ""; + for (MethodInvocation invoker: invokers) { + if (invokerSum.length() != 0) + invokerSum += ", "; + invokerSum += invoker.getSource().declaringClass.getName() + "#"; + invokerSum += invoker.getSource().getName() + "()"; + } + System.out.print(invokerSum); + } + + if (invocations.size() != 0) { + // Invocation in this method body + System.out.print(", Invokes: "); + String invocationSum = ""; + for (MethodInvocation invocation: invocations) { + if (invocationSum.length() != 0) + invocationSum += ", "; + invocationSum += invocation.getDestination().declaringClass.getName() + "#"; + invocationSum += invocation.getDestination().getName() + "()"; + } + System.out.print(invocationSum); + } + System.out.println(); + } + + public void refactor() { + refactored = true; + } + + public boolean isRefactored() { + return refactored; + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/MethodInvocation.java b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/MethodInvocation.java new file mode 100644 index 0000000..dd86cb4 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/MethodInvocation.java @@ -0,0 +1,33 @@ +package test.callGraphTraverser; + +public class MethodInvocation { + private MethodDeclaration source; + private MethodDeclaration destination; + private boolean refactored = false; + + /** + * @param source �Ăяo�����̃��\�b�h + * @param destination �Ăяo����̃��\�b�h + */ + public MethodInvocation(MethodDeclaration source, MethodDeclaration destination) { + this.source = source; + this.destination = destination; + } + + public MethodDeclaration getSource() { + return source; + } + + public MethodDeclaration getDestination() { + return destination; + } + + public void refactor() { + refactored = true; + } + + public boolean isRefactored() { + return refactored; + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/RefactoringPatternDetector.java b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/RefactoringPatternDetector.java new file mode 100644 index 0000000..913caeb --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/RefactoringPatternDetector.java @@ -0,0 +1,27 @@ +package test.callGraphTraverser; + +public class RefactoringPatternDetector { + private static void explore(MethodDeclaration targetMethod) { + System.out.print("Now looking for "); + System.out.print(targetMethod.getDeclaringClass().getName()); + System.out.println("#" + targetMethod.getName() + "()"); + + for (MethodInvocation invoker: targetMethod.getSource()) { + if (!invoker.getSource().isRefactored()) { + explore(invoker.getSource()); + } + } + targetMethod.refactor(); + System.err.println("Refactored " + targetMethod.getDeclaringClass().getName() + "#" + targetMethod.getName() + "()"); + + for (MethodInvocation invoker: targetMethod.getSource()) { + invoker.refactor(); + System.err.println(" Refactored " + targetMethod.getDeclaringClass().getName().toLowerCase() + "." + targetMethod.getName() + "() in " + invoker.getSource().getDeclaringClass().getName() + "#" + invoker.getSource().getName() + "()"); + } + } + + public static void startExplore(GraphBuilder builder) { + Class target = builder.getTarget(); + explore(target.getMethod("constructor")); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/TraverseTest.java b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/TraverseTest.java new file mode 100644 index 0000000..fbd7bf3 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callGraphTraverser/TraverseTest.java @@ -0,0 +1,86 @@ +package test.callGraphTraverser; + +public class TraverseTest { + public static final String PARAM_TYPE = "ParamType"; + public static final String PARAM_TYPE2 = "ParamType2"; + public static final String RETURN_TYPE = "ReturnType"; + + /** + * @param args + */ + public static void main(String[] args) { + GraphBuilder builder = new GraphBuilder(); + builder.addClass(RETURN_TYPE); + builder.addClass(PARAM_TYPE); + builder.addClass(PARAM_TYPE2); + + builder.addClass("A"); + builder.addMethod("A", "mA", RETURN_TYPE, new String[] {PARAM_TYPE, PARAM_TYPE2}); + + builder.addClass("B"); + builder.addMethod("B", "mB", RETURN_TYPE, new String[] {PARAM_TYPE}); + + builder.addClass("C"); + builder.addMethod("C", "mC", RETURN_TYPE); + + builder.addClass("D"); + builder.addMethod("D", "mD", RETURN_TYPE); + + builder.addClass("E"); + builder.addMethod("E", "mE", RETURN_TYPE); + + builder.addClass("F"); + builder.addMethod("F", "mF", RETURN_TYPE); + + builder.addClass("G"); + builder.addMethod("G", "mG", RETURN_TYPE); + + builder.addClass("H"); + builder.addMethod("H", "mH", RETURN_TYPE); + + builder.addClass("I"); + builder.addMethod("I", "mI", RETURN_TYPE); + + builder.addClass("J"); + builder.addMethod("J", "mJ", RETURN_TYPE); + + builder.addClass("K"); + builder.addMethod("K", "mK", RETURN_TYPE); + + builder.addClass("L"); + builder.addMethod("L", "mL", RETURN_TYPE); + + builder.addClass("M"); + builder.addMethod("M", "mM", RETURN_TYPE); + + builder.addClass("N"); + builder.addMethod("N", "mN", RETURN_TYPE); + + builder.addClass("Target"); + builder.addMethod("Target", "constructor", RETURN_TYPE); + + builder.invoke("A", "mA", new String[] {PARAM_TYPE, PARAM_TYPE2}, "F", "mF", new String[] {}); + builder.invoke("B", "mB", new String[] {PARAM_TYPE}, "G", "mG", new String[] {}); + builder.invoke("F", "mF", new String[] {}, "H", "mH", new String[] {}); + builder.invoke("G", "mG", new String[] {}, "H", "mH", new String[] {}); + builder.invoke("C", "mC", new String[] {}, "H", "mH", new String[] {}); + builder.invoke("F", "mF", new String[] {}, "I", "mI", new String[] {}); + builder.invoke("H", "mH", new String[] {}, "I", "mI", new String[] {}); + builder.invoke("D", "mD", new String[] {}, "I", "mI", new String[] {}); + builder.invoke("E", "mE", new String[] {}, "J", "mJ", new String[] {}); + builder.invoke("J", "mJ", new String[] {}, "K", "mK", new String[] {}); + builder.invoke("K", "mK", new String[] {}, "L", "mL", new String[] {}); + builder.invoke("L", "mL", new String[] {}, "M", "mM", new String[] {}); + builder.invoke("I", "mI", new String[] {}, "N", "mN", new String[] {}); + builder.invoke("M", "mM", new String[] {}, "N", "mN", new String[] {}); + builder.invoke("N", "mN", new String[] {}, "Target", "constructor", new String[] {}); + + builder.setTarget("Target"); + + builder.print(); + + System.out.println("RefactoringPatternDetector is running..."); + RefactoringPatternDetector.startExplore(builder); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/A.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/A.java new file mode 100644 index 0000000..078c4da --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/A.java @@ -0,0 +1,9 @@ +package test.callTree; + +public class A { + public F f = new F(); + + public void mA() { + f.mF(new Target("Created By A")); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/B.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/B.java new file mode 100644 index 0000000..a472b9d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/B.java @@ -0,0 +1,10 @@ +package test.callTree; + +public class B { + public G g = new G(); + + public void mB() { + g.mG(new Target("Created By B")); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/C.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/C.java new file mode 100644 index 0000000..aea3d8e --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/C.java @@ -0,0 +1,9 @@ +package test.callTree; + +public class C { + public H h = new H(); + + public void mC() { + h.mH(new Target("Created By C")); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/D.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/D.java new file mode 100644 index 0000000..d23bca0 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/D.java @@ -0,0 +1,9 @@ +package test.callTree; + +public class D { + public I i = new I(); + + public void mD() { + i.mI(new Target("Created By D")); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/E.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/E.java new file mode 100644 index 0000000..9e0d73d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/E.java @@ -0,0 +1,9 @@ +package test.callTree; + +public class E { + public J j = new J(); + + public void mE() { + j.mJ(new Target("Created By E")); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/F.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/F.java new file mode 100644 index 0000000..098eaa7 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/F.java @@ -0,0 +1,11 @@ +package test.callTree; + +public class F { + public H h = new H(); + public I i = new I(); + + public void mF(Target target) { + i.mI(target); + h.mH(target); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/G.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/G.java new file mode 100644 index 0000000..cb5a4fd --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/G.java @@ -0,0 +1,10 @@ +package test.callTree; + +public class G { + public H h = new H(); + + public void mG(Target target) { + h.mH(target); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/H.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/H.java new file mode 100644 index 0000000..959665d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/H.java @@ -0,0 +1,10 @@ +package test.callTree; + +public class H { + public I i = new I(); + + public void mH(Target target) { + i.mI(target); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/I.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/I.java new file mode 100644 index 0000000..4df9bfb --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/I.java @@ -0,0 +1,10 @@ +package test.callTree; + +public class I { + private N n = new N(); + + public void mI(Target target) { + n.mN(target); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/J.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/J.java new file mode 100644 index 0000000..9f05f70 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/J.java @@ -0,0 +1,10 @@ +package test.callTree; + +public class J { + public K k = new K(); + + public void mJ(Target target) { + k.mK(target); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/K.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/K.java new file mode 100644 index 0000000..936c780 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/K.java @@ -0,0 +1,10 @@ +package test.callTree; + +public class K { + public N n = new N(); + + public void mK(Target target) { + n.mN(target); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/N.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/N.java new file mode 100644 index 0000000..ca74b9f --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/N.java @@ -0,0 +1,9 @@ +package test.callTree; + +public class N { + + public void mN(Target target) { + target.printMessage(); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/callTree/Target.java b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/Target.java new file mode 100644 index 0000000..21e88bd --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/callTree/Target.java @@ -0,0 +1,14 @@ +package test.callTree; + +public class Target { + private String message = ""; + + public Target(String newMessage) { + message = newMessage; + } + + public void printMessage() { + System.out.println(message); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/RefactoringQueueDetectionStarter.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/RefactoringQueueDetectionStarter.java new file mode 100644 index 0000000..e3a06bc --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/RefactoringQueueDetectionStarter.java @@ -0,0 +1,49 @@ +package test.pseudocode; + +import java.util.List; + +import test.pseudocode.core.DepthFirstTopologicalSorter; +import test.pseudocode.core.Node; +import test.pseudocode.core.RefactoringTaskGenerator; +import test.pseudocode.testCase.TestCase1Factory; +import test.pseudocode.testCase.TestCaseModelFactory; + +public class RefactoringQueueDetectionStarter { + + public static void main(String[] args) { + new RefactoringQueueDetectionStarter().start(); + } + + private TestCaseModelFactory[] createCodeModelFactories() { + return new TestCaseModelFactory[] { + new TestCase1Factory(), +// new TestCase2Factory() +// new TestCase3Factory(), +// new TestCase4Factory(), +// new TestCase5Factory() + }; + } + + public void start() { + for (TestCaseModelFactory factory: createCodeModelFactories()) { + factory.create(); + + RefactoringTaskGenerator taskGenerator = new RefactoringTaskGenerator(); + taskGenerator.setCfrom(factory.getCFrom()); + taskGenerator.setTargetClass(factory.getTarget()); + List refactoringTasks = taskGenerator.generateTasks(); + + new DepthFirstTopologicalSorter().sort(refactoringTasks); + + printRefactoringPattern(refactoringTasks, factory); + } + } + + private void printRefactoringPattern(List list, TestCaseModelFactory factory) { +// System.out.println("- Test Case " + factory.getCaseNumber() + " -"); + for (int i = 0; i < list.size(); i++) { + System.out.println((i + 1) + ": " + list.get(i).toString()); + } + System.out.println(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/ASTNode.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/ASTNode.java new file mode 100644 index 0000000..8d9bd5c --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/ASTNode.java @@ -0,0 +1,15 @@ +package test.pseudocode.ast; + +public abstract class ASTNode { + private ASTNode parent = null; + + public void setParent(ASTNode parent) { + this.parent = parent; + } + + public ASTNode getParent() { + return parent; + } + + public abstract String toString(); +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/Assignment.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/Assignment.java new file mode 100644 index 0000000..919d499 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/Assignment.java @@ -0,0 +1,47 @@ +package test.pseudocode.ast; + +public class Assignment extends Expression { + private static final String ASSIGN_OPERATOR = "="; + + private String operator = null; + private Expression leftHandSide = null; + private Expression rightHandSide = null; + + public Assignment(Expression leftHandSide, Expression rightHandSide) { + setOperator(ASSIGN_OPERATOR); + setLeftHandSide(leftHandSide); + setRightHandSide(rightHandSide); + } + + public void setOperator(String operator) { + this.operator = operator; + } + + public Expression getLeftHandSide() { + return leftHandSide; + } + + public void setLeftHandSide(Expression leftHandSide) { + this.leftHandSide = leftHandSide; + leftHandSide.setParent(this); + } + + public Expression getRightHandSide() { + return rightHandSide; + } + + public void setRightHandSide(Expression rightHandSide) { + this.rightHandSide = rightHandSide; + rightHandSide.setParent(this); + } + + @Override + public String toString() { + return operator; + } + + @Override + public TypeDeclaration getValueType() { + return rightHandSide.getValueType(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/BodyDeclaration.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/BodyDeclaration.java new file mode 100644 index 0000000..02ac355 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/BodyDeclaration.java @@ -0,0 +1,4 @@ +package test.pseudocode.ast; + +public abstract class BodyDeclaration extends ASTNode { +} \ No newline at end of file diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/Expression.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/Expression.java new file mode 100644 index 0000000..0cfcb80 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/Expression.java @@ -0,0 +1,5 @@ +package test.pseudocode.ast; + +public abstract class Expression extends ASTNode { + public abstract TypeDeclaration getValueType(); +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/FieldAccess.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/FieldAccess.java new file mode 100644 index 0000000..b71d766 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/FieldAccess.java @@ -0,0 +1,19 @@ +package test.pseudocode.ast; + +public class FieldAccess extends Expression { + private FieldDeclaration declaration; + + public FieldAccess(FieldDeclaration declaration) { + this.declaration = declaration; + } + + @Override + public String toString() { + return declaration.getName(); + } + + @Override + public TypeDeclaration getValueType() { + return declaration.getType(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/FieldDeclaration.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/FieldDeclaration.java new file mode 100644 index 0000000..e28009c --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/FieldDeclaration.java @@ -0,0 +1,37 @@ +package test.pseudocode.ast; + +public class FieldDeclaration extends BodyDeclaration { + private TypeDeclaration type; + private String name; + + public FieldDeclaration(TypeDeclaration type, String name) { + setType(type); + setName(name); + } + + @Override + public TypeDeclaration getParent() { + return (TypeDeclaration) super.getParent(); + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "Field dec " + type.getName() + " " + name + " in " + getParent().getName(); + } + + public TypeDeclaration getType() { + return type; + } + + public void setType(TypeDeclaration type) { + this.type = type; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/MethodDeclaration.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/MethodDeclaration.java new file mode 100644 index 0000000..0321e7b --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/MethodDeclaration.java @@ -0,0 +1,165 @@ +package test.pseudocode.ast; + +import java.util.ArrayList; +import java.util.List; + +public class MethodDeclaration extends BodyDeclaration { + private String methodName = ""; + private TypeDeclaration returnType = null; + private List parameters = new ArrayList<>(); + + /** Invocations which invokes this method. */ + private List invokers = new ArrayList<>(); + + private List body = new ArrayList<>(); + + public MethodDeclaration(String methodName, TypeDeclaration returnType, VariableDeclaration... formalParameters) { + setName(methodName); + setReturnType(returnType); + if (formalParameters != null) { + for (VariableDeclaration expression: formalParameters) { + expression.setParent(this); + parameters.add(expression); + } + } + } + + public void setName(String methodName) { + this.methodName = methodName; + } + + public String getName() { + return methodName; + } + + public void setReturnType(TypeDeclaration returnType) { + this.returnType = returnType; + } + + public TypeDeclaration getReturnType() { + return returnType; + } + + public void addInvoker(MethodInvocation invocation) { + invokers.add(invocation); + } + + public void removeInvoker(MethodInvocation invocation) { + invokers.remove(invocation); + } + + public List getInvokers() { + return invokers; + } + + public List getInvocations() { + List result = new ArrayList<>(); + for (Expression expression: body) { + getInvocations(result, expression); + } + return result; + } + + private void getInvocations(List result, Expression expression) { + if (expression instanceof MethodInvocation) { + result.add((MethodInvocation) expression); + getInvocations(result, ((MethodInvocation) expression).getReceiver()); + } else if (expression instanceof Assignment) { + getInvocations(result, ((Assignment) expression).getLeftHandSide()); + getInvocations(result, ((Assignment) expression).getRightHandSide()); + } else if (expression instanceof ReturnValue) { + getInvocations(result, ((ReturnValue) expression).getExpression()); + } + } + + public boolean equals(String name, TypeDeclaration... params) { + if (!getName().equals(name)) { + return false; + } + + if (parameters.size() != params.length) { + return false; + } + + for (int i = 0; i < parameters.size(); i++) { + parameters.get(i).equals(params[i]); + } + + return true; + } + + public String toString() { + return getParent().getName() + "." + getName() + "()"; + } + + public List getParameters() { + return parameters; + } + + public boolean containsAsParameterType(TypeDeclaration target) { + if (parameters.isEmpty()) { + if (target == null) { + return true; + } + return false; + } + + for (VariableDeclaration parameter: parameters) { + TypeDeclaration dec = parameter.getValueType(); + if (dec.equals(target)) { + return true; + } + } + + return false; + } + + public boolean containsAsReturnType(TypeDeclaration target) { + if (returnType == null) { + if (target == null) { + return true; + } + return false; + } + + if (returnType.equals(target)) { + return true; + } + + return false; + } + + public boolean isConstructor() { + if (!getParent().getName().equals(getName())) { + return false; + } + if (!getParent().equals(returnType)) { + return false; + } + return true; + } + + @Override + public TypeDeclaration getParent() { + return (TypeDeclaration) super.getParent(); + } + + public List getReturnValues() { + List result = new ArrayList<>(); + for (Expression expression: body) { + if (expression instanceof ReturnValue) { + result.add((ReturnValue) expression); + } + } + return result; + } + + public List getExpressions() { + return body; + } + + public void addExpression(Expression expression) { + body.add(expression); + expression.setParent(this); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/MethodInvocation.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/MethodInvocation.java new file mode 100644 index 0000000..9b9fe73 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/MethodInvocation.java @@ -0,0 +1,95 @@ +package test.pseudocode.ast; + +import java.util.ArrayList; +import java.util.List; + +public class MethodInvocation extends Expression { + private Expression receiver; + private MethodDeclaration declaration; + private List parameters = new ArrayList<>(); + + public MethodInvocation(Expression receiver, MethodDeclaration methodDeclaration, Expression... actualParameters) { + setReceiver(receiver); + setDeclaration(methodDeclaration); + if (actualParameters != null) { + for (Expression expression: actualParameters) { + expression.setParent(this); + parameters.add(expression); + } + } + } + + public void setDeclaration(MethodDeclaration declaration) { + if (declaration != null) { + declaration.removeInvoker(this); + } + this.declaration = declaration; + declaration.addInvoker(this); + } + + public List getParameters() { + return parameters; + } + + public MethodDeclaration getDeclaration() { + return declaration; + } + + public boolean isConstructor() { + return declaration.isConstructor(); + } + + public boolean containsAsParameterType(TypeDeclaration target) { + return declaration.containsAsParameterType(target); + } + + public boolean containsAsReturnType(TypeDeclaration target) { + return declaration.containsAsReturnType(target); + } + + public String toString() { + String result = ""; + if (receiver != null) { + result += receiver.toString() + "."; + } + return result + declaration.getName() + "() in " + getMethod().toString(); + } + + private MethodDeclaration getMethod() { + ASTNode result = this; + + do { + result = result.getParent(); + } while(result != null && !(result instanceof MethodDeclaration)); + + return (MethodDeclaration) result; + } + + public boolean isReceiverType(TypeDeclaration dec) { + if (receiver == null) { + if (dec == null) { + return true; + } else { + return false; + } + } + return receiver.getValueType().equals(dec); + } + + @Override + public TypeDeclaration getValueType() { + return declaration.getReturnType(); + } + + public Expression getReceiver() { + return receiver; + } + + public void setReceiver(Expression receiver) { + this.receiver = receiver; + if (receiver == null) { + return; + } + receiver.setParent(this); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/ReturnValue.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/ReturnValue.java new file mode 100644 index 0000000..c714f8b --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/ReturnValue.java @@ -0,0 +1,44 @@ +package test.pseudocode.ast; + +public class ReturnValue extends Expression { + private Expression expression = null; + + public ReturnValue(Expression returnValue) { + setReturnValue(returnValue); + } + + public void setReturnValue(Expression expression) { + if (this.expression != null) { + this.expression.setParent(null); + } + this.expression = expression; + if (expression == null) { + return; + } + expression.setParent(this); + } + + public Expression getExpression() { + return expression; + } + + @Override + public String toString() { + return "return value " + expression.toString() + " in " + getMethod().toString(); + } + + private MethodDeclaration getMethod() { + ASTNode result = this; + + do { + result = result.getParent(); + } while(result != null && !(result instanceof MethodDeclaration)); + + return (MethodDeclaration) result; + } + + @Override + public TypeDeclaration getValueType() { + return expression.getValueType(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/ThisExpression.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/ThisExpression.java new file mode 100644 index 0000000..e6ce6e3 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/ThisExpression.java @@ -0,0 +1,20 @@ +package test.pseudocode.ast; + +public class ThisExpression extends Expression { + private TypeDeclaration declaration; + + public ThisExpression(TypeDeclaration declaration) { + this.declaration = declaration; + } + + @Override + public TypeDeclaration getValueType() { + return declaration; + } + + @Override + public String toString() { + return "this of " + declaration.getName(); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/TypeDeclaration.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/TypeDeclaration.java new file mode 100644 index 0000000..86177b3 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/TypeDeclaration.java @@ -0,0 +1,93 @@ +package test.pseudocode.ast; + +import java.util.ArrayList; +import java.util.List; + +public class TypeDeclaration extends BodyDeclaration { + private String packageName = ""; + private String typeName = ""; + private List bodyDeclarations = new ArrayList<>(); + + public TypeDeclaration(String name) { + setName(name); + } + + public void setPackage(String name) { + packageName = name; + } + + public String getPackage() { + return packageName; + } + + public void setName(String name) { + typeName = name; + } + + public String getName() { + return typeName; + } + + public List getDeclarations() { + return bodyDeclarations; + } + + public void addDeclaration(BodyDeclaration declaration) { + bodyDeclarations.add(declaration); + declaration.setParent(this); + } + + public ASTNode getMethod(String name, TypeDeclaration... params) { + for (BodyDeclaration declaration: getDeclarations()) { + if (declaration instanceof MethodDeclaration) { + MethodDeclaration method = (MethodDeclaration) declaration; + if (method.equals(name, params)) { + return method; + } + } + } + return null; + } + + public List getFields() { + List result = new ArrayList<>(); + for (BodyDeclaration bodyDeclaration: getDeclarations()) { + if (bodyDeclaration instanceof FieldDeclaration) { + result.add((FieldDeclaration) bodyDeclaration); + } + } + return result; + } + + public List getMethods() { + List result = new ArrayList<>(); + for (BodyDeclaration bodyDeclaration: getDeclarations()) { + if (bodyDeclaration instanceof MethodDeclaration) { + result.add((MethodDeclaration) bodyDeclaration); + } + } + return result; + } + + public boolean equals(TypeDeclaration obj) { + if (!obj.getName().equals(getName())) { + return false; + } + + if (!obj.getPackage().equals(packageName)) { + return false; + } + + return true; + } + + @Override + public String toString() { + String result = ""; + if (packageName != null && !packageName.isEmpty()) { + result += packageName + "."; + } + result += getName(); + return result; + } +} \ No newline at end of file diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/VariableAccess.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/VariableAccess.java new file mode 100644 index 0000000..e071bd5 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/VariableAccess.java @@ -0,0 +1,23 @@ +package test.pseudocode.ast; + +public class VariableAccess extends Expression { + private VariableDeclaration declaration; + + public VariableAccess(VariableDeclaration declaration) { + setDeclaration(declaration); + } + + private void setDeclaration(VariableDeclaration declaration) { + this.declaration = declaration; + } + + @Override + public String toString() { + return declaration.getName(); + } + + @Override + public TypeDeclaration getValueType() { + return declaration.getValueType(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/VariableDeclaration.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/VariableDeclaration.java new file mode 100644 index 0000000..b763dd5 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/ast/VariableDeclaration.java @@ -0,0 +1,30 @@ +package test.pseudocode.ast; + +public class VariableDeclaration extends Expression { + private TypeDeclaration type; + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public VariableDeclaration(TypeDeclaration type, String name) { + setName(name); + this.type = type; + } + + @Override + public String toString() { + return "variable dec " + type.getName() + " " + name; + } + + @Override + public TypeDeclaration getValueType() { + return type; + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/core/DepthFirstTopologicalSorter.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/core/DepthFirstTopologicalSorter.java new file mode 100644 index 0000000..7f4eeb4 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/core/DepthFirstTopologicalSorter.java @@ -0,0 +1,27 @@ +package test.pseudocode.core; + +import java.util.ArrayList; +import java.util.List; + +public class DepthFirstTopologicalSorter { + private List L = new ArrayList<>(); + + public void sort(List list) { + L.clear(); + for (Node node: list) { + visit(node); + } + list.clear(); + list.addAll(L); + } + + private void visit(Node n) { + if (n.isNotVisited()) { + n.visited(); + for (Node m: n.getDependents()) { + visit(m); + } + L.add(n); + } + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/core/Node.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/core/Node.java new file mode 100644 index 0000000..01c4e22 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/core/Node.java @@ -0,0 +1,9 @@ +package test.pseudocode.core; + +import java.util.List; + +public interface Node { + boolean isNotVisited(); + void visited(); + List getDependents(); +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/core/RefactoringTaskGenerator.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/core/RefactoringTaskGenerator.java new file mode 100644 index 0000000..e6cc273 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/core/RefactoringTaskGenerator.java @@ -0,0 +1,296 @@ +package test.pseudocode.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import test.pseudocode.ast.ASTNode; +import test.pseudocode.ast.Assignment; +import test.pseudocode.ast.BodyDeclaration; +import test.pseudocode.ast.Expression; +import test.pseudocode.ast.FieldDeclaration; +import test.pseudocode.ast.MethodDeclaration; +import test.pseudocode.ast.MethodInvocation; +import test.pseudocode.ast.ReturnValue; +import test.pseudocode.ast.TypeDeclaration; +import test.pseudocode.ast.VariableDeclaration; +import test.pseudocode.refactoring.HideDelegate; +import test.pseudocode.refactoring.IntroduceParameterObject; +import test.pseudocode.refactoring.IntroduceReturnValueObject; +import test.pseudocode.refactoring.PreserveWholeObject; +import test.pseudocode.refactoring.PrimitiveRefactoring; +import test.pseudocode.refactoring.Refactoring; +import test.pseudocode.refactoring.ContractedRefactoring; +import test.pseudocode.refactoring.ReplaceTypeByHiding; +import test.pseudocode.refactoring.ReturnWholeObject; + +public class RefactoringTaskGenerator { + private TypeDeclaration targetClass = null; + private List cFrom = null; + + /** Refactoring Unit, Refactoring*/ + public Map> refactoringTasks = new HashMap<>(); + + public List generateTasks() { + refactoringTasks.clear(); + + exploreClasses(); + resolveDependenceOfTasks(); + contractRefactorings(); + + return refactoringTasksToList(); + } + + private void exploreClasses() { + for (TypeDeclaration node: cFrom) { + for (BodyDeclaration declaration: node.getDeclarations()) { + if (declaration instanceof MethodDeclaration) { + exproleMethod((MethodDeclaration) declaration); + } else if (declaration instanceof FieldDeclaration) { + FieldDeclaration field = (FieldDeclaration) declaration; + if (field.getType().equals(targetClass)) { + addRefactoringTask(node, new ReplaceTypeByHiding((FieldDeclaration) declaration)); + } + } + } + } + } + + private void exproleMethod(MethodDeclaration method) { + if (method.containsAsParameterType(targetClass)) { + for (MethodInvocation invoker: method.getInvokers()) { + MethodDeclaration invokerDeclaration = (MethodDeclaration) invoker.getParent(); + if (!isCFrom(invokerDeclaration)) { + addRefactoringTask(method, new IntroduceParameterObject(method)); + } + } + } + for (Expression expression: method.getExpressions()) { + exproleMethodBodyExpression(method, expression); + } + } + + private void exproleMethodBodyExpression(MethodDeclaration ml, Expression expression) { + if (expression instanceof Assignment) { + exproleMethodBodyExpression(ml, ((Assignment) expression).getLeftHandSide()); + exproleMethodBodyExpression(ml, ((Assignment) expression).getRightHandSide()); + } + if (expression instanceof MethodInvocation) { + MethodInvocation invocation = (MethodInvocation) expression; + if (invocation.containsAsParameterType(targetClass)) { + MethodDeclaration invokeeDeclaration = invocation.getDeclaration(); + addRefactoringTask(invokeeDeclaration, new PreserveWholeObject(invocation)); + } + if (invocation.containsAsReturnType(targetClass) && !isCFrom(invocation) && !isConstructorOfTarget(invocation)) { + MethodDeclaration invokeeDeclaration = invocation.getDeclaration(); + addRefactoringTask(invokeeDeclaration, new IntroduceReturnValueObject(invocation)); + } + if (invocation.isReceiverType(targetClass)) { + addRefactoringTask(ml, new HideDelegate(invocation)); + } + } + if (expression instanceof VariableDeclaration) { + addRefactoringTask(ml.getParent(), new ReplaceTypeByHiding((VariableDeclaration) expression)); + } + if (expression instanceof ReturnValue) { + ReturnValue returnExpression = (ReturnValue) expression; + exproleMethodBodyExpression(ml, returnExpression.getExpression()); + if (returnExpression.getValueType().equals(targetClass)) { + addRefactoringTask(ml, new ReturnWholeObject(returnExpression)); + } + } + } + + private boolean isConstructorOfTarget(MethodInvocation invocation) { + if (!invocation.isConstructor()) { + return false; + } + return invocation.getValueType().equals(targetClass); + } + + private void addRefactoringTask(ASTNode refactoringUnit, Refactoring refactoring) { + List list = refactoringTasks.get(refactoringUnit); + if (list == null) { + list = new ArrayList(); + refactoringTasks.put(refactoringUnit, list); + } + list.add(refactoring); + } + + private boolean isCFrom(ASTNode node) { + TypeDeclaration targetClass = null; + if (node instanceof TypeDeclaration) { + targetClass = (TypeDeclaration) node; + } else if (node instanceof MethodDeclaration) { + targetClass = (TypeDeclaration) node.getParent(); + } else if (node instanceof MethodInvocation) { + targetClass = ((MethodInvocation) node).getDeclaration().getParent(); + } + + return cFrom.contains(targetClass); + } + + private void resolveDependenceOfTasks() { + for (Iterator> i = refactoringTasks.values().iterator(); i.hasNext();) { + for (Refactoring refactoring: i.next()) { + establishDependenceFor((PrimitiveRefactoring) refactoring); + } + } + } + + @SuppressWarnings("unchecked") + private void establishDependenceFor(PrimitiveRefactoring refactoring) { + // �R�����g�͂��ׂ�ApplicationPoint���N�_�Ƃ���B + if (refactoring.isInstanceOf(IntroduceParameterObject.class)) { + // �ˑ����Ȃ� + } else if (refactoring.isInstanceOf(IntroduceReturnValueObject.class)) { + // �ˑ����Ȃ� + } else if (refactoring.isInstanceOf(ReplaceTypeByHiding.class)) { + ASTNode applicationPoint = refactoring.getApplicationPoint(); + if (applicationPoint instanceof FieldDeclaration) { + FieldDeclaration l = (FieldDeclaration) applicationPoint; + TypeDeclaration parentType = l.getParent(); + for (MethodDeclaration m: parentType.getMethods()) { + refactoring.dependsOn(findRefactorings(m, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class})); + for (MethodInvocation l2: m.getInvocations()) { + MethodDeclaration mDash = l2.getDeclaration(); + refactoring.dependsOn(findRefactorings(mDash, new Class[] {ReturnWholeObject.class, IntroduceReturnValueObject.class})); + } + } + } + if (applicationPoint instanceof VariableDeclaration) { + VariableDeclaration l = (VariableDeclaration) applicationPoint; + MethodDeclaration ml = m(l); + refactoring.dependsOn(findRefactorings(ml, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class})); + + for (MethodInvocation l2: ml.getInvocations()) { + MethodDeclaration m = l2.getDeclaration(); + refactoring.dependsOn(findRefactorings(m, new Class[] {ReturnWholeObject.class, IntroduceReturnValueObject.class})); + } + } + refactoring.dependsOn(findRefactorings(applicationPoint, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class})); + } else if (refactoring.isInstanceOf(HideDelegate.class)) { + // ���\�b�h����ReplaceTypeByHiding�Ɉˑ�����B + MethodInvocation invocation = (MethodInvocation) refactoring.getApplicationPoint(); + MethodDeclaration enclosing = (MethodDeclaration) invocation.getParent(); + refactoring.dependsOn(findRefactorings(enclosing, new Class[] { + IntroduceParameterObject.class, + PreserveWholeObject.class, + IntroduceReturnValueObject.class, + ReturnWholeObject.class, + ReplaceTypeByHiding.class})); + } else if (refactoring.isInstanceOf(PreserveWholeObject.class)) { + // �Ăяo�����̒�`�ɑ΂�������ύX�Ɉˑ�����B + // �Ăяo������ReplaceTypeByHiding�Ɉˑ�����? + MethodInvocation applicationPoint = (MethodInvocation) refactoring.getApplicationPoint(); + MethodDeclaration enclosing = (MethodDeclaration) applicationPoint.getParent(); + refactoring.dependsOn(findRefactorings(enclosing, new Class[] {IntroduceParameterObject.class, + PreserveWholeObject.class})); + TypeDeclaration type = enclosing.getParent(); + refactoring.dependsOn(findRefactorings(type, new Class[] {ReplaceTypeByHiding.class})); + + // �Ăяo����̒�`�ɑ΂���߂�l�̌^�ύX�Ɉˑ�����B + for (MethodInvocation invocation: enclosing.getInvocations()) { + if (invocation.equals(applicationPoint)) { + continue; + } + MethodDeclaration declaration = invocation.getDeclaration(); + refactoring.dependsOn(findRefactorings(declaration, new Class[] { ReturnWholeObject.class, + IntroduceReturnValueObject.class})); + } + } else if (refactoring.isInstanceOf(ReturnWholeObject.class)) { + // �e�Ăяo����̒�`�ɑ΂���߂�l�̌^�ύX�Ɉˑ�����B + ReturnValue returnStatement = (ReturnValue) refactoring.getApplicationPoint(); + MethodDeclaration enclosing = (MethodDeclaration) m(returnStatement); + refactoring.dependsOn(findRefactorings(enclosing, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class})); + TypeDeclaration type = enclosing.getParent(); + refactoring.dependsOn(findRefactorings(type, new Class[] {ReplaceTypeByHiding.class})); + for (MethodInvocation invocation: enclosing.getInvocations()) { + MethodDeclaration invokeeDeclaration = invocation.getDeclaration(); + refactoring.dependsOn(findRefactorings(invokeeDeclaration, new Class[] {IntroduceReturnValueObject.class, ReturnWholeObject.class})); + } + } + } + + private MethodDeclaration m(ASTNode node) { + ASTNode result = node; + + do { + result = result.getParent(); + } while(result != null && !(result instanceof MethodDeclaration)); + + return (MethodDeclaration) result; + } + + private List findRefactorings(ASTNode refactoringUnit, Class[] refactoringTypes) { + List list = refactoringTasks.get(refactoringUnit); + return findRefactorings(list, refactoringTypes); + } + + private List findRefactorings(List findFrom, Class[] refactoringTypes) { + List result = new ArrayList<>(); + + if (findFrom == null) { + return result; + } + + for (Refactoring candidate: findFrom) { + for (Class type: refactoringTypes) { + if (candidate.isInstanceOf(type)) { + result.add(candidate); + } + } + } + return result; + } + + /** + * �������\�b�h�̃V�O�j�`����ύX����Introduce Parameter Object��Preserve Whole Object���܂Ƃ߂�B + */ + @SuppressWarnings("unchecked") + private void contractRefactorings() { + for (Iterator> i = refactoringTasks.values().iterator(); i.hasNext();) { + // ����JavaElement�ɑ΂��ēK�p���郊�t�@�N�^�����O�Q + List list = i.next(); + contractRefactorings("Change Signature", list, new Class[] {IntroduceParameterObject.class, PreserveWholeObject.class}); + contractRefactorings("Hide Delegates", list, new Class[] {HideDelegate.class}); + } + } + + private void contractRefactorings(String name, List list, Class[] refactoringTypes) { + List primitives = findRefactorings(list, refactoringTypes); + + // ����”\�ȃ��t�@�N�^�����O��2�ˆȏ゠��΍�������B + if (primitives.size() >= 2) { + ContractedRefactoring composition = new ContractedRefactoring(name); + composition.addAll(primitives); + replace(list, primitives, composition); + } + } + + private void replace(List list, List primitives, ContractedRefactoring composition) { + list.add(composition); + list.removeAll(primitives); + } + + private List refactoringTasksToList() { + List list = new ArrayList<>(); + + for (Iterator> i = refactoringTasks.values().iterator(); i.hasNext();) { + list.addAll(i.next()); + } + + return list; + } + + public void setCfrom(List cFrom) { + this.cFrom = cFrom; + } + + public void setTargetClass(TypeDeclaration targetClass) { + this.targetClass = targetClass; + } + +} \ No newline at end of file diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase2Factory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase2Factory.java new file mode 100644 index 0000000..e754b0d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase2Factory.java @@ -0,0 +1,35 @@ +package test.pseudocode.factory; + +import test.pseudocode.javaElement.Class; +import test.pseudocode.javaElement.MethodDeclaration; + +public class TestCase2Factory extends TestCaseModelFactory { + + @Override + public void create() { + Class e = new Class("E"); // Target Class + MethodDeclaration eConstructor = e.addMethod(e.getName(), e, (Class[]) null); + target = e; + + Class d = new Class("D"); + MethodDeclaration dSetE = d.addMethod("setE", null, e); + + Class c = new Class("C"); + MethodDeclaration cCreateE = c.addMethod("createE", e, (Class[]) null); + cCreateE.addMethodInvocation(eConstructor); + + Class b = new Class("B"); + MethodDeclaration bGetE = b.addMethod("getE", e, (Class[]) null); + bGetE.addMethodInvocation(cCreateE); + bGetE.addReturnStatement(cCreateE.getReturnType()); + + Class a = new Class("A"); + MethodDeclaration am = a.addMethod("m", null, (Class[]) null); + am.addMethodInvocation(bGetE); + am.addMethodInvocation(dSetE); + + addCfrom(a); + addCfrom(b); + addCfrom(d); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase3Factory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase3Factory.java new file mode 100644 index 0000000..7d72bc8 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase3Factory.java @@ -0,0 +1,36 @@ +package test.pseudocode.factory; + +import test.pseudocode.javaElement.Class; +import test.pseudocode.javaElement.MethodDeclaration; + +public class TestCase3Factory extends TestCaseModelFactory { + + @Override + public void create() { + Class t = new Class("T"); // Target Class + setTarget(t); + + Class c = new Class("C"); + MethodDeclaration cSetT = c.addMethod("setT", null, t); + + Class b = new Class("B"); + MethodDeclaration bSetT = b.addMethod("setT", null, t); + bSetT.addMethodInvocation(cSetT); + + Class a = new Class("A"); + MethodDeclaration am = a.addMethod("m", null, (Class[]) null); + am.addMethodInvocation(bSetT); + + Class e = new Class("E"); + MethodDeclaration eSetT = e.addMethod("setT", null, t); + eSetT.addMethodInvocation(cSetT); + + Class d = new Class("D"); + MethodDeclaration dm = d.addMethod("m", null, (Class[]) null); + dm.addMethodInvocation(eSetT); + + addCfrom(b); + addCfrom(c); + addCfrom(e); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase4Factory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase4Factory.java new file mode 100644 index 0000000..e607587 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase4Factory.java @@ -0,0 +1,41 @@ +package test.pseudocode.factory; + +import test.pseudocode.javaElement.Class; +import test.pseudocode.javaElement.MethodDeclaration; + +public class TestCase4Factory extends TestCaseModelFactory { + + @Override + public void create() { + Class t = new Class("T"); // Target Class + setTarget(t); + + Class c = new Class("C"); + MethodDeclaration cSetT = c.addMethod("setT", null, t); + + Class f = new Class("F"); + MethodDeclaration fSetT = f.addMethod("setT", null, t); + + Class e = new Class("E"); + MethodDeclaration eSetT = e.addMethod("setT", null, t); + eSetT.addMethodInvocation(fSetT); + eSetT.addMethodInvocation(cSetT); + + Class b = new Class("B"); + MethodDeclaration bSetT = b.addMethod("setT", null, t); + bSetT.addMethodInvocation(cSetT); + + Class a = new Class("A"); + MethodDeclaration am = a.addMethod("m", null, (Class[]) null); + am.addMethodInvocation(bSetT); + + Class d = new Class("D"); + MethodDeclaration dm = d.addMethod("m", null, (Class[]) null); + dm.addMethodInvocation(eSetT); + + addCfrom(b); + addCfrom(c); + addCfrom(e); + addCfrom(f); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase5Factory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase5Factory.java new file mode 100644 index 0000000..afe3f92 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCase5Factory.java @@ -0,0 +1,46 @@ +package test.pseudocode.factory; + +import test.pseudocode.javaElement.Class; +import test.pseudocode.javaElement.MethodDeclaration; + +public class TestCase5Factory extends TestCaseModelFactory { + + @Override + public void create() { + Class t = new Class("T"); // Target Class + setTarget(t); + + Class h = new Class("H"); + MethodDeclaration hSetT = h.addMethod("setT", null, t); + + Class d = new Class("D"); + MethodDeclaration dSetT = d.addMethod("setT", null, t); + + Class g = new Class("G"); + MethodDeclaration gSetT = g.addMethod("setT", null, t); + gSetT.addMethodInvocation(hSetT); + gSetT.addMethodInvocation(dSetT); + + Class e = new Class("E"); + MethodDeclaration em = e.addMethod("m", null, (Class[]) null); + em.addMethodInvocation(gSetT); + + Class c = new Class("C"); + MethodDeclaration cSetT = c.addMethod("setT", null, t); + cSetT.addMethodInvocation(dSetT); + + Class b = new Class("B"); + MethodDeclaration bSetT = b.addMethod("setT", null, t); + bSetT.addMethodInvocation(cSetT); + bSetT.addMethodInvocation(gSetT); + + Class a = new Class("A"); + MethodDeclaration am = a.addMethod("m", null, (Class[]) null); + am.addMethodInvocation(bSetT); + + addCfrom(b); + addCfrom(c); + addCfrom(g); + addCfrom(h); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCaseModelFactory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCaseModelFactory.java new file mode 100644 index 0000000..7368773 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/factory/TestCaseModelFactory.java @@ -0,0 +1,42 @@ +package test.pseudocode.factory; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import test.pseudocode.javaElement.Class; + +public abstract class TestCaseModelFactory { + protected Class target = null; + protected List cFrom = new ArrayList<>(); + + public abstract void create(); + + /** �N���X������A�Ԃ��擾���� */ + public int getCaseNumber() { + String name = this.getClass().getSimpleName(); + Pattern pattern = Pattern.compile("(?!\\D)(\\d+)(?=\\D+)"); + Matcher matcher = pattern.matcher(name); + if (matcher.find()) { + return Integer.valueOf(matcher.group(0)); + } + return -1; + } + + public Class getTarget() { + return target; + } + + public void setTarget(Class target) { + this.target = target; + } + + public void addCfrom(Class element) { + cFrom.add(element); + } + + public List getCFrom() { + return cFrom; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/Class.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/Class.java new file mode 100644 index 0000000..2420302 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/Class.java @@ -0,0 +1,61 @@ +package test.pseudocode.javaElement; + +import java.util.ArrayList; +import java.util.List; + +public class Class extends JavaElement { + private List methods = new ArrayList<>(); + private String packageName = ""; + + public Class(String name) { + super(name); + } + + public void setPackage(String name) { + packageName = name; + } + + public String getPackage() { + return packageName; + } + + public MethodDeclaration addMethod(String name, Class returnType, Class... paramType) { + MethodDeclaration method = new MethodDeclaration(name, returnType, paramType); + method.setEnclosing(this); + methods.add(method); + return method; + } + + public JavaElement getMethod(String name, Class... params) { + for (MethodDeclaration method: methods) { + if (method.equals(name, params)) { + return method; + } + } + return null; + } + + public List getMethods() { + return methods; + } + + public boolean equals(Class obj) { + if (!obj.getName().equals(getName())) { + return false; + } + + if (!obj.getPackage().equals(packageName)) { + return false; + } + + return true; + } + + public void print() { + System.out.println(packageName + "." + getName()); + for (MethodDeclaration method: methods) { + method.print(); + } + System.out.println(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/JavaElement.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/JavaElement.java new file mode 100644 index 0000000..3429b5d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/JavaElement.java @@ -0,0 +1,35 @@ +package test.pseudocode.javaElement; + +public class JavaElement { + private String name = ""; + private boolean explored = false; + private JavaElement enclosing = null; + + public JavaElement(String name) { + this.name = name; + } + + public void rename(String newName) { + this.name = newName; + } + + public String getName() { + return name; + } + + public void explored() { + explored = true; + } + + public boolean alreadyExplored() { + return explored; + } + + public void setEnclosing(JavaElement enclosing) { + this.enclosing = enclosing; + } + + public JavaElement getEnclosing() { + return enclosing; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/MethodDeclaration.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/MethodDeclaration.java new file mode 100644 index 0000000..b65a063 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/MethodDeclaration.java @@ -0,0 +1,174 @@ +package test.pseudocode.javaElement; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MethodDeclaration extends JavaElement { + private Class returnType; + private List parameters = new ArrayList<>(); + + /** Invocations in this method body. */ + private List invokees = new ArrayList<>(); + + /** Invocations which invokes this method. */ + private List invokers = new ArrayList<>(); + private List returnStatements = new ArrayList<>(); + + public MethodDeclaration(String methodName, Class returnType, Class... parameters) { + super(methodName); + this.returnType = returnType; + + if (parameters != null) { + this.parameters.addAll(Arrays.asList(parameters)); + } + } + + public void changeReturnType(Class returnType) { + this.returnType = returnType; + } + + public Class getReturnType() { + return returnType; + } + + public List getInvokers() { + return invokers; + } + + public List getInvocations() { + return invokees; + } + + public boolean equals(String name, Class... params) { + if (!getName().equals(name)) + return false; + + if (parameters.size() != params.length) + return false; + + for (int i = 0; i < parameters.size(); i++) { + parameters.get(i).equals(params[i]); + } + + return true; + } + + public MethodInvocation addMethodInvocation(MethodDeclaration method) { + MethodInvocation invocation = new MethodInvocation(this, method); + invokees.add(invocation); + method.invokers.add(invocation); + return invocation; + } + + public void print() { + // Return Type, Method Name, Parameters... + System.out.print(returnType.getName() + " " + getName() + "("); + String paramSum = ""; + for (Class param: parameters) { + if (paramSum.length() != 0) + paramSum += ", "; + paramSum += param.getName(); + } + System.out.print(paramSum + ")"); + + if (invokers.size() != 0) { + // Invoked by ... + System.out.print(", Invoked By: "); + String invokerSum = ""; + for (MethodInvocation invoker: invokers) { + if (invokerSum.length() != 0) + invokerSum += ", "; + invokerSum += invoker.getEnclosing().getEnclosing().getName() + "#"; + invokerSum += invoker.getEnclosing().getName() + "()"; + } + System.out.print(invokerSum); + } + + if (invokees.size() != 0) { + // Invocation in this method body + System.out.print(", Invokes: "); + String invocationSum = ""; + for (MethodInvocation invocation: invokees) { + if (invocationSum.length() != 0) + invocationSum += ", "; + invocationSum += invocation.getDeclaration().getEnclosing().getName() + "#"; + invocationSum += invocation.getDeclaration().getName() + "()"; + } + System.out.print(invocationSum); + } + System.out.println(); + } + + public List getParameterTypes() { + return parameters; + } + + public boolean containsAsParameterType(Class target) { + if (parameters.isEmpty()) { + if (target == null) { + return true; + } + return false; + } + + for (Class parameter: parameters) { + if (parameter.equals(target)) { + return true; + } + } + return false; + } + + public boolean containsAsReturnType(Class target) { + if (returnType == null) { + if (target == null) { + return true; + } + return false; + } + + if (returnType.equals(target)) { + return true; + } + + return false; + } + + public boolean isConstructor() { + if (!getEnclosing().getName().equals(getName())) { + return false; + } + if (!getEnclosing().equals(returnType)) { + return false; + } + return true; + } + + public boolean instantiates(Class target) { + for (MethodInvocation invokee: invokees) { + if (invokee.isConstructor()) { + return true; + } + } + return false; + } + + @Override + public Class getEnclosing() { + return (Class) super.getEnclosing(); + } + + public void addReturnStatement(ReturnStatement statement) { + returnStatements.add(statement); + } + + public List getReturnStatements() { + return returnStatements; + } + + public void addReturnStatement(Class returnValueType) { + ReturnStatement returnStatement = new ReturnStatement(this, returnValueType); + returnStatements.add(returnStatement); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/MethodInvocation.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/MethodInvocation.java new file mode 100644 index 0000000..83b007f --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/MethodInvocation.java @@ -0,0 +1,32 @@ +package test.pseudocode.javaElement; + +public class MethodInvocation extends Statement { + private MethodDeclaration declaration; + + public MethodInvocation(JavaElement enclosing, MethodDeclaration declaration) { + super(declaration.getName()); + setEnclosing(enclosing); + this.declaration = declaration; + } + + @Override + public MethodDeclaration getEnclosing() { + return (MethodDeclaration) super.getEnclosing(); + } + + public MethodDeclaration getDeclaration() { + return declaration; + } + + public boolean isConstructor() { + return declaration.isConstructor(); + } + + public boolean containsAsParameterType(Class target) { + return declaration.containsAsParameterType(target); + } + + public boolean containsAsReturnType(Class target) { + return declaration.containsAsReturnType(target); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/ReturnStatement.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/ReturnStatement.java new file mode 100644 index 0000000..a4c8a31 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/ReturnStatement.java @@ -0,0 +1,19 @@ +package test.pseudocode.javaElement; + +public class ReturnStatement extends Statement { + private Class returnType = null; + + public ReturnStatement(MethodDeclaration enclosing, Class returnType) { + super("return"); + setEnclosing(enclosing); + this.returnType = returnType; + } + + public void setReturnType(Class type) { + this.returnType = type; + } + + public Class getReturnType() { + return returnType; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/Statement.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/Statement.java new file mode 100644 index 0000000..71e1517 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/javaElement/Statement.java @@ -0,0 +1,8 @@ +package test.pseudocode.javaElement; + +public class Statement extends JavaElement { + + public Statement(String name) { + super(name); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/ContractedRefactoring.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/ContractedRefactoring.java new file mode 100644 index 0000000..ceb5f70 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/ContractedRefactoring.java @@ -0,0 +1,96 @@ +package test.pseudocode.refactoring; + +import java.util.ArrayList; +import java.util.List; + +import test.pseudocode.ast.ASTNode; +import test.pseudocode.core.Node; + +public class ContractedRefactoring extends Refactoring { + private List children = new ArrayList<>(); + + public ContractedRefactoring() { + super("Refactoring Composition"); + } + + public ContractedRefactoring(String name) { + super(name); + } + + public void add(Refactoring primitive) { + children.add(primitive); + primitive.setParent(this); + } + + public void addAll(List primitives) { + children.addAll(primitives); + for (Refactoring primitive: primitives) { + primitive.setParent(this); + } + } + + public List getPrimitives() { + return children; + } + + @Override + public boolean isInstanceOf(Class type) { + for (Refactoring primitive: getPrimitives()) { + if (primitive.isInstanceOf(type)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + String nl = System.getProperty("line.separator"); + String result = "[" + getName() + "] to " + getApplicationPoint().toString() + " {" + nl; + if (!getPrimitives().isEmpty()) { + result += " Contains" + nl; + for (Refactoring primitive: getPrimitives()) { + result += " L [" + primitive.getName() + "] to " + primitive.getApplicationPoint().toString() + nl; + } + } + if (!getDependents().isEmpty()) { + result += " Dependents" + nl; + for (Node dep: getDependents()) { + Refactoring ref = (Refactoring) dep; + ASTNode applicationPoint = ref.getApplicationPoint(); + result += " L [" + ref.getName() + "] to " + applicationPoint.toString() + nl; + } + } + result += "}"; + + return result; + } + + public int size() { + return children.size(); + } + + public Refactoring get(int i) { + return children.get(i); + } + + @Override + public ASTNode getApplicationPoint() { + if (!children.isEmpty()) { + return children.get(0).getApplicationPoint(); + } + return null; + } + + public List getDependents() { + List result = new ArrayList<>(); + for (Refactoring primitive: getPrimitives()) { + for (Node dependent: primitive.getDependents()) { + if (!result.contains(dependent)) { + result.add(dependent); + } + } + } + return result; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/HideDelegate.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/HideDelegate.java new file mode 100644 index 0000000..4c4f32a --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/HideDelegate.java @@ -0,0 +1,15 @@ +package test.pseudocode.refactoring; + +import test.pseudocode.ast.ASTNode; +import test.pseudocode.ast.MethodInvocation; + +public class HideDelegate extends PrimitiveRefactoring { + + public HideDelegate(ASTNode applicationPoint) { + super("Hide Delegate", applicationPoint); + } + + public MethodInvocation getApplicationPoint() { + return (MethodInvocation) super.getApplicationPoint(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/IntroduceParameterObject.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/IntroduceParameterObject.java new file mode 100644 index 0000000..90ef20b --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/IntroduceParameterObject.java @@ -0,0 +1,17 @@ +package test.pseudocode.refactoring; + +import test.pseudocode.ast.ASTNode; +import test.pseudocode.ast.MethodDeclaration; + +public class IntroduceParameterObject extends PrimitiveRefactoring { + + public IntroduceParameterObject(ASTNode applicationPoint) { + super("Introduce Parameter Object", applicationPoint); + } + + @Override + public MethodDeclaration getApplicationPoint() { + return (MethodDeclaration) super.getApplicationPoint(); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/IntroduceReturnValueObject.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/IntroduceReturnValueObject.java new file mode 100644 index 0000000..7b86ada --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/IntroduceReturnValueObject.java @@ -0,0 +1,11 @@ +package test.pseudocode.refactoring; + +import test.pseudocode.ast.ASTNode; + +public class IntroduceReturnValueObject extends PrimitiveRefactoring { + + public IntroduceReturnValueObject(ASTNode applicationPoint) { + super("Introduce Return Value Object", applicationPoint); + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/PreserveWholeObject.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/PreserveWholeObject.java new file mode 100644 index 0000000..849cc09 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/PreserveWholeObject.java @@ -0,0 +1,16 @@ +package test.pseudocode.refactoring; + +import test.pseudocode.ast.ASTNode; +import test.pseudocode.ast.MethodInvocation; + +public class PreserveWholeObject extends PrimitiveRefactoring { + + public PreserveWholeObject(ASTNode applicationPoint) { + super("Preserve Whole Object", applicationPoint); + } + + @Override + public MethodInvocation getApplicationPoint() { + return (MethodInvocation) super.getApplicationPoint(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/PrimitiveRefactoring.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/PrimitiveRefactoring.java new file mode 100644 index 0000000..1ca964d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/PrimitiveRefactoring.java @@ -0,0 +1,59 @@ +package test.pseudocode.refactoring; + +import java.util.ArrayList; +import java.util.List; + +import test.pseudocode.ast.ASTNode; +import test.pseudocode.core.Node; + +public abstract class PrimitiveRefactoring extends Refactoring { + private ASTNode applicationPoint; + private List dependents = new ArrayList<>(); + + public PrimitiveRefactoring(String name, ASTNode applicationPoint) { + super(name); + this.applicationPoint = applicationPoint; + } + + public ASTNode getApplicationPoint() { + return applicationPoint; + } + + @Override + public boolean isInstanceOf(Class type) { + return type.isInstance(this); + } + + @Override + public String toString() { + String result = "[" + getName() + "] to " + getApplicationPoint().toString(); + + if (!getDependents().isEmpty()) { + String nl = System.getProperty("line.separator"); + result += " {" + nl + " Dependents" + nl; + for (Node dep: getDependents()) { + Refactoring ref = (Refactoring) dep; + ASTNode applicationPoint = ref.getApplicationPoint(); + result += " L [" + ref.getName() + "] to " + applicationPoint.toString() + nl; + } + result += "}"; + } + return result; + } + + public void dependsOn(Refactoring refactroing) { + dependents.add(refactroing); + } + + public void dependsOn(List refactorings) { + dependents.addAll(refactorings); + } + + public List getDependents() { + List result = new ArrayList<>(); + for (Node dependent: dependents) { + result.add(((Refactoring) dependent).getRoot()); + } + return result; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/Refactoring.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/Refactoring.java new file mode 100644 index 0000000..af95059 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/Refactoring.java @@ -0,0 +1,46 @@ +package test.pseudocode.refactoring; + +import test.pseudocode.ast.ASTNode; +import test.pseudocode.core.Node; + +public abstract class Refactoring implements Node { + protected String name = ""; + private boolean visited = false; + private Refactoring parent = null; + + public Refactoring(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public abstract boolean isInstanceOf(Class type); + + public abstract ASTNode getApplicationPoint(); + public abstract String toString(); + + public void visited() { + this.visited = true; + } + + public boolean isNotVisited() { + return !visited; + } + + public Refactoring getRoot() { + if (parent == null) { + return this; + } + return parent.getRoot(); + } + + public Refactoring getParent() { + return parent; + } + + public void setParent(Refactoring parent) { + this.parent = parent; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/ReplaceTypeByHiding.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/ReplaceTypeByHiding.java new file mode 100644 index 0000000..6f856d0 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/ReplaceTypeByHiding.java @@ -0,0 +1,10 @@ +package test.pseudocode.refactoring; + +import test.pseudocode.ast.ASTNode; + +public class ReplaceTypeByHiding extends PrimitiveRefactoring { + + public ReplaceTypeByHiding(ASTNode applicationPoint) { + super("Replace Type by Hiding", applicationPoint); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/ReturnWholeObject.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/ReturnWholeObject.java new file mode 100644 index 0000000..a0101a6 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/refactoring/ReturnWholeObject.java @@ -0,0 +1,16 @@ +package test.pseudocode.refactoring; + +import test.pseudocode.ast.ASTNode; +import test.pseudocode.ast.ReturnValue; + +public class ReturnWholeObject extends PrimitiveRefactoring { + + public ReturnWholeObject(ASTNode applicationPoint) { + super("Return Whole Object", applicationPoint); + } + + @Override + public ReturnValue getApplicationPoint() { + return (ReturnValue) super.getApplicationPoint(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase1Factory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase1Factory.java new file mode 100644 index 0000000..3204945 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase1Factory.java @@ -0,0 +1,86 @@ +package test.pseudocode.testCase; + +import test.pseudocode.ast.Assignment; +import test.pseudocode.ast.Expression; +import test.pseudocode.ast.FieldAccess; +import test.pseudocode.ast.FieldDeclaration; +import test.pseudocode.ast.MethodDeclaration; +import test.pseudocode.ast.MethodInvocation; +import test.pseudocode.ast.ThisExpression; +import test.pseudocode.ast.TypeDeclaration; +import test.pseudocode.ast.VariableAccess; +import test.pseudocode.ast.VariableDeclaration; + +public class TestCase1Factory extends TestCaseModelFactory { + + @Override + public void create() { + // GraphicsContext3D + TypeDeclaration graphicsContext3d = new TypeDeclaration("GraphicsContext3D"); + setTarget(graphicsContext3d); + // Constructor + MethodDeclaration gcConst = new MethodDeclaration(graphicsContext3d.getName(), graphicsContext3d, (VariableDeclaration[]) null); + graphicsContext3d.addDeclaration(gcConst); + // setModelTransform() + MethodDeclaration gcSetModelTransform = new MethodDeclaration("setModelTransform", null, (VariableDeclaration[]) null); + graphicsContext3d.addDeclaration(gcSetModelTransform); + // setModelTransform() + MethodDeclaration gcDraw = new MethodDeclaration("draw", null, (VariableDeclaration[]) null); + graphicsContext3d.addDeclaration(gcDraw); + // numLights() + MethodDeclaration gcNumLights = new MethodDeclaration("numLights", null, (VariableDeclaration[]) null); + graphicsContext3d.addDeclaration(gcNumLights); + // addLight() + MethodDeclaration gcAddLight = new MethodDeclaration("addLight", null, (VariableDeclaration[]) null); + graphicsContext3d.addDeclaration(gcAddLight); + + // ObjectRenderer + TypeDeclaration or = new TypeDeclaration("ObjectRenderer"); + FieldDeclaration orGc = new FieldDeclaration(graphicsContext3d, "graphicsContext3D"); + or.addDeclaration(orGc); + // Constructor + VariableDeclaration orParGc3d = new VariableDeclaration(graphicsContext3d, "graphicsContext3D"); + MethodDeclaration orConst = new MethodDeclaration(or.getName(), or, orParGc3d); + or.addDeclaration(orConst); + Assignment orConstAssign = new Assignment(new FieldAccess(orGc), new VariableAccess(orParGc3d)); + orConst.addExpression(orConstAssign); + // postVisit() + MethodDeclaration orPostVisit = new MethodDeclaration("postVisit", null, (VariableDeclaration[]) null); + or.addDeclaration(orPostVisit); + orPostVisit.addExpression(new MethodInvocation(new FieldAccess(orGc), gcSetModelTransform, (Expression[]) null)); + orPostVisit.addExpression(new MethodInvocation(new FieldAccess(orGc), gcDraw, (Expression[]) null)); + + // SceneViewer + TypeDeclaration sceneViewer = new TypeDeclaration("SceneViewer"); + // renderField() + VariableDeclaration svRenderFieldParGc = new VariableDeclaration(graphicsContext3d, "graphicsContext3D"); + MethodDeclaration svRenderField = new MethodDeclaration("renderField", null, svRenderFieldParGc); + sceneViewer.addDeclaration(svRenderField); + svRenderField.addExpression(new MethodInvocation(new VariableAccess(svRenderFieldParGc), gcNumLights, (Expression[]) null)); + svRenderField.addExpression(new MethodInvocation(new VariableAccess(svRenderFieldParGc), gcAddLight, (Expression[]) null)); + + svRenderField.addExpression(new MethodInvocation(null, orConst, new VariableAccess(svRenderFieldParGc))); + svRenderField.addExpression(new MethodInvocation(new VariableAccess(svRenderFieldParGc), gcSetModelTransform, (Expression[]) null)); + svRenderField.addExpression(new MethodInvocation(null, orConst, new VariableAccess(svRenderFieldParGc))); + svRenderField.addExpression(new MethodInvocation(new VariableAccess(svRenderFieldParGc), gcDraw, (Expression[]) null)); + + svRenderField.addExpression(new MethodInvocation(null, orConst, new VariableAccess(svRenderFieldParGc))); + svRenderField.addExpression(new MethodInvocation(new VariableAccess(svRenderFieldParGc), gcSetModelTransform, (Expression[]) null)); + svRenderField.addExpression(new MethodInvocation(new VariableAccess(svRenderFieldParGc), gcDraw, (Expression[]) null)); + + svRenderField.addExpression(new MethodInvocation(null, orConst, new VariableAccess(svRenderFieldParGc))); + + // RWTCanvas3D + TypeDeclaration canvas3d = new TypeDeclaration("RWTCanvas3D"); + // getGraphicsContext3D() + MethodDeclaration getGraphicsContext3d = new MethodDeclaration("getGraphicsContext3D", graphicsContext3d, (VariableDeclaration[]) null); + // renderField() + MethodDeclaration renderField = new MethodDeclaration("renderField", null, (VariableDeclaration[]) null); + canvas3d.addDeclaration(renderField); + VariableDeclaration bg = new VariableDeclaration(sceneViewer, "bg"); + renderField.addExpression(new MethodInvocation(new VariableAccess(bg), svRenderField, new MethodInvocation(new ThisExpression(canvas3d), getGraphicsContext3d, (Expression[]) null))); + + addCfrom(sceneViewer); + addCfrom(or); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase2Factory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase2Factory.java new file mode 100644 index 0000000..6415b36 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase2Factory.java @@ -0,0 +1,70 @@ +package test.pseudocode.testCase; + +import test.pseudocode.ast.Assignment; +import test.pseudocode.ast.Expression; +import test.pseudocode.ast.FieldAccess; +import test.pseudocode.ast.FieldDeclaration; +import test.pseudocode.ast.MethodDeclaration; +import test.pseudocode.ast.MethodInvocation; +import test.pseudocode.ast.ReturnValue; +import test.pseudocode.ast.TypeDeclaration; +import test.pseudocode.ast.VariableAccess; +import test.pseudocode.ast.VariableDeclaration; + +public class TestCase2Factory extends TestCaseModelFactory { + + @Override + public void create() { + // Class E + TypeDeclaration e = new TypeDeclaration("E"); // Target Class + MethodDeclaration eConstructor = new MethodDeclaration(e.getName(), e, (VariableDeclaration[]) null); + e.addDeclaration(eConstructor); + setTarget(e); + + // Class D + TypeDeclaration d = new TypeDeclaration("D"); + // Field + FieldDeclaration de = new FieldDeclaration(e, "e"); + d.addDeclaration(de); + // Method setE() + VariableDeclaration dSetEe = new VariableDeclaration(e, "e"); + MethodDeclaration dSetE = new MethodDeclaration("setE", null, dSetEe); + d.addDeclaration(dSetE); + dSetE.addExpression(new Assignment(new FieldAccess(de), new VariableAccess(dSetEe))); + + // Class C + TypeDeclaration c = new TypeDeclaration("C"); + MethodDeclaration cCreateE = new MethodDeclaration("createE", e, (VariableDeclaration[]) null); + c.addDeclaration(cCreateE); + cCreateE.addExpression(new ReturnValue(new MethodInvocation(null, eConstructor, (Expression[]) null))); + + // Class B + TypeDeclaration b = new TypeDeclaration("B"); + // Field + FieldDeclaration bc = new FieldDeclaration(c, "c"); + b.addDeclaration(bc); + // Method getE() + MethodDeclaration bGetE = new MethodDeclaration("getE", e, (VariableDeclaration[]) null); + b.addDeclaration(bGetE); + bGetE.addExpression(new ReturnValue(new MethodInvocation(new FieldAccess(bc), cCreateE, (Expression[]) null))); + + // Class A + TypeDeclaration a = new TypeDeclaration("A"); + // Fields + FieldDeclaration ab = new FieldDeclaration(b, "b"); + a.addDeclaration(ab); + FieldDeclaration ad = new FieldDeclaration(d, "d"); + a.addDeclaration(ad); + // Method m() + MethodDeclaration am = new MethodDeclaration("m", null, (VariableDeclaration[]) null); + a.addDeclaration(am); + VariableDeclaration ame = new VariableDeclaration(e, "e"); + Assignment amAssignE = new Assignment(ame, new MethodInvocation(new FieldAccess(ab), bGetE, (Expression[]) null)); + am.addExpression(amAssignE); + am.addExpression(new MethodInvocation(new FieldAccess(ad), dSetE, new VariableAccess(ame))); + + addCfrom(a); + addCfrom(b); + addCfrom(d); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase3Factory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase3Factory.java new file mode 100644 index 0000000..3399cf6 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase3Factory.java @@ -0,0 +1,33 @@ +package test.pseudocode.testCase; + +public class TestCase3Factory extends TestCaseModelFactory { + + @Override + public void create() { +// TypeDeclaration t = new TypeDeclaration("T"); // Target Class +// setTarget(t); +// +// TypeDeclaration c = new TypeDeclaration("C"); +// MethodDeclaration cSetT = c.addMethod("setT", null, t); +// +// TypeDeclaration b = new TypeDeclaration("B"); +// MethodDeclaration bSetT = b.addMethod("setT", null, t); +// bSetT.addMethodInvocationOf(cSetT); +// +// TypeDeclaration a = new TypeDeclaration("A"); +// MethodDeclaration am = a.addMethod("m", null, (Class[]) null); +// am.addMethodInvocationOf(bSetT); +// +// TypeDeclaration e = new TypeDeclaration("E"); +// MethodDeclaration eSetT = e.addMethod("setT", null, t); +// eSetT.addMethodInvocationOf(cSetT); +// +// TypeDeclaration d = new TypeDeclaration("D"); +// MethodDeclaration dm = d.addMethod("m", null, (Class[]) null); +// dm.addMethodInvocationOf(eSetT); +// +// addCfrom(b); +// addCfrom(c); +// addCfrom(e); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase4Factory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase4Factory.java new file mode 100644 index 0000000..ba6055d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase4Factory.java @@ -0,0 +1,38 @@ +package test.pseudocode.testCase; + +public class TestCase4Factory extends TestCaseModelFactory { + + @Override + public void create() { +// TypeDeclaration t = new TypeDeclaration("T"); // Target Class +// setTarget(t); +// +// TypeDeclaration c = new TypeDeclaration("C"); +// MethodDeclaration cSetT = c.addMethod("setT", null, t); +// +// TypeDeclaration f = new TypeDeclaration("F"); +// MethodDeclaration fSetT = f.addMethod("setT", null, t); +// +// TypeDeclaration e = new TypeDeclaration("E"); +// MethodDeclaration eSetT = e.addMethod("setT", null, t); +// eSetT.addMethodInvocationOf(fSetT); +// eSetT.addMethodInvocationOf(cSetT); +// +// TypeDeclaration b = new TypeDeclaration("B"); +// MethodDeclaration bSetT = b.addMethod("setT", null, t); +// bSetT.addMethodInvocationOf(cSetT); +// +// TypeDeclaration a = new TypeDeclaration("A"); +// MethodDeclaration am = a.addMethod("m", null, (TypeDeclaration[]) null); +// am.addMethodInvocationOf(bSetT); +// +// TypeDeclaration d = new TypeDeclaration("D"); +// MethodDeclaration dm = d.addMethod("m", null, (TypeDeclaration[]) null); +// dm.addMethodInvocationOf(eSetT); +// +// addCfrom(b); +// addCfrom(c); +// addCfrom(e); +// addCfrom(f); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase5Factory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase5Factory.java new file mode 100644 index 0000000..07a90a9 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCase5Factory.java @@ -0,0 +1,43 @@ +package test.pseudocode.testCase; + +public class TestCase5Factory extends TestCaseModelFactory { + + @Override + public void create() { +// TypeDeclaration t = new TypeDeclaration("T"); // Target Class +// setTarget(t); +// +// TypeDeclaration h = new TypeDeclaration("H"); +// MethodDeclaration hSetT = h.addMethod("setT", null, t); +// +// TypeDeclaration d = new TypeDeclaration("D"); +// MethodDeclaration dSetT = d.addMethod("setT", null, t); +// +// TypeDeclaration g = new TypeDeclaration("G"); +// MethodDeclaration gSetT = g.addMethod("setT", null, t); +// gSetT.addMethodInvocationOf(hSetT); +// gSetT.addMethodInvocationOf(dSetT); +// +// TypeDeclaration e = new TypeDeclaration("E"); +// MethodDeclaration em = e.addMethod("m", null, (TypeDeclaration[]) null); +// em.addMethodInvocationOf(gSetT); +// +// TypeDeclaration c = new TypeDeclaration("C"); +// MethodDeclaration cSetT = c.addMethod("setT", null, t); +// cSetT.addMethodInvocationOf(dSetT); +// +// TypeDeclaration b = new TypeDeclaration("B"); +// MethodDeclaration bSetT = b.addMethod("setT", null, t); +// bSetT.addMethodInvocationOf(cSetT); +// bSetT.addMethodInvocationOf(gSetT); +// +// TypeDeclaration a = new TypeDeclaration("A"); +// MethodDeclaration am = a.addMethod("m", null, (TypeDeclaration[]) null); +// am.addMethodInvocationOf(bSetT); +// +// addCfrom(b); +// addCfrom(c); +// addCfrom(g); +// addCfrom(h); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCaseModelFactory.java b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCaseModelFactory.java new file mode 100644 index 0000000..9bc324a --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/pseudocode/testCase/TestCaseModelFactory.java @@ -0,0 +1,42 @@ +package test.pseudocode.testCase; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import test.pseudocode.ast.TypeDeclaration; + +public abstract class TestCaseModelFactory { + protected TypeDeclaration target = null; + protected List cFrom = new ArrayList<>(); + + public abstract void create(); + + /** �N���X������A�Ԃ��擾���� */ + public int getCaseNumber() { + String name = this.getClass().getSimpleName(); + Pattern pattern = Pattern.compile("(?!\\D)(\\d+)(?=\\D+)"); + Matcher matcher = pattern.matcher(name); + if (matcher.find()) { + return Integer.valueOf(matcher.group(0)); + } + return -1; + } + + public TypeDeclaration getTarget() { + return target; + } + + public void setTarget(TypeDeclaration target) { + this.target = target; + } + + public void addCfrom(TypeDeclaration element) { + cFrom.add(element); + } + + public List getCFrom() { + return cFrom; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/searchClassByUsingSearchEngine/CallersSearchRequestor.java b/org.ntlab.refactoring.decouplingClasses/src/test/searchClassByUsingSearchEngine/CallersSearchRequestor.java new file mode 100644 index 0000000..da30a76 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/searchClassByUsingSearchEngine/CallersSearchRequestor.java @@ -0,0 +1,61 @@ +package test.searchClassByUsingSearchEngine; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.search.SearchMatch; +import org.eclipse.jdt.core.search.SearchParticipant; +import org.eclipse.jdt.core.search.SearchRequestor; + +public class CallersSearchRequestor extends SearchRequestor { + private List callers = new ArrayList(); + + @Override + public void acceptSearchMatch(SearchMatch match) throws CoreException { + if (match.getElement() == null) { + return; + } + + if (match.getElement() instanceof IMember) { + IMember member = (IMember) match.getElement(); + switch (member.getElementType()) { + case IJavaElement.METHOD: + case IJavaElement.TYPE: + case IJavaElement.FIELD: + case IJavaElement.INITIALIZER: + callers.add(member); + break; + } + System.out.println(); + } + } + + @Override + public void beginReporting() { + System.out.println(this.getClass().getSimpleName() + "#beginReporting()"); + } + + @Override + public void endReporting() { + System.out.println(this.getClass().getSimpleName() + "#endReporting()"); + } + + @Override + public void enterParticipant(SearchParticipant participant) { + System.out.println(this.getClass().getSimpleName() + "#enterParticipant()"); + } + + @Override + public void exitParticipant(SearchParticipant participant) { + System.out.println(this.getClass().getSimpleName() + "#exitParticipant()"); + } + + public List getCallers() { + return callers; + } + + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/test/searchClassByUsingSearchEngine/SearchClassByUsingSearchEngineTest.java b/org.ntlab.refactoring.decouplingClasses/src/test/searchClassByUsingSearchEngine/SearchClassByUsingSearchEngineTest.java new file mode 100644 index 0000000..82aec71 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/test/searchClassByUsingSearchEngine/SearchClassByUsingSearchEngineTest.java @@ -0,0 +1,85 @@ +package test.searchClassByUsingSearchEngine; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.core.search.SearchParticipant; +import org.eclipse.jdt.core.search.SearchPattern; + +public class SearchClassByUsingSearchEngineTest { + + public void search(IJavaElement calee, IProgressMonitor monitor) { + SearchPattern pattern = SearchPattern.createPattern( + calee, + IJavaSearchConstants.REFERENCES, + SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH); + SearchParticipant[] participant = new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }; + IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); + CallersSearchRequestor requestor = new CallersSearchRequestor(); + + try { + new SearchEngine().search(pattern, participant, scope, requestor, monitor); + } catch (CoreException e) { + e.printStackTrace(); + } + + System.out.println(this.getClass().getSimpleName() + "#execute()"); + System.out.println("[Calee]"); + System.out.println("Name: " + calee.getElementName()); + System.out.println("Type: " + typeConstantToString(calee.getElementType())); + System.out.println("Parent Name: " + calee.getParent().getElementName()); + System.out.println("Parent Type: " + typeConstantToString(calee.getParent().getElementType())); + System.out.println(); + + System.out.println("[Caller]"); + for (IMember caller: requestor.getCallers()) { + System.out.println("Name: " + caller.getElementName()); + System.out.println("Type: " + typeConstantToString(caller.getElementType())); + System.out.println("Parent Name: " + caller.getParent().getElementName()); + System.out.println("Parent Type: " + typeConstantToString(caller.getParent().getElementType())); + } + } + + private String typeConstantToString(int typeConstant) { + switch (typeConstant) { + case IJavaElement.JAVA_MODEL: + return "JavaModel"; + case IJavaElement.JAVA_PROJECT: + return "JavaProject"; + case IJavaElement.PACKAGE_FRAGMENT_ROOT: + return "PackageFragmentRoot"; + case IJavaElement.PACKAGE_FRAGMENT: + return "PackageFragment"; + case IJavaElement.COMPILATION_UNIT: + return "CompilationUnit"; + case IJavaElement.CLASS_FILE: + return "ClassFile"; + case IJavaElement.TYPE: + return "Type"; + case IJavaElement.FIELD: + return "Field"; + case IJavaElement.METHOD: + return "Method"; + case IJavaElement.INITIALIZER: + return "Initializer"; + case IJavaElement.PACKAGE_DECLARATION: + return "PackageDeclaration"; + case IJavaElement.IMPORT_CONTAINER: + return "ImportContainer"; + case IJavaElement.IMPORT_DECLARATION: + return "ImportDeclaration"; + case IJavaElement.LOCAL_VARIABLE: + return "LocalVariable"; + case IJavaElement.TYPE_PARAMETER: + return "TypeParameter"; + case IJavaElement.ANNOTATION: + return "Annotation"; + } + return "Unknown"; + } + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/A.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/A.java new file mode 100644 index 0000000..a35875c --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/A.java @@ -0,0 +1,11 @@ +package testCase1.after; + +public class A { + B b = new B(); + D d = new D(); + + public void m() { + F f = b.getF(); + d.setF(f); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/B.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/B.java new file mode 100644 index 0000000..d60a999 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/B.java @@ -0,0 +1,9 @@ +package testCase1.after; + +public class B { + C c = new C(); + + public F getF() { + return c.createF(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/C.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/C.java new file mode 100644 index 0000000..9ad0eb1 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/C.java @@ -0,0 +1,8 @@ +package testCase1.after; + +public class C { + + public F createF() { + return new F(new E()); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/D.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/D.java new file mode 100644 index 0000000..83a0480 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/D.java @@ -0,0 +1,9 @@ +package testCase1.after; + +public class D { + F f = null; + + public void setF(F f) { + this.f = f; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/E.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/E.java new file mode 100644 index 0000000..2efcd00 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/E.java @@ -0,0 +1,5 @@ +package testCase1.after; + +public class E { + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/F.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/F.java new file mode 100644 index 0000000..d99ac37 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/F.java @@ -0,0 +1,13 @@ +package testCase1.after; + +public class F { + E e = null; + + public F(E f) { + this.e = f; + } + + public E getE() { + return e; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/Start.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/Start.java new file mode 100644 index 0000000..d7b330a --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/after/Start.java @@ -0,0 +1,8 @@ +package testCase1.after; + +public class Start { + + public static void main(String[] args) { + new A().m(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/A.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/A.java new file mode 100644 index 0000000..664aa4b --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/A.java @@ -0,0 +1,11 @@ +package testCase1.before; + +public class A { + B b = new B(); + D d = new D(); + + public void m() { + E e = b.getE(); + d.setE(e); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/B.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/B.java new file mode 100644 index 0000000..732635d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/B.java @@ -0,0 +1,9 @@ +package testCase1.before; + +public class B { + C c = new C(); + + public E getE() { + return c.createE(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/C.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/C.java new file mode 100644 index 0000000..ff23a0f --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/C.java @@ -0,0 +1,8 @@ +package testCase1.before; + +public class C { + + public E createE() { + return new E(); + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/D.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/D.java new file mode 100644 index 0000000..f2ca83d --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/D.java @@ -0,0 +1,9 @@ +package testCase1.before; + +public class D { + E e = null; + + public void setE(E e) { + this.e = e; + } +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/E.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/E.java new file mode 100644 index 0000000..e9ab227 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/E.java @@ -0,0 +1,5 @@ +package testCase1.before; + +public class E { + +} diff --git a/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/Start.java b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/Start.java new file mode 100644 index 0000000..7dd8f86 --- /dev/null +++ b/org.ntlab.refactoring.decouplingClasses/src/testCase1/before/Start.java @@ -0,0 +1,8 @@ +package testCase1.before; + +public class Start { + + public static void main(String[] args) { + new A().m(); + } +}