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 index 6f3f647..682096d 100644 --- a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringProcessor.java +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/DecoupleClassesRefactoringProcessor.java @@ -137,7 +137,7 @@ taskGenerator.setAllClients(descriptor.getClients()); taskGenerator.setTargetClass(descriptor.getTargetType()); refactoringTasks = taskGenerator.generateTasks(); - + new DepthFirstTopologicalSorter().sort(refactoringTasks); for (int i = 0; i < refactoringTasks.size(); i++) { 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 index ad81c52..8806be6 100644 --- a/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/RefactoringTaskGenerator.java +++ b/org.ntlab.refactoring.decouplingClasses/src/org/ntlab/refactoring/decouplingClasses/RefactoringTaskGenerator.java @@ -24,6 +24,7 @@ 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.VariableDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationStatement; import org.ntlab.refactoring.decouplingClasses.refactoringApplication.ContractedRefactoring; import org.ntlab.refactoring.decouplingClasses.refactoringApplication.HideDelegate; @@ -48,7 +49,7 @@ public List generateTasks() { refactoringTasks.clear(); - exploreClasses(); + exploreClasses2(); resolveDependenceOfTasks(); contractRefactorings(); @@ -300,6 +301,196 @@ } } + private void exploreClasses2() { + ASTParser parser = ASTParser.newParser(AST.JLS8); + + parser.setKind(ASTParser.K_COMPILATION_UNIT); + + for (IType clientType: cFrom) { + parser.setSource(clientType.getCompilationUnit()); + parser.setResolveBindings(true); + parser.setBindingsRecovery(true); + + 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() { + private CompilationUnit cu; + + @Override + public boolean visit(MethodDeclaration node) { + for (Object obj: node.parameters()) { + IMethodBinding methodBinding = node.resolveBinding(); + 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, cu)); + 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, cu)); + } + 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, cu)); + } + 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, mDec, cu)); + } + + 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; @@ -330,76 +521,76 @@ @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})); - // } - // } + // �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 = (TypeDeclaration) 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 = (TypeDeclaration) 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 = (TypeDeclaration) 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) { 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 index 02f4c41..f6b34a6 100644 --- 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 @@ -1,15 +1,29 @@ package org.ntlab.refactoring.decouplingClasses.refactoringApplication; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.Type; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.refactoring.IJavaRefactorings; +import org.eclipse.jdt.core.refactoring.descriptors.IntroduceParameterObjectDescriptor; +import org.eclipse.jdt.core.refactoring.descriptors.RenameJavaElementDescriptor; import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.core.refactoring.RefactoringContribution; +import org.eclipse.ltk.core.refactoring.RefactoringCore; import org.eclipse.ltk.core.refactoring.RefactoringStatus; public class IntroduceParameterObject extends PrimitiveRefactoring { + MethodDeclaration methodDecl; public IntroduceParameterObject(ASTNode applicationPoint, CompilationUnit cu) { super("Introduce Parameter Object", applicationPoint, cu); @@ -35,6 +49,26 @@ @Override public Change perform(IProgressMonitor pm) throws CoreException { System.out.println("perform: " + getName()); + + IPath path = cu.getJavaElement().getPath(); + ASTRewrite rewrite = ASTRewrite.create(cu.getAST()); + ASTNode node = getNode(); + AST ast = methodDecl.getAST(); + Type t = ast.newSimpleType(ast.newSimpleName(wrapperClass.getName().toString())); + rewrite.set(methodDecl, MethodDeclaration.RETURN_TYPE2_PROPERTY, t, null); + + IMethodBinding methodBinding = methodDecl.resolveBinding(); + IMethod iMethod = (IMethod) methodBinding.getJavaElement(); + + ICompilationUnit cu = iMethod.getCompilationUnit(); + + RefactoringContribution contribution = + RefactoringCore.getRefactoringContribution(IJavaRefactorings.INTRODUCE_PARAMETER_OBJECT); + IntroduceParameterObjectDescriptor descriptor = + (IntroduceParameterObjectDescriptor) contribution.createDescriptor(); + + RefactoringStatus status = new RefactoringStatus(); + Refactoring refactoring = descriptor.createRefactoring(status); return null; }